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.tar.gz rockbox-88e32c2fc66544dfe55c2e307461ee01d590fef3.zip |
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 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; |