add support for another variant of vp6
authorAurelien Jacobs <aurel@gnuage.org>
Sun, 14 Jan 2007 18:17:15 +0000 (18:17 +0000)
committerAurelien Jacobs <aurel@gnuage.org>
Sun, 14 Jan 2007 18:17:15 +0000 (18:17 +0000)
with block coeffs coded separatly from other parts of the frame

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

libavcodec/vp56.h
libavcodec/vp6.c

index f8b3a8e4b6f7000917b54cc67c847abeda899146..50e20155044b3f3c56ddd15c4e95bfe1140d81e5 100644 (file)
@@ -76,6 +76,8 @@ struct vp56_context {
     uint8_t *edge_emu_buffer_alloc;
     uint8_t *edge_emu_buffer;
     vp56_range_coder_t c;
+    vp56_range_coder_t cc;
+    vp56_range_coder_t *ccp;
     int sub_version;
 
     /* frame info */
@@ -108,6 +110,7 @@ struct vp56_context {
     int vector_candidate_pos;
 
     /* filtering hints */
+    int filter_header;               /* used in vp6 only */
     int deblock_filtering;
     int filter_selection;
     int filter_mode;
index 381fcc8eed1e8c0b0d939288b6eb1f083ff46628..fdbfd5fb2c16d4d2fefbd4df3b749680ce04bcd5 100644 (file)
@@ -43,13 +43,12 @@ static int vp6_parse_header(vp56_context_t *s, uint8_t *buf, int buf_size,
 {
     vp56_range_coder_t *c = &s->c;
     int parse_filter_info = 0;
+    int coeff_offset = 0;
     int vrt_shift = 0;
     int sub_version;
     int rows, cols;
     int res = 1;
-
-    if (buf[0] & 1)
-        return 0;
+    int separated_coeff = buf[0] & 1;
 
     s->frames[VP56_FRAME_CURRENT].key_frame = !(buf[0] & 0x80);
     vp56_init_dequant(s, (buf[0] >> 1) & 0x3F);
@@ -58,12 +57,16 @@ static int vp6_parse_header(vp56_context_t *s, uint8_t *buf, int buf_size,
         sub_version = buf[1] >> 3;
         if (sub_version > 8)
             return 0;
-        if ((buf[1] & 0x06) != 0x06)
-            return 0;
+        s->filter_header = buf[1] & 0x06;
         if (buf[1] & 1) {
             av_log(s->avctx, AV_LOG_ERROR, "interlacing not supported\n");
             return 0;
         }
+        if (separated_coeff || !s->filter_header) {
+            coeff_offset = BE_16(buf+2) - 2;
+            buf += 2;
+            buf_size -= 2;
+        }
 
         rows = buf[2];  /* number of stored macroblock rows */
         cols = buf[3];  /* number of stored macroblock cols */
@@ -83,7 +86,7 @@ static int vp6_parse_header(vp56_context_t *s, uint8_t *buf, int buf_size,
         vp56_init_range_decoder(c, buf+6, buf_size-6);
         vp56_rac_gets(c, 2);
 
-        parse_filter_info = 1;
+        parse_filter_info = s->filter_header;
         if (sub_version < 8)
             vrt_shift = 5;
         s->sub_version = sub_version;
@@ -91,14 +94,21 @@ static int vp6_parse_header(vp56_context_t *s, uint8_t *buf, int buf_size,
         if (!s->sub_version)
             return 0;
 
+        if (separated_coeff || !s->filter_header) {
+            coeff_offset = BE_16(buf+1) - 2;
+            buf += 2;
+            buf_size -= 2;
+        }
         vp56_init_range_decoder(c, buf+1, buf_size-1);
 
         *golden_frame = vp56_rac_get(c);
+        if (s->filter_header) {
         s->deblock_filtering = vp56_rac_get(c);
         if (s->deblock_filtering)
             vp56_rac_get(c);
         if (s->sub_version > 7)
             parse_filter_info = vp56_rac_get(c);
+        }
     }
 
     if (parse_filter_info) {
@@ -118,6 +128,15 @@ static int vp6_parse_header(vp56_context_t *s, uint8_t *buf, int buf_size,
     }
 
     vp56_rac_get(c);
+
+    if (coeff_offset) {
+        vp56_init_range_decoder(&s->cc, buf+coeff_offset,
+                                buf_size-coeff_offset);
+        s->ccp = &s->cc;
+    } else {
+        s->ccp = &s->c;
+    }
+
     return res;
 }
 
@@ -259,7 +278,7 @@ static void vp6_parse_vector_adjustment(vp56_context_t *s, vp56_mv_t *vect)
 
 static void vp6_parse_coeff(vp56_context_t *s)
 {
-    vp56_range_coder_t *c = &s->c;
+    vp56_range_coder_t *c = s->ccp;
     uint8_t *permute = s->scantable.permutated;
     uint8_t *model, *model2, *model3;
     int coeff, sign, coeff_idx;