summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSascha Sommer <saschasommer@freenet.de>2009-06-12 16:00:26 +0000
committerSascha Sommer <saschasommer@freenet.de>2009-06-12 16:00:26 +0000
commitc0e9b2e84fecbc4cc8efb78ced8fd1eaafae7a9d (patch)
tree83a26fd3cf13798d5060747ffe60172c78a55758
parente8c7f81cf2b5fd78bb95fcf5a7a6e067407dba87 (diff)
Move run level decode functionality to ff_wma_run_level_decode
so that it can be reused for wmapro Originally committed as revision 19171 to svn://svn.ffmpeg.org/ffmpeg/trunk
-rw-r--r--libavcodec/wma.c61
-rw-r--r--libavcodec/wma.h6
-rw-r--r--libavcodec/wmadec.c50
3 files changed, 74 insertions, 43 deletions
diff --git a/libavcodec/wma.c b/libavcodec/wma.c
index dfdb6f6b26..bdca4bce6d 100644
--- a/libavcodec/wma.c
+++ b/libavcodec/wma.c
@@ -424,3 +424,64 @@ int ff_wma_end(AVCodecContext *avctx)
return 0;
}
+
+/**
+ * Decode run level compressed coefficients.
+ * @param avctx codec context
+ * @param gb bitstream reader context
+ * @param vlc vlc table for get_vlc2
+ * @param level_table level codes
+ * @param run_table run codes
+ * @param version 0 for wma1,2 1 for wmapro
+ * @param ptr output buffer
+ * @param offset offset in the output buffer
+ * @param num_coefs number of input coefficents
+ * @param block_len input buffer length (2^n)
+ * @param frame_len_bits number of bits for escaped run codes
+ * @param coef_nb_bits number of bits for escaped level codes
+ * @return 0 on success, -1 otherwise
+ */
+int ff_wma_run_level_decode(AVCodecContext* avctx, GetBitContext* gb,
+ VLC *vlc,
+ const uint16_t *level_table, const uint16_t *run_table,
+ int version, int16_t *ptr, int offset,
+ int num_coefs, int block_len, int frame_len_bits,
+ int coef_nb_bits)
+{
+ int code, run, level, sign;
+ int16_t* eptr = ptr + num_coefs;
+ for(;;) {
+ code = get_vlc2(gb, vlc->table, VLCBITS, VLCMAX);
+ if (code < 0)
+ return -1;
+ if (code == 1) {
+ /* EOB */
+ break;
+ } else if (code == 0) {
+ /* escape */
+ level = get_bits(gb, coef_nb_bits);
+ /* NOTE: this is rather suboptimal. reading
+ block_len_bits would be better */
+ run = get_bits(gb, frame_len_bits);
+ } else {
+ /* normal code */
+ run = run_table[code];
+ level = level_table[code];
+ }
+ sign = get_bits1(gb);
+ if (!sign)
+ level = -level;
+ ptr += run;
+ if (ptr >= eptr)
+ {
+ av_log(NULL, AV_LOG_ERROR, "overflow in spectral RLE, ignoring\n");
+ break;
+ }
+ *ptr++ = level;
+ /* NOTE: EOB can be omitted */
+ if (ptr >= eptr)
+ break;
+ }
+ return 0;
+}
+
diff --git a/libavcodec/wma.h b/libavcodec/wma.h
index 50dcdf0a41..7ac85038d1 100644
--- a/libavcodec/wma.h
+++ b/libavcodec/wma.h
@@ -148,5 +148,11 @@ int av_cold ff_wma_get_frame_len_bits(int sample_rate, int version,
int ff_wma_init(AVCodecContext * avctx, int flags2);
int ff_wma_total_gain_to_bits(int total_gain);
int ff_wma_end(AVCodecContext *avctx);
+int ff_wma_run_level_decode(AVCodecContext* avctx, GetBitContext* gb,
+ VLC *vlc,
+ const uint16_t *level_table, const uint16_t *run_table,
+ int version, int16_t *ptr, int offset,
+ int num_coefs, int block_len, int frame_len_bits,
+ int coef_nb_bits);
#endif /* AVCODEC_WMA_H */
diff --git a/libavcodec/wmadec.c b/libavcodec/wmadec.c
index e06990230a..9dc6ff1810 100644
--- a/libavcodec/wmadec.c
+++ b/libavcodec/wmadec.c
@@ -349,7 +349,7 @@ static void wma_window(WMACodecContext *s, float *out)
*/
static int wma_decode_block(WMACodecContext *s)
{
- int n, v, a, ch, code, bsize;
+ int n, v, a, ch, bsize;
int coef_nb_bits, total_gain;
int nb_coefs[MAX_CHANNELS];
float mdct_norm;
@@ -485,53 +485,17 @@ static int wma_decode_block(WMACodecContext *s)
/* parse spectral coefficients : just RLE encoding */
for(ch = 0; ch < s->nb_channels; ch++) {
if (s->channel_coded[ch]) {
- VLC *coef_vlc;
- int level, run, sign, tindex;
- int16_t *ptr, *eptr;
- const uint16_t *level_table, *run_table;
+ int tindex;
+ int16_t* ptr = &s->coefs1[ch][0];
/* special VLC tables are used for ms stereo because
there is potentially less energy there */
tindex = (ch == 1 && s->ms_stereo);
- coef_vlc = &s->coef_vlc[tindex];
- run_table = s->run_table[tindex];
- level_table = s->level_table[tindex];
- /* XXX: optimize */
- ptr = &s->coefs1[ch][0];
- eptr = ptr + nb_coefs[ch];
memset(ptr, 0, s->block_len * sizeof(int16_t));
- for(;;) {
- code = get_vlc2(&s->gb, coef_vlc->table, VLCBITS, VLCMAX);
- if (code < 0)
- return -1;
- if (code == 1) {
- /* EOB */
- break;
- } else if (code == 0) {
- /* escape */
- level = get_bits(&s->gb, coef_nb_bits);
- /* NOTE: this is rather suboptimal. reading
- block_len_bits would be better */
- run = get_bits(&s->gb, s->frame_len_bits);
- } else {
- /* normal code */
- run = run_table[code];
- level = level_table[code];
- }
- sign = get_bits1(&s->gb);
- if (!sign)
- level = -level;
- ptr += run;
- if (ptr >= eptr)
- {
- av_log(NULL, AV_LOG_ERROR, "overflow in spectral RLE, ignoring\n");
- break;
- }
- *ptr++ = level;
- /* NOTE: EOB can be omitted */
- if (ptr >= eptr)
- break;
- }
+ ff_wma_run_level_decode(s->avctx, &s->gb, &s->coef_vlc[tindex],
+ s->level_table[tindex], s->run_table[tindex],
+ 0, ptr, 0, nb_coefs[ch],
+ s->block_len, s->frame_len_bits, coef_nb_bits);
}
if (s->version == 1 && s->nb_channels >= 2) {
align_get_bits(&s->gb);