]> git.sesse.net Git - ffmpeg/commitdiff
Add support for escape coded wmapro run level coefficients
authorSascha Sommer <saschasommer@freenet.de>
Sat, 20 Jun 2009 10:28:55 +0000 (10:28 +0000)
committerSascha Sommer <saschasommer@freenet.de>
Sat, 20 Jun 2009 10:28:55 +0000 (10:28 +0000)
Originally committed as revision 19232 to svn://svn.ffmpeg.org/ffmpeg/trunk

libavcodec/wma.c
libavcodec/wma.h

index 7cebc9e009686179ca8771760f5951a35f0582dd..cfa9f6b5676fd9f917c811308e1d5ba78a8b51af 100644 (file)
@@ -425,6 +425,28 @@ int ff_wma_end(AVCodecContext *avctx)
     return 0;
 }
 
+/**
+ * Decode an uncompressed coefficient.
+ * @param s codec context
+ * @return the decoded coefficient
+ */
+unsigned int ff_wma_get_large_val(GetBitContext* gb)
+{
+    /** consumes up to 34 bits */
+    int n_bits = 8;
+    /** decode length */
+    if (get_bits1(gb)) {
+        n_bits += 8;
+        if (get_bits1(gb)) {
+            n_bits += 8;
+            if (get_bits1(gb)) {
+                n_bits += 7;
+            }
+        }
+    }
+    return get_bits_long(gb, n_bits);
+}
+
 /**
  * Decode run level compressed coefficients.
  * @param avctx codec context
@@ -450,6 +472,7 @@ int ff_wma_run_level_decode(AVCodecContext* avctx, GetBitContext* gb,
 {
     int code, run, level, sign;
     WMACoef* eptr = ptr + num_coefs;
+    ptr += offset;
     for(;;) {
         code = get_vlc2(gb, vlc->table, VLCBITS, VLCMAX);
         if (code < 0)
@@ -459,10 +482,27 @@ int ff_wma_run_level_decode(AVCodecContext* avctx, GetBitContext* gb,
             break;
         } else if (code == 0) {
             /* escape */
+            if (!version) {
             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 {
+                level = ff_wma_get_large_val(gb);
+                /** escape decode */
+                if (get_bits1(gb)) {
+                    if (get_bits1(gb)) {
+                        if (get_bits1(gb)) {
+                            av_log(avctx,AV_LOG_ERROR,
+                                "broken escape sequence\n");
+                            return -1;
+                        } else
+                            run = get_bits(gb, frame_len_bits) + 4;
+                    } else
+                        run = get_bits(gb, 2) + 1;
+                } else
+                     run = 0;
+            }
         } else {
             /* normal code */
             run = run_table[code];
index 5a163313632ea39ec4009c55612e1344d9348094..a207dfc9565a38d7594a6f39f25493d38ab56c11 100644 (file)
@@ -150,6 +150,7 @@ 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);
+unsigned int ff_wma_get_large_val(GetBitContext* gb);
 int ff_wma_run_level_decode(AVCodecContext* avctx, GetBitContext* gb,
                             VLC *vlc,
                             const uint16_t *level_table, const uint16_t *run_table,