[Ffmpeg-cvslog] r6213 - in trunk: Changelog MAINTAINERS doc/ffmpeg-doc.texi libavcodec/Makefile libavcodec/allcodecs.c libavcodec/avcodec.h libavcodec/vp5.c libavcodec/vp56.c libavcodec/vp56.h libavcodec/vp56data.c libavcodec/vp56data.h libavcodec/vp5data.h libavcodec/vp6.c libavcodec/vp6data.h libavformat/flvdec.c libavformat/nsvdec.c libavformat/riff.c libavformat/swf.c

aurel subversion
Sat Sep 9 19:19:42 CEST 2006


Author: aurel
Date: Sat Sep  9 19:19:37 2006
New Revision: 6213

Added:
   trunk/libavcodec/vp5.c
   trunk/libavcodec/vp56.c
   trunk/libavcodec/vp56.h
   trunk/libavcodec/vp56data.c
   trunk/libavcodec/vp56data.h
   trunk/libavcodec/vp5data.h
   trunk/libavcodec/vp6.c
   trunk/libavcodec/vp6data.h
Modified:
   trunk/Changelog
   trunk/MAINTAINERS
   trunk/doc/ffmpeg-doc.texi
   trunk/libavcodec/Makefile
   trunk/libavcodec/allcodecs.c
   trunk/libavcodec/avcodec.h
   trunk/libavformat/flvdec.c
   trunk/libavformat/nsvdec.c
   trunk/libavformat/riff.c
   trunk/libavformat/swf.c

Log:
VP5 and VP6 video decoder

Modified: trunk/Changelog
==============================================================================
--- trunk/Changelog	(original)
+++ trunk/Changelog	Sat Sep  9 19:19:37 2006
@@ -56,6 +56,8 @@
 - MacIntel support
 - AVISynth support
 - VMware video decoder
+- VP5 video decoder
+- VP6 video decoder
 
 version 0.4.9-pre1:
 

Modified: trunk/MAINTAINERS
==============================================================================
--- trunk/MAINTAINERS	(original)
+++ trunk/MAINTAINERS	Sat Sep  9 19:19:37 2006
@@ -164,6 +164,8 @@
   vcr1.c                                Michael Niedermayer
   vmnc.c                                Kostya Shishkov
   vp3*                                  Mike Melanson
+  vp5                                   Aurelien Jacobs
+  vp6                                   Aurelien Jacobs
   vqavideo.c                            Mike Melanson
   wmv2.c                                Michael Niedermayer
   wnv1.c                                Kostya Shishkov

Modified: trunk/doc/ffmpeg-doc.texi
==============================================================================
--- trunk/doc/ffmpeg-doc.texi	(original)
+++ trunk/doc/ffmpeg-doc.texi	Sat Sep  9 19:19:37 2006
@@ -778,6 +778,8 @@
 @item Sorenson Video 1       @tab  X  @tab  X @tab fourcc: SVQ1
 @item Sorenson Video 3       @tab     @tab  X @tab fourcc: SVQ3
 @item On2 VP3                @tab     @tab  X @tab still experimental
+ at item On2 VP5                @tab     @tab  X @tab fourcc: VP50
+ at item On2 VP6                @tab     @tab  X @tab fourcc: VP62
 @item Theora                 @tab     @tab  X @tab still experimental
 @item Intel Indeo 3          @tab     @tab  X
 @item FLV                    @tab  X  @tab  X @tab Sorenson H.263 used in Flash

Modified: trunk/libavcodec/Makefile
==============================================================================
--- trunk/libavcodec/Makefile	(original)
+++ trunk/libavcodec/Makefile	Sat Sep  9 19:19:37 2006
@@ -123,6 +123,8 @@
 OBJS-$(CONFIG_VMNC_DECODER)            += vmnc.o
 OBJS-$(CONFIG_VORBIS_DECODER)          += vorbis.o
 OBJS-$(CONFIG_VP3_DECODER)             += vp3.o
+OBJS-$(CONFIG_VP5_DECODER)             += vp5.o vp56.o vp56data.o
+OBJS-$(CONFIG_VP6_DECODER)             += vp6.o vp56.o vp56data.o
 OBJS-$(CONFIG_VQA_DECODER)             += vqavideo.o
 OBJS-$(CONFIG_WMAV1_DECODER)           += wmadec.o
 OBJS-$(CONFIG_WMAV2_DECODER)           += wmadec.o

Modified: trunk/libavcodec/allcodecs.c
==============================================================================
--- trunk/libavcodec/allcodecs.c	(original)
+++ trunk/libavcodec/allcodecs.c	Sat Sep  9 19:19:37 2006
@@ -371,6 +371,15 @@
 #ifdef CONFIG_THEORA_DECODER
     register_avcodec(&theora_decoder);
 #endif //CONFIG_THEORA_DECODER
+#ifdef CONFIG_VP5_DECODER
+    register_avcodec(&vp5_decoder);
+#endif //CONFIG_VP5_DECODER
+#ifdef CONFIG_VP6_DECODER
+    register_avcodec(&vp6_decoder);
+#endif //CONFIG_VP6_DECODER
+#ifdef CONFIG_VP6F_DECODER
+    register_avcodec(&vp6f_decoder);
+#endif //CONFIG_VP6F_DECODER
 #ifdef CONFIG_ASV1_DECODER
     register_avcodec(&asv1_decoder);
 #endif //CONFIG_ASV1_DECODER

Modified: trunk/libavcodec/avcodec.h
==============================================================================
--- trunk/libavcodec/avcodec.h	(original)
+++ trunk/libavcodec/avcodec.h	Sat Sep  9 19:19:37 2006
@@ -17,8 +17,8 @@
 #define AV_STRINGIFY(s)         AV_TOSTRING(s)
 #define AV_TOSTRING(s) #s
 
-#define LIBAVCODEC_VERSION_INT  ((51<<16)+(13<<8)+0)
-#define LIBAVCODEC_VERSION      51.13.0
+#define LIBAVCODEC_VERSION_INT  ((51<<16)+(14<<8)+0)
+#define LIBAVCODEC_VERSION      51.14.0
 #define LIBAVCODEC_BUILD        LIBAVCODEC_VERSION_INT
 
 #define LIBAVCODEC_IDENT        "Lavc" AV_STRINGIFY(LIBAVCODEC_VERSION)
@@ -121,6 +121,9 @@
     CODEC_ID_CAVS,
     CODEC_ID_JPEG2000,
     CODEC_ID_VMNC,
+    CODEC_ID_VP5,
+    CODEC_ID_VP6,
+    CODEC_ID_VP6F,
 
     /* various pcm "codecs" */
     CODEC_ID_PCM_S16LE= 0x10000,
@@ -2192,6 +2195,9 @@
 extern AVCodec indeo3_decoder;
 extern AVCodec vp3_decoder;
 extern AVCodec theora_decoder;
+extern AVCodec vp5_decoder;
+extern AVCodec vp6_decoder;
+extern AVCodec vp6f_decoder;
 extern AVCodec amr_nb_decoder;
 extern AVCodec amr_nb_encoder;
 extern AVCodec amr_wb_encoder;

Added: trunk/libavcodec/vp5.c
==============================================================================
--- (empty file)
+++ trunk/libavcodec/vp5.c	Sat Sep  9 19:19:37 2006
@@ -0,0 +1,289 @@
+/**
+ * @file vp5.c
+ * VP5 compatible video decoder
+ *
+ * Copyright (C) 2006  Aurelien Jacobs <aurel at gnuage.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <inttypes.h>
+
+#include "avcodec.h"
+#include "dsputil.h"
+#include "bitstream.h"
+#include "mpegvideo.h"
+
+#include "vp56.h"
+#include "vp56data.h"
+#include "vp5data.h"
+
+
+static int vp5_parse_header(vp56_context_t *s, uint8_t *buf, int buf_size,
+                            int *golden_frame)
+{
+    vp56_range_coder_t *c = &s->c;
+    int rows, cols;
+
+    vp56_init_range_decoder(&s->c, buf, buf_size);
+    s->frames[VP56_FRAME_CURRENT].key_frame = !vp56_rac_get(c);
+    vp56_rac_get(c);
+    vp56_init_dequant(s, vp56_rac_gets(c, 6));
+    if (s->frames[VP56_FRAME_CURRENT].key_frame)
+    {
+        vp56_rac_gets(c, 8);
+        if(vp56_rac_gets(c, 5) > 5)
+            return 0;
+        vp56_rac_gets(c, 2);
+        if (vp56_rac_get(c)) {
+            av_log(s->avctx, AV_LOG_ERROR, "interlacing not supported\n");
+            return 0;
+        }
+        rows = vp56_rac_gets(c, 8);  /* number of stored macroblock rows */
+        cols = vp56_rac_gets(c, 8);  /* number of stored macroblock cols */
+        vp56_rac_gets(c, 8);  /* number of displayed macroblock rows */
+        vp56_rac_gets(c, 8);  /* number of displayed macroblock cols */
+        vp56_rac_gets(c, 2);
+        if (16*cols != s->avctx->coded_width ||
+            16*rows != s->avctx->coded_height) {
+            avcodec_set_dimensions(s->avctx, 16*cols, 16*rows);
+            return 2;
+        }
+    }
+    return 1;
+}
+
+/* Gives very similar result than the vp6 version except in a few cases */
+static int vp5_adjust(int v, int t)
+{
+    int s2, s1 = v >> 31;
+    v ^= s1;
+    v -= s1;
+    v *= v < 2*t;
+    v -= t;
+    s2 = v >> 31;
+    v ^= s2;
+    v -= s2;
+    v = t - v;
+    v += s1;
+    v ^= s1;
+    return v;
+}
+
+static void vp5_parse_vector_adjustment(vp56_context_t *s, vp56_mv_t *vector)
+{
+    vp56_range_coder_t *c = &s->c;
+    int comp, di;
+
+    for (comp=0; comp<2; comp++) {
+        int delta = 0;
+        if (vp56_rac_get_prob(c, s->vector_model_dct[comp])) {
+            int sign = vp56_rac_get_prob(c, s->vector_model_sig[comp]);
+            di  = vp56_rac_get_prob(c, s->vector_model_pdi[comp][0]);
+            di |= vp56_rac_get_prob(c, s->vector_model_pdi[comp][1]) << 1;
+            delta = vp56_rac_get_tree(c, vp56_pva_tree,
+                                      s->vector_model_pdv[comp]);
+            delta = di | (delta << 2);
+            delta = (delta ^ -sign) + sign;
+        }
+        if (!comp)
+            vector->x = delta;
+        else
+            vector->y = delta;
+    }
+}
+
+static void vp5_parse_vector_models(vp56_context_t *s)
+{
+    vp56_range_coder_t *c = &s->c;
+    int comp, node;
+
+    for (comp=0; comp<2; comp++) {
+        if (vp56_rac_get_prob(c, vp5_vmc_pct[comp][0]))
+            s->vector_model_dct[comp] = vp56_rac_gets_nn(c, 7);
+        if (vp56_rac_get_prob(c, vp5_vmc_pct[comp][1]))
+            s->vector_model_sig[comp] = vp56_rac_gets_nn(c, 7);
+        if (vp56_rac_get_prob(c, vp5_vmc_pct[comp][2]))
+            s->vector_model_pdi[comp][0] = vp56_rac_gets_nn(c, 7);
+        if (vp56_rac_get_prob(c, vp5_vmc_pct[comp][3]))
+            s->vector_model_pdi[comp][1] = vp56_rac_gets_nn(c, 7);
+    }
+
+    for (comp=0; comp<2; comp++)
+        for (node=0; node<7; node++)
+            if (vp56_rac_get_prob(c, vp5_vmc_pct[comp][4 + node]))
+                s->vector_model_pdv[comp][node] = vp56_rac_gets_nn(c, 7);
+}
+
+static void vp5_parse_coeff_models(vp56_context_t *s)
+{
+    vp56_range_coder_t *c = &s->c;
+    uint8_t def_prob[11];
+    int node, cg, ctx;
+    int ct;    /* code type */
+    int pt;    /* plane type (0 for Y, 1 for U or V) */
+
+    memset(def_prob, 0x80, sizeof(def_prob));
+
+    for (pt=0; pt<2; pt++)
+        for (node=0; node<11; node++)
+            if (vp56_rac_get_prob(c, vp5_dccv_pct[pt][node])) {
+                def_prob[node] = vp56_rac_gets_nn(c, 7);
+                s->coeff_model_dccv[pt][node] = def_prob[node];
+            } else if (s->frames[VP56_FRAME_CURRENT].key_frame) {
+                s->coeff_model_dccv[pt][node] = def_prob[node];
+            }
+
+    for (ct=0; ct<3; ct++)
+        for (pt=0; pt<2; pt++)
+            for (cg=0; cg<6; cg++)
+                for (node=0; node<11; node++)
+                    if (vp56_rac_get_prob(c, vp5_ract_pct[ct][pt][cg][node])) {
+                        def_prob[node] = vp56_rac_gets_nn(c, 7);
+                        s->coeff_model_ract[pt][ct][cg][node] = def_prob[node];
+                    } else if (s->frames[VP56_FRAME_CURRENT].key_frame) {
+                        s->coeff_model_ract[pt][ct][cg][node] = def_prob[node];
+                    }
+
+    /* coeff_model_dcct is a linear combination of coeff_model_dccv */
+    for (pt=0; pt<2; pt++)
+        for (ctx=0; ctx<36; ctx++)
+            for (node=0; node<5; node++)
+                s->coeff_model_dcct[pt][ctx][node] = clip(((s->coeff_model_dccv[pt][node] * vp5_dccv_lc[node][ctx][0] + 128) >> 8) + vp5_dccv_lc[node][ctx][1], 1, 254);
+
+    /* coeff_model_acct is a linear combination of coeff_model_ract */
+    for (ct=0; ct<3; ct++)
+        for (pt=0; pt<2; pt++)
+            for (cg=0; cg<3; cg++)
+                for (ctx=0; ctx<6; ctx++)
+                    for (node=0; node<5; node++)
+                        s->coeff_model_acct[pt][ct][cg][ctx][node] = clip(((s->coeff_model_ract[pt][ct][cg][node] * vp5_ract_lc[ct][cg][node][ctx][0] + 128) >> 8) + vp5_ract_lc[ct][cg][node][ctx][1], 1, 254);
+}
+
+static void vp5_parse_coeff(vp56_context_t *s)
+{
+    vp56_range_coder_t *c = &s->c;
+    uint8_t *permute = s->scantable.permutated;
+    uint8_t *model, *model2;
+    int coeff, sign, coeff_idx;
+    int b, i, cg, idx, ctx, ctx_last;
+    int pt = 0;    /* plane type (0 for Y, 1 for U or V) */
+
+    for (b=0; b<6; b++) {
+        int ct = 1;    /* code type */
+
+        if (b > 3) pt = 1;
+
+        ctx = 6*s->coeff_ctx[vp56_b6to4[b]][0]
+              + s->above_blocks[s->above_block_idx[b]].not_null_dc;
+        model = s->coeff_model_dccv[pt];
+        model2 = s->coeff_model_dcct[pt][ctx];
+
+        for (coeff_idx=0; coeff_idx<64; ) {
+            if (vp56_rac_get_prob(c, model2[0])) {
+                if (vp56_rac_get_prob(c, model2[2])) {
+                    if (vp56_rac_get_prob(c, model2[3])) {
+                        s->coeff_ctx[vp56_b6to4[b]][coeff_idx] = 4;
+                        idx = vp56_rac_get_tree(c, vp56_pc_tree, model);
+                        sign = vp56_rac_get(c);
+                        coeff = vp56_coeff_bias[idx];
+                        for (i=vp56_coeff_bit_length[idx]; i>=0; i--)
+                            coeff += vp56_rac_get_prob(c, vp56_coeff_parse_table[idx][i]) << i;
+                    } else {
+                        if (vp56_rac_get_prob(c, model2[4])) {
+                            coeff = 3 + vp56_rac_get_prob(c, model[5]);
+                            s->coeff_ctx[vp56_b6to4[b]][coeff_idx] = 3;
+                        } else {
+                            coeff = 2;
+                            s->coeff_ctx[vp56_b6to4[b]][coeff_idx] = 2;
+                        }
+                        sign = vp56_rac_get(c);
+                    }
+                    ct = 2;
+                } else {
+                    ct = 1;
+                    s->coeff_ctx[vp56_b6to4[b]][coeff_idx] = 1;
+                    sign = vp56_rac_get(c);
+                    coeff = 1;
+                }
+                coeff = (coeff ^ -sign) + sign;
+                if (coeff_idx)
+                    coeff *= s->dequant_ac;
+                s->block_coeff[b][permute[coeff_idx]] = coeff;
+            } else {
+                if (ct && !vp56_rac_get_prob(c, model2[1]))
+                    break;
+                ct = 0;
+                s->coeff_ctx[vp56_b6to4[b]][coeff_idx] = 0;
+            }
+
+            cg = vp5_coeff_groups[++coeff_idx];
+            ctx = s->coeff_ctx[vp56_b6to4[b]][coeff_idx];
+            model = s->coeff_model_ract[pt][ct][cg];
+            model2 = cg > 2 ? model : s->coeff_model_acct[pt][ct][cg][ctx];
+        }
+
+        ctx_last = FFMIN(s->coeff_ctx_last[vp56_b6to4[b]], 24);
+        s->coeff_ctx_last[vp56_b6to4[b]] = coeff_idx;
+        if (coeff_idx < ctx_last)
+            for (i=coeff_idx; i<=ctx_last; i++)
+                s->coeff_ctx[vp56_b6to4[b]][i] = 5;
+        s->above_blocks[s->above_block_idx[b]].not_null_dc = s->coeff_ctx[vp56_b6to4[b]][0];
+    }
+}
+
+static void vp5_default_models_init(vp56_context_t *s)
+{
+    int i;
+
+    for (i=0; i<2; i++) {
+        s->vector_model_sig[i] = 0x80;
+        s->vector_model_dct[i] = 0x80;
+        s->vector_model_pdi[i][0] = 0x55;
+        s->vector_model_pdi[i][1] = 0x80;
+    }
+    memcpy(s->mb_types_stats, vp56_def_mb_types_stats, sizeof(s->mb_types_stats));
+    memset(s->vector_model_pdv, 0x80, sizeof(s->vector_model_pdv));
+}
+
+static int vp5_decode_init(AVCodecContext *avctx)
+{
+    vp56_context_t *s = avctx->priv_data;
+
+    vp56_init(s, avctx, 1);
+    s->vp56_coord_div = vp5_coord_div;
+    s->parse_vector_adjustment = vp5_parse_vector_adjustment;
+    s->adjust = vp5_adjust;
+    s->parse_coeff = vp5_parse_coeff;
+    s->default_models_init = vp5_default_models_init;
+    s->parse_vector_models = vp5_parse_vector_models;
+    s->parse_coeff_models = vp5_parse_coeff_models;
+    s->parse_header = vp5_parse_header;
+
+    return 0;
+}
+
+AVCodec vp5_decoder = {
+    "vp5",
+    CODEC_TYPE_VIDEO,
+    CODEC_ID_VP5,
+    sizeof(vp56_context_t),
+    vp5_decode_init,
+    NULL,
+    vp56_free,
+    vp56_decode_frame,
+};

