diff options
| author | Dave Chapman <dave@dchapman.com> | 2007-07-09 17:24:00 +0000 |
|---|---|---|
| committer | Dave Chapman <dave@dchapman.com> | 2007-07-09 17:24:00 +0000 |
| commit | 88e32c2fc66544dfe55c2e307461ee01d590fef3 (patch) | |
| tree | 9b192ebacf8b12c6bcbb24335c32207113af56f8 /apps/codecs/wma.c | |
| parent | 01e8fce28760ab32c45ca330a8506c5cf45abf14 (diff) | |
| download | rockbox-88e32c2fc66544dfe55c2e307461ee01d590fef3.zip rockbox-88e32c2fc66544dfe55c2e307461ee01d590fef3.tar.gz rockbox-88e32c2fc66544dfe55c2e307461ee01d590fef3.tar.bz2 rockbox-88e32c2fc66544dfe55c2e307461ee01d590fef3.tar.xz | |
Reorganise the wma_decode_superframe() function - split into a separate init and decode functions. Each call to the decode function now decodes a single frame (2048 samples) instead of an entire superframe (which typically contained about 7 or 8 frames and can in theory contain up to 16 frames). This allows us to replace the 256KB output buffer with a 8KB buffer, and also perform more yields in the main decoding loop.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13833 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/codecs/wma.c')
| -rw-r--r-- | apps/codecs/wma.c | 51 |
1 files changed, 29 insertions, 22 deletions
diff --git a/apps/codecs/wma.c b/apps/codecs/wma.c index a8e386a..ab4a808 100644 --- a/apps/codecs/wma.c +++ b/apps/codecs/wma.c @@ -23,16 +23,15 @@ CODEC_HEADER -#define MAX_BLOCKSIZE 2048 +/* The output buffer containing the decoded samples (channels 0 and 1) + BLOCK_MAX_SIZE is 2048 (samples) and MAX_CHANNELS is 2. + */ -/* The output buffers containing the decoded samples (channels 0 and 1) */ +static uint16_t decoded[BLOCK_MAX_SIZE * MAX_CHANNELS]; /* NOTE: WMADecodeContext is 142688 bytes (on x86) */ static WMADecodeContext wmadec; -/* TODO: Check the size of this */ -#define OUTBUF_SIZE 256*1024 - enum asf_error_e { ASF_ERROR_INTERNAL = -1, /* incorrect input to API calls */ ASF_ERROR_OUTOFMEM = -2, /* some malloc inside program failed */ @@ -286,8 +285,8 @@ enum codec_status codec_main(void) unsigned char* inbuffer; size_t resume_offset; size_t n; - int wmares, res, padding, outbufsize; - uint8_t* outbuf; + int i; + int wmares, res, padding; /* Generic codec initialisation */ ci->configure(CODEC_SET_FILEBUF_WATERMARK, 1024*512); @@ -313,8 +312,6 @@ enum codec_status codec_main(void) goto exit; } - outbuf = codec_malloc(OUTBUF_SIZE); - /* Copy the format metadata we've stored in the id3 TOC field. This saves us from parsing it again here. */ memcpy(&wfx, ci->id3->toc, sizeof(wfx)); @@ -355,21 +352,31 @@ enum codec_status codec_main(void) if (res > 0) { inbuffer = ci->request_buffer(&n, res - padding); - wmares = wma_decode_superframe(&wmadec, - outbuf,&outbufsize, - inbuffer,res - padding); - - ci->advance_buffer(res); - - if (wmares > 0) { - ci->pcmbuf_insert(outbuf, NULL, outbufsize / (wfx.channels * 2)); - samplesdone += (outbufsize / (wfx.channels * 2)); - DEBUGF("Decoded %d samples\n",(outbufsize / (wfx.channels * 2))); - elapsedtime = (samplesdone*10)/(wfx.rate/100); - ci->set_elapsed(elapsedtime); + wma_decode_superframe_init(&wmadec, + inbuffer,res - padding); + + for (i=0; i < wmadec.nb_frames; i++) + { + wmares = wma_decode_superframe_frame(&wmadec, + decoded, + inbuffer,res - padding); + + ci->yield (); + + if (wmares < 0) + { + LOGF("WMA decode error %d\n",wmares); + goto done; + } else if (wmares > 0) { + ci->pcmbuf_insert(decoded, NULL, wmares); + samplesdone += wmares; + elapsedtime = (samplesdone*10)/(wfx.rate/100); + ci->set_elapsed(elapsedtime); + } + ci->yield (); } - ci->yield (); + ci->advance_buffer(res); } } retval = CODEC_OK; |