From 88e32c2fc66544dfe55c2e307461ee01d590fef3 Mon Sep 17 00:00:00 2001 From: Dave Chapman Date: Mon, 9 Jul 2007 17:24:00 +0000 Subject: 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 --- apps/codecs/wma.c | 51 +++++++++++++++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 22 deletions(-) (limited to 'apps/codecs/wma.c') 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 @@ 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; -- cgit v1.2.3