Added: trunk/libavcodec/vp56.c
==============================================================================
--- (empty file)
+++ trunk/libavcodec/vp56.c	Sat Sep  9 19:19:37 2006
@@ -0,0 +1,662 @@
+/**
+ * @file vp56.c
+ * VP5 and VP6 compatible video decoder (common features)
+ *
+ * Copyright (C) 2006  Aurelien Jacobs <aurel at gnuage.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "avcodec.h"
+
+#include "vp56.h"
+#include "vp56data.h"
+
+
+void vp56_init_dequant(vp56_context_t *s, int quantizer)
+{
+    s->quantizer = quantizer;
+    s->dequant_dc = vp56_dc_dequant[quantizer] << 2;
+    s->dequant_ac = vp56_ac_dequant[quantizer] << 2;
+}
+
+static int vp56_get_vectors_predictors(vp56_context_t *s, int row, int col,
+                                       vp56_frame_t ref_frame)
+{
+    int nb_pred = 0;
+    vp56_mv_t vector[2] = {{0,0}, {0,0}};
+    int pos, offset;
+    vp56_mv_t mvp;
+
+    for (pos=0; pos<12; pos++) {
+        mvp.x = col + vp56_candidate_predictor_pos[pos][0];
+        mvp.y = row + vp56_candidate_predictor_pos[pos][1];
+        if (mvp.x < 0 || mvp.x >= s->mb_width ||
+            mvp.y < 0 || mvp.y >= s->mb_height)
+            continue;
+        offset = mvp.x + s->mb_width*mvp.y;
+
+        if (vp56_reference_frame[s->macroblocks[offset].type] != ref_frame)
+            continue;
+        if ((s->macroblocks[offset].mv.x == vector[0].x &&
+             s->macroblocks[offset].mv.y == vector[0].y) ||
+            (s->macroblocks[offset].mv.x == 0 &&
+             s->macroblocks[offset].mv.y == 0))
+            continue;
+
+        vector[nb_pred++] = s->macroblocks[offset].mv;
+        if (nb_pred > 1) {
+            nb_pred = -1;
+            break;
+        }
+        s->vector_candidate_pos = pos;
+    }
+
+    s->vector_candidate[0] = vector[0];
+    s->vector_candidate[1] = vector[1];
+
+    return nb_pred+1;
+}
+
+static void vp56_parse_mb_type_models(vp56_context_t *s)
+{
+    vp56_range_coder_t *c = &s->c;
+    int i, ctx, type;
+
+    for (ctx=0; ctx<3; ctx++) {
+        if (vp56_rac_get_prob(c, 174)) {
+            int idx = vp56_rac_gets(c, 4);
+            memcpy(s->mb_types_stats[ctx],vp56_pre_def_mb_type_stats[idx][ctx],
+                   sizeof(s->mb_types_stats[ctx]));
+        }
+        if (vp56_rac_get_prob(c, 254)) {
+            for (type=0; type<10; type++) {
+                for(i=0; i<2; i++) {
+                    if (vp56_rac_get_prob(c, 205)) {
+                        int delta, sign = vp56_rac_get(c);
+
+                        delta = vp56_rac_get_tree(c, vp56_pmbtm_tree,
+                                                  vp56_mb_type_model_model);
+                        if (!delta)
+                            delta = 4 * vp56_rac_gets(c, 7);
+                        s->mb_types_stats[ctx][type][i] += (delta ^ -sign) + sign;
+                    }
+                }
+            }
+        }
+    }
+
+    /* compute MB type probability tables based on previous MB type */
+    for (ctx=0; ctx<3; ctx++) {
+        int p[10];
+
+        for (type=0; type<10; type++)
+            p[type] = 100 * s->mb_types_stats[ctx][type][1];
+
+        for (type=0; type<10; type++) {
+            int p02, p34, p0234, p17, p56, p89, p5689, p156789;
+
+            /* conservative MB type probability */
+            s->mb_type_model[ctx][type][0] = 255 - (255 * s->mb_types_stats[ctx][type][0]) / (1 + s->mb_types_stats[ctx][type][0] + s->mb_types_stats[ctx][type][1]);
+
+            p[type] = 0;    /* same MB type => weight is null */
+
+            /* binary tree parsing probabilities */
+            p02 = p[0] + p[2];
+            p34 = p[3] + p[4];
+            p0234 = p02 + p34;
+            p17 = p[1] + p[7];
+            p56 = p[5] + p[6];
+            p89 = p[8] + p[9];
+            p5689 = p56 + p89;
+            p156789 = p17 + p5689;
+
+            s->mb_type_model[ctx][type][1] = 1 + 255 * p0234/(1+p0234+p156789);
+            s->mb_type_model[ctx][type][2] = 1 + 255 * p02  / (1+p0234);
+            s->mb_type_model[ctx][type][3] = 1 + 255 * p17  / (1+p156789);
+            s->mb_type_model[ctx][type][4] = 1 + 255 * p[0] / (1+p02);
+            s->mb_type_model[ctx][type][5] = 1 + 255 * p[3] / (1+p34);
+            s->mb_type_model[ctx][type][6] = 1 + 255 * p[1] / (1+p17);
+            s->mb_type_model[ctx][type][7] = 1 + 255 * p56  / (1+p5689);
+            s->mb_type_model[ctx][type][8] = 1 + 255 * p[5] / (1+p56);
+            s->mb_type_model[ctx][type][9] = 1 + 255 * p[8] / (1+p89);
+
+            /* restore initial value */
+            p[type] = 100 * s->mb_types_stats[ctx][type][1];
+        }
+    }
+}
+
+static vp56_mb_t vp56_parse_mb_type(vp56_context_t *s,
+                                    vp56_mb_t prev_type, int ctx)
+{
+    uint8_t *mb_type_model = s->mb_type_model[ctx][prev_type];
+    vp56_range_coder_t *c = &s->c;
+
+    if (vp56_rac_get_prob(c, mb_type_model[0]))
+        return prev_type;
+    else
+        return vp56_rac_get_tree(c, vp56_pmbt_tree, mb_type_model);
+}
+
+static void vp56_decode_4mv(vp56_context_t *s, int row, int col)
+{
+    vp56_mv_t mv = {0,0};
+    int type[4];
+    int b;
+
+    /* parse each block type */
+    for (b=0; b<4; b++) {
+        type[b] = vp56_rac_gets(&s->c, 2);
+        if (type[b])
+            type[b]++;  /* only returns 0, 2, 3 or 4 (all INTER_PF) */
+    }
+
+    /* get vectors */
+    for (b=0; b<4; b++) {
+        switch (type[b]) {
+            case VP56_MB_INTER_NOVEC_PF:
+                s->mv[b] = (vp56_mv_t) {0,0};
+                break;
+            case VP56_MB_INTER_DELTA_PF:
+                s->parse_vector_adjustment(s, &s->mv[b]);
+                break;
+            case VP56_MB_INTER_V1_PF:
+                s->mv[b] = s->vector_candidate[0];
+                break;
+            case VP56_MB_INTER_V2_PF:
+                s->mv[b] = s->vector_candidate[1];
+                break;
+        }
+        mv.x += s->mv[b].x;
+        mv.y += s->mv[b].y;
+    }
+
+    /* this is the one selected for the whole MB for prediction */
+    s->macroblocks[row * s->mb_width + col].mv = s->mv[3];
+
+    /* chroma vectors are average luma vectors */
+    if (s->avctx->codec->id == CODEC_ID_VP5) {
+        s->mv[4].x = s->mv[5].x = RSHIFT(mv.x,2);
+        s->mv[4].y = s->mv[5].y = RSHIFT(mv.y,2);
+    } else {
+        s->mv[4] = s->mv[5] = (vp56_mv_t) {mv.x/4, mv.y/4};
+    }
+}
+
+static vp56_mb_t vp56_decode_mv(vp56_context_t *s, int row, int col)
+{
+    vp56_mv_t *mv, vector = {0,0};
+    int ctx, b;
+
+    ctx = vp56_get_vectors_predictors(s, row, col, VP56_FRAME_PREVIOUS);
+    s->mb_type = vp56_parse_mb_type(s, s->mb_type, ctx);
+    s->macroblocks[row * s->mb_width + col].type = s->mb_type;
+
+    switch (s->mb_type) {
+        case VP56_MB_INTER_V1_PF:
+            mv = &s->vector_candidate[0];
+            break;
+
+        case VP56_MB_INTER_V2_PF:
+            mv = &s->vector_candidate[1];
+            break;
+
+        case VP56_MB_INTER_V1_GF:
+            vp56_get_vectors_predictors(s, row, col, VP56_FRAME_GOLDEN);
+            mv = &s->vector_candidate[0];
+            break;
+
+        case VP56_MB_INTER_V2_GF:
+            vp56_get_vectors_predictors(s, row, col, VP56_FRAME_GOLDEN);
+            mv = &s->vector_candidate[1];
+            break;
+
+        case VP56_MB_INTER_DELTA_PF:
+            s->parse_vector_adjustment(s, &vector);
+            mv = &vector;
+            break;
+
+        case VP56_MB_INTER_DELTA_GF:
+            vp56_get_vectors_predictors(s, row, col, VP56_FRAME_GOLDEN);
+            s->parse_vector_adjustment(s, &vector);
+            mv = &vector;
+            break;
+
+        case VP56_MB_INTER_4V:
+            vp56_decode_4mv(s, row, col);
+            return s->mb_type;
+
+        default:
+            mv = &vector;
+            break;
+    }
+
+    s->macroblocks[row*s->mb_width + col].mv = *mv;
+
+    /* same vector for all blocks */
+    for (b=0; b<6; b++)
+        s->mv[b] = *mv;
+
+    return s->mb_type;
+}
+
+static void vp56_add_predictors_dc(vp56_context_t *s, vp56_frame_t ref_frame)
+{
+    int idx = s->scantable.permutated[0];
+    int i;
+
+    for (i=0; i<6; i++) {
+        vp56_ref_dc_t *ab = &s->above_blocks[s->above_block_idx[i]];
+        vp56_ref_dc_t *lb = &s->left_block[vp56_b6to4[i]];
+        int count = 0;
+        int dc = 0;
+
+        if (ref_frame == lb->ref_frame) {
+            dc += lb->dc_coeff;
+            count++;
+        }
+        if (ref_frame == ab->ref_frame) {
+            dc += ab->dc_coeff;
+            count++;
+        }
+        if (s->avctx->codec->id == CODEC_ID_VP5) {
+            if (count < 2 && ref_frame == ab[-1].ref_frame) {
+                dc += ab[-1].dc_coeff;
+                count++;
+            }
+            if (count < 2 && ref_frame == ab[1].ref_frame) {
+                dc += ab[1].dc_coeff;
+                count++;
+            }
+        }
+        if (count == 0)
+            dc = s->prev_dc[vp56_b6to3[i]][ref_frame];
+        else if (count == 2)
+            dc /= 2;
+
+        s->block_coeff[i][idx] += dc;
+        s->prev_dc[vp56_b6to3[i]][ref_frame] = s->block_coeff[i][idx];
+        ab->dc_coeff = s->block_coeff[i][idx];
+        ab->ref_frame = ref_frame;
+        lb->dc_coeff = s->block_coeff[i][idx];
+        lb->ref_frame = ref_frame;
+        s->block_coeff[i][idx] *= s->dequant_dc;
+    }
+}
+
+static void vp56_edge_filter(vp56_context_t *s, uint8_t *yuv,
+                             int pix_inc, int line_inc, int t)
+{
+    int pix2_inc = 2 * pix_inc;
+    int i, v;
+
+    for (i=0; i<12; i++) {
+        v = (yuv[-pix2_inc] + 3*(yuv[0]-yuv[-pix_inc]) - yuv[pix_inc] + 4) >>3;
+        v = s->adjust(v, t);
+        yuv[-pix_inc] = clip_uint8(yuv[-pix_inc] + v);
+        yuv[0] = clip_uint8(yuv[0] - v);
+        yuv += line_inc;
+    }
+}
+
+static void vp56_deblock_filter(vp56_context_t *s, uint8_t *yuv,
+                                int stride, int dx, int dy)
+{
+    int t = vp56_filter_threshold[s->quantizer];
+    if (dx)  vp56_edge_filter(s, yuv +         10-dx ,      1, stride, t);
+    if (dy)  vp56_edge_filter(s, yuv + stride*(10-dy), stride,      1, t);
+}
+
+static void vp56_mc(vp56_context_t *s, int b, uint8_t *src,
+                    int stride, int x, int y)
+{
+    int plane = vp56_b6to3[b];
+    uint8_t *dst= s->frames[VP56_FRAME_CURRENT].data[plane]+s->block_offset[b];
+    uint8_t *src_block;
+    int src_offset;
+    int overlap_offset = 0;
+    int mask = s->vp56_coord_div[b] - 1;
+    int deblock_filtering = s->deblock_filtering;
+    int dx;
+    int dy;
+
+    if (s->avctx->skip_loop_filter >= AVDISCARD_ALL ||
+        (s->avctx->skip_loop_filter >= AVDISCARD_NONKEY
+         && !s->frames[VP56_FRAME_CURRENT].key_frame))
+        deblock_filtering = 0;
+
+    dx = s->mv[b].x / s->vp56_coord_div[b];
+    dy = s->mv[b].y / s->vp56_coord_div[b];
+
+    if (b >= 4) {
+        x /= 2;
+        y /= 2;
+    }
+    x += dx - 2;
+    y += dy - 2;
+
+    if (x<0 || x+12>=s->plane_width[plane] ||
+        y<0 || y+12>=s->plane_height[plane]) {
+        ff_emulated_edge_mc(s->edge_emu_buffer,
+                            src + s->block_offset[b] + (dy-2)*stride + (dx-2),
+                            stride, 12, 12, x, y,
+                            s->plane_width[plane],
+                            s->plane_height[plane]);
+        src_block = s->edge_emu_buffer;
+        src_offset = 2 + 2*stride;
+    } else if (deblock_filtering) {
+        /* only need a 12x12 block, but there is no such dsp function, */
+        /* so copy a 16x12 block */
+        s->dsp.put_pixels_tab[0][0](s->edge_emu_buffer,
+                                    src + s->block_offset[b] + (dy-2)*stride + (dx-2),
+                                    stride, 12);
+        src_block = s->edge_emu_buffer;
+        src_offset = 2 + 2*stride;
+    } else {
+        src_block = src;
+        src_offset = s->block_offset[b] + dy*stride + dx;
+    }
+
+    if (deblock_filtering)
+        vp56_deblock_filter(s, src_block, stride, dx&7, dy&7);
+
+    if (s->mv[b].x & mask)
+        overlap_offset += (s->mv[b].x > 0) ? 1 : -1;
+    if (s->mv[b].y & mask)
+        overlap_offset += (s->mv[b].y > 0) ? stride : -stride;
+
+    if (overlap_offset) {
+        if (s->filter)
+            s->filter(s, dst, src_block, src_offset, src_offset+overlap_offset,
+                      stride, s->mv[b], mask, s->filter_selection, b<4);
+        else
+            s->dsp.put_no_rnd_pixels_l2[1](dst, src_block+src_offset,
+                                           src_block+src_offset+overlap_offset,
+                                           stride, 8);
+    } else {
+        s->dsp.put_pixels_tab[1][0](dst, src_block+src_offset, stride, 8);
+    }
+}
+
+static void vp56_decode_mb(vp56_context_t *s, int row, int col)
+{
+    AVFrame *frame_current, *frame_ref;
+    vp56_mb_t mb_type;
+    vp56_frame_t ref_frame;
+    int b, plan, off;
+
+    if (s->frames[VP56_FRAME_CURRENT].key_frame)
+        mb_type = VP56_MB_INTRA;
+    else
+        mb_type = vp56_decode_mv(s, row, col);
+    ref_frame = vp56_reference_frame[mb_type];
+
+    memset(s->block_coeff, 0, sizeof(s->block_coeff));
+
+    s->parse_coeff(s);
+
+    vp56_add_predictors_dc(s, ref_frame);
+
+    frame_current = &s->frames[VP56_FRAME_CURRENT];
+    frame_ref = &s->frames[ref_frame];
+
+    switch (mb_type) {
+        case VP56_MB_INTRA:
+            for (b=0; b<6; b++) {
+                plan = vp56_b6to3[b];
+                s->dsp.idct_put(frame_current->data[plan] + s->block_offset[b],
+                                s->stride[plan], s->block_coeff[b]);
+            }
+            break;
+
+        case VP56_MB_INTER_NOVEC_PF:
+        case VP56_MB_INTER_NOVEC_GF:
+            for (b=0; b<6; b++) {
+                plan = vp56_b6to3[b];
+                off = s->block_offset[b];
+                s->dsp.put_pixels_tab[1][0](frame_current->data[plan] + off,
+                                            frame_ref->data[plan] + off,
+                                            s->stride[plan], 8);
+                s->dsp.idct_add(frame_current->data[plan] + off,
+                                s->stride[plan], s->block_coeff[b]);
+            }
+            break;
+
+        case VP56_MB_INTER_DELTA_PF:
+        case VP56_MB_INTER_V1_PF:
+        case VP56_MB_INTER_V2_PF:
+        case VP56_MB_INTER_DELTA_GF:
+        case VP56_MB_INTER_4V:
+        case VP56_MB_INTER_V1_GF:
+        case VP56_MB_INTER_V2_GF:
+            for (b=0; b<6; b++) {
+                int x_off = b==1 || b==3 ? 8 : 0;
+                int y_off = b==2 || b==3 ? 8 : 0;
+                plan = vp56_b6to3[b];
+                vp56_mc(s, b, frame_ref->data[plan], s->stride[plan],
+                        16*col+x_off, 16*row+y_off);
+                s->dsp.idct_add(frame_current->data[plan] + s->block_offset[b],
+                                s->stride[plan], s->block_coeff[b]);
+            }
+            break;
+    }
+}
+
+static int vp56_size_changed(AVCodecContext *avctx, vp56_context_t *s)
+{
+    int stride = s->frames[VP56_FRAME_CURRENT].linesize[0];
+    int i;
+
+    s->plane_width[0] = s->avctx->width;
+    s->plane_width[1] = s->plane_width[2] = s->avctx->width/2;
+    s->plane_height[0] = s->avctx->height;
+    s->plane_height[1] = s->plane_height[2] = s->avctx->height/2;
+
+    for (i=0; i<3; i++)
+        s->stride[i] = s->flip * s->frames[VP56_FRAME_CURRENT].linesize[i];
+
+    s->mb_width = (s->avctx->width+15) / 16;
+    s->mb_height = (s->avctx->height+15) / 16;
+
+    if (s->mb_width > 1000 || s->mb_height > 1000) {
+        av_log(avctx, AV_LOG_ERROR, "picture too big\n");
+        return -1;
+    }
+
+    s->above_blocks = av_realloc(s->above_blocks,
+                                 (4*s->mb_width+6) * sizeof(*s->above_blocks));
+    s->macroblocks = av_realloc(s->macroblocks,
+                                s->mb_width*s->mb_height*sizeof(*s->macroblocks));
+    s->edge_emu_buffer_alloc = av_realloc(s->edge_emu_buffer_alloc, 16*stride);
+    s->edge_emu_buffer = s->edge_emu_buffer_alloc;
+    if (s->flip < 0)
+        s->edge_emu_buffer += 15 * stride;
+
+    return 0;
+}
+
+int vp56_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
+                      uint8_t *buf, int buf_size)
+{
+    vp56_context_t *s = avctx->priv_data;
+    AVFrame *const p = &s->frames[VP56_FRAME_CURRENT];
+    AVFrame *picture = data;
+    int mb_row, mb_col, mb_row_flip, mb_offset = 0;
+    int block, y, uv, stride_y, stride_uv;
+    int golden_frame = 0;
+    int res;
+
+    res = s->parse_header(s, buf, buf_size, &golden_frame);
+    if (!res)
+        return -1;
+
+    p->reference = 1;
+    if (avctx->get_buffer(avctx, p) < 0) {
+        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+        return -1;
+    }
+
+    if (res == 2)
+        if (vp56_size_changed(avctx, s)) {
+            avctx->release_buffer(avctx, p);
+            return -1;
+        }
+
+    if (p->key_frame) {
+        p->pict_type = FF_I_TYPE;
+        s->default_models_init(s);
+        for (block=0; block<s->mb_height*s->mb_width; block++)
+            s->macroblocks[block].type = VP56_MB_INTRA;
+    } else {
+        p->pict_type = FF_P_TYPE;
+        vp56_parse_mb_type_models(s);
+        s->parse_vector_models(s);
+        s->mb_type = VP56_MB_INTER_NOVEC_PF;
+    }
+
+    s->parse_coeff_models(s);
+
+    memset(s->prev_dc, 0, sizeof(s->prev_dc));
+    s->prev_dc[1][VP56_FRAME_CURRENT] = 128;
+    s->prev_dc[2][VP56_FRAME_CURRENT] = 128;
+
+    for (block=0; block < 4*s->mb_width+6; block++) {
+        s->above_blocks[block].ref_frame = -1;
+        s->above_blocks[block].dc_coeff = 0;
+        s->above_blocks[block].not_null_dc = 0;
+    }
+    s->above_blocks[2*s->mb_width + 2].ref_frame = 0;
+    s->above_blocks[3*s->mb_width + 4].ref_frame = 0;
+
+    stride_y  = p->linesize[0];
+    stride_uv = p->linesize[1];
+
+    if (s->flip < 0)
+        mb_offset = 7;
+
+    /* main macroblocks loop */
+    for (mb_row=0; mb_row<s->mb_height; mb_row++) {
+        if (s->flip < 0)
+            mb_row_flip = s->mb_height - mb_row - 1;
+        else
+            mb_row_flip = mb_row;
+
+        for (block=0; block<4; block++) {
+            s->left_block[block].ref_frame = -1;
+            s->left_block[block].dc_coeff = 0;
+            s->left_block[block].not_null_dc = 0;
+            memset(s->coeff_ctx[block], 0, 64*sizeof(s->coeff_ctx[block][0]));
+        }
+        memset(s->coeff_ctx_last, 24, sizeof(s->coeff_ctx_last));
+
+        s->above_block_idx[0] = 1;
+        s->above_block_idx[1] = 2;
+        s->above_block_idx[2] = 1;
+        s->above_block_idx[3] = 2;
+        s->above_block_idx[4] = 2*s->mb_width + 2 + 1;
+        s->above_block_idx[5] = 3*s->mb_width + 4 + 1;
+
+        s->block_offset[s->frbi] = (mb_row_flip*16 + mb_offset) * stride_y;
+        s->block_offset[s->srbi] = s->block_offset[s->frbi] + 8*stride_y;
+        s->block_offset[1] = s->block_offset[0] + 8;
+        s->block_offset[3] = s->block_offset[2] + 8;
+        s->block_offset[4] = (mb_row_flip*8 + mb_offset) * stride_uv;
+        s->block_offset[5] = s->block_offset[4];
+
+        for (mb_col=0; mb_col<s->mb_width; mb_col++) {
+            vp56_decode_mb(s, mb_row, mb_col);
+
+            for (y=0; y<4; y++) {
+                s->above_block_idx[y] += 2;
+                s->block_offset[y] += 16;
+            }
+
+            for (uv=4; uv<6; uv++) {
+                s->above_block_idx[uv] += 1;
+                s->block_offset[uv] += 8;
+            }
+        }
+    }
+
+    if (s->frames[VP56_FRAME_PREVIOUS].data[0]
+        && (s->frames[VP56_FRAME_PREVIOUS].data[0]
+            != s->frames[VP56_FRAME_GOLDEN].data[0])) {
+        avctx->release_buffer(avctx, &s->frames[VP56_FRAME_PREVIOUS]);
+    }
+    if (p->key_frame || golden_frame) {
+        if (s->frames[VP56_FRAME_GOLDEN].data[0])
+            avctx->release_buffer(avctx, &s->frames[VP56_FRAME_GOLDEN]);
+        s->frames[VP56_FRAME_GOLDEN] = *p;
+    }
+    s->frames[VP56_FRAME_PREVIOUS] = *p;
+
+    *picture = *p;
+    *data_size = sizeof(AVPicture);
+
+    return buf_size;
+}
+
+void vp56_init(vp56_context_t *s, AVCodecContext *avctx, int flip)
+{
+    int i;
+
+    s->avctx = avctx;
+    avctx->pix_fmt = PIX_FMT_YUV420P;
+
+    if (s->avctx->idct_algo == FF_IDCT_AUTO)
+        s->avctx->idct_algo = FF_IDCT_VP3;
+    dsputil_init(&s->dsp, s->avctx);
+    ff_init_scantable(s->dsp.idct_permutation, &s->scantable,ff_zigzag_direct);
+
+    avcodec_set_dimensions(s->avctx, 0, 0);
+
+    for (i=0; i<3; i++)
+        s->frames[i].data[0] = NULL;
+    s->edge_emu_buffer_alloc = NULL;
+
+    s->above_blocks = NULL;
+    s->macroblocks = NULL;
+    s->quantizer = -1;
+    s->deblock_filtering = 1;
+
+    s->filter = NULL;
+
+    if (flip) {
+        s->flip = -1;
+        s->frbi = 2;
+        s->srbi = 0;
+    } else {
+        s->flip = 1;
+        s->frbi = 0;
+        s->srbi = 2;
+    }
+}
+
+int vp56_free(AVCodecContext *avctx)
+{
+    vp56_context_t *s = avctx->priv_data;
+
+    av_free(s->above_blocks);
+    av_free(s->macroblocks);
+    av_free(s->edge_emu_buffer_alloc);
+    if (s->frames[VP56_FRAME_GOLDEN].data[0]
+        && (s->frames[VP56_FRAME_PREVIOUS].data[0]
+            != s->frames[VP56_FRAME_GOLDEN].data[0]))
+        avctx->release_buffer(avctx, &s->frames[VP56_FRAME_GOLDEN]);
+    if (s->frames[VP56_FRAME_PREVIOUS].data[0])
+        avctx->release_buffer(avctx, &s->frames[VP56_FRAME_PREVIOUS]);
+    return 0;
+}

