summaryrefslogtreecommitdiff
path: root/apps/codecs/libwmapro
diff options
context:
space:
mode:
authorMohamed Tarek <mt@rockbox.org>2010-07-26 22:03:20 +0000
committerMohamed Tarek <mt@rockbox.org>2010-07-26 22:03:20 +0000
commit5dd8c53b960d0b6680a0555a99e3232a5f890d07 (patch)
treee69f972fa214d6ef2587a885120b190b5577b788 /apps/codecs/libwmapro
parent87d59ab56c30eadc4691a41ba7540cca868c9b50 (diff)
downloadrockbox-5dd8c53b960d0b6680a0555a99e3232a5f890d07.zip
rockbox-5dd8c53b960d0b6680a0555a99e3232a5f890d07.tar.gz
rockbox-5dd8c53b960d0b6680a0555a99e3232a5f890d07.tar.bz2
rockbox-5dd8c53b960d0b6680a0555a99e3232a5f890d07.tar.xz
Modify the wma pro decoder to produce non-interleaved samples, and work directly on the buffers in WMAProDecCtx instead to avoid the redundant copying of the output data. ~10% speedup (-2MHz) on pp502x and ~1.5% speedup (-3.8Mhz)
on mcf2049. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@27583 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/codecs/libwmapro')
-rw-r--r--apps/codecs/libwmapro/wmaprodec.c49
-rw-r--r--apps/codecs/libwmapro/wmaprodec.h2
2 files changed, 25 insertions, 26 deletions
diff --git a/apps/codecs/libwmapro/wmaprodec.c b/apps/codecs/libwmapro/wmaprodec.c
index 1f65157..e2dff46 100644
--- a/apps/codecs/libwmapro/wmaprodec.c
+++ b/apps/codecs/libwmapro/wmaprodec.c
@@ -236,7 +236,7 @@ typedef struct WMAProDecodeCtx {
uint32_t frame_num; ///< current frame number
GetBitContext gb; ///< bitstream reader context
int buf_bit_size; ///< buffer size in bits
- int32_t* samples;
+ int32_t samples;
int32_t* samples_end; ///< maximum samplebuffer pointer
uint8_t drc_gain; ///< gain for the DRC tool
int8_t skip_frame; ///< skip output step
@@ -1282,7 +1282,7 @@ static int decode_subframe(WMAProDecodeCtx *s)
}
-
+
/** apply imdct (ff_imdct_half == DCTIV with reverse) */
imdct_half(av_log2(subframe_len)+1,
s->channel[c].coeffs, s->tmp);
@@ -1319,13 +1319,18 @@ static int decode_frame(WMAProDecodeCtx *s)
int len = 0;
int i;
+
+#if 0
/** check for potential output buffer overflow */
+ /* Rockbox : No need to check that anymore since we work directly on the
+ buffers in the WMAProDecCtx */
if (s->num_channels * s->samples_per_frame > s->samples_end - s->samples) {
/** return an error if no frame could be decoded at all */
DEBUGF("not enough space for the output samples\n");
s->packet_loss = 1;
return 0;
}
+#endif
/** get frame length */
if (s->len_prefix)
@@ -1389,24 +1394,7 @@ static int decode_frame(WMAProDecodeCtx *s)
return 0;
}
}
-
- /** interleave samples and write them to the output buffer */
- for (i = 0; i < s->num_channels; i++) {
- int32_t* ptr = s->samples + i;
- int incr = s->num_channels;
- int32_t* iptr = s->channel[i].out;
- int32_t* iend = iptr + s->samples_per_frame;
-
- while (iptr < iend) {
- *ptr = *iptr++ << 1;
- ptr += incr;
- }
-
- /** reuse second half of the IMDCT output for the next frame */
- memcpy(&s->channel[i].out[0],
- &s->channel[i].out[s->samples_per_frame],
- s->samples_per_frame * sizeof(*s->channel[i].out) >> 1);
- }
+ s->samples += s->num_channels * s->samples_per_frame;
if (s->skip_frame) {
s->skip_frame = 0;
@@ -1502,7 +1490,7 @@ static void save_bits(WMAProDecodeCtx *s, GetBitContext* gb, int len,
*@param avpkt input packet
*@return number of bytes that were read from the input buffer
*/
-int decode_packet(asf_waveformatex_t *wfx, void *data, int *data_size,
+int decode_packet(asf_waveformatex_t *wfx, int32_t *dec[2], int *data_size,
void* pktdata, int size)
{
WMAProDecodeCtx *s = &globWMAProDecCtx;
@@ -1510,10 +1498,18 @@ int decode_packet(asf_waveformatex_t *wfx, void *data, int *data_size,
const uint8_t* buf = pktdata;
int buf_size = size;
int num_bits_prev_frame;
- int packet_sequence_number;
+ int packet_sequence_number;\
+ int i;
- s->samples = data;
- s->samples_end = (int32_t*)((int8_t*)data + *data_size);
+ /** reuse second half of the IMDCT output for the next frame */
+ /* NOTE : Relies on the WMAProDecCtx being static */
+ for(i = 0; i < s->num_channels; i++)
+ memcpy(&s->channel[i].out[0],
+ &s->channel[i].out[s->samples_per_frame],
+ s->samples_per_frame * sizeof(*s->channel[i].out) >> 1);
+
+
+ s->samples = 0;
*data_size = 0;
if (s->packet_done || s->packet_loss) {
@@ -1583,7 +1579,10 @@ int decode_packet(asf_waveformatex_t *wfx, void *data, int *data_size,
save_bits(s, gb, remaining_bits(s, gb), 0);
}
- *data_size = (int8_t *)s->samples - (int8_t *)data;
+ dec[0] = s->channel[0].out;
+ dec[1] = s->channel[1].out;
+
+ *data_size = s->samples;
s->packet_offset = get_bits_count(gb) & 7;
s->frame_num++;
diff --git a/apps/codecs/libwmapro/wmaprodec.h b/apps/codecs/libwmapro/wmaprodec.h
index 3203dda..2e7d01a 100644
--- a/apps/codecs/libwmapro/wmaprodec.h
+++ b/apps/codecs/libwmapro/wmaprodec.h
@@ -28,4 +28,4 @@
int decode_init(asf_waveformatex_t *wfx);
int decode_packet(asf_waveformatex_t *wfx,
- void *data, int *data_size, void* pktdata, int size);
+ int32_t *dec[2], int *data_size, void* pktdata, int size);