summaryrefslogtreecommitdiff
path: root/apps/codecs/libwma
diff options
context:
space:
mode:
authorDave Chapman <dave@dchapman.com>2007-07-09 17:24:00 +0000
committerDave Chapman <dave@dchapman.com>2007-07-09 17:24:00 +0000
commit88e32c2fc66544dfe55c2e307461ee01d590fef3 (patch)
tree9b192ebacf8b12c6bcbb24335c32207113af56f8 /apps/codecs/libwma
parent01e8fce28760ab32c45ca330a8506c5cf45abf14 (diff)
downloadrockbox-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/libwma')
-rw-r--r--apps/codecs/libwma/wmadec.h13
-rw-r--r--apps/codecs/libwma/wmadeci.c105
2 files changed, 75 insertions, 43 deletions
diff --git a/apps/codecs/libwma/wmadec.h b/apps/codecs/libwma/wmadec.h
index e23d7c2..fd2d63c 100644
--- a/apps/codecs/libwma/wmadec.h
+++ b/apps/codecs/libwma/wmadec.h
@@ -137,6 +137,11 @@ typedef struct WMADecodeContext
fixed64 lsp_pow_m_table1[(1 << LSP_POW_BITS)];
fixed64 lsp_pow_m_table2[(1 << LSP_POW_BITS)];
+ /* State of current superframe decoding */
+ int bit_offset;
+ int nb_frames;
+ int current_frame;
+
#ifdef TRACE
int frame_count;
@@ -145,7 +150,9 @@ typedef struct WMADecodeContext
WMADecodeContext;
int wma_decode_init(WMADecodeContext* s, asf_waveformatex_t *wfx);
-int wma_decode_superframe(WMADecodeContext* s,
- void *data, int *data_size,
- uint8_t *buf, int buf_size);
+int wma_decode_superframe_init(WMADecodeContext* s,
+ uint8_t *buf, int buf_size);
+int wma_decode_superframe_frame(WMADecodeContext* s,
+ int16_t *samples,
+ uint8_t *buf, int buf_size);
#endif
diff --git a/apps/codecs/libwma/wmadeci.c b/apps/codecs/libwma/wmadeci.c
index c266316..1a7081f 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)
init_coef_vlc(&s->coef_vlc[1], &s->run_table[1], &s->level_table[1],
&coef_vlcs[coef_vlc_table * 2 + 1], 1);
+ s->last_superframe_len = 0;
+ s->last_bitoffset = 0;
+
return 0;
}
@@ -1666,42 +1669,67 @@ static int wma_decode_frame(WMADecodeContext *s, int16_t *samples)
return 0;
}
-int wma_decode_superframe(WMADecodeContext* s,
- void *data, /*output*/
- int *data_size,
- uint8_t *buf, /*input*/
- int buf_size)
-{
- //WMADecodeContext *s = avctx->priv_data;
- int nb_frames, bit_offset, i, pos, len;
- uint8_t *q;
- int16_t *samples;
+/* Initialise the superframe decoding */
+int wma_decode_superframe_init(WMADecodeContext* s,
+ uint8_t *buf, /*input*/
+ int buf_size)
+{
if (buf_size==0)
{
s->last_superframe_len = 0;
return 0;
}
- samples = data;
+ s->current_frame = 0;
+
init_get_bits(&s->gb, buf, buf_size*8);
+
if (s->use_bit_reservoir)
{
/* read super frame header */
get_bits(&s->gb, 4); /* super frame index */
- nb_frames = get_bits(&s->gb, 4) - 1;
+ s->nb_frames = get_bits(&s->gb, 4);
+
+ if (s->last_superframe_len == 0)
+ s->nb_frames --;
+ else if (s->nb_frames == 0)
+ s->nb_frames++;
+
+ s->bit_offset = get_bits(&s->gb, s->byte_offset_bits + 3);
+ } else {
+ s->nb_frames = 1;
+ }
- bit_offset = get_bits(&s->gb, s->byte_offset_bits + 3);
+ return 1;
+}
+
+
+/* Decode a single frame in the current superframe - return -1 if
+ there was a decoding error, or the number of samples decoded.
+*/
+
+int wma_decode_superframe_frame(WMADecodeContext* s,
+ int16_t* samples, /*output*/
+ uint8_t *buf, /*input*/
+ int buf_size)
+{
+ int pos, len;
+ uint8_t *q;
+ int done = 0;
+
+ if ((s->use_bit_reservoir) && (s->current_frame == 0))
+ {
if (s->last_superframe_len > 0)
{
- /* add bit_offset bits to last frame */
- if ((s->last_superframe_len + ((bit_offset + 7) >> 3)) >
+ /* add s->bit_offset bits to last frame */
+ if ((s->last_superframe_len + ((s->bit_offset + 7) >> 3)) >
MAX_CODED_SUPERFRAME_SIZE)
{
goto fail;
}
q = s->last_superframe + s->last_superframe_len;
- len = bit_offset;
+ len = s->bit_offset;
while (len > 0)
{
*q++ = (get_bits)(&s->gb, 8);
@@ -1712,39 +1740,46 @@ int wma_decode_superframe(WMADecodeContext* s,
*q++ = (get_bits)(&s->gb, len) << (8 - len);
}
- /* XXX: bit_offset bits into last frame */
+ /* XXX: s->bit_offset bits into last frame */
init_get_bits(&s->gb, s->last_superframe, MAX_CODED_SUPERFRAME_SIZE*8);
/* skip unused bits */
if (s->last_bitoffset > 0)
skip_bits(&s->gb, s->last_bitoffset);
+
/* this frame is stored in the last superframe and in the
current one */
if (wma_decode_frame(s, samples) < 0)
{
goto fail;
}
- samples += s->nb_channels * s->frame_len;
+ done = 1;
}
- /* read each frame starting from bit_offset */
- pos = bit_offset + 4 + 4 + s->byte_offset_bits + 3;
+ /* read each frame starting from s->bit_offset */
+ pos = s->bit_offset + 4 + 4 + s->byte_offset_bits + 3;
init_get_bits(&s->gb, buf + (pos >> 3), (MAX_CODED_SUPERFRAME_SIZE - (pos >> 3))*8);
len = pos & 7;
if (len > 0)
skip_bits(&s->gb, len);
s->reset_block_lengths = 1;
- for(i=0;i<nb_frames;++i)
+ }
+
+ /* If we haven't decoded a frame yet, do it now */
+ if (!done)
+ {
+ if (wma_decode_frame(s, samples) < 0)
{
- if (wma_decode_frame(s, samples) < 0)
- {
- goto fail;
- }
- samples += s->nb_channels * s->frame_len;
+ goto fail;
}
+ }
+
+ s->current_frame++;
+ if ((s->use_bit_reservoir) && (s->current_frame == s->nb_frames))
+ {
/* we copy the end of the frame in the last frame buffer */
- pos = get_bits_count(&s->gb) + ((bit_offset + 4 + 4 + s->byte_offset_bits + 3) & ~7);
+ pos = get_bits_count(&s->gb) + ((s->bit_offset + 4 + 4 + s->byte_offset_bits + 3) & ~7);
s->last_bitoffset = pos & 7;
pos >>= 3;
len = buf_size - pos;
@@ -1755,21 +1790,11 @@ int wma_decode_superframe(WMADecodeContext* s,
s->last_superframe_len = len;
memcpy(s->last_superframe, buf + pos, len);
}
- else
- {
- /* single frame decode */
- if (wma_decode_frame(s, samples) < 0)
- {
- goto fail;
- }
- samples += s->nb_channels * s->frame_len;
- }
- *data_size = (int8_t *)samples - (int8_t *)data;
- return s->block_align;
+
+ return s->frame_len;
+
fail:
/* when error, we reset the bit reservoir */
s->last_superframe_len = 0;
return -1;
}
-
-