Added: trunk/libavcodec/vp56.h
==============================================================================
--- (empty file)
+++ trunk/libavcodec/vp56.h	Sat Sep  9 19:19:37 2006
@@ -0,0 +1,248 @@
+/**
+ * @file vp56.h
+ * VP5 and VP6 compatible video decoder (common features)
+ *
+ * Copyright (C) 2006  Aurelien Jacobs <aurel at gnuage.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef VP56_H
+#define VP56_H
+
+#include <stdint.h>
+
+#include "vp56data.h"
+#include "dsputil.h"
+#include "mpegvideo.h"
+
+
+typedef struct vp56_context vp56_context_t;
+typedef struct vp56_mv vp56_mv_t;
+
+typedef void (*vp56_parse_vector_adjustment_t)(vp56_context_t *s,
+                                               vp56_mv_t *vector);
+typedef int (*vp56_adjust_t)(int v, int t);
+typedef void (*vp56_filter_t)(vp56_context_t *s, uint8_t *dst, uint8_t *src,
+                              int offset1, int offset2, int stride,
+                              vp56_mv_t mv, int mask, int select, int luma);
+typedef void (*vp56_parse_coeff_t)(vp56_context_t *s);
+typedef void (*vp56_default_models_init_t)(vp56_context_t *s);
+typedef void (*vp56_parse_vector_models_t)(vp56_context_t *s);
+typedef void (*vp56_parse_coeff_models_t)(vp56_context_t *s);
+typedef int (*vp56_parse_header_t)(vp56_context_t *s, uint8_t *buf,
+                                   int buf_size, int *golden_frame);
+
+typedef struct {
+    int high;
+    int bits;
+    const uint8_t *buffer;
+    unsigned long code_word;
+} vp56_range_coder_t;
+
+typedef struct {
+    uint8_t not_null_dc;
+    vp56_frame_t ref_frame;
+    DCTELEM dc_coeff;
+} vp56_ref_dc_t;
+
+struct vp56_mv {
+    int x;
+    int y;
+};
+
+typedef struct {
+    uint8_t type;
+    vp56_mv_t mv;
+} vp56_macroblock_t;
+
+struct vp56_context {
+    AVCodecContext *avctx;
+    DSPContext dsp;
+    ScanTable scantable;
+    AVFrame frames[3];
+    uint8_t *edge_emu_buffer_alloc;
+    uint8_t *edge_emu_buffer;
+    vp56_range_coder_t c;
+
+    /* frame info */
+    int plane_width[3];
+    int plane_height[3];
+    int mb_width;   /* number of horizontal MB */
+    int mb_height;  /* number of vertical MB */
+    int block_offset[6];
+
+    int quantizer;
+    uint16_t dequant_dc;
+    uint16_t dequant_ac;
+
+    /* DC predictors management */
+    vp56_ref_dc_t *above_blocks;
+    vp56_ref_dc_t left_block[4];
+    int above_block_idx[6];
+    DCTELEM prev_dc[3][3];    /* [plan][ref_frame] */
+
+    /* blocks / macroblock */
+    vp56_mb_t mb_type;
+    vp56_macroblock_t *macroblocks;
+    DECLARE_ALIGNED_16(DCTELEM, block_coeff[6][64]);
+    uint8_t coeff_reorder[64];       /* used in vp6 only */
+    uint8_t coeff_index_to_pos[64];  /* used in vp6 only */
+
+    /* motion vectors */
+    vp56_mv_t mv[6];  /* vectors for each block in MB */
+    vp56_mv_t vector_candidate[2];
+    int vector_candidate_pos;
+
+    /* filtering hints */
+    int deblock_filtering;
+    int filter_selection;
+    int filter_mode;
+    int max_vector_length;
+    int sample_variance_threshold;
+
+    /* AC models */
+    uint8_t vector_model_sig[2];           /* delta sign */
+    uint8_t vector_model_dct[2];           /* delta coding types */
+    uint8_t vector_model_pdi[2][2];        /* predefined delta init */
+    uint8_t vector_model_pdv[2][7];        /* predefined delta values */
+    uint8_t vector_model_fdv[2][8];        /* 8 bit delta value definition */
+    uint8_t mb_type_model[3][10][10];      /* model for decoding MB type */
+    uint8_t coeff_model_dccv[2][11];       /* DC coeff value */
+    uint8_t coeff_model_ract[2][3][6][11]; /* Run/AC coding type and AC coeff value */
+    uint8_t coeff_model_acct[2][3][3][6][5];/* vp5 only AC coding type for coding group < 3 */
+    uint8_t coeff_model_dcct[2][36][5];    /* DC coeff coding type */
+    uint8_t coeff_model_runv[2][14];       /* run value (vp6 only) */
+    uint8_t mb_types_stats[3][10][2];      /* contextual, next MB type stats */
+    uint8_t coeff_ctx[4][64];              /* used in vp5 only */
+    uint8_t coeff_ctx_last[4];             /* used in vp5 only */
+
+    /* upside-down flipping hints */
+    int flip;  /* are we flipping ? */
+    int frbi;  /* first row block index in MB */
+    int srbi;  /* second row block index in MB */
+    int stride[3];  /* stride for each plan */
+
+    const uint8_t *vp56_coord_div;
+    vp56_parse_vector_adjustment_t parse_vector_adjustment;
+    vp56_adjust_t adjust;
+    vp56_filter_t filter;
+    vp56_parse_coeff_t parse_coeff;
+    vp56_default_models_init_t default_models_init;
+    vp56_parse_vector_models_t parse_vector_models;
+    vp56_parse_coeff_models_t parse_coeff_models;
+    vp56_parse_header_t parse_header;
+};
+
+
+void vp56_init(vp56_context_t *s, AVCodecContext *avctx, int flip);
+int vp56_free(AVCodecContext *avctx);
+void vp56_init_dequant(vp56_context_t *s, int quantizer);
+int vp56_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
+                      uint8_t *buf, int buf_size);
+
+
+/**
+ * vp56 specific range coder implementation
+ */
+
+static inline void vp56_init_range_decoder(vp56_range_coder_t *c,
+                                           const uint8_t *buf, int buf_size)
+{
+    c->high = 255;
+    c->bits = 8;
+    c->buffer = buf;
+    c->code_word = *c->buffer++ << 8;
+    c->code_word |= *c->buffer++;
+}
+
+static inline int vp56_rac_get_prob(vp56_range_coder_t *c, uint8_t prob)
+{
+    unsigned int low = 1 + (((c->high - 1) * prob) / 256);
+    unsigned int low_shift = low << 8;
+    int bit = c->code_word >= low_shift;
+
+    if (bit) {
+        c->high -= low;
+        c->code_word -= low_shift;
+    } else {
+        c->high = low;
+    }
+
+    /* normalize */
+    while (c->high < 128) {
+        c->high <<= 1;
+        c->code_word <<= 1;
+        if (--c->bits == 0) {
+            c->bits = 8;
+            c->code_word |= *c->buffer++;
+        }
+    }
+    return bit;
+}
+
+static inline int vp56_rac_get(vp56_range_coder_t *c)
+{
+    /* equiprobable */
+    int low = (c->high + 1) >> 1;
+    unsigned int low_shift = low << 8;
+    int bit = c->code_word >= low_shift;
+    if (bit) {
+        c->high = (c->high - low) << 1;
+        c->code_word -= low_shift;
+    } else {
+        c->high = low << 1;
+    }
+
+    /* normalize */
+    c->code_word <<= 1;
+    if (--c->bits == 0) {
+        c->bits = 8;
+        c->code_word |= *c->buffer++;
+    }
+    return bit;
+}
+
+static inline int vp56_rac_gets(vp56_range_coder_t *c, int bits)
+{
+    int value = 0;
+
+    while (bits--) {
+        value = (value << 1) | vp56_rac_get(c);
+    }
+
+    return value;
+}
+
+static inline int vp56_rac_gets_nn(vp56_range_coder_t *c, int bits)
+{
+    int v = vp56_rac_gets(c, 7) << 1;
+    return v + !v;
+}
+
+static inline int vp56_rac_get_tree(vp56_range_coder_t *c,
+                                    const vp56_tree_t *tree,
+                                    const uint8_t *probs)
+{
+    while (tree->val > 0) {
+        if (vp56_rac_get_prob(c, probs[tree->prob_idx]))
+            tree += tree->val;
+        else
+            tree++;
+    }
+    return -tree->val;
+}
+
+#endif /* VP56_H */

