Move run level decode functionality to ff_wma_run_level_decode
authorSascha Sommer <saschasommer@freenet.de>
Fri, 12 Jun 2009 16:00:26 +0000 (16:00 +0000)
committerSascha Sommer <saschasommer@freenet.de>
Fri, 12 Jun 2009 16:00:26 +0000 (16:00 +0000)
so that it can be reused for wmapro

Originally committed as revision 19171 to svn://svn.ffmpeg.org/ffmpeg/trunk

libavcodec/wma.c
libavcodec/wma.h
libavcodec/wmadec.c

index dfdb6f6..bdca4bc 100644 (file)
@@ -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;
+}
+
index 50dcdf0..7ac8503 100644 (file)
@@ -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 */
index e069902..9dc6ff1 100644 (file)
@@ -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);