diff options
Diffstat (limited to 'apps')
-rw-r--r-- | apps/codecs/libwma/wmadec.h | 13 | ||||
-rw-r--r-- | apps/codecs/libwma/wmadeci.c | 105 | ||||
-rw-r--r-- | apps/codecs/wma.c | 51 |
3 files changed, 104 insertions, 65 deletions
diff --git a/apps/codecs/libwma/wmadec.h b/apps/codecs/libwma/wmadec.h index e23d7c20b0..fd2d63c9d4 100644 --- a/apps/codecs/libwma/wmadec.h +++ b/apps/codecs/libwma/wmadec.h | |||
@@ -137,6 +137,11 @@ typedef struct WMADecodeContext | |||
137 | fixed64 lsp_pow_m_table1[(1 << LSP_POW_BITS)]; | 137 | fixed64 lsp_pow_m_table1[(1 << LSP_POW_BITS)]; |
138 | fixed64 lsp_pow_m_table2[(1 << LSP_POW_BITS)]; | 138 | fixed64 lsp_pow_m_table2[(1 << LSP_POW_BITS)]; |
139 | 139 | ||
140 | /* State of current superframe decoding */ | ||
141 | int bit_offset; | ||
142 | int nb_frames; | ||
143 | int current_frame; | ||
144 | |||
140 | #ifdef TRACE | 145 | #ifdef TRACE |
141 | 146 | ||
142 | int frame_count; | 147 | int frame_count; |
@@ -145,7 +150,9 @@ typedef struct WMADecodeContext | |||
145 | WMADecodeContext; | 150 | WMADecodeContext; |
146 | 151 | ||
147 | int wma_decode_init(WMADecodeContext* s, asf_waveformatex_t *wfx); | 152 | int wma_decode_init(WMADecodeContext* s, asf_waveformatex_t *wfx); |
148 | int wma_decode_superframe(WMADecodeContext* s, | 153 | int wma_decode_superframe_init(WMADecodeContext* s, |
149 | void *data, int *data_size, | 154 | uint8_t *buf, int buf_size); |
150 | uint8_t *buf, int buf_size); | 155 | int wma_decode_superframe_frame(WMADecodeContext* s, |
156 | int16_t *samples, | ||
157 | uint8_t *buf, int buf_size); | ||
151 | #endif | 158 | #endif |
diff --git a/apps/codecs/libwma/wmadeci.c b/apps/codecs/libwma/wmadeci.c index c266316cf9..1a7081fd29 100644 --- a/apps/codecs/libwma/wmadeci.c +++ b/apps/codecs/libwma/wmadeci.c | |||
@@ -935,6 +935,9 @@ int wma_decode_init(WMADecodeContext* s, asf_waveformatex_t *wfx) | |||
935 | init_coef_vlc(&s->coef_vlc[1], &s->run_table[1], &s->level_table[1], | 935 | init_coef_vlc(&s->coef_vlc[1], &s->run_table[1], &s->level_table[1], |
936 | &coef_vlcs[coef_vlc_table * 2 + 1], 1); | 936 | &coef_vlcs[coef_vlc_table * 2 + 1], 1); |
937 | 937 | ||
938 | s->last_superframe_len = 0; | ||
939 | s->last_bitoffset = 0; | ||
940 | |||
938 | return 0; | 941 | return 0; |
939 | } | 942 | } |
940 | 943 | ||
@@ -1666,42 +1669,67 @@ static int wma_decode_frame(WMADecodeContext *s, int16_t *samples) | |||
1666 | return 0; | 1669 | return 0; |
1667 | } | 1670 | } |
1668 | 1671 | ||
1669 | int wma_decode_superframe(WMADecodeContext* s, | 1672 | /* Initialise the superframe decoding */ |
1670 | void *data, /*output*/ | ||
1671 | int *data_size, | ||
1672 | uint8_t *buf, /*input*/ | ||
1673 | int buf_size) | ||
1674 | { | ||
1675 | //WMADecodeContext *s = avctx->priv_data; | ||
1676 | int nb_frames, bit_offset, i, pos, len; | ||
1677 | uint8_t *q; | ||
1678 | int16_t *samples; | ||
1679 | 1673 | ||
1674 | int wma_decode_superframe_init(WMADecodeContext* s, | ||
1675 | uint8_t *buf, /*input*/ | ||
1676 | int buf_size) | ||
1677 | { | ||
1680 | if (buf_size==0) | 1678 | if (buf_size==0) |
1681 | { | 1679 | { |
1682 | s->last_superframe_len = 0; | 1680 | s->last_superframe_len = 0; |
1683 | return 0; | 1681 | return 0; |
1684 | } | 1682 | } |
1685 | 1683 | ||
1686 | samples = data; | 1684 | s->current_frame = 0; |
1685 | |||
1687 | init_get_bits(&s->gb, buf, buf_size*8); | 1686 | init_get_bits(&s->gb, buf, buf_size*8); |
1687 | |||
1688 | if (s->use_bit_reservoir) | 1688 | if (s->use_bit_reservoir) |
1689 | { | 1689 | { |
1690 | /* read super frame header */ | 1690 | /* read super frame header */ |
1691 | get_bits(&s->gb, 4); /* super frame index */ | 1691 | get_bits(&s->gb, 4); /* super frame index */ |
1692 | nb_frames = get_bits(&s->gb, 4) - 1; | 1692 | s->nb_frames = get_bits(&s->gb, 4); |
1693 | |||
1694 | if (s->last_superframe_len == 0) | ||
1695 | s->nb_frames --; | ||
1696 | else if (s->nb_frames == 0) | ||
1697 | s->nb_frames++; | ||
1698 | |||
1699 | s->bit_offset = get_bits(&s->gb, s->byte_offset_bits + 3); | ||
1700 | } else { | ||
1701 | s->nb_frames = 1; | ||
1702 | } | ||
1693 | 1703 | ||
1694 | bit_offset = get_bits(&s->gb, s->byte_offset_bits + 3); | 1704 | return 1; |
1705 | } | ||
1706 | |||
1707 | |||
1708 | /* Decode a single frame in the current superframe - return -1 if | ||
1709 | there was a decoding error, or the number of samples decoded. | ||
1710 | */ | ||
1711 | |||
1712 | int wma_decode_superframe_frame(WMADecodeContext* s, | ||
1713 | int16_t* samples, /*output*/ | ||
1714 | uint8_t *buf, /*input*/ | ||
1715 | int buf_size) | ||
1716 | { | ||
1717 | int pos, len; | ||
1718 | uint8_t *q; | ||
1719 | int done = 0; | ||
1720 | |||
1721 | if ((s->use_bit_reservoir) && (s->current_frame == 0)) | ||
1722 | { | ||
1695 | if (s->last_superframe_len > 0) | 1723 | if (s->last_superframe_len > 0) |
1696 | { | 1724 | { |
1697 | /* add bit_offset bits to last frame */ | 1725 | /* add s->bit_offset bits to last frame */ |
1698 | if ((s->last_superframe_len + ((bit_offset + 7) >> 3)) > | 1726 | if ((s->last_superframe_len + ((s->bit_offset + 7) >> 3)) > |
1699 | MAX_CODED_SUPERFRAME_SIZE) | 1727 | MAX_CODED_SUPERFRAME_SIZE) |
1700 | { | 1728 | { |
1701 | goto fail; | 1729 | goto fail; |
1702 | } | 1730 | } |
1703 | q = s->last_superframe + s->last_superframe_len; | 1731 | q = s->last_superframe + s->last_superframe_len; |
1704 | len = bit_offset; | 1732 | len = s->bit_offset; |
1705 | while (len > 0) | 1733 | while (len > 0) |
1706 | { | 1734 | { |
1707 | *q++ = (get_bits)(&s->gb, 8); | 1735 | *q++ = (get_bits)(&s->gb, 8); |
@@ -1712,39 +1740,46 @@ int wma_decode_superframe(WMADecodeContext* s, | |||
1712 | *q++ = (get_bits)(&s->gb, len) << (8 - len); | 1740 | *q++ = (get_bits)(&s->gb, len) << (8 - len); |
1713 | } | 1741 | } |
1714 | 1742 | ||
1715 | /* XXX: bit_offset bits into last frame */ | 1743 | /* XXX: s->bit_offset bits into last frame */ |
1716 | init_get_bits(&s->gb, s->last_superframe, MAX_CODED_SUPERFRAME_SIZE*8); | 1744 | init_get_bits(&s->gb, s->last_superframe, MAX_CODED_SUPERFRAME_SIZE*8); |
1717 | /* skip unused bits */ | 1745 | /* skip unused bits */ |
1718 | if (s->last_bitoffset > 0) | 1746 | if (s->last_bitoffset > 0) |
1719 | skip_bits(&s->gb, s->last_bitoffset); | 1747 | skip_bits(&s->gb, s->last_bitoffset); |
1748 | |||
1720 | /* this frame is stored in the last superframe and in the | 1749 | /* this frame is stored in the last superframe and in the |
1721 | current one */ | 1750 | current one */ |
1722 | if (wma_decode_frame(s, samples) < 0) | 1751 | if (wma_decode_frame(s, samples) < 0) |
1723 | { | 1752 | { |
1724 | goto fail; | 1753 | goto fail; |
1725 | } | 1754 | } |
1726 | samples += s->nb_channels * s->frame_len; | 1755 | done = 1; |
1727 | } | 1756 | } |
1728 | 1757 | ||
1729 | /* read each frame starting from bit_offset */ | 1758 | /* read each frame starting from s->bit_offset */ |
1730 | pos = bit_offset + 4 + 4 + s->byte_offset_bits + 3; | 1759 | pos = s->bit_offset + 4 + 4 + s->byte_offset_bits + 3; |
1731 | init_get_bits(&s->gb, buf + (pos >> 3), (MAX_CODED_SUPERFRAME_SIZE - (pos >> 3))*8); | 1760 | init_get_bits(&s->gb, buf + (pos >> 3), (MAX_CODED_SUPERFRAME_SIZE - (pos >> 3))*8); |
1732 | len = pos & 7; | 1761 | len = pos & 7; |
1733 | if (len > 0) | 1762 | if (len > 0) |
1734 | skip_bits(&s->gb, len); | 1763 | skip_bits(&s->gb, len); |
1735 | 1764 | ||
1736 | s->reset_block_lengths = 1; | 1765 | s->reset_block_lengths = 1; |
1737 | for(i=0;i<nb_frames;++i) | 1766 | } |
1767 | |||
1768 | /* If we haven't decoded a frame yet, do it now */ | ||
1769 | if (!done) | ||
1770 | { | ||
1771 | if (wma_decode_frame(s, samples) < 0) | ||
1738 | { | 1772 | { |
1739 | if (wma_decode_frame(s, samples) < 0) | 1773 | goto fail; |
1740 | { | ||
1741 | goto fail; | ||
1742 | } | ||
1743 | samples += s->nb_channels * s->frame_len; | ||
1744 | } | 1774 | } |
1775 | } | ||
1776 | |||
1777 | s->current_frame++; | ||
1745 | 1778 | ||
1779 | if ((s->use_bit_reservoir) && (s->current_frame == s->nb_frames)) | ||
1780 | { | ||
1746 | /* we copy the end of the frame in the last frame buffer */ | 1781 | /* we copy the end of the frame in the last frame buffer */ |
1747 | pos = get_bits_count(&s->gb) + ((bit_offset + 4 + 4 + s->byte_offset_bits + 3) & ~7); | 1782 | pos = get_bits_count(&s->gb) + ((s->bit_offset + 4 + 4 + s->byte_offset_bits + 3) & ~7); |
1748 | s->last_bitoffset = pos & 7; | 1783 | s->last_bitoffset = pos & 7; |
1749 | pos >>= 3; | 1784 | pos >>= 3; |
1750 | len = buf_size - pos; | 1785 | len = buf_size - pos; |
@@ -1755,21 +1790,11 @@ int wma_decode_superframe(WMADecodeContext* s, | |||
1755 | s->last_superframe_len = len; | 1790 | s->last_superframe_len = len; |
1756 | memcpy(s->last_superframe, buf + pos, len); | 1791 | memcpy(s->last_superframe, buf + pos, len); |
1757 | } | 1792 | } |
1758 | else | 1793 | |
1759 | { | 1794 | return s->frame_len; |
1760 | /* single frame decode */ | 1795 | |
1761 | if (wma_decode_frame(s, samples) < 0) | ||
1762 | { | ||
1763 | goto fail; | ||
1764 | } | ||
1765 | samples += s->nb_channels * s->frame_len; | ||
1766 | } | ||
1767 | *data_size = (int8_t *)samples - (int8_t *)data; | ||
1768 | return s->block_align; | ||
1769 | fail: | 1796 | fail: |
1770 | /* when error, we reset the bit reservoir */ | 1797 | /* when error, we reset the bit reservoir */ |
1771 | s->last_superframe_len = 0; | 1798 | s->last_superframe_len = 0; |
1772 | return -1; | 1799 | return -1; |
1773 | } | 1800 | } |
1774 | |||
1775 | |||
diff --git a/apps/codecs/wma.c b/apps/codecs/wma.c index a8e386a177..ab4a808f92 100644 --- a/apps/codecs/wma.c +++ b/apps/codecs/wma.c | |||
@@ -23,16 +23,15 @@ | |||
23 | 23 | ||
24 | CODEC_HEADER | 24 | CODEC_HEADER |
25 | 25 | ||
26 | #define MAX_BLOCKSIZE 2048 | 26 | /* The output buffer containing the decoded samples (channels 0 and 1) |
27 | BLOCK_MAX_SIZE is 2048 (samples) and MAX_CHANNELS is 2. | ||
28 | */ | ||
27 | 29 | ||
28 | /* The output buffers containing the decoded samples (channels 0 and 1) */ | 30 | static uint16_t decoded[BLOCK_MAX_SIZE * MAX_CHANNELS]; |
29 | 31 | ||
30 | /* NOTE: WMADecodeContext is 142688 bytes (on x86) */ | 32 | /* NOTE: WMADecodeContext is 142688 bytes (on x86) */ |
31 | static WMADecodeContext wmadec; | 33 | static WMADecodeContext wmadec; |
32 | 34 | ||
33 | /* TODO: Check the size of this */ | ||
34 | #define OUTBUF_SIZE 256*1024 | ||
35 | |||
36 | enum asf_error_e { | 35 | enum asf_error_e { |
37 | ASF_ERROR_INTERNAL = -1, /* incorrect input to API calls */ | 36 | ASF_ERROR_INTERNAL = -1, /* incorrect input to API calls */ |
38 | ASF_ERROR_OUTOFMEM = -2, /* some malloc inside program failed */ | 37 | ASF_ERROR_OUTOFMEM = -2, /* some malloc inside program failed */ |
@@ -286,8 +285,8 @@ enum codec_status codec_main(void) | |||
286 | unsigned char* inbuffer; | 285 | unsigned char* inbuffer; |
287 | size_t resume_offset; | 286 | size_t resume_offset; |
288 | size_t n; | 287 | size_t n; |
289 | int wmares, res, padding, outbufsize; | 288 | int i; |
290 | uint8_t* outbuf; | 289 | int wmares, res, padding; |
291 | 290 | ||
292 | /* Generic codec initialisation */ | 291 | /* Generic codec initialisation */ |
293 | ci->configure(CODEC_SET_FILEBUF_WATERMARK, 1024*512); | 292 | ci->configure(CODEC_SET_FILEBUF_WATERMARK, 1024*512); |
@@ -313,8 +312,6 @@ enum codec_status codec_main(void) | |||
313 | goto exit; | 312 | goto exit; |
314 | } | 313 | } |
315 | 314 | ||
316 | outbuf = codec_malloc(OUTBUF_SIZE); | ||
317 | |||
318 | /* Copy the format metadata we've stored in the id3 TOC field. This | 315 | /* Copy the format metadata we've stored in the id3 TOC field. This |
319 | saves us from parsing it again here. */ | 316 | saves us from parsing it again here. */ |
320 | memcpy(&wfx, ci->id3->toc, sizeof(wfx)); | 317 | memcpy(&wfx, ci->id3->toc, sizeof(wfx)); |
@@ -355,21 +352,31 @@ enum codec_status codec_main(void) | |||
355 | if (res > 0) { | 352 | if (res > 0) { |
356 | inbuffer = ci->request_buffer(&n, res - padding); | 353 | inbuffer = ci->request_buffer(&n, res - padding); |
357 | 354 | ||
358 | wmares = wma_decode_superframe(&wmadec, | 355 | wma_decode_superframe_init(&wmadec, |
359 | outbuf,&outbufsize, | 356 | inbuffer,res - padding); |
360 | inbuffer,res - padding); | 357 | |
361 | 358 | for (i=0; i < wmadec.nb_frames; i++) | |
362 | ci->advance_buffer(res); | 359 | { |
363 | 360 | wmares = wma_decode_superframe_frame(&wmadec, | |
364 | if (wmares > 0) { | 361 | decoded, |
365 | ci->pcmbuf_insert(outbuf, NULL, outbufsize / (wfx.channels * 2)); | 362 | inbuffer,res - padding); |
366 | samplesdone += (outbufsize / (wfx.channels * 2)); | 363 | |
367 | DEBUGF("Decoded %d samples\n",(outbufsize / (wfx.channels * 2))); | 364 | ci->yield (); |
368 | elapsedtime = (samplesdone*10)/(wfx.rate/100); | 365 | |
369 | ci->set_elapsed(elapsedtime); | 366 | if (wmares < 0) |
367 | { | ||
368 | LOGF("WMA decode error %d\n",wmares); | ||
369 | goto done; | ||
370 | } else if (wmares > 0) { | ||
371 | ci->pcmbuf_insert(decoded, NULL, wmares); | ||
372 | samplesdone += wmares; | ||
373 | elapsedtime = (samplesdone*10)/(wfx.rate/100); | ||
374 | ci->set_elapsed(elapsedtime); | ||
375 | } | ||
376 | ci->yield (); | ||
370 | } | 377 | } |
371 | 378 | ||
372 | ci->yield (); | 379 | ci->advance_buffer(res); |
373 | } | 380 | } |
374 | } | 381 | } |
375 | retval = CODEC_OK; | 382 | retval = CODEC_OK; |