Added: trunk/libavcodec/vp56data.c
==============================================================================
--- (empty file)
+++ trunk/libavcodec/vp56data.c	Sat Sep  9 19:19:37 2006
@@ -0,0 +1,65 @@
+/**
+ * @file vp56data.c
+ * VP5 and VP6 compatible video decoder (common data)
+ *
+ * Copyright (C) 2006  Aurelien Jacobs <aurel at gnuage.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <inttypes.h>
+#include "vp56data.h"
+
+const uint8_t vp56_b6to3[] = { 0, 0, 0, 0, 1, 2 };
+const uint8_t vp56_b6to4[] = { 0, 0, 1, 1, 2, 3 };
+
+const uint8_t vp56_coeff_parse_table[6][11] = {
+    { 159,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0 },
+    { 145, 165,   0,   0,   0,   0,   0,   0,   0,   0,   0 },
+    { 140, 148, 173,   0,   0,   0,   0,   0,   0,   0,   0 },
+    { 135, 140, 155, 176,   0,   0,   0,   0,   0,   0,   0 },
+    { 130, 134, 141, 157, 180,   0,   0,   0,   0,   0,   0 },
+    { 129, 130, 133, 140, 153, 177, 196, 230, 243, 254, 254 },
+};
+
+const uint8_t vp56_def_mb_types_stats[3][10][2] = {
+    { {  69, 42 }, {   1,  2 }, {  1,   7 }, {  44, 42 }, {  6, 22 },
+      {   1,  3 }, {   0,  2 }, {  1,   5 }, {   0,  1 }, {  0,  0 }, },
+    { { 229,  8 }, {   1,  1 }, {  0,   8 }, {   0,  0 }, {  0,  0 },
+      {   1,  2 }, {   0,  1 }, {  0,   0 }, {   1,  1 }, {  0,  0 }, },
+    { { 122, 35 }, {   1,  1 }, {  1,   6 }, {  46, 34 }, {  0,  0 },
+      {   1,  2 }, {   0,  1 }, {  0,   1 }, {   1,  1 }, {  0,  0 }, },
+};
+
+const vp56_tree_t vp56_pva_tree[] = {
+    { 8, 0},
+    { 4, 1},
+    { 2, 2}, {-0}, {-1},
+    { 2, 3}, {-2}, {-3},
+    { 4, 4},
+    { 2, 5}, {-4}, {-5},
+    { 2, 6}, {-6}, {-7},
+};
+
+const vp56_tree_t vp56_pc_tree[] = {
+    { 4, 6},
+    { 2, 7}, {-0}, {-1},
+    { 4, 8},
+    { 2, 9}, {-2}, {-3},
+    { 2,10}, {-4}, {-5},
+};
+
+const uint8_t vp56_coeff_bias[] = { 5, 7, 11, 19, 35, 67 };
+const uint8_t vp56_coeff_bit_length[] = { 0, 1, 2, 3, 4, 10 };

Added: trunk/libavcodec/vp56data.h
==============================================================================
--- (empty file)
+++ trunk/libavcodec/vp56data.h	Sat Sep  9 19:19:37 2006
@@ -0,0 +1,246 @@
+/**
+ * @file vp56data.h
+ * VP5 and VP6 compatible video decoder (common data)
+ *
+ * Copyright (C) 2006  Aurelien Jacobs <aurel at gnuage.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef VP56DATA_H
+#define VP56DATA_H
+
+#include <inttypes.h>
+
+typedef enum {
+    VP56_FRAME_CURRENT  = 0,
+    VP56_FRAME_PREVIOUS = 1,
+    VP56_FRAME_GOLDEN   = 2,
+} vp56_frame_t;
+
+typedef enum {
+    VP56_MB_INTER_NOVEC_PF = 0,  /**< Inter MB, no vector, from previous frame */
+    VP56_MB_INTRA          = 1,  /**< Intra MB */
+    VP56_MB_INTER_DELTA_PF = 2,  /**< Inter MB, above/left vector + delta, from previous frame */
+    VP56_MB_INTER_V1_PF    = 3,  /**< Inter MB, first vector, from previous frame */
+    VP56_MB_INTER_V2_PF    = 4,  /**< Inter MB, second vector, from previous frame */
+    VP56_MB_INTER_NOVEC_GF = 5,  /**< Inter MB, no vector, from golden frame */
+    VP56_MB_INTER_DELTA_GF = 6,  /**< Inter MB, above/left vector + delta, from golden frame */
+    VP56_MB_INTER_4V       = 7,  /**< Inter MB, 4 vectors, from previous frame */
+    VP56_MB_INTER_V1_GF    = 8,  /**< Inter MB, first vector, from golden frame */
+    VP56_MB_INTER_V2_GF    = 9,  /**< Inter MB, second vector, from golden frame */
+} vp56_mb_t;
+
+typedef struct {
+  int8_t val;
+  int8_t prob_idx;
+} vp56_tree_t;
+
+extern const uint8_t vp56_b6to3[];
+extern const uint8_t vp56_b6to4[];
+extern const uint8_t vp56_coeff_parse_table[6][11];
+extern const uint8_t vp56_def_mb_types_stats[3][10][2];
+extern const vp56_tree_t vp56_pva_tree[];
+extern const vp56_tree_t vp56_pc_tree[];
+extern const uint8_t vp56_coeff_bias[];
+extern const uint8_t vp56_coeff_bit_length[];
+
+static const vp56_frame_t vp56_reference_frame[] = {
+    VP56_FRAME_PREVIOUS,  /* VP56_MB_INTER_NOVEC_PF */
+    VP56_FRAME_CURRENT,   /* VP56_MB_INTRA */
+    VP56_FRAME_PREVIOUS,  /* VP56_MB_INTER_DELTA_PF */
+    VP56_FRAME_PREVIOUS,  /* VP56_MB_INTER_V1_PF */
+    VP56_FRAME_PREVIOUS,  /* VP56_MB_INTER_V2_PF */
+    VP56_FRAME_GOLDEN,    /* VP56_MB_INTER_NOVEC_GF */
+    VP56_FRAME_GOLDEN,    /* VP56_MB_INTER_DELTA_GF */
+    VP56_FRAME_PREVIOUS,  /* VP56_MB_INTER_4V */
+    VP56_FRAME_GOLDEN,    /* VP56_MB_INTER_V1_GF */
+    VP56_FRAME_GOLDEN,    /* VP56_MB_INTER_V2_GF */
+};
+
+static const uint8_t vp56_ac_dequant[64] = {
+    94, 92, 90, 88, 86, 82, 78, 74,
+    70, 66, 62, 58, 54, 53, 52, 51,
+    50, 49, 48, 47, 46, 45, 44, 43,
+    42, 40, 39, 37, 36, 35, 34, 33,
+    32, 31, 30, 29, 28, 27, 26, 25,
+    24, 23, 22, 21, 20, 19, 18, 17,
+    16, 15, 14, 13, 12, 11, 10,  9,
+     8,  7,  6,  5,  4,  3,  2,  1,
+};
+
+static const uint8_t vp56_dc_dequant[64] = {
+    47, 47, 47, 47, 45, 43, 43, 43,
+    43, 43, 42, 41, 41, 40, 40, 40,
+    40, 35, 35, 35, 35, 33, 33, 33,
+    33, 32, 32, 32, 27, 27, 26, 26,
+    25, 25, 24, 24, 23, 23, 19, 19,
+    19, 19, 18, 18, 17, 16, 16, 16,
+    16, 16, 15, 11, 11, 11, 10, 10,
+     9,  8,  7,  5,  3,  3,  2,  2,
+};
+
+static const uint8_t vp56_pre_def_mb_type_stats[16][3][10][2] = {
+  { { {   9, 15 }, {  32, 25 }, {  7,  19 }, {   9, 21 }, {  1, 12 },
+      {  14, 12 }, {   3, 18 }, { 14,  23 }, {   3, 10 }, {  0,  4 }, },
+    { {  41, 22 }, {   1,  0 }, {  1,  31 }, {   0,  0 }, {  0,  0 },
+      {   0,  1 }, {   1,  7 }, {  0,   1 }, {  98, 25 }, {  4, 10 }, },
+    { {   2,  3 }, {   2,  3 }, {  0,   2 }, {   0,  2 }, {  0,  0 },
+      {  11,  4 }, {   1,  4 }, {  0,   2 }, {   3,  2 }, {  0,  4 }, }, },
+  { { {  48, 39 }, {   1,  2 }, { 11,  27 }, {  29, 44 }, {  7, 27 },
+      {   1,  4 }, {   0,  3 }, {  1,   6 }, {   1,  2 }, {  0,  0 }, },
+    { { 123, 37 }, {   6,  4 }, {  1,  27 }, {   0,  0 }, {  0,  0 },
+      {   5,  8 }, {   1,  7 }, {  0,   1 }, {  12, 10 }, {  0,  2 }, },
+    { {  49, 46 }, {   3,  4 }, {  7,  31 }, {  42, 41 }, {  0,  0 },
+      {   2,  6 }, {   1,  7 }, {  1,   4 }, {   2,  4 }, {  0,  1 }, }, },
+  { { {  21, 32 }, {   1,  2 }, {  4,  10 }, {  32, 43 }, {  6, 23 },
+      {   2,  3 }, {   1, 19 }, {  1,   6 }, {  12, 21 }, {  0,  7 }, },
+    { {  26, 14 }, {  14, 12 }, {  0,  24 }, {   0,  0 }, {  0,  0 },
+      {  55, 17 }, {   1,  9 }, {  0,  36 }, {   5,  7 }, {  1,  3 }, },
+    { {  26, 25 }, {   1,  1 }, {  2,  10 }, {  67, 39 }, {  0,  0 },
+      {   1,  1 }, {   0, 14 }, {  0,   2 }, {  31, 26 }, {  1,  6 }, }, },
+  { { {  69, 83 }, {   0,  0 }, {  0,   2 }, {  10, 29 }, {  3, 12 },
+      {   0,  1 }, {   0,  3 }, {  0,   3 }, {   2,  2 }, {  0,  0 }, },
+    { { 209,  5 }, {   0,  0 }, {  0,  27 }, {   0,  0 }, {  0,  0 },
+      {   0,  1 }, {   0,  1 }, {  0,   1 }, {   0,  0 }, {  0,  0 }, },
+    { { 103, 46 }, {   1,  2 }, {  2,  10 }, {  33, 42 }, {  0,  0 },
+      {   1,  4 }, {   0,  3 }, {  0,   1 }, {   1,  3 }, {  0,  0 }, }, },
+  { { {  11, 20 }, {   1,  4 }, { 18,  36 }, {  43, 48 }, { 13, 35 },
+      {   0,  2 }, {   0,  5 }, {  3,  12 }, {   1,  2 }, {  0,  0 }, },
+    { {   2,  5 }, {   4,  5 }, {  0, 121 }, {   0,  0 }, {  0,  0 },
+      {   0,  3 }, {   2,  4 }, {  1,   4 }, {   2,  2 }, {  0,  1 }, },
+    { {  14, 31 }, {   9, 13 }, { 14,  54 }, {  22, 29 }, {  0,  0 },
+      {   2,  6 }, {   4, 18 }, {  6,  13 }, {   1,  5 }, {  0,  1 }, }, },
+  { { {  70, 44 }, {   0,  1 }, {  2,  10 }, {  37, 46 }, {  8, 26 },
+      {   0,  2 }, {   0,  2 }, {  0,   2 }, {   0,  1 }, {  0,  0 }, },
+    { { 175,  5 }, {   0,  1 }, {  0,  48 }, {   0,  0 }, {  0,  0 },
+      {   0,  2 }, {   0,  1 }, {  0,   2 }, {   0,  1 }, {  0,  0 }, },
+    { {  85, 39 }, {   0,  0 }, {  1,   9 }, {  69, 40 }, {  0,  0 },
+      {   0,  1 }, {   0,  3 }, {  0,   1 }, {   2,  3 }, {  0,  0 }, }, },
+  { { {   8, 15 }, {   0,  1 }, {  8,  21 }, {  74, 53 }, { 22, 42 },
+      {   0,  1 }, {   0,  2 }, {  0,   3 }, {   1,  2 }, {  0,  0 }, },
+    { {  83,  5 }, {   2,  3 }, {  0, 102 }, {   0,  0 }, {  0,  0 },
+      {   1,  3 }, {   0,  2 }, {  0,   1 }, {   0,  0 }, {  0,  0 }, },
+    { {  31, 28 }, {   0,  0 }, {  3,  14 }, { 130, 34 }, {  0,  0 },
+      {   0,  1 }, {   0,  3 }, {  0,   1 }, {   3,  3 }, {  0,  1 }, }, },
+  { { { 141, 42 }, {   0,  0 }, {  1,   4 }, {  11, 24 }, {  1, 11 },
+      {   0,  1 }, {   0,  1 }, {  0,   2 }, {   0,  0 }, {  0,  0 }, },
+    { { 233,  6 }, {   0,  0 }, {  0,   8 }, {   0,  0 }, {  0,  0 },
+      {   0,  1 }, {   0,  1 }, {  0,   0 }, {   0,  1 }, {  0,  0 }, },
+    { { 171, 25 }, {   0,  0 }, {  1,   5 }, {  25, 21 }, {  0,  0 },
+      {   0,  1 }, {   0,  1 }, {  0,   0 }, {   0,  0 }, {  0,  0 }, }, },
+  { { {   8, 19 }, {   4, 10 }, { 24,  45 }, {  21, 37 }, {  9, 29 },
+      {   0,  3 }, {   1,  7 }, { 11,  25 }, {   0,  2 }, {  0,  1 }, },
+    { {  34, 16 }, { 112, 21 }, {  1,  28 }, {   0,  0 }, {  0,  0 },
+      {   6,  8 }, {   1,  7 }, {  0,   3 }, {   2,  5 }, {  0,  2 }, },
+    { {  17, 21 }, {  68, 29 }, {  6,  15 }, {  13, 22 }, {  0,  0 },
+      {   6, 12 }, {   3, 14 }, {  4,  10 }, {   1,  7 }, {  0,  3 }, }, },
+  { { {  46, 42 }, {   0,  1 }, {  2,  10 }, {  54, 51 }, { 10, 30 },
+      {   0,  2 }, {   0,  2 }, {  0,   1 }, {   0,  1 }, {  0,  0 }, },
+    { { 159, 35 }, {   2,  2 }, {  0,  25 }, {   0,  0 }, {  0,  0 },
+      {   3,  6 }, {   0,  5 }, {  0,   1 }, {   4,  4 }, {  0,  1 }, },
+    { {  51, 39 }, {   0,  1 }, {  2,  12 }, {  91, 44 }, {  0,  0 },
+      {   0,  2 }, {   0,  3 }, {  0,   1 }, {   2,  3 }, {  0,  1 }, }, },
+  { { {  28, 32 }, {   0,  0 }, {  3,  10 }, {  75, 51 }, { 14, 33 },
+      {   0,  1 }, {   0,  2 }, {  0,   1 }, {   1,  2 }, {  0,  0 }, },
+    { {  75, 39 }, {   5,  7 }, {  2,  48 }, {   0,  0 }, {  0,  0 },
+      {   3, 11 }, {   2, 16 }, {  1,   4 }, {   7, 10 }, {  0,  2 }, },
+    { {  81, 25 }, {   0,  0 }, {  2,   9 }, { 106, 26 }, {  0,  0 },
+      {   0,  1 }, {   0,  1 }, {  0,   1 }, {   1,  1 }, {  0,  0 }, }, },
+  { { { 100, 46 }, {   0,  1 }, {  3,   9 }, {  21, 37 }, {  5, 20 },
+      {   0,  1 }, {   0,  2 }, {  1,   2 }, {   0,  1 }, {  0,  0 }, },
+    { { 212, 21 }, {   0,  1 }, {  0,   9 }, {   0,  0 }, {  0,  0 },
+      {   1,  2 }, {   0,  2 }, {  0,   0 }, {   2,  2 }, {  0,  0 }, },
+    { { 140, 37 }, {   0,  1 }, {  1,   8 }, {  24, 33 }, {  0,  0 },
+      {   1,  2 }, {   0,  2 }, {  0,   1 }, {   1,  2 }, {  0,  0 }, }, },
+  { { {  27, 29 }, {   0,  1 }, {  9,  25 }, {  53, 51 }, { 12, 34 },
+      {   0,  1 }, {   0,  3 }, {  1,   5 }, {   0,  2 }, {  0,  0 }, },
+    { {   4,  2 }, {   0,  0 }, {  0, 172 }, {   0,  0 }, {  0,  0 },
+      {   0,  1 }, {   0,  2 }, {  0,   0 }, {   2,  0 }, {  0,  0 }, },
+    { {  14, 23 }, {   1,  3 }, { 11,  53 }, {  90, 31 }, {  0,  0 },
+      {   0,  3 }, {   1,  5 }, {  2,   6 }, {   1,  2 }, {  0,  0 }, }, },
+  { { {  80, 38 }, {   0,  0 }, {  1,   4 }, {  69, 33 }, {  5, 16 },
+      {   0,  1 }, {   0,  1 }, {  0,   0 }, {   0,  1 }, {  0,  0 }, },
+    { { 187, 22 }, {   1,  1 }, {  0,  17 }, {   0,  0 }, {  0,  0 },
+      {   3,  6 }, {   0,  4 }, {  0,   1 }, {   4,  4 }, {  0,  1 }, },
+    { { 123, 29 }, {   0,  0 }, {  1,   7 }, {  57, 30 }, {  0,  0 },
+      {   0,  1 }, {   0,  1 }, {  0,   1 }, {   0,  1 }, {  0,  0 }, }, },
+  { { {  16, 20 }, {   0,  0 }, {  2,   8 }, { 104, 49 }, { 15, 33 },
+      {   0,  1 }, {   0,  1 }, {  0,   1 }, {   1,  1 }, {  0,  0 }, },
+    { { 133,  6 }, {   1,  2 }, {  1,  70 }, {   0,  0 }, {  0,  0 },
+      {   0,  2 }, {   0,  4 }, {  0,   3 }, {   1,  1 }, {  0,  0 }, },
+    { {  13, 14 }, {   0,  0 }, {  4,  20 }, { 175, 20 }, {  0,  0 },
+      {   0,  1 }, {   0,  1 }, {  0,   1 }, {   1,  1 }, {  0,  0 }, }, },
+  { { { 194, 16 }, {   0,  0 }, {  1,   1 }, {   1,  9 }, {  1,  3 },
+      {   0,  0 }, {   0,  1 }, {  0,   1 }, {   0,  0 }, {  0,  0 }, },
+    { { 251,  1 }, {   0,  0 }, {  0,   2 }, {   0,  0 }, {  0,  0 },
+      {   0,  0 }, {   0,  0 }, {  0,   0 }, {   0,  0 }, {  0,  0 }, },
+    { { 202, 23 }, {   0,  0 }, {  1,   3 }, {   2,  9 }, {  0,  0 },
+      {   0,  1 }, {   0,  1 }, {  0,   1 }, {   0,  0 }, {  0,  0 }, }, },
+};
+
+static const uint8_t vp56_filter_threshold[] = {
+    14, 14, 13, 13, 12, 12, 10, 10,
+    10, 10,  8,  8,  8,  8,  8,  8,
+     8,  8,  8,  8,  8,  8,  8,  8,
+     8,  8,  8,  8,  8,  8,  8,  8,
+     8,  8,  8,  8,  7,  7,  7,  7,
+     7,  7,  6,  6,  6,  6,  6,  6,
+     5,  5,  5,  5,  4,  4,  4,  4,
+     4,  4,  4,  3,  3,  3,  3,  2,
+};
+
+static const uint8_t vp56_mb_type_model_model[] = {
+    171, 83, 199, 140, 125, 104,
+};
+
+static const vp56_tree_t vp56_pmbtm_tree[] = {
+    { 4, 0},
+    { 2, 1}, {-8}, {-4},
+    { 8, 2},
+    { 6, 3},
+    { 4, 4},
+    { 2, 5}, {-24}, {-20}, {-16}, {-12}, {-0},
+};
+
+static const vp56_tree_t vp56_pmbt_tree[] = {
+    { 8, 1},
+    { 4, 2},
+    { 2, 4}, {-VP56_MB_INTER_NOVEC_PF}, {-VP56_MB_INTER_DELTA_PF},
+    { 2, 5}, {-VP56_MB_INTER_V1_PF},    {-VP56_MB_INTER_V2_PF},
+    { 4, 3},
+    { 2, 6}, {-VP56_MB_INTRA},          {-VP56_MB_INTER_4V},
+    { 4, 7},
+    { 2, 8}, {-VP56_MB_INTER_NOVEC_GF}, {-VP56_MB_INTER_DELTA_GF},
+    { 2, 9}, {-VP56_MB_INTER_V1_GF},    {-VP56_MB_INTER_V2_GF},
+};
+
+/* relative pos of surrounding blocks, from closest to farthest */
+static const int8_t vp56_candidate_predictor_pos[12][2] = {
+    {  0, -1 },
+    { -1,  0 },
+    { -1, -1 },
+    {  1, -1 },
+    {  0, -2 },
+    { -2,  0 },
+    { -2, -1 },
+    { -1, -2 },
+    {  1, -2 },
+    {  2, -1 },
+    { -2, -2 },
+    {  2, -2 },
+};
+
+#endif /* VP56DATA */

Added: trunk/libavcodec/vp5data.h
==============================================================================
--- (empty file)
+++ trunk/libavcodec/vp5data.h	Sat Sep  9 19:19:37 2006
@@ -0,0 +1,173 @@
+/**
+ * @file vp5data.h
+ * VP5 compatible video decoder
+ *
+ * Copyright (C) 2006  Aurelien Jacobs <aurel at gnuage.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef VP5DATA_H
+#define VP5DATA_H
+
+#include <inttypes.h>
+
+static const uint8_t vp5_coeff_groups[] = {
+    -1, 0, 1, 1, 2, 1, 1, 2,
+     2, 1, 1, 2, 2, 2, 1, 2,
+     2, 2, 2, 2, 1, 1, 2, 2,
+     3, 3, 4, 3, 4, 4, 4, 3,
+     3, 3, 3, 3, 4, 3, 3, 3,
+     4, 4, 4, 4, 4, 3, 3, 4,
+     4, 4, 3, 4, 4, 4, 4, 4,
+     4, 4, 5, 5, 5, 5, 5, 5,
+};
+
+static const uint8_t vp5_vmc_pct[2][11] = {
+    { 243, 220, 251, 253, 237, 232, 241, 245, 247, 251, 253 },
+    { 235, 211, 246, 249, 234, 231, 248, 249, 252, 252, 254 },
+};
+
+static const uint8_t vp5_dccv_pct[2][11] = {
+    { 146, 197, 181, 207, 232, 243, 238, 251, 244, 250, 249 },
+    { 179, 219, 214, 240, 250, 254, 244, 254, 254, 254, 254 },
+};
+
+static const uint8_t vp5_ract_pct[3][2][6][11] = {
+    { { { 227, 246, 230, 247, 244, 254, 254, 254, 254, 254, 254 },
+        { 202, 254, 209, 231, 231, 249, 249, 253, 254, 254, 254 },
+        { 206, 254, 225, 242, 241, 251, 253, 254, 254, 254, 254 },
+        { 235, 254, 241, 253, 252, 254, 254, 254, 254, 254, 254 },
+        { 234, 254, 248, 254, 254, 254, 254, 254, 254, 254, 254 },
+        { 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 } },
+      { { 240, 254, 248, 254, 254, 254, 254, 254, 254, 254, 254 },
+        { 238, 254, 240, 253, 254, 254, 254, 254, 254, 254, 254 },
+        { 244, 254, 251, 254, 254, 254, 254, 254, 254, 254, 254 },
+        { 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 },
+        { 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 },
+        { 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 } } },
+    { { { 206, 203, 227, 239, 247, 254, 253, 254, 254, 254, 254 },
+        { 207, 199, 220, 236, 243, 252, 252, 254, 254, 254, 254 },
+        { 212, 219, 230, 243, 244, 253, 252, 254, 254, 254, 254 },
+        { 236, 237, 247, 252, 253, 254, 254, 254, 254, 254, 254 },
+        { 240, 240, 248, 254, 254, 254, 254, 254, 254, 254, 254 },
+        { 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 } },
+      { { 230, 233, 249, 254, 254, 254, 254, 254, 254, 254, 254 },
+        { 238, 238, 250, 254, 254, 254, 254, 254, 254, 254, 254 },
+        { 248, 251, 254, 254, 254, 254, 254, 254, 254, 254, 254 },
+        { 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 },
+        { 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 },
+        { 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 } } },
+    { { { 225, 239, 227, 231, 244, 253, 243, 254, 254, 253, 254 },
+        { 232, 234, 224, 228, 242, 249, 242, 252, 251, 251, 254 },
+        { 235, 249, 238, 240, 251, 254, 249, 254, 253, 253, 254 },
+        { 249, 253, 251, 250, 254, 254, 254, 254, 254, 254, 254 },
+        { 251, 250, 249, 254, 254, 254, 254, 254, 254, 254, 254 },
+        { 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 } },
+      { { 243, 244, 250, 250, 254, 254, 254, 254, 254, 254, 254 },
+        { 249, 248, 250, 253, 254, 254, 254, 254, 254, 254, 254 },
+        { 253, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 },
+        { 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 },
+        { 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 },
+        { 254, 254, 254, 254, 254, 254, 254, 254, 254, 254, 254 } } },
+};
+
+static const int16_t vp5_dccv_lc[5][36][2] = {
+    { {154,  61}, {141,  54}, { 90,  45}, { 54,  34}, { 54,  13}, {128, 109},
+      {136,  54}, {148,  45}, { 92,  41}, { 54,  33}, { 51,  15}, { 87, 113},
+      { 87,  44}, { 97,  40}, { 67,  36}, { 46,  29}, { 41,  15}, { 64,  80},
+      { 59,  33}, { 61,  31}, { 51,  28}, { 44,  22}, { 33,  12}, { 49,  63},
+      { 69,  12}, { 59,  16}, { 46,  14}, { 31,  13}, { 26,   6}, { 92,  26},
+      {128, 108}, { 77, 119}, { 54,  84}, { 26,  71}, { 87,  19}, { 95, 155} },
+    { {154,   4}, {182,   0}, {159,  -8}, {128,  -5}, {143,  -5}, {187,  55},
+      {182,   0}, {228,  -3}, {187,  -7}, {174,  -9}, {189, -11}, {169,  79},
+      {161,  -9}, {192,  -8}, {187,  -9}, {169, -10}, {136,  -9}, {184,  40},
+      {164, -11}, {179, -10}, {174, -10}, {161, -10}, {115,  -7}, {197,  20},
+      {195, -11}, {195, -11}, {146, -10}, {110,  -6}, { 95,  -4}, {195,  39},
+      {182,  55}, {172,  77}, {177,  37}, {169,  29}, {172,  52}, { 92, 162} },
+    { {174,  80}, {164,  80}, { 95,  80}, { 46,  66}, { 56,  24}, { 36, 193},
+      {164,  80}, {166,  77}, {105,  76}, { 49,  68}, { 46,  31}, { 49, 186},
+      { 97,  78}, {110,  74}, { 72,  72}, { 44,  60}, { 33,  30}, { 69, 131},
+      { 61,  61}, { 69,  63}, { 51,  57}, { 31,  48}, { 26,  27}, { 64,  89},
+      { 67,  23}, { 51,  32}, { 36,  33}, { 26,  28}, { 20,  12}, { 44,  68},
+      { 26, 197}, { 41, 189}, { 61, 129}, { 28, 103}, { 49,  52}, {-12, 245} },
+    { {102, 141}, { 79, 166}, { 72, 162}, { 97, 125}, {179,   4}, {307,   0},
+      { 72, 168}, { 69, 175}, { 84, 160}, {105, 127}, {148,  34}, {310,   0},
+      { 84, 151}, { 82, 161}, { 87, 153}, { 87, 135}, {115,  51}, {317,   0},
+      { 97, 125}, {102, 131}, {105, 125}, { 87, 122}, { 84,  64}, { 54, 184},
+      {166,  18}, {146,  43}, {125,  51}, { 90,  64}, { 95,   7}, { 38, 154},
+      {294,   0}, { 13, 225}, { 10, 225}, { 67, 168}, {  0, 167}, {161,  94} },
+    { {172,  76}, {172,  75}, {136,  80}, { 64,  98}, { 74,  67}, {315,   0},
+      {169,  76}, {207,  56}, {164,  66}, { 97,  80}, { 67,  72}, {328,   0},
+      {136,  80}, {187,  53}, {154,  62}, { 72,  85}, { -2, 105}, {305,   0},
+      { 74,  91}, {128,  64}, {113,  64}, { 61,  77}, { 41,  75}, {259,   0},
+      { 46,  84}, { 51,  81}, { 28,  89}, { 31,  78}, { 23,  77}, {202,   0},
+      {323,   0}, {323,   0}, {300,   0}, {236,   0}, {195,   0}, {328,   0} },
+};
+
+static const int16_t vp5_ract_lc[3][3][5][6][2] = {
+    { { { {276,  0}, {238,  0}, {195,  0}, {156,  0}, {113,  0}, {274,  0} },
+        { {  0,  1}, {  0,  1}, {  0,  1}, {  0,  1}, {  0,  1}, {  0,  1} },
+        { {192, 59}, {182, 50}, {141, 48}, {110, 40}, { 92, 19}, {125,128} },
+        { {169, 87}, {169, 83}, {184, 62}, {220, 16}, {184,  0}, {264,  0} },
+        { {212, 40}, {212, 36}, {169, 49}, {174, 27}, {  8,120}, {182, 71} } },
+      { { {259, 10}, {197, 19}, {143, 22}, {123, 16}, {110,  8}, {133, 88} },
+        { {  0,  1}, {256,  0}, {  0,  1}, {  0,  1}, {  0,  1}, {  0,  1} },
+        { {207, 46}, {187, 50}, { 97, 83}, { 23,100}, { 41, 56}, { 56,188} },
+        { {166, 90}, {146,108}, {161, 88}, {136, 95}, {174,  0}, {266,  0} },
+        { {264,  7}, {243, 18}, {184, 43}, {-14,154}, { 20,112}, { 20,199} } },
+      { { {230, 26}, {197, 22}, {159, 20}, {146, 12}, {136,  4}, { 54,162} },
+        { {  0,  1}, {  0,  1}, {  0,  1}, {  0,  1}, {  0,  1}, {  0,  1} },
+        { {192, 59}, {156, 72}, { 84,101}, { 49,101}, { 79, 47}, { 79,167} },
+        { {138,115}, {136,116}, {166, 80}, {238,  0}, {195,  0}, {261,  0} },
+        { {225, 33}, {205, 42}, {159, 61}, { 79, 96}, { 92, 66}, { 28,195} } },
+    }, {
+      { { {200, 37}, {197, 18}, {159, 13}, {143,  7}, {102,  5}, {123,126} },
+        { {197,  3}, {220, -9}, {210,-12}, {187, -6}, {151, -2}, {174, 80} },
+        { {200, 53}, {187, 47}, {159, 40}, {118, 38}, {100, 18}, {141,111} },
+        { {179, 78}, {166, 86}, {197, 50}, {207, 27}, {187,  0}, {115,139} },
+        { {218, 34}, {220, 29}, {174, 46}, {128, 61}, { 54, 89}, {187, 65} } },
+      { { {238, 14}, {197, 18}, {125, 26}, { 90, 25}, { 82, 13}, {161, 86} },
+        { {189,  1}, {205, -2}, {156, -4}, {143, -4}, {146, -4}, {172, 72} },
+        { {230, 31}, {192, 45}, {102, 76}, { 38, 85}, { 56, 41}, { 64,173} },
+        { {166, 91}, {141,111}, {128,116}, {118,109}, {177,  0}, { 23,222} },
+        { {253, 14}, {236, 21}, {174, 49}, { 33,118}, { 44, 93}, { 23,187} } },
+      { { {218, 28}, {179, 28}, {118, 35}, { 95, 30}, { 72, 24}, {128,108} },
+        { {187,  1}, {174, -1}, {125, -1}, {110, -1}, {108, -1}, {202, 52} },
+        { {197, 53}, {146, 75}, { 46,118}, { 33,103}, { 64, 50}, {118,126} },
+        { {138,114}, {128,122}, {161, 86}, {243, -6}, {195,  0}, { 38,210} },
+        { {215, 39}, {179, 58}, { 97,101}, { 95, 85}, { 87, 70}, { 69,152} } },
+    }, {
+      { { {236, 24}, {205, 18}, {172, 12}, {154,  6}, {125,  1}, {169, 75} },
+        { {187,  4}, {230, -2}, {228, -4}, {236, -4}, {241, -2}, {192, 66} },
+        { {200, 46}, {187, 42}, {159, 34}, {136, 25}, {105, 10}, {179, 62} },
+        { {207, 55}, {192, 63}, {192, 54}, {195, 36}, {177,  1}, {143, 98} },
+        { {225, 27}, {207, 34}, {200, 30}, {131, 57}, { 97, 60}, {197, 45} } },
+      { { {271,  8}, {218, 13}, {133, 19}, { 90, 19}, { 72,  7}, {182, 51} },
+        { {179,  1}, {225, -1}, {154, -2}, {110, -1}, { 92,  0}, {195, 41} },
+        { {241, 26}, {189, 40}, { 82, 64}, { 33, 60}, { 67, 17}, {120, 94} },
+        { {192, 68}, {151, 94}, {146, 90}, {143, 72}, {161,  0}, {113,128} },
+        { {256, 12}, {218, 29}, {166, 48}, { 44, 99}, { 31, 87}, {148, 78} } },
+      { { {238, 20}, {184, 22}, {113, 27}, { 90, 22}, { 74,  9}, {192, 37} },
+        { {184,  0}, {215, -1}, {141, -1}, { 97,  0}, { 49,  0}, {264, 13} },
+        { {182, 51}, {138, 61}, { 95, 63}, { 54, 59}, { 64, 25}, {200, 45} },
+        { {179, 75}, {156, 87}, {174, 65}, {177, 44}, {174,  0}, {164, 85} },
+        { {195, 45}, {148, 65}, {105, 79}, { 95, 72}, { 87, 60}, {169, 63} } },
+    }
+};
+
+static const uint8_t vp5_coord_div[] = { 2, 2, 2, 2, 4, 4 };
+
+#endif /* VP5DATA_H */

Added: trunk/libavcodec/vp6.c
==============================================================================
--- (empty file)
+++ trunk/libavcodec/vp6.c	Sat Sep  9 19:19:37 2006
@@ -0,0 +1,512 @@
+/**
+ * @file vp6.c
+ * VP6 compatible video decoder
+ *
+ * Copyright (C) 2006  Aurelien Jacobs <aurel at gnuage.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include <stdlib.h>
+#include <inttypes.h>
+
+#include "avcodec.h"
+#include "dsputil.h"
+#include "bitstream.h"
+#include "mpegvideo.h"
+
+#include "vp56.h"
+#include "vp56data.h"
+#include "vp6data.h"
+
+
+static int vp6_parse_header(vp56_context_t *s, uint8_t *buf, int buf_size,
+                            int *golden_frame)
+{
+    vp56_range_coder_t *c = &s->c;
+    int parse_filter_info;
+    int rows, cols;
+    int res = 1;
+
+    if (buf[0] & 1)
+        return 0;
+
+    s->frames[VP56_FRAME_CURRENT].key_frame = !(buf[0] & 0x80);
+    vp56_init_dequant(s, (buf[0] >> 1) & 0x3F);
+
+    if (s->frames[VP56_FRAME_CURRENT].key_frame) {
+        if ((buf[1] & 0xFE) != 0x46)  /* would be 0x36 for VP61 */
+            return 0;
+        if (buf[1] & 1) {
+            av_log(s->avctx, AV_LOG_ERROR, "interlacing not supported\n");
+            return 0;
+        }
+
+        rows = buf[2];  /* number of stored macroblock rows */
+        cols = buf[3];  /* number of stored macroblock cols */
+        /* buf[4] is number of displayed macroblock rows */
+        /* buf[5] is number of displayed macroblock cols */
+
+        if (16*cols != s->avctx->coded_width ||
+            16*rows != s->avctx->coded_height) {
+            avcodec_set_dimensions(s->avctx, 16*cols, 16*rows);
+            res = 2;
+        }
+
+        vp56_init_range_decoder(c, buf+6, buf_size-6);
+        vp56_rac_gets(c, 2);
+
+        parse_filter_info = 1;
+    } else {
+        vp56_init_range_decoder(c, buf+1, buf_size-1);
+
+        *golden_frame = vp56_rac_get(c);
+        s->deblock_filtering = vp56_rac_get(c);
+        if (s->deblock_filtering)
+            vp56_rac_get(c);
+        parse_filter_info = vp56_rac_get(c);
+    }
+
+    if (parse_filter_info) {
+        if (vp56_rac_get(c)) {
+            s->filter_mode = 2;
+            s->sample_variance_threshold = vp56_rac_gets(c, 5);
+            s->max_vector_length = 2 << vp56_rac_gets(c, 3);
+        } else if (vp56_rac_get(c)) {
+            s->filter_mode = 1;
+        } else {
+            s->filter_mode = 0;
+        }
+        s->filter_selection = vp56_rac_gets(c, 4);
+    }
+
+    vp56_rac_get(c);
+    return res;
+}
+
+static void vp6_coeff_order_table_init(vp56_context_t *s)
+{
+    int i, pos, idx = 1;
+
+    s->coeff_index_to_pos[0] = 0;
+    for (i=0; i<16; i++)
+        for (pos=1; pos<64; pos++)
+            if (s->coeff_reorder[pos] == i)
+                s->coeff_index_to_pos[idx++] = pos;
+}
+
+static void vp6_default_models_init(vp56_context_t *s)
+{
+    s->vector_model_dct[0] = 0xA2;
+    s->vector_model_dct[1] = 0xA4;
+    s->vector_model_sig[0] = 0x80;
+    s->vector_model_sig[1] = 0x80;
+
+    memcpy(s->mb_types_stats, vp56_def_mb_types_stats, sizeof(s->mb_types_stats));
+    memcpy(s->vector_model_fdv, vp6_def_fdv_vector_model, sizeof(s->vector_model_fdv));
+    memcpy(s->vector_model_pdv, vp6_def_pdv_vector_model, sizeof(s->vector_model_pdv));
+    memcpy(s->coeff_model_runv, vp6_def_runv_coeff_model, sizeof(s->coeff_model_runv));
+    memcpy(s->coeff_reorder, vp6_def_coeff_reorder, sizeof(s->coeff_reorder));
+
+    vp6_coeff_order_table_init(s);
+}
+
+static void vp6_parse_vector_models(vp56_context_t *s)
+{
+    vp56_range_coder_t *c = &s->c;
+    int comp, node;
+
+    for (comp=0; comp<2; comp++) {
+        if (vp56_rac_get_prob(c, vp6_sig_dct_pct[comp][0]))
+            s->vector_model_dct[comp] = vp56_rac_gets_nn(c, 7);
+        if (vp56_rac_get_prob(c, vp6_sig_dct_pct[comp][1]))
+            s->vector_model_sig[comp] = vp56_rac_gets_nn(c, 7);
+    }
+
+    for (comp=0; comp<2; comp++)
+        for (node=0; node<7; node++)
+            if (vp56_rac_get_prob(c, vp6_pdv_pct[comp][node]))
+                s->vector_model_pdv[comp][node] = vp56_rac_gets_nn(c, 7);
+
+    for (comp=0; comp<2; comp++)
+        for (node=0; node<8; node++)
+            if (vp56_rac_get_prob(c, vp6_fdv_pct[comp][node]))
+                s->vector_model_fdv[comp][node] = vp56_rac_gets_nn(c, 7);
+}
+
+static void vp6_parse_coeff_models(vp56_context_t *s)
+{
+    vp56_range_coder_t *c = &s->c;
+    int def_prob[11];
+    int node, cg, ctx, pos;
+    int ct;    /* code type */
+    int pt;    /* plane type (0 for Y, 1 for U or V) */
+
+    memset(def_prob, 0x80, sizeof(def_prob));
+
+    for (pt=0; pt<2; pt++)
+        for (node=0; node<11; node++)
+            if (vp56_rac_get_prob(c, vp6_dccv_pct[pt][node])) {
+                def_prob[node] = vp56_rac_gets_nn(c, 7);
+                s->coeff_model_dccv[pt][node] = def_prob[node];
+            } else if (s->frames[VP56_FRAME_CURRENT].key_frame) {
+                s->coeff_model_dccv[pt][node] = def_prob[node];
+            }
+
+    if (vp56_rac_get(c)) {
+        for (pos=1; pos<64; pos++)
+            if (vp56_rac_get_prob(c, vp6_coeff_reorder_pct[pos]))
+                s->coeff_reorder[pos] = vp56_rac_gets(c, 4);
+        vp6_coeff_order_table_init(s);
+    }
+
+    for (cg=0; cg<2; cg++)
+        for (node=0; node<14; node++)
+            if (vp56_rac_get_prob(c, vp6_runv_pct[cg][node]))
+                s->coeff_model_runv[cg][node] = vp56_rac_gets_nn(c, 7);
+
+    for (ct=0; ct<3; ct++)
+        for (pt=0; pt<2; pt++)
+            for (cg=0; cg<6; cg++)
+                for (node=0; node<11; node++)
+                    if (vp56_rac_get_prob(c, vp6_ract_pct[ct][pt][cg][node])) {
+                        def_prob[node] = vp56_rac_gets_nn(c, 7);
+                        s->coeff_model_ract[pt][ct][cg][node] = def_prob[node];
+                    } else if (s->frames[VP56_FRAME_CURRENT].key_frame) {
+                        s->coeff_model_ract[pt][ct][cg][node] = def_prob[node];
+                    }
+
+    /* coeff_model_dcct is a linear combination of coeff_model_dccv */
+    for (pt=0; pt<2; pt++)
+        for (ctx=0; ctx<3; ctx++)
+            for (node=0; node<5; node++)
+                s->coeff_model_dcct[pt][ctx][node] = clip(((s->coeff_model_dccv[pt][node] * vp6_dccv_lc[ctx][node][0] + 128) >> 8) + vp6_dccv_lc[ctx][node][1], 1, 255);
+}
+
+static void vp6_parse_vector_adjustment(vp56_context_t *s, vp56_mv_t *vector)
+{
+    vp56_range_coder_t *c = &s->c;
+    int comp;
+
+    *vector = (vp56_mv_t) {0,0};
+    if (s->vector_candidate_pos < 2)
+        *vector = s->vector_candidate[0];
+
+    for (comp=0; comp<2; comp++) {
+        int i, delta = 0;
+
+        if (vp56_rac_get_prob(c, s->vector_model_dct[comp])) {
+            static const uint8_t prob_order[] = {0, 1, 2, 7, 6, 5, 4};
+            for (i=0; i<sizeof(prob_order); i++) {
+                int j = prob_order[i];
+                delta |= vp56_rac_get_prob(c, s->vector_model_fdv[comp][j])<<j;
+            }
+            if (delta & 0xF0)
+                delta |= vp56_rac_get_prob(c, s->vector_model_fdv[comp][3])<<3;
+            else
+                delta |= 8;
+        } else {
+            delta = vp56_rac_get_tree(c, vp56_pva_tree,
+                                      s->vector_model_pdv[comp]);
+        }
+
+        if (delta && vp56_rac_get_prob(c, s->vector_model_sig[comp]))
+            delta = -delta;
+
+        if (!comp)
+            vector->x += delta;
+        else
+            vector->y += delta;
+    }
+}
+
+static void vp6_parse_coeff(vp56_context_t *s)
+{
+    vp56_range_coder_t *c = &s->c;
+    uint8_t *permute = s->scantable.permutated;
+    uint8_t *model, *model2, *model3;
+    int coeff, sign, coeff_idx;
+    int b, i, cg, idx, ctx;
+    int pt = 0;    /* plane type (0 for Y, 1 for U or V) */
+
+    for (b=0; b<6; b++) {
+        int ct = 1;    /* code type */
+        int run = 1;
+
+        if (b > 3) pt = 1;
+
+        ctx = s->left_block[vp56_b6to4[b]].not_null_dc
+              + s->above_blocks[s->above_block_idx[b]].not_null_dc;
+        model = s->coeff_model_dccv[pt];
+        model2 = s->coeff_model_dcct[pt][ctx];
+
+        for (coeff_idx=0; coeff_idx<64; ) {
+            if ((coeff_idx>1 && ct==0) || vp56_rac_get_prob(c, model2[0])) {
+                /* parse a coeff */
+                if (coeff_idx == 0) {
+                    s->left_block[vp56_b6to4[b]].not_null_dc = 1;
+                    s->above_blocks[s->above_block_idx[b]].not_null_dc = 1;
+                }
+
+                if (vp56_rac_get_prob(c, model2[2])) {
+                    if (vp56_rac_get_prob(c, model2[3])) {
+                        idx = vp56_rac_get_tree(c, vp56_pc_tree, model);
+                        coeff = vp56_coeff_bias[idx];
+                        for (i=vp56_coeff_bit_length[idx]; i>=0; i--)
+                            coeff += vp56_rac_get_prob(c, vp56_coeff_parse_table[idx][i]) << i;
+                    } else {
+                        if (vp56_rac_get_prob(c, model2[4]))
+                            coeff = 3 + vp56_rac_get_prob(c, model[5]);
+                        else
+                            coeff = 2;
+                    }
+                    ct = 2;
+                } else {
+                    ct = 1;
+                    coeff = 1;
+                }
+                sign = vp56_rac_get(c);
+                coeff = (coeff ^ -sign) + sign;
+                if (coeff_idx)
+                    coeff *= s->dequant_ac;
+                idx = s->coeff_index_to_pos[coeff_idx];
+                s->block_coeff[b][permute[idx]] = coeff;
+                run = 1;
+            } else {
+                /* parse a run */
+                ct = 0;
+                if (coeff_idx == 0) {
+                    s->left_block[vp56_b6to4[b]].not_null_dc = 0;
+                    s->above_blocks[s->above_block_idx[b]].not_null_dc = 0;
+                } else {
+                    if (!vp56_rac_get_prob(c, model2[1]))
+                        break;
+
+                    model3 = s->coeff_model_runv[coeff_idx >= 6];
+                    run = vp56_rac_get_tree(c, vp6_pcr_tree, model3);
+                    if (!run)
+                        for (run=9, i=0; i<6; i++)
+                            run += vp56_rac_get_prob(c, model3[i+8]) << i;
+                }
+            }
+
+            cg = vp6_coeff_groups[coeff_idx+=run];
+            model = model2 = s->coeff_model_ract[pt][ct][cg];
+        }
+    }
+}
+
+static int vp6_adjust(int v, int t)
+{
+    int V = v, s = v >> 31;
+    V ^= s;
+    V -= s;
+    if (V-t-1 >= (unsigned)(t-1))
+        return v;
+    V = 2*t - V;
+    V += s;
+    V ^= s;
+    return V;
+}
+
+static int vp6_block_variance(uint8_t *src, int stride)
+{
+    int sum = 0, square_sum = 0;
+    int y, x;
+
+    for (y=0; y<8; y+=2) {
+        for (x=0; x<8; x+=2) {
+            sum += src[x];
+            square_sum += src[x]*src[x];
+        }
+        src += 2*stride;
+    }
+    return (16*square_sum - sum*sum) / (16*16);
+}
+
+static void vp6_filter_hv2(vp56_context_t *s, uint8_t *dst, uint8_t *src,
+                           int stride, int delta, int16_t weight)
+{
+    s->dsp.put_pixels_tab[1][0](dst, src, stride, 8);
+    s->dsp.biweight_h264_pixels_tab[3](dst, src+delta, stride, 2,
+                                       8-weight, weight, 0);
+}
+
+static void vp6_filter_hv4(uint8_t *dst, uint8_t *src, int stride,
+                           int delta, const int16_t *weights)
+{
+    int x, y;
+
+    for (y=0; y<8; y++) {
+        for (x=0; x<8; x++) {
+            dst[x] = clip_uint8((  src[x-delta  ] * weights[0]
+                                 + src[x        ] * weights[1]
+                                 + src[x+delta  ] * weights[2]
+                                 + src[x+2*delta] * weights[3] + 64) >> 7);
+        }
+        src += stride;
+        dst += stride;
+    }
+}
+
+static void vp6_filter_diag2(vp56_context_t *s, uint8_t *dst, uint8_t *src,
+                             int stride, int h_weight, int v_weight)
+{
+    uint8_t *tmp = s->edge_emu_buffer+16;
+    int x, xmax;
+
+    s->dsp.put_pixels_tab[1][0](tmp, src, stride, 8);
+    s->dsp.biweight_h264_pixels_tab[3](tmp, src+1, stride, 2,
+                                       8-h_weight, h_weight, 0);
+    /* we need a 8x9 block to do vertical filter, so compute one more line */
+    for (x=8*stride, xmax=x+8; x<xmax; x++)
+        tmp[x] = (src[x]*(8-h_weight) + src[x+1]*h_weight + 4) >> 3;
+
+    s->dsp.put_pixels_tab[1][0](dst, tmp, stride, 8);
+    s->dsp.biweight_h264_pixels_tab[3](dst, tmp+stride, stride, 2,
+                                       8-v_weight, v_weight, 0);
+}
+
+static void vp6_filter_diag4(uint8_t *dst, uint8_t *src, int stride,
+                             const int16_t *h_weights,const int16_t *v_weights)
+{
+    int x, y;
+    int tmp[8*11];
+    int *t = tmp;
+
+    src -= stride;
+
+    for (y=0; y<11; y++) {
+        for (x=0; x<8; x++) {
+            t[x] = clip_uint8((  src[x-1] * h_weights[0]
+                               + src[x  ] * h_weights[1]
+                               + src[x+1] * h_weights[2]
+                               + src[x+2] * h_weights[3] + 64) >> 7);
+        }
+        src += stride;
+        t += 8;
+    }
+
+    t = tmp + 8;
+    for (y=0; y<8; y++) {
+        for (x=0; x<8; x++) {
+            dst[x] = clip_uint8((  t[x-8 ] * v_weights[0]
+                                 + t[x   ] * v_weights[1]
+                                 + t[x+8 ] * v_weights[2]
+                                 + t[x+16] * v_weights[3] + 64) >> 7);
+        }
+        dst += stride;
+        t += 8;
+    }
+}
+
+static void vp6_filter(vp56_context_t *s, uint8_t *dst, uint8_t *src,
+                       int offset1, int offset2, int stride,
+                       vp56_mv_t mv, int mask, int select, int luma)
+{
+    int filter4 = 0;
+    int x8 = mv.x & mask;
+    int y8 = mv.y & mask;
+
+    if (luma) {
+        x8 *= 2;
+        y8 *= 2;
+        filter4 = s->filter_mode;
+        if (filter4 == 2) {
+            if (s->max_vector_length &&
+                (ABS(mv.x) > s->max_vector_length ||
+                 ABS(mv.y) > s->max_vector_length)) {
+                filter4 = 0;
+            } else if (!s->sample_variance_threshold
+                       || (vp6_block_variance(src+offset1, stride)
+                           < s->sample_variance_threshold)) {
+                filter4 = 0;
+            }
+        }
+    }
+
+    if ((y8 && (offset2-offset1)*s->flip<0) || (!y8 && offset1 > offset2)) {
+        offset1 = offset2;
+    }
+
+    if (filter4) {
+        if (!y8) {                      /* left or right combine */
+            vp6_filter_hv4(dst, src+offset1, stride, 1,
+                           vp6_block_copy_filter[select][x8]);
+        } else if (!x8) {               /* above or below combine */
+            vp6_filter_hv4(dst, src+offset1, stride, stride,
+                           vp6_block_copy_filter[select][y8]);
+        } else if ((mv.x^mv.y) >> 31) { /* lower-left or upper-right combine */
+            vp6_filter_diag4(dst, src+offset1-1, stride,
+                             vp6_block_copy_filter[select][x8],
+                             vp6_block_copy_filter[select][y8]);
+        } else {                        /* lower-right or upper-left combine */
+            vp6_filter_diag4(dst, src+offset1, stride,
+                             vp6_block_copy_filter[select][x8],
+                             vp6_block_copy_filter[select][y8]);
+        }
+    } else {
+        if (!y8) {                      /* left or right combine */
+            vp6_filter_hv2(s, dst, src+offset1, stride, 1, x8);
+        } else if (!x8) {               /* above or below combine */
+            vp6_filter_hv2(s, dst, src+offset1, stride, stride, y8);
+        } else if ((mv.x^mv.y) >> 31) { /* lower-left or upper-right combine */
+            vp6_filter_diag2(s, dst, src+offset1-1, stride, x8, y8);
+        } else {                        /* lower-right or upper-left combine */
+            vp6_filter_diag2(s, dst, src+offset1, stride, x8, y8);
+        }
+    }
+}
+
+static int vp6_decode_init(AVCodecContext *avctx)
+{
+    vp56_context_t *s = avctx->priv_data;
+
+    vp56_init(s, avctx, avctx->codec->id == CODEC_ID_VP6);
+    s->vp56_coord_div = vp6_coord_div;
+    s->parse_vector_adjustment = vp6_parse_vector_adjustment;
+    s->adjust = vp6_adjust;
+    s->filter = vp6_filter;
+    s->parse_coeff = vp6_parse_coeff;
+    s->default_models_init = vp6_default_models_init;
+    s->parse_vector_models = vp6_parse_vector_models;
+    s->parse_coeff_models = vp6_parse_coeff_models;
+    s->parse_header = vp6_parse_header;
+
+    return 0;
+}
+
+AVCodec vp6_decoder = {
+    "vp6",
+    CODEC_TYPE_VIDEO,
+    CODEC_ID_VP6,
+    sizeof(vp56_context_t),
+    vp6_decode_init,
+    NULL,
+    vp56_free,
+    vp56_decode_frame,
+};
+
+/* flash version, not flipped upside-down */
+AVCodec vp6f_decoder = {
+    "vp6f",
+    CODEC_TYPE_VIDEO,
+    CODEC_ID_VP6F,
+    sizeof(vp56_context_t),
+    vp6_decode_init,
+    NULL,
+    vp56_free,
+    vp56_decode_frame,
+};

Added: trunk/libavcodec/vp6data.h
==============================================================================
--- (empty file)
+++ trunk/libavcodec/vp6data.h	Sat Sep  9 19:19:37 2006
@@ -0,0 +1,291 @@
+/**
+ * @file vp6data.h
+ * VP6 compatible video decoder
+ *
+ * Copyright (C) 2006  Aurelien Jacobs <aurel at gnuage.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef VP6DATA_H
+#define VP6DATA_H
+
+#include <inttypes.h>
+#include "vp56data.h"
+
+static const uint8_t vp6_def_fdv_vector_model[2][8] = {
+    { 247, 210, 135, 68, 138, 220, 239, 246 },
+    { 244, 184, 201, 44, 173, 221, 239, 253 },
+};
+
+static const uint8_t vp6_def_pdv_vector_model[2][7] = {
+    { 225, 146, 172, 147, 214,  39, 156 },
+    { 204, 170, 119, 235, 140, 230, 228 },
+};
+
+static const uint8_t vp6_def_coeff_reorder[] = {
+     0,  0,  1,  1,  1,  2,  2,  2,
+     2,  2,  2,  3,  3,  4,  4,  4,
+     5,  5,  5,  5,  6,  6,  7,  7,
+     7,  7,  7,  8,  8,  9,  9,  9,
+     9,  9,  9, 10, 10, 11, 11, 11,
+    11, 11, 11, 12, 12, 12, 12, 12,
+    12, 13, 13, 13, 13, 13, 14, 14,
+    14, 14, 15, 15, 15, 15, 15, 15,
+};
+
+static const uint8_t vp6_def_runv_coeff_model[2][14] = {
+    { 198, 197, 196, 146, 198, 204, 169, 142, 130, 136, 149, 149, 191, 249 },
+    { 135, 201, 181, 154,  98, 117, 132, 126, 146, 169, 184, 240, 246, 254 },
+};
+
+static const uint8_t vp6_sig_dct_pct[2][2] = {
+    { 237, 246 },
+    { 231, 243 },
+};
+
+static const uint8_t vp6_pdv_pct[2][7] = {
+    { 253, 253, 254, 254, 254, 254, 254 },
+    { 245, 253, 254, 254, 254, 254, 254 },
+};
+
+static const uint8_t vp6_fdv_pct[2][8] = {
+    { 254, 254, 254, 254, 254, 250, 250, 252 },
+    { 254, 254, 254, 254, 254, 251, 251, 254 },
+};
+
+static const uint8_t vp6_dccv_pct[2][11] = {
+    { 146, 255, 181, 207, 232, 243, 238, 251, 244, 250, 249 },
+    { 179, 255, 214, 240, 250, 255, 244, 255, 255, 255, 255 },
+};
+
+static const uint8_t vp6_coeff_reorder_pct[] =  {
+    255, 132, 132, 159, 153, 151, 161, 170,
+    164, 162, 136, 110, 103, 114, 129, 118,
+    124, 125, 132, 136, 114, 110, 142, 135,
+    134, 123, 143, 126, 153, 183, 166, 161,
+    171, 180, 179, 164, 203, 218, 225, 217,
+    215, 206, 203, 217, 229, 241, 248, 243,
+    253, 255, 253, 255, 255, 255, 255, 255,
+    255, 255, 255, 255, 255, 255, 255, 255,
+};
+
+static const uint8_t vp6_runv_pct[2][14] = {
+  { 219, 246, 238, 249, 232, 239, 249, 255, 248, 253, 239, 244, 241, 248 },
+  { 198, 232, 251, 253, 219, 241, 253, 255, 248, 249, 244, 238, 251, 255 },
+};
+
+static const uint8_t vp6_ract_pct[3][2][6][11] = {
+  { { { 227, 246, 230, 247, 244, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 209, 231, 231, 249, 249, 253, 255, 255, 255 },
+      { 255, 255, 225, 242, 241, 251, 253, 255, 255, 255, 255 },
+      { 255, 255, 241, 253, 252, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 248, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } },
+    { { 240, 255, 248, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 240, 253, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } } },
+  { { { 206, 203, 227, 239, 247, 255, 253, 255, 255, 255, 255 },
+      { 207, 199, 220, 236, 243, 252, 252, 255, 255, 255, 255 },
+      { 212, 219, 230, 243, 244, 253, 252, 255, 255, 255, 255 },
+      { 236, 237, 247, 252, 253, 255, 255, 255, 255, 255, 255 },
+      { 240, 240, 248, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } },
+    { { 230, 233, 249, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 238, 238, 250, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 248, 251, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } } },
+  { { { 225, 239, 227, 231, 244, 253, 243, 255, 255, 253, 255 },
+      { 232, 234, 224, 228, 242, 249, 242, 252, 251, 251, 255 },
+      { 235, 249, 238, 240, 251, 255, 249, 255, 253, 253, 255 },
+      { 249, 253, 251, 250, 255, 255, 255, 255, 255, 255, 255 },
+      { 251, 250, 249, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } },
+    { { 243, 244, 250, 250, 255, 255, 255, 255, 255, 255, 255 },
+      { 249, 248, 250, 253, 255, 255, 255, 255, 255, 255, 255 },
+      { 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 },
+      { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255 } } }
+};
+
+static const int vp6_dccv_lc[3][5][2] = {
+  { { 122, 133 }, { 0, 1 }, { 78,  171 }, { 139, 117 }, { 168, 79 } },
+  { { 133,  51 }, { 0, 1 }, { 169,  71 }, { 214,  44 }, { 210, 38 } },
+  { { 142, -16 }, { 0, 1 }, { 221, -30 }, { 246,  -3 }, { 203, 17 } },
+};
+
+static const uint8_t vp6_coeff_groups[] = {
+    0, 0, 1, 1, 1, 2, 2, 2,
+    2, 2, 2, 3, 3, 3, 3, 3,
+    3, 3, 3, 3, 3, 3, 4, 4,
+    4, 4, 4, 4, 4, 4, 4, 4,
+    4, 4, 4, 4, 4, 5, 5, 5,
+    5, 5, 5, 5, 5, 5, 5, 5,
+    5, 5, 5, 5, 5, 5, 5, 5,
+    5, 5, 5, 5, 5, 5, 5, 5,
+};
+
+static const int16_t vp6_block_copy_filter[16][8][4] = {
+  { {   0, 128,   0,   0  },  /* 0 */
+    {  -3, 122,   9,   0  },
+    {  -4, 109,  24,  -1  },
+    {  -5,  91,  45,  -3  },
+    {  -4,  68,  68,  -4  },
+    {  -3,  45,  91,  -5  },
+    {  -1,  24, 109,  -4  },
+    {   0,   9, 122,  -3  } },
+  { {   0, 128,   0,   0  },  /* 1 */
+    {  -4, 124,   9,  -1  },
+    {  -5, 110,  25,  -2  },
+    {  -6,  91,  46,  -3  },
+    {  -5,  69,  69,  -5  },
+    {  -3,  46,  91,  -6  },
+    {  -2,  25, 110,  -5  },
+    {  -1,   9, 124,  -4  } },
+  { {   0, 128,   0,   0  },  /* 2 */
+    {  -4, 123,  10,  -1  },
+    {  -6, 110,  26,  -2  },
+    {  -7,  92,  47,  -4  },
+    {  -6,  70,  70,  -6  },
+    {  -4,  47,  92,  -7  },
+    {  -2,  26, 110,  -6  },
+    {  -1,  10, 123,  -4  } },
+  { {   0, 128,   0,   0  },  /* 3 */
+    {  -5, 124,  10,  -1  },
+    {  -7, 110,  27,  -2  },
+    {  -7,  91,  48,  -4  },
+    {  -6,  70,  70,  -6  },
+    {  -4,  48,  92,  -8  },
+    {  -2,  27, 110,  -7  },
+    {  -1,  10, 124,  -5  } },
+  { {   0, 128,   0,   0  },  /* 4 */
+    {  -6, 124,  11,  -1  },
+    {  -8, 111,  28,  -3  },
+    {  -8,  92,  49,  -5  },
+    {  -7,  71,  71,  -7  },
+    {  -5,  49,  92,  -8  },
+    {  -3,  28, 111,  -8  },
+    {  -1,  11, 124,  -6  } },
+  { {  0,  128,   0,   0  },  /* 5 */
+    {  -6, 123,  12,  -1  },
+    {  -9, 111,  29,  -3  },
+    {  -9,  93,  50,  -6  },
+    {  -8,  72,  72,  -8  },
+    {  -6,  50,  93,  -9  },
+    {  -3,  29, 111,  -9  },
+    {  -1,  12, 123,  -6  } },
+  { {   0, 128,   0,   0  },  /* 6 */
+    {  -7, 124,  12,  -1  },
+    { -10, 111,  30,  -3  },
+    { -10,  93,  51,  -6  },
+    {  -9,  73,  73,  -9  },
+    {  -6,  51,  93, -10  },
+    {  -3,  30, 111, -10  },
+    {  -1,  12, 124,  -7  } },
+  { {   0, 128,   0,   0  },  /* 7 */
+    {  -7, 123,  13,  -1  },
+    { -11, 112,  31,  -4  },
+    { -11,  94,  52,  -7  },
+    { -10,  74,  74, -10  },
+    {  -7,  52,  94, -11  },
+    {  -4,  31, 112, -11  },
+    {  -1,  13, 123,  -7  } },
+  { {   0, 128,   0,  0  },  /* 8 */
+    {  -8, 124,  13,  -1  },
+    { -12, 112,  32,  -4  },
+    { -12,  94,  53,  -7  },
+    { -10,  74,  74, -10  },
+    {  -7,  53,  94, -12  },
+    {  -4,  32, 112, -12  },
+    {  -1,  13, 124,  -8  } },
+  { {   0, 128,   0,   0  },  /* 9 */
+    {  -9, 124,  14,  -1  },
+    { -13, 112,  33,  -4  },
+    { -13,  95,  54,  -8  },
+    { -11,  75,  75, -11  },
+    {  -8,  54,  95, -13  },
+    {  -4,  33, 112, -13  },
+    {  -1,  14, 124,  -9  } },
+  { {   0, 128,   0,   0  },  /* 10 */
+    {  -9, 123,  15,  -1  },
+    { -14, 113,  34,  -5  },
+    { -14,  95,  55,  -8  },
+    { -12,  76,  76, -12  },
+    {  -8,  55,  95, -14  },
+    {  -5,  34, 112, -13  },
+    {  -1,  15, 123,  -9  } },
+  { {   0, 128,   0,   0  },  /* 11 */
+    { -10, 124,  15,  -1  },
+    { -14, 113,  34,  -5  },
+    { -15,  96,  56,  -9  },
+    { -13,  77,  77, -13  },
+    {  -9,  56,  96, -15  },
+    {  -5,  34, 113, -14  },
+    {  -1,  15, 124, -10  } },
+  { {   0, 128,   0,   0  },  /* 12 */
+    { -10, 123,  16,  -1  },
+    { -15, 113,  35,  -5  },
+    { -16,  98,  56, -10  },
+    { -14,  78,  78, -14  },
+    { -10,  56,  98, -16  },
+    {  -5,  35, 113, -15  },
+    {  -1,  16, 123, -10  } },
+  { {   0, 128,   0,   0  },  /* 13 */
+    { -11, 124,  17,  -2  },
+    { -16, 113,  36,  -5  },
+    { -17,  98,  57, -10  },
+    { -14,  78,  78, -14  },
+    { -10,  57,  98, -17  },
+    {  -5,  36, 113, -16  },
+    {  -2,  17, 124, -11  } },
+  { {   0, 128,   0,   0  },  /* 14 */
+    { -12, 125,  17,  -2  },
+    { -17, 114,  37,  -6  },
+    { -18,  99,  58, -11  },
+    { -15,  79,  79, -15  },
+    { -11,  58,  99, -18  },
+    {  -6,  37, 114, -17  },
+    {  -2,  17, 125, -12  } },
+  { {   0, 128,   0,   0  },  /* 15 */
+    { -12, 124,  18,  -2  },
+    { -18, 114,  38,  -6  },
+    { -19,  99,  59, -11  },
+    { -16,  80,  80, -16  },
+    { -11,  59,  99, -19  },
+    {  -6,  38, 114, -18  },
+    {  -2,  18, 124, -12  } },
+};
+
+const vp56_tree_t vp6_pcr_tree[] = {
+    { 8, 0},
+    { 4, 1},
+    { 2, 2}, {-1}, {-2},
+    { 2, 3}, {-3}, {-4},
+    { 8, 4},
+    { 4, 5},
+    { 2, 6}, {-5}, {-6},
+    { 2, 7}, {-7}, {-8},
+             {-0},
+};
+
+static const uint8_t vp6_coord_div[] = { 4, 4, 4, 4, 8, 8 };
+
+#endif /* VP6DATA_H */

Modified: trunk/libavformat/flvdec.c
==============================================================================
--- trunk/libavformat/flvdec.c	(original)
+++ trunk/libavformat/flvdec.c	Sat Sep  9 19:19:37 2006
@@ -184,6 +184,11 @@
             switch(flags & 0xF){
             case 2: st->codec->codec_id = CODEC_ID_FLV1; break;
             case 3: st->codec->codec_id = CODEC_ID_FLASHSV; break;
+            case 4:
+                st->codec->codec_id = CODEC_ID_VP6F;
+                get_byte(&s->pb); /* width and height adjustment */
+                size--;
+                break;
             default:
                     av_log(s, AV_LOG_INFO, "Unsupported video codec (%x)\n", flags & 0xf);
                 st->codec->codec_tag= flags & 0xF;

Modified: trunk/libavformat/nsvdec.c
==============================================================================
--- trunk/libavformat/nsvdec.c	(original)
+++ trunk/libavformat/nsvdec.c	Sat Sep  9 19:19:37 2006
@@ -182,15 +182,15 @@
     { CODEC_ID_VP3, MKTAG('V', 'P', '3', ' ') },
     { CODEC_ID_VP3, MKTAG('V', 'P', '3', '0') },
     { CODEC_ID_VP3, MKTAG('V', 'P', '3', '1') },
+    { CODEC_ID_VP5, MKTAG('V', 'P', '5', ' ') },
+    { CODEC_ID_VP5, MKTAG('V', 'P', '5', '0') },
+    { CODEC_ID_VP6, MKTAG('V', 'P', '6', '2') },
 /*
     { CODEC_ID_VP4, MKTAG('V', 'P', '4', ' ') },
     { CODEC_ID_VP4, MKTAG('V', 'P', '4', '0') },
-    { CODEC_ID_VP5, MKTAG('V', 'P', '5', ' ') },
-    { CODEC_ID_VP5, MKTAG('V', 'P', '5', '0') },
     { CODEC_ID_VP6, MKTAG('V', 'P', '6', ' ') },
     { CODEC_ID_VP6, MKTAG('V', 'P', '6', '0') },
     { CODEC_ID_VP6, MKTAG('V', 'P', '6', '1') },
-    { CODEC_ID_VP6, MKTAG('V', 'P', '6', '2') },
 */
     { CODEC_ID_XVID, MKTAG('X', 'V', 'I', 'D') }, /* cf sample xvid decoder from nsv_codec_sdk.zip */
     { CODEC_ID_RAWVIDEO, MKTAG('R', 'G', 'B', '3') },

Modified: trunk/libavformat/riff.c
==============================================================================
--- trunk/libavformat/riff.c	(original)
+++ trunk/libavformat/riff.c	Sat Sep  9 19:19:37 2006
@@ -114,6 +114,8 @@
     { CODEC_ID_INDEO3, MKTAG('I', 'V', '3', '2') },
     { CODEC_ID_VP3, MKTAG('V', 'P', '3', '1') },
     { CODEC_ID_VP3, MKTAG('V', 'P', '3', '0') },
+    { CODEC_ID_VP5, MKTAG('V', 'P', '5', '0') },
+    { CODEC_ID_VP6, MKTAG('V', 'P', '6', '2') },
     { CODEC_ID_ASV1, MKTAG('A', 'S', 'V', '1') },
     { CODEC_ID_ASV2, MKTAG('A', 'S', 'V', '2') },
     { CODEC_ID_VCR1, MKTAG('V', 'C', 'R', '1') },

Modified: trunk/libavformat/swf.c
==============================================================================
--- trunk/libavformat/swf.c	(original)
+++ trunk/libavformat/swf.c	Sat Sep  9 19:19:37 2006
@@ -19,6 +19,7 @@
  */
 #include "avformat.h"
 #include "bitstream.h"
+#include "riff.h"    /* for CodecTag */
 
 /* should have a generic way to indicate probable size */
 #define DUMMY_FILE_SIZE   (100 * 1024 * 1024)
@@ -45,8 +46,6 @@
 #define FLAG_SETFILL0    0x02
 #define FLAG_SETFILL1    0x04
 
-#define SWF_VIDEO_CODEC_FLV1    0x02
-
 #define AUDIO_FIFO_SIZE 65536
 
 /* character id used */
@@ -80,6 +79,12 @@
     int audio_type;
 } SWFContext;
 
+static const CodecTag swf_codec_tags[] = {
+    {CODEC_ID_FLV1, 0x02},
+    {CODEC_ID_VP6F, 0x04},
+    {0, 0},
+};
+
 static const int sSampleRates[3][4] = {
     {44100, 48000, 32000, 0},
     {22050, 24000, 16000, 0},
@@ -328,10 +333,12 @@
         if (enc->codec_type == CODEC_TYPE_AUDIO)
             audio_enc = enc;
         else {
-            if ( enc->codec_id == CODEC_ID_FLV1 || enc->codec_id == CODEC_ID_MJPEG ) {
+            if ( enc->codec_id == CODEC_ID_VP6F ||
+                 enc->codec_id == CODEC_ID_FLV1 ||
+                 enc->codec_id == CODEC_ID_MJPEG ) {
                 video_enc = enc;
             } else {
-                av_log(enc, AV_LOG_ERROR, "SWF only supports FLV1 and MJPEG\n");
+                av_log(enc, AV_LOG_ERROR, "SWF only supports VP6, FLV1 and MJPEG\n");
                 return -1;
             }
         }
@@ -361,7 +368,9 @@
     }
 
     put_tag(pb, "FWS");
-    if ( video_enc && video_enc->codec_id == CODEC_ID_FLV1 ) {
+    if ( video_enc && video_enc->codec_id == CODEC_ID_VP6F ) {
+        put_byte(pb, 8); /* version (version 8 and above support VP6 codec) */
+    } else if ( video_enc && video_enc->codec_id == CODEC_ID_FLV1 ) {
         put_byte(pb, 6); /* version (version 6 and above support FLV1 codec) */
     } else {
         put_byte(pb, 4); /* version (should use 4 for mpeg audio support) */
@@ -375,7 +384,8 @@
     put_le16(pb, (uint16_t)(DUMMY_DURATION * (int64_t)rate / rate_base)); /* frame count */
 
     /* define a shape with the jpeg inside */
-    if ( video_enc && video_enc->codec_id == CODEC_ID_FLV1 ) {
+    if ( video_enc && (video_enc->codec_id == CODEC_ID_VP6F ||
+                       video_enc->codec_id == CODEC_ID_FLV1 )) {
     } else if ( video_enc && video_enc->codec_id == CODEC_ID_MJPEG ) {
         put_swf_tag(s, TAG_DEFINESHAPE);
 
@@ -512,7 +522,8 @@
         }
     }
 
-            if ( swf->video_type == CODEC_ID_FLV1 ) {
+            if ( swf->video_type == CODEC_ID_VP6F ||
+                 swf->video_type == CODEC_ID_FLV1 ) {
                 if ( swf->video_frame_number == 0 ) {
                     /* create a new video object */
                     put_swf_tag(s, TAG_VIDEOSTREAM);
@@ -521,7 +532,7 @@
                     put_le16(pb, enc->width);
                     put_le16(pb, enc->height);
                     put_byte(pb, 0);
-                    put_byte(pb, SWF_VIDEO_CODEC_FLV1);
+                    put_byte(pb,codec_get_tag(swf_codec_tags,swf->video_type));
                     put_swf_end_tag(s);
 
                     /* place the video object for the first time */
@@ -784,18 +795,20 @@
             return AVERROR_IO;
         }
         if ( tag == TAG_VIDEOSTREAM && !vst) {
+            int codec_id;
             swf->ch_id = get_le16(pb);
             get_le16(pb);
             get_le16(pb);
             get_le16(pb);
             get_byte(pb);
             /* Check for FLV1 */
-            if ( get_byte(pb) == SWF_VIDEO_CODEC_FLV1 ) {
+            codec_id = codec_get_id(swf_codec_tags, get_byte(pb));
+            if ( codec_id ) {
                 vst = av_new_stream(s, 0);
                 av_set_pts_info(vst, 24, 1, 1000); /* 24 bit pts in ms */
 
                 vst->codec->codec_type = CODEC_TYPE_VIDEO;
-                vst->codec->codec_id = CODEC_ID_FLV1;
+                vst->codec->codec_id = codec_id;
                 if ( swf->samples_per_frame ) {
                     vst->codec->time_base.den = 1000. / swf->ms_per_frame;
                     vst->codec->time_base.num = 1;




More information about the ffmpeg-cvslog mailing list