[Ffmpeg-cvslog] r5530 - in trunk/libavcodec: vc1.c vc1acdata.h vc1data.h

kostya subversion
Tue Jun 27 05:12:01 CEST 2006


Author: kostya
Date: Tue Jun 27 05:11:51 2006
New Revision: 5530

Added:
   trunk/libavcodec/vc1acdata.h
Modified:
   trunk/libavcodec/vc1.c
   trunk/libavcodec/vc1data.h

Log:
VC-1 decoder with I-frames support and partial P-frames decoding


Modified: trunk/libavcodec/vc1.c
==============================================================================
--- trunk/libavcodec/vc1.c	(original)
+++ trunk/libavcodec/vc1.c	Tue Jun 27 05:11:51 2006
@@ -1,8 +1,7 @@
 /*
  * VC-1 and WMV3 decoder
- * Copyright (c) 2005 Anonymous
- * Copyright (c) 2005 Alex Beregszaszi
- * Copyright (c) 2005 Michael Niedermayer
+ * Copyright (c) 2006 Konstantin Shishkov
+ * Partly based on vc9.c (c) 2005 Anonymous, Alex Beregszaszi, Michael Niedermayer
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -24,14 +23,13 @@
  * @file vc1.c
  * VC-1 and WMV3 decoder
  *
- * TODO: most AP stuff, optimize, most of MB layer, transform, filtering and motion compensation, etc
- * TODO: use MPV_ !!
  */
 #include "common.h"
 #include "dsputil.h"
 #include "avcodec.h"
 #include "mpegvideo.h"
 #include "vc1data.h"
+#include "vc1acdata.h"
 
 #undef NDEBUG
 #include <assert.h>
@@ -41,92 +39,108 @@
 extern VLC ff_msmp4_dc_luma_vlc[2], ff_msmp4_dc_chroma_vlc[2];
 #define MB_INTRA_VLC_BITS 9
 extern VLC ff_msmp4_mb_i_vlc;
+extern const uint16_t ff_msmp4_mb_i_table[64][2];
 #define DC_VLC_BITS 9
+#define AC_VLC_BITS 9
 static const uint16_t table_mb_intra[64][2];
 
-/* Some inhibiting stuff */
-#define HAS_ADVANCED_PROFILE   0
-#define TRACE                  1
-
-#if TRACE
-#  define INIT_VLC(vlc, nb_bits, nb_codes, bits, bits_wrap, bits_size, \
-                   codes, codes_wrap, codes_size, use_static)          \
-  if (init_vlc(vlc, nb_bits, nb_codes, bits, bits_wrap, bits_size,     \
-               codes, codes_wrap, codes_size, use_static) < 0)         \
-  {                                                                    \
-    av_log(v->s.avctx, AV_LOG_ERROR, "Error for " # vlc " (%i)\n", i);   \
-    return -1;                                                         \
-  }
-#else
-#  define INIT_VLC(vlc, nb_bits, nb_codes, bits, bits_wrap, bits_size, \
-                   codes, codes_wrap, codes_size, use_static)          \
-  init_vlc(vlc, nb_bits, nb_codes, bits, bits_wrap, bits_size,         \
-           codes, codes_wrap, codes_size, use_static)
-#endif
 
 /** Available Profiles */
 //@{
-#define PROFILE_SIMPLE   0
-#define PROFILE_MAIN     1
-#define PROFILE_COMPLEX  2 ///< TODO: WMV9 specific
-#define PROFILE_ADVANCED 3
+enum Profile {
+    PROFILE_SIMPLE,
+    PROFILE_MAIN,
+    PROFILE_COMPLEX, ///< TODO: WMV9 specific
+    PROFILE_ADVANCED
+};
 //@}
 
 /** Sequence quantizer mode */
 //@{
-#define QUANT_FRAME_IMPLICIT   0 ///< Implicitly specified at frame level
-#define QUANT_FRAME_EXPLICIT   1 ///< Explicitly specified at frame level
-#define QUANT_NON_UNIFORM      2 ///< Non-uniform quant used for all frames
-#define QUANT_UNIFORM          3 ///< Uniform quant used for all frames
+enum QuantMode {
+    QUANT_FRAME_IMPLICIT,    ///< Implicitly specified at frame level
+    QUANT_FRAME_EXPLICIT,    ///< Explicitly specified at frame level
+    QUANT_NON_UNIFORM,       ///< Non-uniform quant used for all frames
+    QUANT_UNIFORM            ///< Uniform quant used for all frames
+};
 //@}
 
 /** Where quant can be changed */
 //@{
-#define DQPROFILE_FOUR_EDGES   0
-#define DQPROFILE_DOUBLE_EDGES 1
-#define DQPROFILE_SINGLE_EDGE  2
-#define DQPROFILE_ALL_MBS      3
+enum DQProfile {
+    DQPROFILE_FOUR_EDGES,
+    DQPROFILE_DOUBLE_EDGES,
+    DQPROFILE_SINGLE_EDGE,
+    DQPROFILE_ALL_MBS
+};
 //@}
 
 /** @name Where quant can be changed
  */
 //@{
-#define DQPROFILE_FOUR_EDGES   0
-#define DQSINGLE_BEDGE_LEFT   0
-#define DQSINGLE_BEDGE_TOP    1
-#define DQSINGLE_BEDGE_RIGHT  2
-#define DQSINGLE_BEDGE_BOTTOM 3
+enum DQSingleEdge {
+    DQSINGLE_BEDGE_LEFT,
+    DQSINGLE_BEDGE_TOP,
+    DQSINGLE_BEDGE_RIGHT,
+    DQSINGLE_BEDGE_BOTTOM
+};
 //@}
 
 /** Which pair of edges is quantized with ALTPQUANT */
 //@{
-#define DQDOUBLE_BEDGE_TOPLEFT     0
-#define DQDOUBLE_BEDGE_TOPRIGHT    1
-#define DQDOUBLE_BEDGE_BOTTOMRIGHT 2
-#define DQDOUBLE_BEDGE_BOTTOMLEFT  3
+enum DQDoubleEdge {
+    DQDOUBLE_BEDGE_TOPLEFT,
+    DQDOUBLE_BEDGE_TOPRIGHT,
+    DQDOUBLE_BEDGE_BOTTOMRIGHT,
+    DQDOUBLE_BEDGE_BOTTOMLEFT
+};
 //@}
 
 /** MV modes for P frames */
 //@{
-#define MV_PMODE_1MV_HPEL_BILIN   0
-#define MV_PMODE_1MV              1
-#define MV_PMODE_1MV_HPEL         2
-#define MV_PMODE_MIXED_MV         3
-#define MV_PMODE_INTENSITY_COMP   4
+enum MVModes {
+    MV_PMODE_1MV_HPEL_BILIN,
+    MV_PMODE_1MV,
+    MV_PMODE_1MV_HPEL,
+    MV_PMODE_MIXED_MV,
+    MV_PMODE_INTENSITY_COMP
+};
 //@}
 
 /** @name MV types for B frames */
 //@{
-#define BMV_TYPE_BACKWARD          0
-#define BMV_TYPE_BACKWARD          0
-#define BMV_TYPE_FORWARD           1
-#define BMV_TYPE_INTERPOLATED      3
+enum BMVTypes {
+    BMV_TYPE_BACKWARD,
+    BMV_TYPE_FORWARD,
+    BMV_TYPE_INTERPOLATED = 3 //XXX: ??
+};
+//@}
+
+/** @name Block types for P/B frames */
+//@{
+enum TransformTypes {
+    TT_8X8,
+    TT_8X4_BOTTOM,
+    TT_8X4_TOP,
+    TT_8X4, //Both halves
+    TT_4X8_RIGHT,
+    TT_4X8_LEFT,
+    TT_4X8, //Both halves
+    TT_4X4
+};
 //@}
 
+/** Table for conversion between TTBLK and TTMB */
+static const int ttblk_to_tt[3][8] = {
+  { TT_8X4, TT_4X8, TT_8X8, TT_4X4, TT_8X4_TOP, TT_8X4_BOTTOM, TT_4X8_RIGHT, TT_4X8_LEFT },
+  { TT_8X8, TT_4X8_RIGHT, TT_4X8_LEFT, TT_4X4, TT_8X4, TT_4X8, TT_8X4_BOTTOM, TT_8X4_TOP },
+  { TT_8X8, TT_4X8, TT_4X4, TT_8X4_BOTTOM, TT_4X8_RIGHT, TT_4X8_LEFT, TT_8X4, TT_8X4_TOP }
+};
+
 /** MV P mode - the 5th element is only used for mode 1 */
 static const uint8_t mv_pmode_table[2][5] = {
-  { MV_PMODE_1MV_HPEL_BILIN, MV_PMODE_1MV, MV_PMODE_1MV_HPEL, MV_PMODE_MIXED_MV, MV_PMODE_INTENSITY_COMP },
-  { MV_PMODE_1MV, MV_PMODE_MIXED_MV, MV_PMODE_1MV_HPEL, MV_PMODE_1MV_HPEL_BILIN, MV_PMODE_INTENSITY_COMP }
+  { MV_PMODE_1MV_HPEL_BILIN, MV_PMODE_1MV, MV_PMODE_1MV_HPEL, MV_PMODE_INTENSITY_COMP, MV_PMODE_MIXED_MV },
+  { MV_PMODE_1MV, MV_PMODE_MIXED_MV, MV_PMODE_1MV_HPEL, MV_PMODE_INTENSITY_COMP, MV_PMODE_1MV_HPEL_BILIN }
 };
 
 /** One more frame type */
@@ -174,8 +188,21 @@
 static VLC vc1_ttblk_vlc[3];
 #define VC1_SUBBLKPAT_VLC_BITS 6
 static VLC vc1_subblkpat_vlc[3];
+
+static VLC vc1_ac_coeff_table[8];
 //@}
 
+enum CodingSet {
+    CS_HIGH_MOT_INTRA = 0,
+    CS_HIGH_MOT_INTER,
+    CS_LOW_MOT_INTRA,
+    CS_LOW_MOT_INTER,
+    CS_MID_RATE_INTRA,
+    CS_MID_RATE_INTER,
+    CS_HIGH_RATE_INTRA,
+    CS_HIGH_RATE_INTER
+};
+
 /** Bitplane struct
  * We mainly need data and is_raw, so this struct could be avoided
  * to save a level of indirection; feel free to modify
@@ -190,6 +217,16 @@
     uint8_t is_raw;     ///< Bit values must be read at MB level
 } BitPlane;
 
+
+/** Block data for DC/AC prediction
+*/
+typedef struct Block {
+    uint16_t dc;
+    int16_t hor_ac[7];
+    int16_t vert_ac[7];
+    int16_t dcstep, step;
+} Block;
+
 /** The VC1 Context
  * @fixme Change size wherever another size is more efficient
  * Many members are only used for Advanced Profile
@@ -197,6 +234,8 @@
 typedef struct VC1Context{
     MpegEncContext s;
 
+    int bits;
+
     /** Simple/Main Profile sequence header */
     //@{
     int res_sm;           ///< reserved, 2b
@@ -210,7 +249,6 @@
     int reserved;         ///< reserved
     //@}
 
-#if HAS_ADVANCED_PROFILE
     /** Advanced Profile */
     //@{
     int level;            ///< 3bits, for Advanced/Simple Profile, provided by TS layer
@@ -227,8 +265,6 @@
     int hrd_param_flag;   ///< Presence of Hypothetical Reference
                           ///< Decoder parameters
     //@}
-#endif
-
 
     /** Sequence header data for all Profiles
      * TODO: choose between ints, uint8_ts and monobit flags
@@ -252,6 +288,7 @@
     uint8_t mv_mode2;     ///< Secondary MV coding mode (B frames)
     int k_x;              ///< Number of bits for MVs (depends on MV range)
     int k_y;              ///< Number of bits for MVs (depends on MV range)
+    int range_x, range_y; ///< MV range
     uint8_t pq, altpq;    ///< Current/alternate frame quantizer scale
     /** pquant parameters */
     //@{
@@ -271,6 +308,11 @@
     uint8_t ttmbf;        ///< Transform type flag
     int ttmb;             ///< Transform type
     uint8_t ttblk4x4;     ///< Value of ttblk which indicates a 4x4 transform
+    int codingset;        ///< index of current table set from 11.8 to use for luma block decoding
+    int codingset2;       ///< index of current table set from 11.8 to use for chroma block decoding
+    int pqindex;          ///< raw pqindex used in coding set selection
+
+
     /** Luma compensation parameters */
     //@{
     uint8_t lumscale;
@@ -301,7 +343,6 @@
     uint8_t interpfrm;
     //@}
 
-#if HAS_ADVANCED_PROFILE
     /** Frame decoding info for Advanced profile */
     //@{
     uint8_t fcm; ///< 0->Progressive, 2->Frame-Interlace, 3->Field-Interlace
@@ -327,7 +368,6 @@
     uint8_t range_mapy;
     uint8_t range_mapuv;
     //@}
-#endif
 } VC1Context;
 
 /**
@@ -341,7 +381,11 @@
 static int get_prefix(GetBitContext *gb, int stop, int len)
 {
 #if 1
-  int i = 0, tmp = !stop;
+    int i;
+
+    for(i = 0; i < len && get_bits1(gb) != stop; i++);
+    return i;
+/*  int i = 0, tmp = !stop;
 
   while (i != len && tmp != stop)
   {
@@ -349,7 +393,7 @@
     i++;
   }
   if (i == len && tmp != stop) return len+1;
-  return i;
+  return i;*/
 #else
   unsigned int buf;
   int log;
@@ -372,6 +416,15 @@
 #endif
 }
 
+static inline int decode210(GetBitContext *gb){
+    int n;
+    n = get_bits1(gb);
+    if (n == 1)
+        return 0;
+    else
+        return 2 - get_bits1(gb);
+}
+
 /**
  * Init VC-1 specific tables and VC1Context members
  * @param v The VC1Context to initialize
@@ -386,63 +439,56 @@
     v->mv_type_mb_plane = (struct BitPlane) { NULL, 0, 0, 0 };
     v->direct_mb_plane = (struct BitPlane) { NULL, 0, 0, 0 };
     v->skip_mb_plane = (struct BitPlane) { NULL, 0, 0, 0 };
-#if HAS_ADVANCED_PROFILE
     v->ac_pred_plane = v->over_flags_plane = (struct BitPlane) { NULL, 0, 0, 0 };
     v->hrd_rate = v->hrd_buffer = NULL;
-#endif
 
     /* VLC tables */
-#if 0 // spec -> actual tables converter
-    for(i=0; i<64; i++){
-        int code= (vc1_norm6_spec[i][1] << vc1_norm6_spec[i][4]) + vc1_norm6_spec[i][3];
-        av_log(NULL, AV_LOG_DEBUG, "0x%03X, ", code);
-        if(i%16==15) av_log(NULL, AV_LOG_DEBUG, "\n");
-    }
-    for(i=0; i<64; i++){
-        int code= vc1_norm6_spec[i][2] + vc1_norm6_spec[i][4];
-        av_log(NULL, AV_LOG_DEBUG, "%2d, ", code);
-        if(i%16==15) av_log(NULL, AV_LOG_DEBUG, "\n");
-    }
-#endif
     if(!done)
     {
         done = 1;
-        INIT_VLC(&vc1_bfraction_vlc, VC1_BFRACTION_VLC_BITS, 23,
+        init_vlc(&vc1_bfraction_vlc, VC1_BFRACTION_VLC_BITS, 23,
                  vc1_bfraction_bits, 1, 1,
                  vc1_bfraction_codes, 1, 1, 1);
-        INIT_VLC(&vc1_norm2_vlc, VC1_NORM2_VLC_BITS, 4,
+        init_vlc(&vc1_norm2_vlc, VC1_NORM2_VLC_BITS, 4,
                  vc1_norm2_bits, 1, 1,
                  vc1_norm2_codes, 1, 1, 1);
-        INIT_VLC(&vc1_norm6_vlc, VC1_NORM6_VLC_BITS, 64,
+        init_vlc(&vc1_norm6_vlc, VC1_NORM6_VLC_BITS, 64,
                  vc1_norm6_bits, 1, 1,
                  vc1_norm6_codes, 2, 2, 1);
-        INIT_VLC(&vc1_imode_vlc, VC1_IMODE_VLC_BITS, 7,
+        init_vlc(&vc1_imode_vlc, VC1_IMODE_VLC_BITS, 7,
                  vc1_imode_bits, 1, 1,
                  vc1_imode_codes, 1, 1, 1);
         for (i=0; i<3; i++)
         {
-            INIT_VLC(&vc1_ttmb_vlc[i], VC1_TTMB_VLC_BITS, 16,
+            init_vlc(&vc1_ttmb_vlc[i], VC1_TTMB_VLC_BITS, 16,
                      vc1_ttmb_bits[i], 1, 1,
                      vc1_ttmb_codes[i], 2, 2, 1);
-            INIT_VLC(&vc1_ttblk_vlc[i], VC1_TTBLK_VLC_BITS, 8,
+            init_vlc(&vc1_ttblk_vlc[i], VC1_TTBLK_VLC_BITS, 8,
                      vc1_ttblk_bits[i], 1, 1,
                      vc1_ttblk_codes[i], 1, 1, 1);
-            INIT_VLC(&vc1_subblkpat_vlc[i], VC1_SUBBLKPAT_VLC_BITS, 15,
+            init_vlc(&vc1_subblkpat_vlc[i], VC1_SUBBLKPAT_VLC_BITS, 15,
                      vc1_subblkpat_bits[i], 1, 1,
                      vc1_subblkpat_codes[i], 1, 1, 1);
         }
         for(i=0; i<4; i++)
         {
-            INIT_VLC(&vc1_4mv_block_pattern_vlc[i], VC1_4MV_BLOCK_PATTERN_VLC_BITS, 16,
+            init_vlc(&vc1_4mv_block_pattern_vlc[i], VC1_4MV_BLOCK_PATTERN_VLC_BITS, 16,
                      vc1_4mv_block_pattern_bits[i], 1, 1,
                      vc1_4mv_block_pattern_codes[i], 1, 1, 1);
-            INIT_VLC(&vc1_cbpcy_p_vlc[i], VC1_CBPCY_P_VLC_BITS, 64,
+            init_vlc(&vc1_cbpcy_p_vlc[i], VC1_CBPCY_P_VLC_BITS, 64,
                      vc1_cbpcy_p_bits[i], 1, 1,
                      vc1_cbpcy_p_codes[i], 2, 2, 1);
-            INIT_VLC(&vc1_mv_diff_vlc[i], VC1_MV_DIFF_VLC_BITS, 73,
+            init_vlc(&vc1_mv_diff_vlc[i], VC1_MV_DIFF_VLC_BITS, 73,
                      vc1_mv_diff_bits[i], 1, 1,
                      vc1_mv_diff_codes[i], 2, 2, 1);
         }
+        for(i=0; i<8; i++)
+            init_vlc(&vc1_ac_coeff_table[i], AC_VLC_BITS, vc1_ac_sizes[i],
+                     &vc1_ac_tables[i][0][1], 8, 4,
+                     &vc1_ac_tables[i][0][0], 8, 4, 1);
+        init_vlc(&ff_msmp4_mb_i_vlc, MB_INTRA_VLC_BITS, 64,
+                 &ff_msmp4_mb_i_table[0][1], 4, 2,
+                 &ff_msmp4_mb_i_table[0][0], 4, 2, 1);
     }
 
     /* Other defaults */
@@ -452,279 +498,538 @@
     return 0;
 }
 
-#if HAS_ADVANCED_PROFILE
+/***********************************************************************/
 /**
- * Decode sequence header's Hypothetic Reference Decoder data
- * @see 6.2.1, p32
- * @param v The VC1Context to initialize
- * @param gb A GetBitContext initialized from AVCodecContext extra_data
+ * @defgroup bitplane VC9 Bitplane decoding
+ * @see 8.7, p56
+ * @{
+ */
+
+/** @addtogroup bitplane
+ * Imode types
+ * @{
+ */
+enum Imode {
+    IMODE_RAW,
+    IMODE_NORM2,
+    IMODE_DIFF2,
+    IMODE_NORM6,
+    IMODE_DIFF6,
+    IMODE_ROWSKIP,
+    IMODE_COLSKIP
+};
+/** @} */ //imode defines
+
+/** Allocate the buffer from a bitplane, given its dimensions
+ * @param bp Bitplane which buffer is to allocate
+ * @param[in] width Width of the buffer
+ * @param[in] height Height of the buffer
  * @return Status
+ * @todo TODO: Take into account stride
+ * @todo TODO: Allow use of external buffers ?
  */
-static int decode_hrd(VC1Context *v, GetBitContext *gb)
+static int alloc_bitplane(BitPlane *bp, int width, int height)
 {
-    int i, num;
-
-    num = 1 + get_bits(gb, 5);
+    if (!bp || bp->width<0 || bp->height<0) return -1;
+    bp->data = (uint8_t*)av_malloc(width*height);
+    if (!bp->data) return -1;
+    bp->width = bp->stride = width;
+    bp->height = height;
+    return 0;
+}
 
-    /*hrd rate*/
-    if (v->hrd_rate || num != v->hrd_num_leaky_buckets)
-    {
-        av_freep(&v->hrd_rate);
-    }
-    if (!v->hrd_rate) v->hrd_rate = av_malloc(num*sizeof(uint16_t));
-    if (!v->hrd_rate) return -1;
+/** Free the bitplane's buffer
+ * @param bp Bitplane which buffer is to free
+ */
+static void free_bitplane(BitPlane *bp)
+{
+    bp->width = bp->stride = bp->height = 0;
+    if (bp->data) av_freep(&bp->data);
+}
 
-    /*hrd buffer*/
-    if (v->hrd_buffer || num != v->hrd_num_leaky_buckets)
-    {
-        av_freep(&v->hrd_buffer);
-    }
-    if (!v->hrd_buffer) v->hrd_buffer = av_malloc(num*sizeof(uint16_t));
-    if (!v->hrd_buffer)
-    {
-        av_freep(&v->hrd_rate);
-        return -1;
-    }
+/** Decode rows by checking if they are skipped
+ * @param plane Buffer to store decoded bits
+ * @param[in] width Width of this buffer
+ * @param[in] height Height of this buffer
+ * @param[in] stride of this buffer
+ */
+static void decode_rowskip(uint8_t* plane, int width, int height, int stride, GetBitContext *gb){
+    int x, y;
 
-    /*hrd fullness*/
-    if (v->hrd_fullness || num != v->hrd_num_leaky_buckets)
-    {
-        av_freep(&v->hrd_buffer);
-    }
-    if (!v->hrd_fullness) v->hrd_fullness = av_malloc(num*sizeof(uint8_t));
-    if (!v->hrd_fullness)
-    {
-        av_freep(&v->hrd_rate);
-        av_freep(&v->hrd_buffer);
-        return -1;
+    for (y=0; y<height; y++){
+        if (!get_bits(gb, 1)) //rowskip
+            memset(plane, 0, width);
+        else
+            for (x=0; x<width; x++)
+                plane[x] = get_bits(gb, 1);
+        plane += stride;
     }
-    v->hrd_num_leaky_buckets = num;
+}
 
-    //exponent in base-2 for rate
-    v->bit_rate_exponent = 6 + get_bits(gb, 4);
-    //exponent in base-2 for buffer_size
-    v->buffer_size_exponent = 4 + get_bits(gb, 4);
+/** Decode columns by checking if they are skipped
+ * @param plane Buffer to store decoded bits
+ * @param[in] width Width of this buffer
+ * @param[in] height Height of this buffer
+ * @param[in] stride of this buffer
+ * @fixme FIXME: Optimize
+ */
+static void decode_colskip(uint8_t* plane, int width, int height, int stride, GetBitContext *gb){
+    int x, y;
 
-    for (i=0; i<num; i++)
-    {
-        //mantissae, ordered (if not, use a function ?
-        v->hrd_rate[i] = 1 + get_bits(gb, 16);
-        if (i && v->hrd_rate[i-1]>=v->hrd_rate[i])
-        {
-            av_log(v->s.avctx, AV_LOG_ERROR, "HDR Rates aren't strictly increasing:"
-                   "%i vs %i\n", v->hrd_rate[i-1], v->hrd_rate[i]);
-            return -1;
-        }
-        v->hrd_buffer[i] = 1 + get_bits(gb, 16);
-        if (i && v->hrd_buffer[i-1]<v->hrd_buffer[i])
-        {
-            av_log(v->s.avctx, AV_LOG_ERROR, "HDR Buffers aren't decreasing:"
-                   "%i vs %i\n", v->hrd_buffer[i-1], v->hrd_buffer[i]);
-            return -1;
-        }
+    for (x=0; x<width; x++){
+        if (!get_bits(gb, 1)) //colskip
+            for (y=0; y<height; y++)
+                plane[y*stride] = 0;
+        else
+            for (y=0; y<height; y++)
+                plane[y*stride] = get_bits(gb, 1);
+        plane ++;
     }
-    return 0;
 }
 
-/**
- * Decode sequence header for Advanced Profile
- * @see Table 2, p18
- * @see 6.1.7, pp21-27
- * @param v The VC1Context to initialize
- * @param gb A GetBitContext initialized from AVCodecContext extra_data
+/** Decode a bitplane's bits
+ * @param bp Bitplane where to store the decode bits
+ * @param v VC-1 context for bit reading and logging
  * @return Status
+ * @fixme FIXME: Optimize
+ * @todo TODO: Decide if a struct is needed
  */
-static int decode_advanced_sequence_header(AVCodecContext *avctx, GetBitContext *gb)
+static int bitplane_decoding(BitPlane *bp, VC1Context *v)
 {
-    VC1Context *v = avctx->priv_data;
-    int nr, dr, aspect_ratio;
+    GetBitContext *gb = &v->s.gb;
 
-    v->postprocflag = get_bits(gb, 1);
-    v->broadcast = get_bits(gb, 1);
-    v->interlace = get_bits(gb, 1);
-
-    v->tfcntrflag = get_bits(gb, 1);
-    v->finterpflag = get_bits(gb, 1); //common
-    v->panscanflag = get_bits(gb, 1);
-    v->reserved = get_bits(gb, 1);
-    if (v->reserved)
-    {
-        av_log(avctx, AV_LOG_ERROR, "RESERVED should be 0 (is %i)\n",
-               v->reserved);
-        return -1;
-    }
-    if (v->extended_mv)
-        v->extended_dmv = get_bits(gb, 1);
+    int imode, x, y, code, offset;
+    uint8_t invert, *planep = bp->data;
+
+    invert = get_bits(gb, 1);
+    imode = get_vlc2(gb, vc1_imode_vlc.table, VC1_IMODE_VLC_BITS, 1);
 
-    /* 6.1.7, p21 */
-    if (get_bits(gb, 1) /* pic_size_flag */)
+    bp->is_raw = 0;
+    switch (imode)
     {
-        avctx->coded_width = get_bits(gb, 12) << 1;
-        avctx->coded_height = get_bits(gb, 12) << 1;
-        if ( get_bits(gb, 1) /* disp_size_flag */)
+    case IMODE_RAW:
+        //Data is actually read in the MB layer (same for all tests == "raw")
+        bp->is_raw = 1; //invert ignored
+        return invert;
+    case IMODE_DIFF2:
+    case IMODE_NORM2:
+        if ((bp->height * bp->width) & 1)
         {
-            avctx->width = get_bits(gb, 14);
-            avctx->height = get_bits(gb, 14);
+            *planep++ = get_bits(gb, 1);
+            offset = 1;
         }
-
-        /* 6.1.7.4, p23 */
-        if ( get_bits(gb, 1) /* aspect_ratio_flag */)
-        {
-            aspect_ratio = get_bits(gb, 4); //SAR
-            if (aspect_ratio == 0x0F) //FF_ASPECT_EXTENDED
-            {
-                avctx->sample_aspect_ratio.num = 1 + get_bits(gb, 8);
-                avctx->sample_aspect_ratio.den = 1 + get_bits(gb, 8);
+        else offset = 0;
+        // decode bitplane as one long line
+        for (y = offset; y < bp->height * bp->width; y += 2) {
+            code = get_vlc2(gb, vc1_norm2_vlc.table, VC1_NORM2_VLC_BITS, 1);
+            *planep++ = code & 1;
+            offset++;
+            if(offset == bp->width) {
+                offset = 0;
+                planep += bp->stride - bp->width;
+            }
+            *planep++ = code >> 1;
+            offset++;
+            if(offset == bp->width) {
+                offset = 0;
+                planep += bp->stride - bp->width;
             }
-            else if (aspect_ratio == 0x0E)
-            {
-                av_log(avctx, AV_LOG_DEBUG, "Reserved AR found\n");
+        }
+        break;
+    case IMODE_DIFF6:
+    case IMODE_NORM6:
+        if(!(bp->height % 3) && (bp->width % 3)) { // use 2x3 decoding
+            for(y = 0; y < bp->height; y+= 3) {
+                for(x = bp->width & 1; x < bp->width; x += 2) {
+                    code = get_vlc2(gb, vc1_norm6_vlc.table, VC1_NORM6_VLC_BITS, 2);
+                    if(code < 0){
+                        av_log(v->s.avctx, AV_LOG_DEBUG, "invalid NORM-6 VLC\n");
+                        return -1;
+                    }
+                    planep[x + 0] = (code >> 0) & 1;
+                    planep[x + 1] = (code >> 1) & 1;
+                    planep[x + 0 + bp->stride] = (code >> 2) & 1;
+                    planep[x + 1 + bp->stride] = (code >> 3) & 1;
+                    planep[x + 0 + bp->stride * 2] = (code >> 4) & 1;
+                    planep[x + 1 + bp->stride * 2] = (code >> 5) & 1;
+                }
+                planep += bp->stride * 3;
             }
-            else
-            {
-              avctx->sample_aspect_ratio = vc1_pixel_aspect[aspect_ratio];
+            if(bp->width & 1) decode_colskip(bp->data, 1, bp->height, bp->stride, &v->s.gb);
+        } else { // 3x2
+            for(y = bp->height & 1; y < bp->height; y += 2) {
+                for(x = bp->width % 3; x < bp->width; x += 3) {
+                    code = get_vlc2(gb, vc1_norm6_vlc.table, VC1_NORM6_VLC_BITS, 2);
+                    if(code < 0){
+                        av_log(v->s.avctx, AV_LOG_DEBUG, "invalid NORM-6 VLC\n");
+                        return -1;
+                    }
+                    planep[x + 0] = (code >> 0) & 1;
+                    planep[x + 1] = (code >> 1) & 1;
+                    planep[x + 2] = (code >> 2) & 1;
+                    planep[x + 0 + bp->stride] = (code >> 3) & 1;
+                    planep[x + 1 + bp->stride] = (code >> 4) & 1;
+                    planep[x + 2 + bp->stride] = (code >> 5) & 1;
+                }
+                planep += bp->stride * 2;
             }
+            x = bp->width % 3;
+            if(x) decode_colskip(bp->data  ,             x, bp->height    , bp->stride, &v->s.gb);
+            if(bp->height & 1) decode_rowskip(bp->data+x, bp->width - x, bp->height & 1, bp->stride, &v->s.gb);
         }
-    }
-    else
-    {
-        avctx->coded_width = avctx->width;
-        avctx->coded_height = avctx->height;
+        break;
+    case IMODE_ROWSKIP:
+        decode_rowskip(bp->data, bp->width, bp->height, bp->stride, &v->s.gb);
+        break;
+    case IMODE_COLSKIP:
+        decode_colskip(bp->data, bp->width, bp->height, bp->stride, &v->s.gb);
+        break;
+    default: break;
     }
 
-    /* 6.1.8, p23 */
-    if ( get_bits(gb, 1) /* framerateflag */)
+    /* Applying diff operator */
+    if (imode == IMODE_DIFF2 || imode == IMODE_DIFF6)
     {
-        if ( !get_bits(gb, 1) /* framerateind */)
+        planep = bp->data;
+        planep[0] ^= invert;
+        for (x=1; x<bp->width; x++)
+            planep[x] ^= planep[x-1];
+        for (y=1; y<bp->height; y++)
         {
-            nr = get_bits(gb, 8);
-            dr = get_bits(gb, 4);
-            if (nr<1)
-            {
-                av_log(avctx, AV_LOG_ERROR, "0 is forbidden for FRAMERATENR\n");
-                return -1;
-            }
-            if (nr>5)
-            {
-                av_log(avctx, AV_LOG_ERROR,
-                       "Reserved FRAMERATENR %i not handled\n", nr);
-                nr = 5; /* overflow protection */
-            }
-            if (dr<1)
-            {
-                av_log(avctx, AV_LOG_ERROR, "0 is forbidden for FRAMERATEDR\n");
-                return -1;
-            }
-            if (dr>2)
+            planep += bp->stride;
+            planep[0] ^= planep[-bp->stride];
+            for (x=1; x<bp->width; x++)
             {
-                av_log(avctx, AV_LOG_ERROR,
-                       "Reserved FRAMERATEDR %i not handled\n", dr);
-                dr = 2; /* overflow protection */
+                if (planep[x-1] != planep[x-bp->stride]) planep[x] ^= invert;
+                else                                     planep[x] ^= planep[x-1];
             }
-            avctx->time_base.num = fps_nr[dr - 1];
-            avctx->time_base.den = fps_nr[nr - 1];
-        }
-        else
-        {
-            nr = get_bits(gb, 16);
-            // 0.03125->2048Hz / 0.03125Hz
-            avctx->time_base.den = 1000000;
-            avctx->time_base.num = 31250*(1+nr);
-        }
-    }
-
-    /* 6.1.9, p25 */
-    if ( get_bits(gb, 1) /* color_format_flag */)
-    {
-        //Chromacity coordinates of color primaries
-        //like ITU-R BT.709-2, BT.470-2, ...
-        v->color_prim = get_bits(gb, 8);
-        if (v->color_prim<1)
-        {
-            av_log(avctx, AV_LOG_ERROR, "0 for COLOR_PRIM is forbidden\n");
-            return -1;
-        }
-        if (v->color_prim == 3 || v->color_prim>6)
-        {
-            av_log(avctx, AV_LOG_DEBUG, "Reserved COLOR_PRIM %i found\n",
-                   v->color_prim);
-            return -1;
-        }
-
-        //Opto-electronic transfer characteristics
-        v->transfer_char = get_bits(gb, 8);
-        if (v->transfer_char < 1)
-        {
-            av_log(avctx, AV_LOG_ERROR, "0 for TRAMSFER_CHAR is forbidden\n");
-            return -1;
-        }
-        if (v->transfer_char == 3 || v->transfer_char>8)
-        {
-            av_log(avctx, AV_LOG_DEBUG, "Reserved TRANSFERT_CHAR %i found\n",
-                   v->color_prim);
-            return -1;
-        }
-
-        //Matrix coefficient for primariev->YCbCr
-        v->matrix_coef = get_bits(gb, 8);
-        if (v->matrix_coef < 1)
-        {
-            av_log(avctx, AV_LOG_ERROR, "0 for MATRIX_COEF is forbidden\n");
-            return -1;
-        }
-        if ((v->matrix_coef > 2 && v->matrix_coef < 6) || v->matrix_coef > 7)
-        {
-            av_log(avctx, AV_LOG_DEBUG, "Reserved MATRIX_COEF %i found\n",
-                   v->color_prim);
-            return -1;
         }
     }
-
-    //Hypothetical reference decoder indicator flag
-    v->hrd_param_flag = get_bits(gb, 1);
-    if (v->hrd_param_flag)
+    else if (invert)
     {
-      if (decode_hrd(v, gb) < 0) return -1;
+        planep = bp->data;
+        for (x=0; x<bp->width*bp->height; x++) planep[x] = !planep[x]; //FIXME stride
     }
-
-    /*reset scaling ranges, 6.2.2 & 6.2.3, p33*/
-    v->range_mapy_flag = 0;
-    v->range_mapuv_flag = 0;
-
-    av_log(avctx, AV_LOG_DEBUG, "Advanced profile not supported yet\n");
-    return -1;
+    return (imode<<1) + invert;
 }
-#endif
+/** @} */ //Bitplane group
 
-/**
- * Decode Simple/Main Profiles sequence header
- * @see Figure 7-8, p16-17
- * @param avctx Codec context
- * @param gb GetBit context initialized from Codec context extra_data
- * @return Status
+/***********************************************************************/
+/** VOP Dquant decoding
+ * @param v VC-1 Context
  */
-static int decode_sequence_header(AVCodecContext *avctx, GetBitContext *gb)
+static int vop_dquant_decoding(VC1Context *v)
 {
-    VC1Context *v = avctx->priv_data;
+    GetBitContext *gb = &v->s.gb;
+    int pqdiff;
 
-    av_log(avctx, AV_LOG_DEBUG, "Header: %0X\n", show_bits(gb, 32));
-    v->profile = get_bits(gb, 2);
-    if (v->profile == 2)
+    //variable size
+    if (v->dquant == 2)
     {
-        av_log(avctx, AV_LOG_ERROR, "Profile value 2 is forbidden\n");
-        return -1;
+        pqdiff = get_bits(gb, 3);
+        if (pqdiff == 7) v->altpq = get_bits(gb, 5);
+        else v->altpq = v->pq + pqdiff + 1;
     }
-
-#if HAS_ADVANCED_PROFILE
-    if (v->profile == PROFILE_ADVANCED)
+    else
     {
-        v->level = get_bits(gb, 3);
-        if(v->level >= 5)
+        v->dquantfrm = get_bits(gb, 1);
+        if ( v->dquantfrm )
         {
-            av_log(avctx, AV_LOG_ERROR, "Reserved LEVEL %i\n",v->level);
-        }
-        v->chromaformat = get_bits(gb, 2);
-        if (v->chromaformat != 1)
+            v->dqprofile = get_bits(gb, 2);
+            switch (v->dqprofile)
+            {
+            case DQPROFILE_SINGLE_EDGE:
+            case DQPROFILE_DOUBLE_EDGES:
+                v->dqsbedge = get_bits(gb, 2);
+                break;
+            case DQPROFILE_ALL_MBS:
+                v->dqbilevel = get_bits(gb, 1);
+            default: break; //Forbidden ?
+            }
+            if (!v->dqbilevel || v->dqprofile != DQPROFILE_ALL_MBS)
+            {
+                pqdiff = get_bits(gb, 3);
+                if (pqdiff == 7) v->altpq = get_bits(gb, 5);
+                else v->altpq = v->pq + pqdiff + 1;
+            }
+        }
+    }
+    return 0;
+}
+
+
+/** Do inverse transform
+ */
+static void vc1_inv_trans(DCTELEM block[64], int M, int N)
+{
+    int i;
+    register int t1,t2,t3,t4,t5,t6,t7,t8;
+    DCTELEM *src, *dst;
+
+    src = block;
+    dst = block;
+    if(M==4){
+        for(i = 0; i < N; i++){
+            t1 = 17 * (src[0] + src[2]);
+            t2 = 17 * (src[0] - src[2]);
+            t3 = 22 * src[1];
+            t4 = 22 * src[3];
+            t5 = 10 * src[1];
+            t6 = 10 * src[3];
+
+            dst[0] = (t1 + t3 + t6 + 4) >> 3;
+            dst[1] = (t2 - t4 + t5 + 4) >> 3;
+            dst[2] = (t2 + t4 - t5 + 4) >> 3;
+            dst[3] = (t1 - t3 - t6 + 4) >> 3;
+
+            src += 8;
+            dst += 8;
+        }
+    }else{
+        for(i = 0; i < N; i++){
+            t1 = 12 * (src[0] + src[4]);
+            t2 = 12 * (src[0] - src[4]);
+            t3 = 16 * src[2] +  6 * src[6];
+            t4 =  6 * src[2] - 16 * src[6];
+
+            t5 = t1 + t3;
+            t6 = t2 + t4;
+            t7 = t2 - t4;
+            t8 = t1 - t3;
+
+            t1 = 16 * src[1] + 15 * src[3] +  9 * src[5] +  4 * src[7];
+            t2 = 15 * src[1] -  4 * src[3] - 16 * src[5] -  9 * src[7];
+            t3 =  9 * src[1] - 16 * src[3] +  4 * src[5] + 15 * src[7];
+            t4 =  4 * src[1] -  9 * src[3] + 15 * src[5] - 16 * src[7];
+
+            dst[0] = (t5 + t1 + 4) >> 3;
+            dst[1] = (t6 + t2 + 4) >> 3;
+            dst[2] = (t7 + t3 + 4) >> 3;
+            dst[3] = (t8 + t4 + 4) >> 3;
+            dst[4] = (t8 - t4 + 4) >> 3;
+            dst[5] = (t7 - t3 + 4) >> 3;
+            dst[6] = (t6 - t2 + 4) >> 3;
+            dst[7] = (t5 - t1 + 4) >> 3;
+
+            src += 8;
+            dst += 8;
+        }
+    }
+
+    src = block;
+    dst = block;
+    if(N==4){
+        for(i = 0; i < M; i++){
+            t1 = 17 * (src[ 0] + src[16]);
+            t2 = 17 * (src[ 0] - src[16]);
+            t3 = 22 * src[ 8];
+            t4 = 22 * src[24];
+            t5 = 10 * src[ 8];
+            t6 = 10 * src[24];
+
+            dst[ 0] = (t1 + t3 + t6 + 64) >> 7;
+            dst[ 8] = (t2 - t4 + t5 + 64) >> 7;
+            dst[16] = (t2 + t4 - t5 + 64) >> 7;
+            dst[24] = (t1 - t3 - t6 + 64) >> 7;
+
+            src ++;
+            dst ++;
+        }
+    }else{
+        for(i = 0; i < M; i++){
+            t1 = 12 * (src[ 0] + src[32]);
+            t2 = 12 * (src[ 0] - src[32]);
+            t3 = 16 * src[16] +  6 * src[48];
+            t4 =  6 * src[16] - 16 * src[48];
+
+            t5 = t1 + t3;
+            t6 = t2 + t4;
+            t7 = t2 - t4;
+            t8 = t1 - t3;
+
+            t1 = 16 * src[ 8] + 15 * src[24] +  9 * src[40] +  4 * src[56];
+            t2 = 15 * src[ 8] -  4 * src[24] - 16 * src[40] -  9 * src[56];
+            t3 =  9 * src[ 8] - 16 * src[24] +  4 * src[40] + 15 * src[56];
+            t4 =  4 * src[ 8] -  9 * src[24] + 15 * src[40] - 16 * src[56];
+
+            dst[ 0] = (t5 + t1 + 64) >> 7;
+            dst[ 8] = (t6 + t2 + 64) >> 7;
+            dst[16] = (t7 + t3 + 64) >> 7;
+            dst[24] = (t8 + t4 + 64) >> 7;
+            dst[32] = (t8 - t4 + 64 + 1) >> 7;
+            dst[40] = (t7 - t3 + 64 + 1) >> 7;
+            dst[48] = (t6 - t2 + 64 + 1) >> 7;
+            dst[56] = (t5 - t1 + 64 + 1) >> 7;
+
+            src++;
+            dst++;
+        }
+    }
+}
+
+/** Apply overlap transform
+ * @todo optimize
+ * @todo move to DSPContext
+ */
+static void vc1_overlap_block(MpegEncContext *s, DCTELEM block[64], int n, int do_hor, int do_vert)
+{
+    int i;
+
+    if(do_hor) { //TODO
+    }
+    if(do_vert) { //TODO
+    }
+
+    for(i = 0; i < 64; i++)
+        block[i] += 128;
+}
+
+
+/** Put block onto picture
+ * @todo move to DSPContext
+ */
+static void vc1_put_block(VC1Context *v, DCTELEM block[6][64])
+{
+    uint8_t *Y;
+    int ys, us, vs;
+    DSPContext *dsp = &v->s.dsp;
+
+    ys = v->s.current_picture.linesize[0];
+    us = v->s.current_picture.linesize[1];
+    vs = v->s.current_picture.linesize[2];
+    Y = v->s.dest[0];
+
+    dsp->put_pixels_clamped(block[0], Y, ys);
+    dsp->put_pixels_clamped(block[1], Y + 8, ys);
+    Y += ys * 8;
+    dsp->put_pixels_clamped(block[2], Y, ys);
+    dsp->put_pixels_clamped(block[3], Y + 8, ys);
+
+    dsp->put_pixels_clamped(block[4], v->s.dest[1], us);
+    dsp->put_pixels_clamped(block[5], v->s.dest[2], vs);
+}
+
+/** Do motion compensation over 1 macroblock
+ * Mostly adapted hpel_motion and qpel_motion from mpegvideo.c
+ */
+static void vc1_mc_1mv(VC1Context *v)
+{
+    MpegEncContext *s = &v->s;
+    DSPContext *dsp = &v->s.dsp;
+    uint8_t *srcY, *srcU, *srcV;
+    int dxy, mx, my, src_x, src_y;
+    int width = s->mb_width * 16, height = s->mb_height * 16;
+
+    if(!v->s.last_picture.data[0])return;
+
+    mx = s->mv[0][0][0] >> s->mspel;
+    my = s->mv[0][0][1] >> s->mspel;
+    srcY = s->last_picture.data[0];
+    srcU = s->last_picture.data[1];
+    srcV = s->last_picture.data[2];
+
+    if(s->mspel) { // hpel mc
+        dxy = ((my & 1) << 1) | (mx & 1);
+        src_x = s->mb_x * 16 + (mx >> 1);
+        src_y = s->mb_y * 16 + (my >> 1);
+/*        src_x = clip(src_x, -16, width); //FIXME unneeded for emu?
+        if (src_x == width)
+            dxy &= ~1;
+        src_y = clip(src_y, -16, height);
+        if (src_y == height)
+            dxy &= ~2;*/
+        srcY += src_y * s->linesize + src_x;
+        srcU += (src_y >> 1) * s->uvlinesize + (src_x >> 1);
+        srcV += (src_y >> 1) * s->uvlinesize + (src_x >> 1);
+
+        if((unsigned)src_x > s->h_edge_pos - (mx&1) - 16
+           || (unsigned)src_y > s->v_edge_pos - (my&1) - 16){
+            uint8_t *uvbuf= s->edge_emu_buffer + 18 * s->linesize;
+
+            ff_emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize, 16+1, 16+1,
+                             src_x, src_y, s->h_edge_pos, s->v_edge_pos);
+            srcY = s->edge_emu_buffer;
+            ff_emulated_edge_mc(uvbuf, srcU, s->uvlinesize, 8+1, 8+1,
+                             src_x >> 1, src_y >> 1, s->h_edge_pos >> 1, s->v_edge_pos >> 1);
+            ff_emulated_edge_mc(uvbuf + 16, srcV, s->uvlinesize, 8+1, 8+1,
+                             src_x >> 1, src_y >> 1, s->h_edge_pos >> 1, s->v_edge_pos >> 1);
+            srcU = uvbuf;
+            srcV = uvbuf + 16;
+        }
+        dsp->put_no_rnd_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize, 16);
+        dsp->put_no_rnd_pixels_tab[1][0](s->dest[1], srcU, s->uvlinesize, 8);
+        dsp->put_no_rnd_pixels_tab[1][0](s->dest[2], srcV, s->uvlinesize, 8);
+    } else {
+        int motion_x = mx, motion_y = my, uvdxy, uvsrc_x, uvsrc_y;
+        dxy = ((motion_y & 3) << 2) | (motion_x & 3);
+        src_x = s->mb_x * 16 + (mx >> 2);
+        src_y = s->mb_y * 16 + (my >> 2);
+
+        mx= motion_x/2;
+        my= motion_y/2;
+
+        mx= (mx>>1)|(mx&1);
+        my= (my>>1)|(my&1);
+
+        uvdxy= (mx&1) | ((my&1)<<1);
+        mx>>=1;
+        my>>=1;
+
+        uvsrc_x = s->mb_x * 8 + mx;
+        uvsrc_y = s->mb_y * 8 + my;
+
+        srcY = s->last_picture.data[0] +   src_y *   s->linesize +   src_x;
+        srcU = s->last_picture.data[1] + uvsrc_y * s->uvlinesize + uvsrc_x;
+        srcV = s->last_picture.data[2] + uvsrc_y * s->uvlinesize + uvsrc_x;
+
+        if(   (unsigned)src_x > s->h_edge_pos - (motion_x&3) - 16
+              || (unsigned)src_y > s->v_edge_pos - (motion_y&3) - 16  ){
+            uint8_t *uvbuf= s->edge_emu_buffer + 18*s->linesize;
+            ff_emulated_edge_mc(s->edge_emu_buffer, srcY, s->linesize, 17, 17,
+                                src_x, src_y, s->h_edge_pos, s->v_edge_pos);
+            srcY = s->edge_emu_buffer;
+            ff_emulated_edge_mc(uvbuf, srcU, s->uvlinesize, 9, 9,
+                                    uvsrc_x, uvsrc_y, s->h_edge_pos>>1, s->v_edge_pos>>1);
+            ff_emulated_edge_mc(uvbuf + 16, srcV, s->uvlinesize, 9, 9,
+                                    uvsrc_x, uvsrc_y, s->h_edge_pos>>1, s->v_edge_pos>>1);
+            srcU = uvbuf;
+            srcV = uvbuf + 16;
+        }
+
+        dsp->put_no_rnd_qpel_pixels_tab[0][dxy](s->dest[0], srcY, s->linesize);
+        dsp->put_no_rnd_pixels_tab[1][uvdxy](s->dest[1], srcU, s->uvlinesize, 8);
+        dsp->put_no_rnd_pixels_tab[1][uvdxy](s->dest[2], srcV, s->uvlinesize, 8);
+    }
+}
+
+/**
+ * Decode Simple/Main Profiles sequence header
+ * @see Figure 7-8, p16-17
+ * @param avctx Codec context
+ * @param gb GetBit context initialized from Codec context extra_data
+ * @return Status
+ */
+static int decode_sequence_header(AVCodecContext *avctx, GetBitContext *gb)
+{
+    VC1Context *v = avctx->priv_data;
+
+    av_log(avctx, AV_LOG_INFO, "Header: %0X\n", show_bits(gb, 32));
+    v->profile = get_bits(gb, 2);
+    if (v->profile == 2)
+    {
+        av_log(avctx, AV_LOG_ERROR, "Profile value 2 is forbidden (and WMV3 Complex Profile is unsupported)\n");
+        return -1;
+    }
+
+    if (v->profile == PROFILE_ADVANCED)
+    {
+        v->level = get_bits(gb, 3);
+        if(v->level >= 5)
+        {
+            av_log(avctx, AV_LOG_ERROR, "Reserved LEVEL %i\n",v->level);
+        }
+        v->chromaformat = get_bits(gb, 2);
+        if (v->chromaformat != 1)
         {
             av_log(avctx, AV_LOG_ERROR,
                    "Only 4:2:0 chroma format supported\n");
@@ -732,7 +1037,6 @@
         }
     }
     else
-#endif
     {
         v->res_sm = get_bits(gb, 2); //reserved
         if (v->res_sm)
@@ -754,9 +1058,7 @@
                "LOOPFILTER shell not be enabled in simple profile\n");
     }
 
-#if HAS_ADVANCED_PROFILE
     if (v->profile < PROFILE_ADVANCED)
-#endif
     {
         v->res_x8 = get_bits(gb, 1); //reserved
         if (v->res_x8)
@@ -792,9 +1094,7 @@
     v->dquant =  get_bits(gb, 2); //common
     v->vstransform =  get_bits(gb, 1); //common
 
-#if HAS_ADVANCED_PROFILE
     if (v->profile < PROFILE_ADVANCED)
-#endif
     {
         v->res_transtab = get_bits(gb, 1);
         if (v->res_transtab)
@@ -807,15 +1107,13 @@
 
     v->overlap = get_bits(gb, 1); //common
 
-#if HAS_ADVANCED_PROFILE
     if (v->profile < PROFILE_ADVANCED)
-#endif
     {
         v->s.resync_marker = get_bits(gb, 1);
         v->rangered = get_bits(gb, 1);
         if (v->rangered && v->profile == PROFILE_SIMPLE)
         {
-            av_log(avctx, AV_LOG_DEBUG,
+            av_log(avctx, AV_LOG_INFO,
                    "RANGERED should be set to 0 in simple profile\n");
         }
     }
@@ -823,9 +1121,7 @@
     v->s.max_b_frames = avctx->max_b_frames = get_bits(gb, 3); //common
     v->quantizer_mode = get_bits(gb, 2); //common
 
-#if HAS_ADVANCED_PROFILE
     if (v->profile < PROFILE_ADVANCED)
-#endif
     {
         v->finterpflag = get_bits(gb, 1); //common
         v->res_rtm_flag = get_bits(gb, 1); //reserved
@@ -835,828 +1131,134 @@
                    "0 for reserved RES_RTM_FLAG is forbidden\n");
             //return -1;
         }
-#if TRACE
-        av_log(avctx, AV_LOG_INFO,
+        av_log(avctx, AV_LOG_DEBUG,
                "Profile %i:\nfrmrtq_postproc=%i, bitrtq_postproc=%i\n"
                "LoopFilter=%i, MultiRes=%i, FastUVMV=%i, Extended MV=%i\n"
                "Rangered=%i, VSTransform=%i, Overlap=%i, SyncMarker=%i\n"
                "DQuant=%i, Quantizer mode=%i, Max B frames=%i\n",
                v->profile, v->frmrtq_postproc, v->bitrtq_postproc,
                v->s.loop_filter, v->multires, v->fastuvmc, v->extended_mv,
-               v->rangered, v->vstransform, v->overlap, v->s.resync_marker,
-               v->dquant, v->quantizer_mode, avctx->max_b_frames
-               );
-        return 0;
-#endif
-    }
-#if HAS_ADVANCED_PROFILE
-    else return decode_advanced_sequence_header(avctx, gb);
-#endif
-}
-
-
-#if HAS_ADVANCED_PROFILE
-/** Entry point decoding (Advanced Profile)
- * @param avctx Codec context
- * @param gb GetBit context initialized from avctx->extra_data
- * @return Status
- */
-static int advanced_entry_point_process(AVCodecContext *avctx, GetBitContext *gb)
-{
-    VC1Context *v = avctx->priv_data;
-    int i;
-    if (v->profile != PROFILE_ADVANCED)
-    {
-        av_log(avctx, AV_LOG_ERROR,
-               "Entry point are only defined in Advanced Profile!\n");
-        return -1; //Only for advanced profile!
-    }
-    if (v->hrd_param_flag)
-    {
-        //Update buffer fullness
-        av_log(avctx, AV_LOG_DEBUG, "Buffer fullness update\n");
-        assert(v->hrd_num_leaky_buckets > 0);
-        for (i=0; i<v->hrd_num_leaky_buckets; i++)
-            v->hrd_fullness[i] = get_bits(gb, 8);
-    }
-    if ((v->range_mapy_flag = get_bits(gb, 1)))
-    {
-        //RANGE_MAPY
-        av_log(avctx, AV_LOG_DEBUG, "RANGE_MAPY\n");
-        v->range_mapy = get_bits(gb, 3);
-    }
-    if ((v->range_mapuv_flag = get_bits(gb, 1)))
-    {
-        //RANGE_MAPUV
-        av_log(avctx, AV_LOG_DEBUG, "RANGE_MAPUV\n");
-        v->range_mapuv = get_bits(gb, 3);
-    }
-    if (v->panscanflag)
-    {
-        //NUMPANSCANWIN
-        v->numpanscanwin = get_bits(gb, 3);
-        av_log(avctx, AV_LOG_DEBUG, "NUMPANSCANWIN: %u\n", v->numpanscanwin);
-    }
-    return 0;
-}
-#endif
-
-/***********************************************************************/
-/**
- * @defgroup bitplane VC1 Bitplane decoding
- * @see 8.7, p56
- * @{
- */
-
-/** @addtogroup bitplane
- * Imode types
- * @{
- */
-#define IMODE_RAW     0
-#define IMODE_NORM2   1
-#define IMODE_DIFF2   2
-#define IMODE_NORM6   3
-#define IMODE_DIFF6   4
-#define IMODE_ROWSKIP 5
-#define IMODE_COLSKIP 6
-/** @} */ //imode defines
-
-/** Allocate the buffer from a bitplane, given its dimensions
- * @param bp Bitplane which buffer is to allocate
- * @param[in] width Width of the buffer
- * @param[in] height Height of the buffer
- * @return Status
- * @todo TODO: Take into account stride
- * @todo TODO: Allow use of external buffers ?
- */
-static int alloc_bitplane(BitPlane *bp, int width, int height)
-{
-    if (!bp || bp->width<0 || bp->height<0) return -1;
-    bp->data = (uint8_t*)av_malloc(width*height);
-    if (!bp->data) return -1;
-    bp->width = bp->stride = width;
-    bp->height = height;
-    return 0;
-}
-
-/** Free the bitplane's buffer
- * @param bp Bitplane which buffer is to free
- */
-static void free_bitplane(BitPlane *bp)
-{
-    bp->width = bp->stride = bp->height = 0;
-    if (bp->data) av_freep(&bp->data);
-}
-
-/** Decode rows by checking if they are skipped
- * @param plane Buffer to store decoded bits
- * @param[in] width Width of this buffer
- * @param[in] height Height of this buffer
- * @param[in] stride of this buffer
- */
-static void decode_rowskip(uint8_t* plane, int width, int height, int stride, GetBitContext *gb){
-    int x, y;
-
-    for (y=0; y<height; y++){
-        if (!get_bits(gb, 1)) //rowskip
-            memset(plane, 0, width);
-        else
-            for (x=0; x<width; x++)
-                plane[x] = get_bits(gb, 1);
-        plane += stride;
-    }
-}
-
-/** Decode columns by checking if they are skipped
- * @param plane Buffer to store decoded bits
- * @param[in] width Width of this buffer
- * @param[in] height Height of this buffer
- * @param[in] stride of this buffer
- * @fixme FIXME: Optimize
- */
-static void decode_colskip(uint8_t* plane, int width, int height, int stride, GetBitContext *gb){
-    int x, y;
-
-    for (x=0; x<width; x++){
-        if (!get_bits(gb, 1)) //colskip
-            for (y=0; y<height; y++)
-                plane[y*stride] = 0;
-        else
-            for (y=0; y<height; y++)
-                plane[y*stride] = get_bits(gb, 1);
-        plane ++;
-    }
-}
-
-/** Decode a bitplane's bits
- * @param bp Bitplane where to store the decode bits
- * @param v VC1 context for bit reading and logging
- * @return Status
- * @fixme FIXME: Optimize
- * @todo TODO: Decide if a struct is needed
- */
-static int bitplane_decoding(BitPlane *bp, VC1Context *v)
-{
-    GetBitContext *gb = &v->s.gb;
-
-    int imode, x, y, code, use_vertical_tile, tile_w, tile_h, offset;
-    uint8_t invert, *planep = bp->data;
-
-    invert = get_bits(gb, 1);
-    imode = get_vlc2(gb, vc1_imode_vlc.table, VC1_IMODE_VLC_BITS, 2);
-
-    bp->is_raw = 0;
-    switch (imode)
-    {
-    case IMODE_RAW:
-        //Data is actually read in the MB layer (same for all tests == "raw")
-        bp->is_raw = 1; //invert ignored
-        return invert;
-    case IMODE_DIFF2:
-    case IMODE_NORM2:
-        if ((bp->height*bp->width) & 1)
-        {
-            *(++planep) = get_bits(gb, 1);
-            offset = x = 1;
-        }
-        else offset = x = 0;
-
-        for (y=0; y<bp->height; y++)
-        {
-            for(; x<bp->width; x+=2)
-            {
-                code = get_vlc2(gb, vc1_norm2_vlc.table, VC1_NORM2_VLC_BITS, 2);
-                *(++planep) = code&1; //lsb => left
-                *(++planep) = (code>>1)&1; //msb => right
-            }
-            planep += bp->stride-bp->width;
-            if ((bp->width-offset)&1) //Odd number previously processed
-            {
-                code = get_vlc2(gb, vc1_norm2_vlc.table, VC1_NORM2_VLC_BITS, 2);
-                *planep = code&1;
-                planep += bp->stride-bp->width;
-                *planep = (code>>1)&1; //msb => right
-                offset = x = 1;
-            }
-            else
-            {
-                offset = x = 0;
-                planep += bp->stride-bp->width;
-            }
-        }
-        break;
-    case IMODE_DIFF6:
-    case IMODE_NORM6:
-        use_vertical_tile=  bp->height%3==0 &&  bp->width%3!=0;
-        tile_w= use_vertical_tile ? 2 : 3;
-        tile_h= use_vertical_tile ? 3 : 2;
-
-        for(y=  bp->height%tile_h; y< bp->height; y+=tile_h){
-            for(x=  bp->width%tile_w; x< bp->width; x+=tile_w){
-                code = get_vlc2(gb, vc1_norm6_vlc.table, VC1_NORM6_VLC_BITS, 2);
-                if(code<0){
-                    av_log(v->s.avctx, AV_LOG_DEBUG, "invalid NORM-6 VLC\n");
-                    return -1;
-                }
-                //FIXME following is a pure guess and probably wrong
-                //FIXME A bitplane (0 | !0), so could the shifts be avoided ?
-                planep[x     + 0*bp->stride]= (code>>0)&1;
-                planep[x + 1 + 0*bp->stride]= (code>>1)&1;
-                //FIXME Does branch prediction help here?
-                if(use_vertical_tile){
-                    planep[x + 0 + 1*bp->stride]= (code>>2)&1;
-                    planep[x + 1 + 1*bp->stride]= (code>>3)&1;
-                    planep[x + 0 + 2*bp->stride]= (code>>4)&1;
-                    planep[x + 1 + 2*bp->stride]= (code>>5)&1;
-                }else{
-                    planep[x + 2 + 0*bp->stride]= (code>>2)&1;
-                    planep[x + 0 + 1*bp->stride]= (code>>3)&1;
-                    planep[x + 1 + 1*bp->stride]= (code>>4)&1;
-                    planep[x + 2 + 1*bp->stride]= (code>>5)&1;
-                }
-            }
-        }
-
-        x=  bp->width % tile_w;
-        decode_colskip(bp->data  ,             x, bp->height         , bp->stride, &v->s.gb);
-        decode_rowskip(bp->data+x, bp->width - x, bp->height % tile_h, bp->stride, &v->s.gb);
-
-        break;
-    case IMODE_ROWSKIP:
-        decode_rowskip(bp->data, bp->width, bp->height, bp->stride, &v->s.gb);
-        break;
-    case IMODE_COLSKIP:
-        decode_colskip(bp->data, bp->width, bp->height, bp->stride, &v->s.gb);
-        break;
-    default: break;
-    }
-
-    /* Applying diff operator */
-    if (imode == IMODE_DIFF2 || imode == IMODE_DIFF6)
-    {
-        planep = bp->data;
-        planep[0] ^= invert;
-        for (x=1; x<bp->width; x++)
-            planep[x] ^= planep[x-1];
-        for (y=1; y<bp->height; y++)
-        {
-            planep += bp->stride;
-            planep[0] ^= planep[-bp->stride];
-            for (x=1; x<bp->width; x++)
-            {
-                if (planep[x-1] != planep[x-bp->stride]) planep[x] ^= invert;
-                else                                     planep[x] ^= planep[x-1];
-            }
-        }
-    }
-    else if (invert)
-    {
-        planep = bp->data;
-        for (x=0; x<bp->width*bp->height; x++) planep[x] = !planep[x]; //FIXME stride
-    }
-    return (imode<<1) + invert;
-}
-/** @} */ //Bitplane group
-
-/***********************************************************************/
-/** VOP Dquant decoding
- * @param v VC1 Context
- */
-static int vop_dquant_decoding(VC1Context *v)
-{
-    GetBitContext *gb = &v->s.gb;
-    int pqdiff;
-
-    //variable size
-    if (v->dquant == 2)
-    {
-        pqdiff = get_bits(gb, 3);
-        if (pqdiff == 7) v->altpq = get_bits(gb, 5);
-        else v->altpq = v->pq + pqdiff + 1;
-    }
-    else
-    {
-        v->dquantfrm = get_bits(gb, 1);
-        if ( v->dquantfrm )
-        {
-            v->dqprofile = get_bits(gb, 2);
-            switch (v->dqprofile)
-            {
-            case DQPROFILE_SINGLE_EDGE:
-            case DQPROFILE_DOUBLE_EDGES:
-                v->dqsbedge = get_bits(gb, 2);
-                break;
-            case DQPROFILE_ALL_MBS:
-                v->dqbilevel = get_bits(gb, 1);
-            default: break; //Forbidden ?
-            }
-            if (!v->dqbilevel || v->dqprofile != DQPROFILE_ALL_MBS)
-            {
-                pqdiff = get_bits(gb, 3);
-                if (pqdiff == 7) v->altpq = get_bits(gb, 5);
-                else v->altpq = v->pq + pqdiff + 1;
-            }
-        }
-    }
-    return 0;
-}
-
-/***********************************************************************/
-/**
- * @defgroup all_frame_hdr All VC1 profiles frame header
- * @brief Part of the frame header decoding from all profiles
- * @warning Only pro/epilog differs between Simple/Main and Advanced => check caller
- * @{
- */
-/** B and BI frame header decoding, primary part
- * @see Tables 11+12, p62-65
- * @param v VC1 context
- * @return Status
- * @warning Also handles BI frames
- */
-static int decode_b_picture_primary_header(VC1Context *v)
-{
-    GetBitContext *gb = &v->s.gb;
-    int pqindex;
-
-    /* Prolog common to all frametypes should be done in caller */
-    if (v->profile == PROFILE_SIMPLE)
-    {
-        av_log(v->s.avctx, AV_LOG_ERROR, "Found a B frame while in Simple Profile!\n");
-        return FRAME_SKIPPED;
-    }
-    v->bfraction = vc1_bfraction_lut[get_vlc2(gb, vc1_bfraction_vlc.table,
-                                              VC1_BFRACTION_VLC_BITS, 2)];
-    if (v->bfraction < -1)
-    {
-        av_log(v->s.avctx, AV_LOG_ERROR, "Invalid BFRaction\n");
-        return FRAME_SKIPPED;
-    }
-    else if (!v->bfraction)
-    {
-        /* We actually have a BI frame */
-        v->s.pict_type = BI_TYPE;
-        v->buffer_fullness = get_bits(gb, 7);
-    }
-
-    /* Read the quantization stuff */
-    pqindex = get_bits(gb, 5);
-    if (v->quantizer_mode == QUANT_FRAME_IMPLICIT)
-        v->pq = pquant_table[0][pqindex];
-    else
-    {
-        v->pq = pquant_table[v->quantizer_mode-1][pqindex];
-    }
-    if (pqindex < 9) v->halfpq = get_bits(gb, 1);
-    if (v->quantizer_mode == QUANT_FRAME_EXPLICIT)
-        v->pquantizer = get_bits(gb, 1);
-#if HAS_ADVANCED_PROFILE
-    if (v->profile == PROFILE_ADVANCED)
-    {
-        if (v->postprocflag) v->postproc = get_bits(gb, 2);
-        if (v->extended_mv == 1 && v->s.pict_type != BI_TYPE)
-            v->mvrange = get_prefix(gb, 0, 3);
-    }
-#endif
-    else
-    {
-        if (v->extended_mv == 1)
-            v->mvrange = get_prefix(gb, 0, 3);
-    }
-    /* Read the MV mode */
-    if (v->s.pict_type != BI_TYPE)
-    {
-        v->mv_mode = get_bits(gb, 1);
-        if (v->pq < 13)
-        {
-            if (!v->mv_mode)
-            {
-                v->mv_mode = get_bits(gb, 2);
-                if (v->mv_mode)
-                av_log(v->s.avctx, AV_LOG_ERROR,
-                       "mv_mode for lowquant B frame was %i\n", v->mv_mode);
-            }
-        }
-        else
-        {
-            if (!v->mv_mode)
-            {
-                if (get_bits(gb, 1))
-                     av_log(v->s.avctx, AV_LOG_ERROR,
-                            "mv_mode for highquant B frame was %i\n", v->mv_mode);
-            }
-            v->mv_mode = 1-v->mv_mode; //To match (pq < 13) mapping
-        }
-    }
-
-    return 0;
-}
-
-/** B and BI frame header decoding, secondary part
- * @see Tables 11+12, p62-65
- * @param v VC1 context
- * @return Status
- * @warning Also handles BI frames
- * @warning To call once all MB arrays are allocated
- * @todo Support Advanced Profile headers
- */
-static int decode_b_picture_secondary_header(VC1Context *v)
-{
-    GetBitContext *gb = &v->s.gb;
-    int status;
-
-    status = bitplane_decoding(&v->skip_mb_plane, v);
-    if (status < 0) return -1;
-#if TRACE
-    if (v->mv_mode == MV_PMODE_MIXED_MV)
-    {
-        status = bitplane_decoding(&v->mv_type_mb_plane, v);
-        if (status < 0)
-            return -1;
-#if TRACE
-        av_log(v->s.avctx, AV_LOG_DEBUG, "MB MV Type plane encoding: "
-               "Imode: %i, Invert: %i\n", status>>1, status&1);
-#endif
-    }
-
-    //bitplane
-    status = bitplane_decoding(&v->direct_mb_plane, v);
-    if (status < 0) return -1;
-#if TRACE
-    av_log(v->s.avctx, AV_LOG_DEBUG, "MB Direct plane encoding: "
-           "Imode: %i, Invert: %i\n", status>>1, status&1);
-#endif
-
-    av_log(v->s.avctx, AV_LOG_DEBUG, "Skip MB plane encoding: "
-           "Imode: %i, Invert: %i\n", status>>1, status&1);
-#endif
-
-    /* FIXME: what is actually chosen for B frames ? */
-    v->s.mv_table_index = get_bits(gb, 2); //but using vc1_ tables
-    v->cbpcy_vlc = &vc1_cbpcy_p_vlc[get_bits(gb, 2)];
-
-    if (v->dquant)
-    {
-        vop_dquant_decoding(v);
-    }
-
-    if (v->vstransform)
-    {
-        v->ttmbf = get_bits(gb, 1);
-        if (v->ttmbf)
-        {
-            v->ttfrm = get_bits(gb, 2);
-            av_log(v->s.avctx, AV_LOG_INFO, "Transform used: %ix%i\n",
-                   (v->ttfrm & 2) ? 4 : 8, (v->ttfrm & 1) ? 4 : 8);
-        }
-    }
-    /* Epilog (AC/DC syntax) should be done in caller */
-    return 0;
-}
-
-/** I frame header decoding, primary part
- * @see Tables 5+7, p53-54 and 55-57
- * @param v VC1 context
- * @return Status
- * @todo Support Advanced Profile headers
- */
-static int decode_i_picture_primary_header(VC1Context *v)
-{
-    GetBitContext *gb = &v->s.gb;
-    int pqindex;
-
-    /* Prolog common to all frametypes should be done in caller */
-    //BF = Buffer Fullness
-    if (v->profile < PROFILE_ADVANCED && get_bits(gb, 7))
-    {
-        av_log(v->s.avctx, AV_LOG_DEBUG, "I BufferFullness not 0\n");
-    }
-
-    /* Quantizer stuff */
-    pqindex = get_bits(gb, 5);
-    if (v->quantizer_mode == QUANT_FRAME_IMPLICIT)
-        v->pq = pquant_table[0][pqindex];
-    else
-    {
-        v->pq = pquant_table[v->quantizer_mode-1][pqindex];
-    }
-    if (pqindex < 9) v->halfpq = get_bits(gb, 1);
-    if (v->quantizer_mode == QUANT_FRAME_EXPLICIT)
-        v->pquantizer = get_bits(gb, 1);
-    av_log(v->s.avctx, AV_LOG_DEBUG, "I frame: QP=%i (+%i/2)\n",
-           v->pq, v->halfpq);
-    return 0;
-}
-
-/** I frame header decoding, secondary part
- * @param v VC1 context
- * @return Status
- * @warning Not called in A/S/C profiles, it seems
- * @todo Support Advanced Profile headers
- */
-static int decode_i_picture_secondary_header(VC1Context *v)
-{
-#if HAS_ADVANCED_PROFILE
-    int status;
-    if (v->profile == PROFILE_ADVANCED)
-    {
-        v->s.ac_pred = get_bits(&v->s.gb, 1);
-        if (v->postprocflag) v->postproc = get_bits(&v->s.gb, 1);
-        /* 7.1.1.34 + 8.5.2 */
-        if (v->overlap && v->pq<9)
-        {
-            v->condover = get_bits(&v->s.gb, 1);
-            if (v->condover)
-            {
-                v->condover = 2+get_bits(&v->s.gb, 1);
-                if (v->condover == 3)
-                {
-                    status = bitplane_decoding(&v->over_flags_plane, v);
-                    if (status < 0) return -1;
-#  if TRACE
-                    av_log(v->s.avctx, AV_LOG_DEBUG, "Overflags plane encoding: "
-                           "Imode: %i, Invert: %i\n", status>>1, status&1);
-#  endif
-                }
-            }
-        }
-    }
-#endif
-
-    /* Epilog (AC/DC syntax) should be done in caller */
-    return 0;
-}
-
-/** P frame header decoding, primary part
- * @see Tables 5+7, p53-54 and 55-57
- * @param v VC1 context
- * @todo Support Advanced Profile headers
- * @return Status
- */
-static int decode_p_picture_primary_header(VC1Context *v)
-{
-    /* INTERFRM, FRMCNT, RANGEREDFRM read in caller */
-    GetBitContext *gb = &v->s.gb;
-    int lowquant, pqindex;
-
-    pqindex = get_bits(gb, 5);
-    if (v->quantizer_mode == QUANT_FRAME_IMPLICIT)
-        v->pq = pquant_table[0][pqindex];
-    else
-    {
-        v->pq = pquant_table[v->quantizer_mode-1][pqindex];
-    }
-    if (pqindex < 9) v->halfpq = get_bits(gb, 1);
-    if (v->quantizer_mode == QUANT_FRAME_EXPLICIT)
-        v->pquantizer = get_bits(gb, 1);
-    av_log(v->s.avctx, AV_LOG_DEBUG, "P Frame: QP=%i (+%i/2)\n",
-           v->pq, v->halfpq);
-    if (v->extended_mv == 1) v->mvrange = get_prefix(gb, 0, 3);
-#if HAS_ADVANCED_PROFILE
-    if (v->profile == PROFILE_ADVANCED)
-    {
-        if (v->postprocflag) v->postproc = get_bits(gb, 1);
-    }
-    else
-#endif
-        if (v->multires) v->respic = get_bits(gb, 2);
-    lowquant = (v->pquantizer>12) ? 0 : 1;
-    v->mv_mode = mv_pmode_table[lowquant][get_prefix(gb, 1, 4)];
-    if (v->mv_mode == MV_PMODE_INTENSITY_COMP)
-    {
-        v->mv_mode2 = mv_pmode_table[lowquant][get_prefix(gb, 1, 3)];
-        v->lumscale = get_bits(gb, 6);
-        v->lumshift = get_bits(gb, 6);
-    }
-    return 0;
-}
-
-/** P frame header decoding, secondary part
- * @see Tables 5+7, p53-54 and 55-57
- * @param v VC1 context
- * @warning To call once all MB arrays are allocated
- * @return Status
- */
-static int decode_p_picture_secondary_header(VC1Context *v)
-{
-    GetBitContext *gb = &v->s.gb;
-    int status = 0;
-    if ((v->mv_mode == MV_PMODE_INTENSITY_COMP &&
-         v->mv_mode2 == MV_PMODE_MIXED_MV)
-        || v->mv_mode == MV_PMODE_MIXED_MV)
-    {
-        status = bitplane_decoding(&v->mv_type_mb_plane, v);
-        if (status < 0) return -1;
-#if TRACE
-        av_log(v->s.avctx, AV_LOG_DEBUG, "MB MV Type plane encoding: "
-               "Imode: %i, Invert: %i\n", status>>1, status&1);
-#endif
-    }
-
-    status = bitplane_decoding(&v->skip_mb_plane, v);
-    if (status < 0) return -1;
-#if TRACE
-    av_log(v->s.avctx, AV_LOG_DEBUG, "MB Skip plane encoding: "
-           "Imode: %i, Invert: %i\n", status>>1, status&1);
-#endif
-
-    /* Hopefully this is correct for P frames */
-    v->s.mv_table_index =get_bits(gb, 2); //but using vc1_ tables
-    v->cbpcy_vlc = &vc1_cbpcy_p_vlc[get_bits(gb, 2)];
-
-    if (v->dquant)
-    {
-        av_log(v->s.avctx, AV_LOG_INFO, "VOP DQuant info\n");
-        vop_dquant_decoding(v);
-    }
-
-    v->ttfrm = 0; //FIXME Is that so ?
-    if (v->vstransform)
-    {
-        v->ttmbf = get_bits(gb, 1);
-        if (v->ttmbf)
-        {
-            v->ttfrm = get_bits(gb, 2);
-            av_log(v->s.avctx, AV_LOG_INFO, "Transform used: %ix%i\n",
-                   (v->ttfrm & 2) ? 4 : 8, (v->ttfrm & 1) ? 4 : 8);
-        }
+               v->rangered, v->vstransform, v->overlap, v->s.resync_marker,
+               v->dquant, v->quantizer_mode, avctx->max_b_frames
+               );
+        return 0;
     }
-    /* Epilog (AC/DC syntax) should be done in caller */
-    return 0;
+    return -1;
 }
-/** @} */ //End of group all_frm_hdr
 
 
-/***********************************************************************/
-/**
- * @defgroup std_frame_hdr VC1 Simple/Main Profiles header decoding
- * @brief Part of the frame header decoding belonging to Simple/Main Profiles
- * @warning Only pro/epilog differs between Simple/Main and Advanced =>
- *          check caller
- * @{
- */
-
-/** Frame header decoding, first part, in Simple and Main profiles
- * @see Tables 5+7, p53-54 and 55-57
- * @param v VC1 context
- * @todo FIXME: RANGEREDFRM element not read if BI frame from Table6, P54
- *              However, 7.1.1.8 says "all frame types, for main profiles"
- * @return Status
- */
-static int standard_decode_picture_primary_header(VC1Context *v)
+static int vc1_parse_frame_header(VC1Context *v, GetBitContext* gb)
 {
-    GetBitContext *gb = &v->s.gb;
-    int status = 0;
+    int pqindex, lowquant, status;
 
-    if (v->finterpflag) v->interpfrm = get_bits(gb, 1);
+    if(v->finterpflag) v->interpfrm = get_bits(gb, 1);
     skip_bits(gb, 2); //framecnt unused
+    v->rangeredfrm = 0;
     if (v->rangered) v->rangeredfrm = get_bits(gb, 1);
     v->s.pict_type = get_bits(gb, 1);
-    if (v->s.avctx->max_b_frames)
-    {
-        if (!v->s.pict_type)
-        {
+    if (v->s.avctx->max_b_frames) {
+        if (!v->s.pict_type) {
             if (get_bits(gb, 1)) v->s.pict_type = I_TYPE;
             else v->s.pict_type = B_TYPE;
-        }
-        else v->s.pict_type = P_TYPE;
-    }
-    else v->s.pict_type++;
+        } else v->s.pict_type = P_TYPE;
+    } else v->s.pict_type = v->s.pict_type ? P_TYPE : I_TYPE;
 
-    switch (v->s.pict_type)
-    {
-    case I_TYPE: status = decode_i_picture_primary_header(v); break;
-    case P_TYPE: status = decode_p_picture_primary_header(v); break;
-    case BI_TYPE: //Same as B
-    case B_TYPE: status = decode_b_picture_primary_header(v); break;
-    }
+    if(v->s.pict_type == I_TYPE)
+        get_bits(gb, 7); // skip buffer fullness
 
-    if (status == FRAME_SKIPPED)
-    {
-      av_log(v->s.avctx, AV_LOG_INFO, "Skipping frame...\n");
-      return status;
-    }
-    return 0;
-}
+    /* Quantizer stuff */
+    pqindex = get_bits(gb, 5);
+    if (v->quantizer_mode == QUANT_FRAME_IMPLICIT)
+        v->pq = pquant_table[0][pqindex];
+    else
+        v->pq = pquant_table[v->quantizer_mode-1][pqindex];
 
-/** Frame header decoding, secondary part
- * @param v VC1 context
- * @warning To call once all MB arrays are allocated
- * @return Status
- */
-static int standard_decode_picture_secondary_header(VC1Context *v)
-{
-    GetBitContext *gb = &v->s.gb;
-    int status = 0;
+    if (v->quantizer_mode == QUANT_FRAME_IMPLICIT)
+        v->pquantizer = pqindex < 9;
+    if (v->quantizer_mode == QUANT_UNIFORM || v->quantizer_mode == QUANT_NON_UNIFORM)
+        v->pquantizer = v->quantizer_mode == QUANT_UNIFORM;
+    v->pqindex = pqindex;
+    if (pqindex < 9) v->halfpq = get_bits(gb, 1);
+    else v->halfpq = 0;
+    if (v->quantizer_mode == QUANT_FRAME_EXPLICIT)
+        v->pquantizer = get_bits(gb, 1);
+    v->dquantfrm = 0;
 
-    switch (v->s.pict_type)
-    {
-    case P_TYPE: status = decode_p_picture_secondary_header(v); break;
-    case B_TYPE: status = decode_b_picture_secondary_header(v); break;
-    case BI_TYPE:
-    case I_TYPE: break; //Nothing needed as it's done in the epilog
-    }
-    if (status < 0) return FRAME_SKIPPED;
+//av_log(v->s.avctx, AV_LOG_INFO, "%c Frame: QP=[%i]%i (+%i/2) %i\n",
+//        (v->s.pict_type == P_TYPE) ? 'P' : ((v->s.pict_type == I_TYPE) ? 'I' : 'B'), pqindex, v->pq, v->halfpq, v->rangeredfrm);
 
-    /* AC Syntax */
-    v->c_ac_table_index = decode012(gb);
-    if (v->s.pict_type == I_TYPE || v->s.pict_type == BI_TYPE)
-    {
-        v->y_ac_table_index = decode012(gb);
-    }
-    /* DC Syntax */
-    v->s.dc_table_index = decode012(gb);
+    //TODO: complete parsing for P/B/BI frames
+    switch(v->s.pict_type) {
+    case P_TYPE:
+        if (v->pq < 5) v->tt_index = 0;
+        else if(v->pq < 13) v->tt_index = 1;
+        else v->tt_index = 2;
+
+        if (v->extended_mv == 1) v->mvrange = get_prefix(gb, 0, 3);
+        v->k_x = v->mvrange + 9 + (v->mvrange >> 1); //k_x can be 9 10 12 13
+        v->k_y = v->mvrange + 8; //k_y can be 8 9 10 11
+        v->range_x = 1 << (v->k_x - 1);
+        v->range_y = 1 << (v->k_y - 1);
+        if (v->profile == PROFILE_ADVANCED)
+        {
+            if (v->postprocflag) v->postproc = get_bits(gb, 1);
+        }
+        else
+            if (v->multires) v->respic = get_bits(gb, 2);
+        lowquant = (v->pq > 12) ? 0 : 1;
+        v->mv_mode = mv_pmode_table[lowquant][get_prefix(gb, 1, 4)];
+        if (v->mv_mode == MV_PMODE_INTENSITY_COMP)
+        {
+            v->mv_mode2 = mv_pmode_table[lowquant][get_prefix(gb, 1, 3)];
+            v->lumscale = get_bits(gb, 6);
+            v->lumshift = get_bits(gb, 6);
+        }
+        if(v->mv_mode == MV_PMODE_1MV_HPEL || v->mv_mode == MV_PMODE_1MV_HPEL_BILIN)
+            v->s.mspel = 1;
+        else
+            v->s.mspel = 0;
 
-    return 0;
+if(v->mv_mode != MV_PMODE_1MV && v->mv_mode != MV_PMODE_1MV_HPEL && v->mv_mode != MV_PMODE_1MV_HPEL_BILIN) {
+    av_log(v->s.avctx, AV_LOG_ERROR, "Only 1MV P-frames are supported by now\n");
+    return -1;
 }
-/** @} */ //End for group std_frame_hdr
-
-#if HAS_ADVANCED_PROFILE
-/***********************************************************************/
-/**
- * @defgroup adv_frame_hdr VC1 Advanced Profile header decoding
- * @brief Part of the frame header decoding belonging to Advanced Profiles
- * @warning Only pro/epilog differs between Simple/Main and Advanced =>
- *          check caller
- * @{
- */
-/** Frame header decoding, primary part
- * @param v VC1 context
- * @return Status
- */
-static int advanced_decode_picture_primary_header(VC1Context *v)
-{
-    GetBitContext *gb = &v->s.gb;
-    static const int type_table[4] = { P_TYPE, B_TYPE, I_TYPE, BI_TYPE };
-    int type;
-
-    if (v->interlace)
-    {
-        v->fcm = get_bits(gb, 1);
-        if (v->fcm) v->fcm = 2+get_bits(gb, 1);
-    }
+        if ((v->mv_mode == MV_PMODE_INTENSITY_COMP &&
+                 v->mv_mode2 == MV_PMODE_MIXED_MV)
+                || v->mv_mode == MV_PMODE_MIXED_MV)
+        {
+            status = bitplane_decoding(&v->mv_type_mb_plane, v);
+            if (status < 0) return -1;
+            av_log(v->s.avctx, AV_LOG_DEBUG, "MB MV Type plane encoding: "
+                   "Imode: %i, Invert: %i\n", status>>1, status&1);
+        }
+        status = bitplane_decoding(&v->skip_mb_plane, v);
+        if (status < 0) return -1;
+        av_log(v->s.avctx, AV_LOG_DEBUG, "MB Skip plane encoding: "
+               "Imode: %i, Invert: %i\n", status>>1, status&1);
 
-    type = get_prefix(gb, 0, 4);
-    if (type > 4 || type < 0) return FRAME_SKIPPED;
-    v->s.pict_type = type_table[type];
-    av_log(v->s.avctx, AV_LOG_INFO, "AP Frame Type: %i\n", v->s.pict_type);
+        /* Hopefully this is correct for P frames */
+        v->s.mv_table_index = get_bits(gb, 2); //but using vc1_ tables
+        v->cbpcy_vlc = &vc1_cbpcy_p_vlc[get_bits(gb, 2)];
 
-    if (v->tfcntrflag) v->tfcntr = get_bits(gb, 8);
-    if (v->broadcast)
-    {
-        if (!v->interlace) v->rptfrm = get_bits(gb, 2);
-        else
+        if (v->dquant)
         {
-            v->tff = get_bits(gb, 1);
-            v->rff = get_bits(gb, 1);
+            av_log(v->s.avctx, AV_LOG_DEBUG, "VOP DQuant info\n");
+            vop_dquant_decoding(v);
         }
-    }
 
-    if (v->panscanflag)
-    {
-#if 0
-        for (i=0; i<v->numpanscanwin; i++)
+        v->ttfrm = 0; //FIXME Is that so ?
+        if (v->vstransform)
         {
-            v->topleftx[i] = get_bits(gb, 16);
-            v->toplefty[i] = get_bits(gb, 16);
-            v->bottomrightx[i] = get_bits(gb, 16);
-            v->bottomrighty[i] = get_bits(gb, 16);
+            v->ttmbf = get_bits(gb, 1);
+            if (v->ttmbf)
+            {
+                v->ttfrm = get_bits(gb, 2);
+            }
         }
-#else
-        skip_bits(gb, 16*4*v->numpanscanwin);
-#endif
-    }
-    v->s.no_rounding = !get_bits(gb, 1);
-    v->uvsamp = get_bits(gb, 1);
-    if (v->finterpflag == 1) v->interpfrm = get_bits(gb, 1);
-
-    switch(v->s.pict_type)
-    {
-    case I_TYPE: if (decode_i_picture_primary_header(v) < 0) return -1;
-    case P_TYPE: if (decode_p_picture_primary_header(v) < 0) return -1;
-    case BI_TYPE:
-    case B_TYPE: if (decode_b_picture_primary_header(v) < 0) return FRAME_SKIPPED;
-    default: return -1;
-    }
-}
-
-/** Frame header decoding, secondary part
- * @param v VC1 context
- * @return Status
- */
-static int advanced_decode_picture_secondary_header(VC1Context *v)
-{
-    GetBitContext *gb = &v->s.gb;
-    int status = 0;
-
-    switch(v->s.pict_type)
-    {
-    case P_TYPE: status = decode_p_picture_secondary_header(v); break;
-    case B_TYPE: status = decode_b_picture_secondary_header(v); break;
-    case BI_TYPE:
-    case I_TYPE: status = decode_i_picture_secondary_header(v); break;
+        break;
+    case B_TYPE:
+        break;
     }
-    if (status<0) return FRAME_SKIPPED;
 
     /* AC Syntax */
     v->c_ac_table_index = decode012(gb);
@@ -1665,16 +1267,14 @@
         v->y_ac_table_index = decode012(gb);
     }
     /* DC Syntax */
-    v->s.dc_table_index = decode012(gb);
+    v->s.dc_table_index = get_bits(gb, 1);
 
     return 0;
 }
-#endif
-/** @} */ //End for adv_frame_hdr
 
 /***********************************************************************/
 /**
- * @defgroup block VC1 Block-level functions
+ * @defgroup block VC-1 Block-level functions
  * @see 7.1.4, p91 and 8.1.1.7, p(1)04
  * @todo TODO: Integrate to MpegEncContext facilities
  * @{
@@ -1726,8 +1326,13 @@
   if (!index) { _dmv_x = _dmv_y = 0; }                              \
   else if (index == 35)                                             \
   {                                                                 \
-    _dmv_x = get_bits(gb, v->k_x);                                  \
-    _dmv_y = get_bits(gb, v->k_y);                                  \
+    _dmv_x = get_bits(gb, v->k_x - s->mspel);                       \
+    _dmv_y = get_bits(gb, v->k_y - s->mspel);                       \
+  }                                                                 \
+  else if (index == 36)                                             \
+  {                                                                 \
+    _dmv_x = 0;                                                     \
+    _dmv_y = 0;                                                     \
     s->mb_intra = 1;                                                \
   }                                                                 \
   else                                                              \
@@ -1747,22 +1352,110 @@
     _dmv_y = (sign ^ ((val>>1) + offset_table[index1])) - sign;     \
   }
 
-/** Get predicted DC value
+/** Predict and set motion vector
+ */
+static inline void vc1_pred_mv(MpegEncContext *s, int dmv_x, int dmv_y, int mv1, int r_x, int r_y)
+{
+    int xy, wrap, off;
+    int16_t *A, *B, *C;
+    int px, py;
+    int sum;
+    int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
+
+    /* scale MV difference to be quad-pel */
+    dmv_x <<= s->mspel;
+    dmv_y <<= s->mspel;
+
+    wrap = s->b8_stride;
+    xy = s->block_index[0];
+
+    C = s->current_picture.motion_val[0][xy - (1 << mv1)];
+    A = s->current_picture.motion_val[0][xy - (wrap << mv1)];
+    off = (s->mb_x == (s->mb_width - 1)) ? -1 : 1;
+    B = s->current_picture.motion_val[0][xy + ((off - wrap) << mv1)];
+
+    if(!s->first_slice_line) { // predictor A is not out of bounds
+        if(s->mb_width == 1) {
+            px = A[0];
+            py = A[1];
+        } else {
+            px = mid_pred(A[0], B[0], C[0]);
+            py = mid_pred(A[1], B[1], C[1]);
+        }
+    } else if(s->mb_x) { // predictor C is not out of bounds
+        px = C[0];
+        py = C[1];
+    } else {
+        px = py = 0;
+    }
+    if(s->mb_intra) px = py = 0;
+
+    /* Pullback MV as specified in 8.3.5.3.4 */
+    {
+        int qx, qy, X, Y;
+        qx = s->mb_x << 6; //FIXME: add real block coords for 4MV mode
+        qy = s->mb_y << 6;
+        X = (s->mb_width << 6) - 4;
+        Y = (s->mb_height << 6) - 4;
+        if(mv1) {
+            if(qx + px < -60) px = -60 - qx;
+            if(qy + py < -60) py = -60 - qy;
+        } else {
+            if(qx + px < -28) px = -28 - qx;
+            if(qy + py < -28) py = -28 - qy;
+        }
+        if(qx + px > X) px = X - qx;
+        if(qy + py > Y) py = Y - qy;
+    }
+    /* Calculate hybrid prediction as specified in 8.3.5.3.5 */
+    if(!s->mb_intra && !s->first_slice_line && s->mb_x) {
+        if(IS_INTRA(s->current_picture.mb_type[mb_pos - s->mb_stride]))
+            sum = ABS(px) + ABS(py);
+        else
+            sum = ABS(px - A[0]) + ABS(py - A[1]);
+        if(sum > 32) {
+            if(get_bits1(&s->gb)) {
+                px = A[0];
+                py = A[1];
+            } else {
+                px = C[0];
+                py = C[1];
+            }
+        } else {
+            if(IS_INTRA(s->current_picture.mb_type[mb_pos - 1]))
+                sum = ABS(px) + ABS(py);
+            else
+                sum = ABS(px - C[0]) + ABS(py - C[1]);
+            if(sum > 32) {
+                if(get_bits1(&s->gb)) {
+                    px = A[0];
+                    py = A[1];
+                } else {
+                    px = C[0];
+                    py = C[1];
+                }
+            }
+        }
+    }
+    /* store MV using signed modulus of MV range defined in 4.11 */
+    s->mv[0][0][0] = s->current_picture.motion_val[0][xy][0] = ((px + dmv_x + r_x) & ((r_x << 1) - 1)) - r_x;
+    s->mv[0][0][1] = s->current_picture.motion_val[0][xy][1] = ((py + dmv_y + r_y) & ((r_y << 1) - 1)) - r_y;
+}
+
+/** Get predicted DC value for I-frames only
  * prediction dir: left=0, top=1
  * @param s MpegEncContext
  * @param[in] n block index in the current MB
  * @param dc_val_ptr Pointer to DC predictor
  * @param dir_ptr Prediction direction for use in AC prediction
- * @todo TODO: Actually do it the VC1 way
- * @todo TODO: Handle properly edges
  */
-static inline int vc1_pred_dc(MpegEncContext *s, int n,
-                              uint16_t **dc_val_ptr, int *dir_ptr)
+static inline int vc1_i_pred_dc(MpegEncContext *s, int overlap, int pq, int n,
+                              int16_t **dc_val_ptr, int *dir_ptr)
 {
     int a, b, c, wrap, pred, scale;
     int16_t *dc_val;
-    static const uint16_t dcpred[31] = {
-        1024,  512,  341,  256,  205,  171,  146,  128,
+    static const uint16_t dcpred[32] = {
+    -1, 1024,  512,  341,  256,  205,  171,  146,  128,
          114,  102,   93,   85,   79,   73,   68,   64,
           60,   57,   54,   51,   49,   47,   45,   43,
           41,   39,   38,   37,   35,   34,   33
@@ -1775,45 +1468,97 @@
     wrap = s->block_wrap[n];
     dc_val= s->dc_val[0] + s->block_index[n];
 
-    /* B C
-     * A X
+    /* B A
+     * C X
      */
-    a = dc_val[ - 1];
+    c = dc_val[ - 1];
     b = dc_val[ - 1 - wrap];
-    c = dc_val[ - wrap];
+    a = dc_val[ - wrap];
 
-    /* XXX: Rule B is used only for I and BI frames in S/M/C profile
-     *      with overlap filtering off
-     */
-    if ((s->pict_type == I_TYPE || s->pict_type == BI_TYPE) &&
-        1 /* XXX: overlap filtering off */)
+    if (pq < 9 || !overlap)
     {
         /* Set outer values */
-        if (s->first_slice_line && n!=2) b=c=dcpred[scale];
-        if (s->mb_x == 0) b=a=dcpred[scale];
+        if (!s->mb_y && (n!=2 && n!=3)) b=a=dcpred[scale];
+        if (s->mb_x == 0 && (n!=1 && n!=3)) b=c=dcpred[scale];
     }
     else
     {
         /* Set outer values */
-        if (s->first_slice_line && n!=2) b=c=0;
-        if (s->mb_x == 0) b=a=0;
-
-        /* XXX: Rule A needs to know if blocks are inter or intra :/ */
-        if (0)
-        {
-            /* update predictor */
-            *dc_val_ptr = &dc_val[0];
-            dir_ptr = 0;
-            return a;
-        }
+        if (!s->mb_y && (n!=2 && n!=3)) b=a=0;
+        if (s->mb_x == 0 && (n!=1 && n!=3)) b=c=0;
     }
 
     if (abs(a - b) <= abs(b - c)) {
         pred = c;
-        *dir_ptr = 1;
+        *dir_ptr = 1;//left
     } else {
         pred = a;
-        *dir_ptr = 0;
+        *dir_ptr = 0;//top
+    }
+
+    /* update predictor */
+    *dc_val_ptr = &dc_val[0];
+    return pred;
+}
+
+
+/** Get predicted DC value
+ * prediction dir: left=0, top=1
+ * @param s MpegEncContext
+ * @param[in] n block index in the current MB
+ * @param dc_val_ptr Pointer to DC predictor
+ * @param dir_ptr Prediction direction for use in AC prediction
+ */
+static inline int vc1_pred_dc(MpegEncContext *s, int overlap, int pq, int n,
+                              int a_avail, int c_avail,
+                              int16_t **dc_val_ptr, int *dir_ptr)
+{
+    int a, b, c, wrap, pred, scale;
+    int16_t *dc_val;
+    int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
+    int mb_pos2, q1, q2;
+
+    /* find prediction - wmv3_dc_scale always used here in fact */
+    if (n < 4)     scale = s->y_dc_scale;
+    else           scale = s->c_dc_scale;
+
+    wrap = s->block_wrap[n];
+    dc_val= s->dc_val[0] + s->block_index[n];
+
+    /* B A
+     * C X
+     */
+    c = dc_val[ - 1];
+    b = dc_val[ - 1 - wrap];
+    a = dc_val[ - wrap];
+
+    if(a_avail && c_avail) {
+        if(abs(a - b) <= abs(b - c)) {
+            pred = c;
+            *dir_ptr = 1;//left
+        } else {
+            pred = a;
+            *dir_ptr = 0;//top
+        }
+    } else if(a_avail) {
+        pred = a;
+        *dir_ptr = 0;//top
+    } else if(c_avail) {
+        pred = c;
+        *dir_ptr = 1;//left
+    } else {
+        pred = 0;
+        *dir_ptr = 1;//left
+    }
+
+    /* scale coeffs if needed */
+    mb_pos2 = mb_pos - *dir_ptr - (1 - *dir_ptr) * s->mb_stride;
+    q1 = s->current_picture.qscale_table[mb_pos];
+    q2 = s->current_picture.qscale_table[mb_pos2];
+    if(0 && q1 && q2 && q1 != q2) {
+        q1 = s->y_dc_scale_table[q1];
+        q2 = s->y_dc_scale_table[q2];
+        pred = (pred * q2 * vc1_dqscale[q1 - 1] + 0x20000) >> 18;
     }
 
     /* update predictor */
@@ -1821,25 +1566,294 @@
     return pred;
 }
 
-/** Decode one block, inter or intra
+
+/**
+ * @defgroup std_mb VC1 Macroblock-level functions in Simple/Main Profiles
+ * @see 7.1.4, p91 and 8.1.1.7, p(1)04
+ * @todo TODO: Integrate to MpegEncContext facilities
+ * @{
+ */
+
+static inline int vc1_coded_block_pred(MpegEncContext * s, int n, uint8_t **coded_block_ptr)
+{
+    int xy, wrap, pred, a, b, c;
+
+    xy = s->block_index[n];
+    wrap = s->b8_stride;
+
+    /* B C
+     * A X
+     */
+    a = s->coded_block[xy - 1       ];
+    b = s->coded_block[xy - 1 - wrap];
+    c = s->coded_block[xy     - wrap];
+
+    if (b == c) {
+        pred = a;
+    } else {
+        pred = c;
+    }
+
+    /* store value */
+    *coded_block_ptr = &s->coded_block[xy];
+
+    return pred;
+}
+
+/**
+ * Decode one AC coefficient
  * @param v The VC1 context
- * @param block 8x8 DCT block
- * @param n Block index in the current MB (<4=>luma)
- * @param coded If the block is coded
- * @param mquant Quantizer step for the current block
- * @see Inter TT: Table 21, p73 + p91-85
- * @see Intra TT: Table 20, p72 + p(1)05-(1)07
- * @todo TODO: Process the blocks
- * @todo TODO: Use M$ MPEG-4 cbp prediction
+ * @param last Last coefficient
+ * @param skip How much zero coefficients to skip
+ * @param value Decoded AC coefficient value
+ * @see 8.1.3.4
+ */
+static void vc1_decode_ac_coeff(VC1Context *v, int *last, int *skip, int *value, int codingset)
+{
+    GetBitContext *gb = &v->s.gb;
+    int index, escape, run = 0, level = 0, lst = 0;
+
+    index = get_vlc2(gb, vc1_ac_coeff_table[codingset].table, AC_VLC_BITS, 3);
+    if (index != vc1_ac_sizes[codingset] - 1) {
+        run = vc1_index_decode_table[codingset][index][0];
+        level = vc1_index_decode_table[codingset][index][1];
+        lst = index >= vc1_last_decode_table[codingset];
+        if(get_bits(gb, 1))
+            level = -level;
+    } else {
+        escape = decode210(gb);
+        if (escape == 0) {
+            index = get_vlc2(gb, vc1_ac_coeff_table[codingset].table, AC_VLC_BITS, 3);
+            run = vc1_index_decode_table[codingset][index][0];
+            level = vc1_index_decode_table[codingset][index][1];
+            lst = index >= vc1_last_decode_table[codingset];
+            if(lst)
+                level += vc1_last_delta_level_table[codingset][run];
+            else
+                level += vc1_delta_level_table[codingset][run];
+            if(get_bits(gb, 1))
+                level = -level;
+        } else if (escape == 1) {
+            index = get_vlc2(gb, vc1_ac_coeff_table[codingset].table, AC_VLC_BITS, 3);
+            run = vc1_index_decode_table[codingset][index][0];
+            level = vc1_index_decode_table[codingset][index][1];
+            lst = index >= vc1_last_decode_table[codingset];
+            if(lst)
+                run += vc1_last_delta_run_table[codingset][level] + 1;
+            else
+                run += vc1_delta_run_table[codingset][level] + 1;
+            if(get_bits(gb, 1))
+                level = -level;
+        } else {
+            int sign;
+            lst = get_bits(gb, 1);
+            if(v->s.esc3_level_length == 0) {
+                if(v->pq < 8 || v->dquantfrm) { // table 59
+                    v->s.esc3_level_length = get_bits(gb, 3);
+                    if(!v->s.esc3_level_length)
+                        v->s.esc3_level_length = get_bits(gb, 2) + 8;
+                } else { //table 60
+                    v->s.esc3_level_length = get_prefix(gb, 1, 6) + 2;
+                }
+                v->s.esc3_run_length = 3 + get_bits(gb, 2);
+            }
+            run = get_bits(gb, v->s.esc3_run_length);
+            sign = get_bits(gb, 1);
+            level = get_bits(gb, v->s.esc3_level_length);
+            if(sign)
+                level = -level;
+        }
+    }
+
+    *last = lst;
+    *skip = run;
+    *value = level;
+}
+
+/** Decode intra block in intra frames - should be faster than decode_intra_block
+ * @param v VC1Context
+ * @param block block to decode
+ * @param coded are AC coeffs present or not
+ * @param codingset set of VLC to decode data
+ */
+static int vc1_decode_i_block(VC1Context *v, DCTELEM block[64], int n, int coded, int codingset)
+{
+    GetBitContext *gb = &v->s.gb;
+    MpegEncContext *s = &v->s;
+    int dc_pred_dir = 0; /* Direction of the DC prediction used */
+    int run_diff, i;
+    int16_t *dc_val;
+    int16_t *ac_val, *ac_val2;
+    int dcdiff;
+
+    /* Get DC differential */
+    if (n < 4) {
+        dcdiff = get_vlc2(&s->gb, ff_msmp4_dc_luma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3);
+    } else {
+        dcdiff = get_vlc2(&s->gb, ff_msmp4_dc_chroma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3);
+    }
+    if (dcdiff < 0){
+        av_log(s->avctx, AV_LOG_ERROR, "Illegal DC VLC\n");
+        return -1;
+    }
+    if (dcdiff)
+    {
+        if (dcdiff == 119 /* ESC index value */)
+        {
+            /* TODO: Optimize */
+            if (v->pq == 1) dcdiff = get_bits(gb, 10);
+            else if (v->pq == 2) dcdiff = get_bits(gb, 9);
+            else dcdiff = get_bits(gb, 8);
+        }
+        else
+        {
+            if (v->pq == 1)
+                dcdiff = (dcdiff<<2) + get_bits(gb, 2) - 3;
+            else if (v->pq == 2)
+                dcdiff = (dcdiff<<1) + get_bits(gb, 1) - 1;
+        }
+        if (get_bits(gb, 1))
+            dcdiff = -dcdiff;
+    }
+
+    /* Prediction */
+    dcdiff += vc1_i_pred_dc(&v->s, v->overlap, v->pq, n, &dc_val, &dc_pred_dir);
+    *dc_val = dcdiff;
+
+    /* Store the quantized DC coeff, used for prediction */
+
+    if (n < 4) {
+        block[0] = dcdiff * s->y_dc_scale;
+    } else {
+        block[0] = dcdiff * s->c_dc_scale;
+    }
+    /* Skip ? */
+    run_diff = 0;
+    i = 0;
+    if (!coded) {
+        goto not_coded;
+    }
+
+    //AC Decoding
+    i = 1;
+
+    {
+        int last = 0, skip, value;
+        const int8_t *zz_table;
+        int scale;
+        int k;
+
+        scale = v->pq * 2 + v->halfpq;
+
+        if(v->s.ac_pred) {
+            if(!dc_pred_dir)
+                zz_table = vc1_horizontal_zz;
+            else
+                zz_table = vc1_vertical_zz;
+        } else
+            zz_table = vc1_normal_zz;
+
+        ac_val = s->ac_val[0][0] + s->block_index[n] * 16;
+        ac_val2 = ac_val;
+        if(dc_pred_dir) //left
+            ac_val -= 16;
+        else //top
+            ac_val -= 16 * s->block_wrap[n];
+
+        while (!last) {
+            vc1_decode_ac_coeff(v, &last, &skip, &value, codingset);
+            i += skip;
+            if(i > 63)
+                break;
+            block[zz_table[i++]] = value;
+        }
+
+        /* apply AC prediction if needed */
+        if(s->ac_pred) {
+            if(dc_pred_dir) { //left
+                for(k = 1; k < 8; k++)
+                    block[k << 3] += ac_val[k];
+            } else { //top
+                for(k = 1; k < 8; k++)
+                    block[k] += ac_val[k + 8];
+            }
+        }
+        /* save AC coeffs for further prediction */
+        for(k = 1; k < 8; k++) {
+            ac_val2[k] = block[k << 3];
+            ac_val2[k + 8] = block[k];
+        }
+
+        /* scale AC coeffs */
+        for(k = 1; k < 64; k++)
+            if(block[k]) {
+                block[k] *= scale;
+                if(!v->pquantizer)
+                    block[k] += (block[k] < 0) ? -v->pq : v->pq;
+            }
+
+        if(s->ac_pred) i = 63;
+    }
+
+not_coded:
+    if(!coded) {
+        int k, scale;
+        ac_val = s->ac_val[0][0] + s->block_index[n] * 16;
+        ac_val2 = ac_val;
+
+        scale = v->pq * 2 + v->halfpq;
+        memset(ac_val2, 0, 16 * 2);
+        if(dc_pred_dir) {//left
+            ac_val -= 16;
+            if(s->ac_pred)
+                memcpy(ac_val2, ac_val, 8 * 2);
+        } else {//top
+            ac_val -= 16 * s->block_wrap[n];
+            if(s->ac_pred)
+                memcpy(ac_val2 + 8, ac_val + 8, 8 * 2);
+        }
+
+        /* apply AC prediction if needed */
+        if(s->ac_pred) {
+            if(dc_pred_dir) { //left
+                for(k = 1; k < 8; k++) {
+                    block[k << 3] = ac_val[k] * scale;
+                    if(!v->pquantizer)
+                        block[k << 3] += (block[k << 3] < 0) ? -v->pq : v->pq;
+                }
+            } else { //top
+                for(k = 1; k < 8; k++) {
+                    block[k] = ac_val[k + 8] * scale;
+                    if(!v->pquantizer)
+                        block[k] += (block[k] < 0) ? -v->pq : v->pq;
+                }
+            }
+            i = 63;
+        }
+    }
+    s->block_last_index[n] = i;
+
+    return 0;
+}
+
+/** Decode intra block in inter frames - more generic version than vc1_decode_i_block
+ * @param v VC1Context
+ * @param block block to decode
+ * @param coded are AC coeffs present or not
+ * @param mquant block quantizer
+ * @param codingset set of VLC to decode data
  */
-static int vc1_decode_block(VC1Context *v, DCTELEM block[64], int n, int coded, int mquant)
+static int vc1_decode_intra_block(VC1Context *v, DCTELEM block[64], int n, int coded, int mquant, int codingset)
 {
     GetBitContext *gb = &v->s.gb;
     MpegEncContext *s = &v->s;
-    int ttblk; /* Transform Type per Block */
-    int subblkpat; /* Sub-block Transform Type Pattern */
-    int dc_pred_dir; /* Direction of the DC prediction used */
+    int dc_pred_dir = 0; /* Direction of the DC prediction used */
     int run_diff, i;
+    int16_t *dc_val;
+    int16_t *ac_val, *ac_val2;
+    int dcdiff;
+    int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
+    int a_avail, c_avail;
 
     /* XXX: Guard against dumb values of mquant */
     mquant = (mquant < 1) ? 0 : ( (mquant>31) ? 31 : mquant );
@@ -1848,167 +1862,300 @@
     s->y_dc_scale = s->y_dc_scale_table[mquant];
     s->c_dc_scale = s->c_dc_scale_table[mquant];
 
-    if (s->mb_intra)
+    /* check if prediction blocks A and C are available */
+    a_avail = c_avail = 0;
+    if((n == 2 || n == 3) || (s->mb_y && IS_INTRA(s->current_picture.mb_type[mb_pos - s->mb_stride])))
+        a_avail = 1;
+    if((n == 1 || n == 3) || (s->mb_x && IS_INTRA(s->current_picture.mb_type[mb_pos - 1])))
+        c_avail = 1;
+    /* Get DC differential */
+    if (n < 4) {
+        dcdiff = get_vlc2(&s->gb, ff_msmp4_dc_luma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3);
+    } else {
+        dcdiff = get_vlc2(&s->gb, ff_msmp4_dc_chroma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3);
+    }
+    if (dcdiff < 0){
+        av_log(s->avctx, AV_LOG_ERROR, "Illegal DC VLC\n");
+        return -1;
+    }
+    if (dcdiff)
     {
-        int dcdiff;
-        uint16_t *dc_val;
-
-        /* Get DC differential */
-        if (n < 4) {
-            dcdiff = get_vlc2(&s->gb, ff_msmp4_dc_luma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3);
-        } else {
-            dcdiff = get_vlc2(&s->gb, ff_msmp4_dc_chroma_vlc[s->dc_table_index].table, DC_VLC_BITS, 3);
-        }
-        if (dcdiff < 0){
-            av_log(s->avctx, AV_LOG_ERROR, "Illegal DC VLC\n");
-            return -1;
-        }
-        if (dcdiff)
+        if (dcdiff == 119 /* ESC index value */)
         {
-            if (dcdiff == 119 /* ESC index value */)
-            {
-                /* TODO: Optimize */
-                if (mquant == 1) dcdiff = get_bits(gb, 10);
-                else if (mquant == 2) dcdiff = get_bits(gb, 9);
-                else dcdiff = get_bits(gb, 8);
-            }
-            else
-            {
-                if (mquant == 1)
-                  dcdiff = (dcdiff<<2) + get_bits(gb, 2) - 3;
-                else if (mquant == 2)
-                  dcdiff = (dcdiff<<1) + get_bits(gb, 1) - 1;
-            }
-            if (get_bits(gb, 1))
-              dcdiff = -dcdiff;
-        }
-
-        /* Prediction */
-        dcdiff += vc1_pred_dc(s, n, &dc_val, &dc_pred_dir);
-        *dc_val = dcdiff;
-        /* Store the quantized DC coeff, used for prediction */
-
-        if (n < 4) {
-            block[0] = dcdiff * s->y_dc_scale;
-        } else {
-            block[0] = dcdiff * s->c_dc_scale;
-        }
-        if (block[0] < 0) {
-#if TRACE
-            //av_log(s->avctx, AV_LOG_ERROR, "DC=%i<0\n", dcdiff);
-#endif
-            //return -1;
+            /* TODO: Optimize */
+            if (mquant == 1) dcdiff = get_bits(gb, 10);
+            else if (mquant == 2) dcdiff = get_bits(gb, 9);
+            else dcdiff = get_bits(gb, 8);
         }
-        /* Skip ? */
-        run_diff = 0;
-        i = 0;
-        if (!coded) {
-            goto not_coded;
+        else
+        {
+            if (mquant == 1)
+                dcdiff = (dcdiff<<2) + get_bits(gb, 2) - 3;
+            else if (mquant == 2)
+                dcdiff = (dcdiff<<1) + get_bits(gb, 1) - 1;
         }
+        if (get_bits(gb, 1))
+            dcdiff = -dcdiff;
     }
-    else
-    {
-        mquant = v->pq;
 
-        /* Get TTBLK */
-        if (v->ttmb < 8) /* per block */
-            ttblk = get_vlc2(gb, vc1_ttblk_vlc[v->tt_index].table, VC1_TTBLK_VLC_BITS, 2);
-        else /* Per frame */
-          ttblk = 0; //FIXME, depends on ttfrm
+    /* Prediction */
+    dcdiff += vc1_pred_dc(&v->s, v->overlap, mquant, n, a_avail, c_avail, &dc_val, &dc_pred_dir);
+    *dc_val = dcdiff;
 
-        /* Get SUBBLKPAT */
-        if (ttblk == v->ttblk4x4) /* 4x4 transform for that qp value */
-            subblkpat = 1+get_vlc2(gb, vc1_subblkpat_vlc[v->tt_index].table,
-                                   VC1_SUBBLKPAT_VLC_BITS, 2);
-        else /* All others: 8x8, 4x8, 8x4 */
-            subblkpat = decode012(gb);
+    /* Store the quantized DC coeff, used for prediction */
+
+    if (n < 4) {
+        block[0] = dcdiff * s->y_dc_scale;
+    } else {
+        block[0] = dcdiff * s->c_dc_scale;
     }
+    /* Skip ? */
+    run_diff = 0;
+    i = 0;
+    if (!coded) {
+        goto not_coded;
+    }
+
+    //AC Decoding
+    i = 1;
+
+    {
+        int last = 0, skip, value;
+        const int8_t *zz_table;
+        int scale;
+        int k;
 
-    //TODO AC Decoding
-    i = 63; //XXX: nothing done yet
+        scale = mquant * 2 + v->halfpq;
 
+        if(v->s.ac_pred) {
+            if(!dc_pred_dir)
+                zz_table = vc1_horizontal_zz;
+            else
+                zz_table = vc1_vertical_zz;
+        } else
+            zz_table = vc1_normal_zz;
+
+        ac_val = s->ac_val[0][0] + s->block_index[n] * 16;
+        ac_val2 = ac_val;
+        if(dc_pred_dir) //left
+            ac_val -= 16;
+        else //top
+            ac_val -= 16 * s->block_wrap[n];
+
+        while (!last) {
+            vc1_decode_ac_coeff(v, &last, &skip, &value, codingset);
+            i += skip;
+            if(i > 63)
+                break;
+            block[zz_table[i++]] = value;
+        }
 
- not_coded:
-    if (s->mb_intra) {
-        mpeg4_pred_ac(s, block, n, dc_pred_dir);
-        if (s->ac_pred) {
-            i = 63; /* XXX: not optimal */
+        /* apply AC prediction if needed */
+        if(s->ac_pred) {
+            /* scale predictors if needed*/
+            int mb_pos2, q1, q2;
+
+            mb_pos2 = mb_pos - dc_pred_dir - (1 - dc_pred_dir) * s->mb_stride;
+            q1 = s->current_picture.qscale_table[mb_pos];
+            q2 = s->current_picture.qscale_table[mb_pos2];
+
+            if(!c_avail) {
+                memset(ac_val, 0, 8 * sizeof(ac_val[0]));
+                dc_pred_dir = 0;
+            }
+            if(!a_avail) {
+                memset(ac_val + 8, 0, 8 * sizeof(ac_val[0]));
+                dc_pred_dir = 1;
+            }
+            if(!q1 && q1 && q2 && q1 != q2) {
+                q1 = q1 * 2 - 1;
+                q2 = q2 * 2 - 1;
+
+                if(dc_pred_dir) { //left
+                    for(k = 1; k < 8; k++)
+                        block[k << 3] += (ac_val[k] * q2 * vc1_dqscale[q1 - 1] + 0x20000) >> 18;
+                } else { //top
+                    for(k = 1; k < 8; k++)
+                        block[k] += (ac_val[k + 8] * q2 * vc1_dqscale[q1 - 1] + 0x20000) >> 18;
+                }
+            } else {
+                if(dc_pred_dir) { //left
+                    for(k = 1; k < 8; k++)
+                        block[k << 3] += ac_val[k];
+                } else { //top
+                    for(k = 1; k < 8; k++)
+                        block[k] += ac_val[k + 8];
+                }
+            }
+        }
+        /* save AC coeffs for further prediction */
+        for(k = 1; k < 8; k++) {
+            ac_val2[k] = block[k << 3];
+            ac_val2[k + 8] = block[k];
+        }
+
+        /* scale AC coeffs */
+        for(k = 1; k < 64; k++)
+            if(block[k]) {
+                block[k] *= scale;
+                if(!v->pquantizer)
+                    block[k] += (block[k] < 0) ? -mquant : mquant;
+            }
+
+        if(s->ac_pred) i = 63;
+    }
+
+not_coded:
+    if(!coded) {
+        int k, scale;
+        ac_val = s->ac_val[0][0] + s->block_index[n] * 16;
+        ac_val2 = ac_val;
+
+        if(!c_avail) {
+            memset(ac_val, 0, 8 * sizeof(ac_val[0]));
+            dc_pred_dir = 0;
+        }
+        if(!a_avail) {
+            memset(ac_val + 8, 0, 8 * sizeof(ac_val[0]));
+            dc_pred_dir = 1;
+        }
+
+        scale = mquant * 2 + v->halfpq;
+        memset(ac_val2, 0, 16 * 2);
+        if(dc_pred_dir) {//left
+            ac_val -= 16;
+            if(s->ac_pred)
+                memcpy(ac_val2, ac_val, 8 * 2);
+        } else {//top
+            ac_val -= 16 * s->block_wrap[n];
+            if(s->ac_pred)
+                memcpy(ac_val2 + 8, ac_val + 8, 8 * 2);
+        }
+
+        /* apply AC prediction if needed */
+        if(s->ac_pred) {
+            if(dc_pred_dir) { //left
+                for(k = 1; k < 8; k++) {
+                    block[k << 3] = ac_val[k] * scale;
+                    if(!v->pquantizer)
+                        block[k << 3] += (block[k << 3] < 0) ? -mquant : mquant;
+                }
+            } else { //top
+                for(k = 1; k < 8; k++) {
+                    block[k] = ac_val[k + 8] * scale;
+                    if(!v->pquantizer)
+                        block[k] += (block[k] < 0) ? -mquant : mquant;
+                }
+            }
+            i = 63;
         }
     }
-    if(i>0) i=63; //FIXME/XXX optimize
     s->block_last_index[n] = i;
+
     return 0;
 }
 
-/** @} */ //End for group block
-
-/***********************************************************************/
-/**
- * @defgroup std_mb VC1 Macroblock-level functions in Simple/Main Profiles
- * @see 7.1.4, p91 and 8.1.1.7, p(1)04
- * @todo TODO: Integrate to MpegEncContext facilities
- * @{
+/** Decode P block
  */
-
-static inline int vc1_coded_block_pred(MpegEncContext * s, int n, uint8_t **coded_block_ptr)
+static int vc1_decode_p_block(VC1Context *v, DCTELEM block[64], int n, int mquant, int ttmb, int first_block)
 {
-    int xy, wrap, pred, a, b, c;
-
-    xy = s->block_index[n];
-    wrap = s->b8_stride;
-
-    /* B C
-     * A X
-     */
-    a = s->coded_block[xy - 1       ];
-    b = s->coded_block[xy - 1 - wrap];
-    c = s->coded_block[xy     - wrap];
+    MpegEncContext *s = &v->s;
+    GetBitContext *gb = &s->gb;
+    int i, j;
+    int subblkpat = 0;
+    int scale, off, idx, last, skip, value;
+    int ttblk = ttmb & 7;
 
-    if (b == c) {
-        pred = a;
-    } else {
-        pred = c;
+    if(ttmb == -1) {
+        ttblk = ttblk_to_tt[v->tt_index][get_vlc2(gb, vc1_ttblk_vlc[v->tt_index].table, VC1_TTBLK_VLC_BITS, 1)];
     }
+    if(ttblk == TT_4X4) {
+        subblkpat = ~(get_vlc2(gb, vc1_subblkpat_vlc[v->tt_index].table, VC1_SUBBLKPAT_VLC_BITS, 1) + 1);
+    }
+    if((ttblk != TT_8X8 && ttblk != TT_4X4) && (v->ttmbf || (ttmb != -1 && (ttmb & 8) && !first_block))) {
+        subblkpat = decode012(gb);
+        if(ttblk == TT_8X4_TOP || ttblk == TT_8X4_BOTTOM) ttblk = TT_8X4;
+        if(ttblk == TT_4X8_RIGHT || ttblk == TT_4X8_LEFT) ttblk = TT_4X8;
+    }
+    scale = 2 * mquant;
 
-    /* store value */
-    *coded_block_ptr = &s->coded_block[xy];
-
-    return pred;
-}
-
-/** Decode one I-frame MB (in Simple/Main profile)
- * @todo TODO: Extend to AP
- */
-static int vc1_decode_i_mb(VC1Context *v, DCTELEM block[6][64])
-{
-    int i, cbp, val;
-    uint8_t *coded_val;
-//    uint32_t * const mb_type_ptr= &v->s.current_picture.mb_type[ v->s.mb_x + v->s.mb_y*v->s.mb_stride ];
+    // convert transforms like 8X4_TOP to generic TT and SUBBLKPAT
+    if(ttblk == TT_8X4_TOP || ttblk == TT_8X4_BOTTOM) {
+        ttblk = TT_8X4;
+        subblkpat = 2 - (ttblk == TT_8X4_TOP);
+    }
+    if(ttblk == TT_4X8_RIGHT || ttblk == TT_4X8_LEFT) {
+        ttblk = TT_4X8;
+        subblkpat = 2 - (ttblk == TT_4X8_LEFT);
+    }
 
-    v->s.mb_intra = 1;
-    cbp = get_vlc2(&v->s.gb, ff_msmp4_mb_i_vlc.table, MB_INTRA_VLC_BITS, 2);
-    if (cbp < 0) return -1;
-    v->s.ac_pred = get_bits(&v->s.gb, 1);
-
-    for (i=0; i<6; i++)
-    {
-        val = ((cbp >> (5 - i)) & 1);
-        if (i < 4) {
-            int pred = vc1_coded_block_pred(&v->s, i, &coded_val);
-            val = val ^ pred;
-            *coded_val = val;
+    switch(ttblk) {
+    case TT_8X8:
+        i = 0;
+        last = 0;
+        while (!last) {
+            vc1_decode_ac_coeff(v, &last, &skip, &value, v->codingset2);
+            i += skip;
+            if(i > 63)
+                break;
+            idx = vc1_simple_progressive_8x8_zz[i++];
+            block[idx] = value * scale;
         }
-        cbp |= val << (5 - i);
-        if (vc1_decode_block(v, block[i], i, val, v->pq) < 0) //FIXME Should be mquant
-        {
-            av_log(v->s.avctx, AV_LOG_ERROR,
-                   "\nerror while decoding block: %d x %d (%d)\n", v->s.mb_x, v->s.mb_y, i);
-            return -1;
+        vc1_inv_trans(block, 8, 8);
+        break;
+    case TT_4X4:
+        for(j = 0; j < 4; j++) {
+            last = subblkpat & (1 << (3 - j));
+            i = 0;
+            off = (j & 1) * 4 + (j & 2) * 32;
+            while (!last) {
+                vc1_decode_ac_coeff(v, &last, &skip, &value, v->codingset2);
+                i += skip;
+                if(i > 15)
+                    break;
+                idx = vc1_simple_progressive_4x4_zz[i++];
+                block[idx + off] = value * scale;
+            }
+            vc1_inv_trans(block + off, 4, 4);
+        }
+        break;
+    case TT_8X4:
+        for(j = 0; j < 2; j++) {
+            last = subblkpat & (1 << (1 - j));
+            i = 0;
+            off = j * 32;
+            while (!last) {
+                vc1_decode_ac_coeff(v, &last, &skip, &value, v->codingset2);
+                i += skip;
+                if(i > 31)
+                    break;
+                idx = vc1_simple_progressive_8x4_zz[i++];
+                block[idx + off] = value * scale;
+            }
+            if(!(subblkpat & (1 << (1 - j)))) vc1_inv_trans(block + off, 8, 4);
         }
+        break;
+    case TT_4X8:
+        for(j = 0; j < 2; j++) {
+            last = subblkpat & (1 << (1 - j));
+            i = 0;
+            off = j * 4;
+            while (!last) {
+                vc1_decode_ac_coeff(v, &last, &skip, &value, v->codingset2);
+                i += skip;
+                if(i > 31)
+                    break;
+                idx = vc1_simple_progressive_8x4_zz[i++];
+                block[idx + off] = value * scale;
+            }
+            vc1_inv_trans(block + off, 4, 8);
+        }
+        break;
     }
     return 0;
 }
 
+
 /** Decode one P-frame MB (in Simple/Main profile)
  * @todo TODO: Extend to AP
  * @fixme FIXME: DC value for inter blocks not set
@@ -2017,14 +2164,13 @@
 {
     MpegEncContext *s = &v->s;
     GetBitContext *gb = &s->gb;
-    int i, mb_offset = s->mb_x + s->mb_y*s->mb_width; /* XXX: mb_stride */
+    int i, j, mb_offset = s->mb_x + s->mb_y*s->mb_width; /* XXX: mb_stride */
+    int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
     int cbp; /* cbp decoding stuff */
     int hybrid_pred; /* Prediction types */
-    int mv_mode_bit = 0;
     int mqdiff, mquant; /* MB quantization */
-    int ttmb; /* MB Transform type */
+    int ttmb = v->ttmb; /* MB Transform type */
     int status;
-    uint8_t *coded_val;
 
     static const int size_table[6] = { 0, 2, 3, 4, 5, 8 },
       offset_table[6] = { 0, 1, 3, 7, 15, 31 };
@@ -2032,6 +2178,8 @@
     int dmv_x, dmv_y; /* Differential MV components */
     int index, index1; /* LUT indices */
     int val, sign; /* temp values */
+    int first_block = 1;
+    int dst_idx, off;
 
     mquant = v->pq; /* Loosy initialization */
 
@@ -2039,29 +2187,22 @@
         v->mv_type_mb_plane.data[mb_offset] = get_bits(gb, 1);
     if (v->skip_mb_plane.is_raw)
         v->skip_mb_plane.data[mb_offset] = get_bits(gb, 1);
-    if (!mv_mode_bit) /* 1MV mode */
+    s->current_picture.mbskip_table[mb_pos] = v->skip_mb_plane.data[mb_offset];
+    if (!v->mv_type_mb_plane.data[mb_offset]) /* 1MV mode */
     {
         if (!v->skip_mb_plane.data[mb_offset])
         {
             GET_MVDATA(dmv_x, dmv_y);
 
-            /* hybrid mv pred, 8.3.5.3.4 */
-            if (v->mv_mode == MV_PMODE_1MV ||
-                v->mv_mode == MV_PMODE_MIXED_MV)
-                hybrid_pred = get_bits(gb, 1);
+            s->current_picture.mb_type[mb_pos] = s->mb_intra ? MB_TYPE_INTRA : MB_TYPE_16x16;
+            vc1_pred_mv(s, dmv_x, dmv_y, 1, v->range_x, v->range_y);
+
             /* FIXME Set DC val for inter block ? */
             if (s->mb_intra && !mb_has_coeffs)
             {
                 GET_MQUANT();
                 s->ac_pred = get_bits(gb, 1);
-                /* XXX: how to handle cbp ? */
                 cbp = 0;
-                for (i=0; i<6; i++)
-                {
-                     s->coded_block[s->block_index[i]] = 0;
-                     vc1_decode_block(v, block[i], i, 0, mquant);
-                }
-                return 0;
             }
             else if (mb_has_coeffs)
             {
@@ -2072,66 +2213,82 @@
             else
             {
                 mquant = v->pq;
-                /* XXX: how to handle cbp ? */
-                /* XXX: how to set values for following predictions ? */
                 cbp = 0;
             }
+            s->current_picture.qscale_table[mb_pos] = mquant;
 
-            if (!v->ttmbf)
+            if (!v->ttmbf && !s->mb_intra && mb_has_coeffs)
                 ttmb = get_vlc2(gb, vc1_ttmb_vlc[v->tt_index].table,
-                                VC1_TTMB_VLC_BITS, 12);
-
+                                VC1_TTMB_VLC_BITS, 2);
+            s->dsp.clear_blocks(block[0]);
+            vc1_mc_1mv(v);
+            dst_idx = 0;
             for (i=0; i<6; i++)
             {
+                s->dc_val[0][s->block_index[i]] = 0;
+                dst_idx += i >> 2;
                 val = ((cbp >> (5 - i)) & 1);
-                if (i < 4) {
-                    int pred = vc1_coded_block_pred(&v->s, i, &coded_val);
-                    val = val ^ pred;
-                    *coded_val = val;
+                off = (i & 4) ? 0 : ((i & 1) * 8 + (i & 2) * 4 * s->linesize);
+                if(s->mb_intra) {
+                    vc1_decode_intra_block(v, block[i], i, val, mquant, (i&4)?v->codingset2:v->codingset);
+                    vc1_inv_trans(s->block[i], 8, 8);
+                    for(j = 0; j < 64; j++) s->block[i][j] += 128;
+                    s->dsp.put_pixels_clamped(s->block[i], s->dest[dst_idx] + off, s->linesize >> ((i & 4) >> 2));
+                } else if(val) {
+                    vc1_decode_p_block(v, block[i], i, mquant, ttmb, first_block);
+                    if(!v->ttmbf && ttmb < 8) ttmb = -1;
+                    first_block = 0;
+                    s->dsp.add_pixels_clamped(s->block[i], s->dest[dst_idx] + off, (i&4)?s->uvlinesize:s->linesize);
                 }
-                vc1_decode_block(v, block[i], i, val, mquant); //FIXME
             }
         }
         else //Skipped
         {
-            /* hybrid mv pred, 8.3.5.3.4 */
-            if (v->mv_mode == MV_PMODE_1MV ||
-                v->mv_mode == MV_PMODE_MIXED_MV)
-                hybrid_pred = get_bits(gb, 1);
-
-            /* TODO: blah */
+            s->mb_intra = 0;
+            s->current_picture.mb_type[mb_pos] = MB_TYPE_SKIP;
+            vc1_pred_mv(s, 0, 0, 1, v->range_x, v->range_y);
+            vc1_mc_1mv(v);
             return 0;
         }
     } //1MV mode
     else //4MV mode
-    {
+    {//FIXME: looks not conforming to standard and is not even theoretically complete
         if (!v->skip_mb_plane.data[mb_offset] /* unskipped MB */)
         {
+            int blk_intra[4], blk_coded[4];
             /* Get CBPCY */
             cbp = get_vlc2(&v->s.gb, v->cbpcy_vlc->table, VC1_CBPCY_P_VLC_BITS, 2);
-            for (i=0; i<6; i++)
+            for (i=0; i<4; i++)
             {
                 val = ((cbp >> (5 - i)) & 1);
-                if (i < 4) {
-                    int pred = vc1_coded_block_pred(&v->s, i, &coded_val);
-                    val = val ^ pred;
-                    *coded_val = val;
-                }
-                if (i<4 && val)
-                {
+                blk_intra[i] = 0;
+                blk_coded[i] = val;
+                if(val) {
                     GET_MVDATA(dmv_x, dmv_y);
+                    blk_intra[i] = s->mb_intra;
                 }
                 if (v->mv_mode == MV_PMODE_MIXED_MV /* Hybrid pred */)
                     hybrid_pred = get_bits(gb, 1);
+            }
+            if((blk_intra[0] | blk_intra[1] | blk_intra[2] | blk_intra[3]) ||
+                (blk_coded[0] | blk_coded[1] | blk_coded[2] | blk_coded[3])) {
                 GET_MQUANT();
 
-                if (s->mb_intra /* One of the 4 blocks is intra */ &&
-                    index /* non-zero pred for that block */)
+                if (s->mb_intra /* One of the 4 blocks is intra */
+                    /* non-zero pred for that block */)
                     s->ac_pred = get_bits(gb, 1);
                 if (!v->ttmbf)
                     ttmb = get_vlc2(gb, vc1_ttmb_vlc[v->tt_index].table,
                                     VC1_TTMB_VLC_BITS, 12);
-                status = vc1_decode_block(v, block[i], i, val, mquant);
+                for(i = 0; i < 6; i++) {
+                    val = ((cbp >> (5 - i)) & 1);
+                    if(i & 4 || blk_intra[i] || val) {
+                        if(i < 4 && blk_intra[i])
+                            status = vc1_decode_intra_block(v, block[i], i, val, mquant, (i&4)?v->codingset2:v->codingset);
+                        else
+                            status = vc1_decode_p_block(v, block[i], i, mquant, ttmb, 0);
+                    }
+                }
             }
             return status;
         }
@@ -2142,10 +2299,7 @@
             {
                 if (v->mv_mode == MV_PMODE_MIXED_MV /* Hybrid pred */)
                     hybrid_pred = get_bits(gb, 1);
-                vc1_decode_block(v, block[i], i, 0, v->pq); //FIXME
             }
-            vc1_decode_block(v, block[4], 4, 0, v->pq); //FIXME
-            vc1_decode_block(v, block[5], 5, 0, v->pq); //FIXME
             /* TODO: blah */
             return 0;
         }
@@ -2155,187 +2309,153 @@
     return -1;
 }
 
-/** Decode one B-frame MB (in Simple/Main profile)
- * @todo TODO: Extend to AP
- * @warning XXX: Used for decoding BI MBs
- * @fixme FIXME: DC value for inter blocks not set
+/** Decode blocks of I-frame
  */
-static int vc1_decode_b_mb(VC1Context *v, DCTELEM block[6][64])
+static void vc1_decode_i_blocks(VC1Context *v)
 {
+    int k;
     MpegEncContext *s = &v->s;
-    GetBitContext *gb = &v->s.gb;
-    int mb_offset, i /* MB / B postion information */;
-    int b_mv_type = BMV_TYPE_BACKWARD;
-    int mquant, mqdiff; /* MB quant stuff */
-    int ttmb; /* MacroBlock transform type */
+    int cbp, val;
+    uint8_t *coded_val;
+    int mb_pos;
 
-    static const int size_table[6] = { 0, 2, 3, 4, 5, 8 },
-        offset_table[6] = { 0, 1, 3, 7, 15, 31 };
-    int mb_has_coeffs = 1; /* last_flag */
-    int dmv1_x, dmv1_y, dmv2_x, dmv2_y; /* Differential MV components */
-    int index, index1; /* LUT indices */
-    int val, sign; /* MVDATA temp values */
+    /* select codingmode used for VLC tables selection */
+    switch(v->y_ac_table_index){
+    case 0:
+        v->codingset = (v->pqindex <= 8) ? CS_HIGH_RATE_INTRA : CS_LOW_MOT_INTRA;
+        break;
+    case 1:
+        v->codingset = CS_HIGH_MOT_INTRA;
+        break;
+    case 2:
+        v->codingset = CS_MID_RATE_INTRA;
+        break;
+    }
 
-    mb_offset = s->mb_width*s->mb_y + s->mb_x; //FIXME: arrays aren't using stride
+    switch(v->c_ac_table_index){
+    case 0:
+        v->codingset2 = (v->pqindex <= 8) ? CS_HIGH_RATE_INTER : CS_LOW_MOT_INTER;
+        break;
+    case 1:
+        v->codingset2 = CS_HIGH_MOT_INTER;
+        break;
+    case 2:
+        v->codingset2 = CS_MID_RATE_INTER;
+        break;
+    }
 
-    if (v->direct_mb_plane.is_raw)
-        v->direct_mb_plane.data[mb_offset] = get_bits(gb, 1);
-    if (v->skip_mb_plane.is_raw)
-        v->skip_mb_plane.data[mb_offset] = get_bits(gb, 1);
+    /* Set DC scale - y and c use the same */
+    s->y_dc_scale = s->y_dc_scale_table[v->pq];
+    s->c_dc_scale = s->c_dc_scale_table[v->pq];
 
-    if (!v->direct_mb_plane.data[mb_offset])
-    {
-        if (v->skip_mb_plane.data[mb_offset])
-        {
-            b_mv_type = decode012(gb);
-            if (v->bfraction > 420 /*1/2*/ &&
-                b_mv_type < 3) b_mv_type = 1-b_mv_type;
-        }
-        else
-        {
-            GET_MVDATA(dmv1_x, dmv1_y);
-            if (!s->mb_intra /* b_mv1 tells not intra */)
-            {
-                b_mv_type = decode012(gb);
-                if (v->bfraction > 420 /*1/2*/ &&
-                    b_mv_type < 3) b_mv_type = 1-b_mv_type;
-            }
-        }
-    }
-    if (!v->skip_mb_plane.data[mb_offset])
-    {
-        if (mb_has_coeffs /* BMV1 == "last" */)
-        {
-            GET_MQUANT();
-            if (s->mb_intra /* intra mb */)
-                s->ac_pred = get_bits(gb, 1);
-        }
-        else
-        {
-            /* if bmv1 tells MVs are interpolated */
-            if (b_mv_type == BMV_TYPE_INTERPOLATED)
-            {
-                GET_MVDATA(dmv2_x, dmv2_y);
-                mquant = v->pq; //FIXME: initialization not necessary ?
-            }
-            /* GET_MVDATA has reset some stuff */
-            if (mb_has_coeffs /* b_mv2 == "last" */)
-            {
-                if (s->mb_intra /* intra_mb */)
-                    s->ac_pred = get_bits(gb, 1);
-                GET_MQUANT();
+    //do frame decode
+    s->mb_x = s->mb_y = 0;
+    s->mb_intra = 1;
+    ff_er_add_slice(s, 0, 0, s->mb_width - 1, s->mb_height - 1, (AC_END|DC_END|MV_END));
+    for(s->mb_y = 0; s->mb_y < s->mb_height; s->mb_y++) {
+        for(s->mb_x = 0; s->mb_x < s->mb_width; s->mb_x++) {
+            ff_init_block_index(s);
+            ff_update_block_index(s);
+            s->dsp.clear_blocks(s->block[0]);
+            mb_pos = s->mb_x + s->mb_y * s->mb_width;
+            s->current_picture.mb_type[mb_pos] = MB_TYPE_INTRA;
+            s->current_picture.qscale_table[mb_pos] = v->pq;
+
+            // do actual MB decoding and displaying
+            cbp = get_vlc2(&v->s.gb, ff_msmp4_mb_i_vlc.table, MB_INTRA_VLC_BITS, 2);
+            v->s.ac_pred = get_bits(&v->s.gb, 1);
+
+            for(k = 0; k < 6; k++) {
+                val = ((cbp >> (5 - k)) & 1);
+                if (k < 4) {
+                    int pred = vc1_coded_block_pred(&v->s, k, &coded_val);
+                    val = val ^ pred;
+                    *coded_val = val;
+                }
+                cbp |= val << (5 - k);
+
+                vc1_decode_i_block(v, s->block[k], k, val, (k<4)? v->codingset : v->codingset2);
+
+                vc1_inv_trans(s->block[k], 8, 8);
+                if(v->pq >= 9 && v->overlap) {
+                    vc1_overlap_block(s, s->block[k], k, (s->mb_y || k>1), (s->mb_x || (k != 0 && k != 2)));
+                }
             }
-        }
-    }
 
-    //End1
-    if (v->ttmbf)
-        ttmb = get_vlc2(gb, vc1_ttmb_vlc[v->tt_index].table,
-                        VC1_TTMB_VLC_BITS, 12);
+            vc1_put_block(v, s->block);
 
-    //End2
-    for (i=0; i<6; i++)
-    {
-        vc1_decode_block(v, block[i], i, 0 /*cbp[i]*/, mquant); //FIXME
+            if(get_bits_count(&s->gb) > v->bits) {
+                av_log(s->avctx, AV_LOG_ERROR, "Bits overconsumption: %i > %i\n", get_bits_count(&s->gb), v->bits);
+                return;
+            }
+        }
+        ff_draw_horiz_band(s, s->mb_y * 16, 16);
     }
-    return 0;
 }
 
-/** Decode all MBs for an I frame in Simple/Main profile
- * @todo TODO: Move out of the loop the picture type case?
-               (branch prediction should help there though)
- */
-static int standard_decode_mbs(VC1Context *v)
+static void vc1_decode_p_blocks(VC1Context *v)
 {
     MpegEncContext *s = &v->s;
 
-    /* Set transform type info depending on pq */
-    if (v->pq < 5)
-    {
-        v->tt_index = 0;
-        v->ttblk4x4 = 3;
-    }
-    else if (v->pq < 13)
-    {
-        v->tt_index = 1;
-        v->ttblk4x4 = 3;
-    }
-    else
-    {
-        v->tt_index = 2;
-        v->ttblk4x4 = 2;
+    /* select codingmode used for VLC tables selection */
+    switch(v->c_ac_table_index){
+    case 0:
+        v->codingset = (v->pqindex <= 8) ? CS_HIGH_RATE_INTRA : CS_LOW_MOT_INTRA;
+        break;
+    case 1:
+        v->codingset = CS_HIGH_MOT_INTRA;
+        break;
+    case 2:
+        v->codingset = CS_MID_RATE_INTRA;
+        break;
     }
 
-    if (s->pict_type != I_TYPE)
-    {
-        /* Select proper long MV range */
-        switch (v->mvrange)
-        {
-        case 1: v->k_x = 10; v->k_y = 9; break;
-        case 2: v->k_x = 12; v->k_y = 10; break;
-        case 3: v->k_x = 13; v->k_y = 11; break;
-        default: /*case 0 too */ v->k_x = 9; v->k_y = 8; break;
-        }
-
-        s->mspel = v->mv_mode & 1; //MV_PMODE is HPEL
-        v->k_x -= s->mspel;
-        v->k_y -= s->mspel;
+    switch(v->c_ac_table_index){
+    case 0:
+        v->codingset2 = (v->pqindex <= 8) ? CS_HIGH_RATE_INTER : CS_LOW_MOT_INTER;
+        break;
+    case 1:
+        v->codingset2 = CS_HIGH_MOT_INTER;
+        break;
+    case 2:
+        v->codingset2 = CS_MID_RATE_INTER;
+        break;
     }
 
-    for (s->mb_y=0; s->mb_y<s->mb_height; s->mb_y++)
-    {
-        for (s->mb_x=0; s->mb_x<s->mb_width; s->mb_x++)
-        {
-            //FIXME Get proper MB DCTELEM
-            //TODO Move out of the loop
-            switch (s->pict_type)
-            {
-            case I_TYPE: vc1_decode_i_mb(v, s->block); break;
-            case P_TYPE: vc1_decode_p_mb(v, s->block); break;
-            case BI_TYPE:
-            case B_TYPE: vc1_decode_b_mb(v, s->block); break;
+    ff_er_add_slice(s, 0, 0, s->mb_width - 1, s->mb_height - 1, (AC_END|DC_END|MV_END));
+    s->first_slice_line = 1;
+    for(s->mb_y = 0; s->mb_y < s->mb_height; s->mb_y++) {
+        for(s->mb_x = 0; s->mb_x < s->mb_width; s->mb_x++) {
+            ff_init_block_index(s);
+            ff_update_block_index(s);
+            s->dsp.clear_blocks(s->block[0]);
+
+            vc1_decode_p_mb(v, s->block);
+            if(get_bits_count(&s->gb) > v->bits || get_bits_count(&s->gb) < 0) {
+                av_log(s->avctx, AV_LOG_ERROR, "Bits overconsumption: %i > %i at %ix%i\n", get_bits_count(&s->gb), v->bits,s->mb_x,s->mb_y);
+                return;
             }
         }
-        //Add a check for overconsumption ?
+        ff_draw_horiz_band(s, s->mb_y * 16, 16);
+        s->first_slice_line = 0;
     }
-    return 0;
 }
-/** @} */ //End for group std_mb
 
-#if HAS_ADVANCED_PROFILE
-/***********************************************************************/
-/**
- * @defgroup adv_mb VC1 Macroblock-level functions in Advanced Profile
- * @todo TODO: Integrate to MpegEncContext facilities
- * @todo TODO: Code P, B and BI
- * @{
- */
-static int advanced_decode_i_mbs(VC1Context *v)
+static void vc1_decode_blocks(VC1Context *v)
 {
-    MpegEncContext *s = &v->s;
-    GetBitContext *gb = &v->s.gb;
-    int mqdiff, mquant, mb_offset = 0, over_flags_mb = 0;
 
-    for (s->mb_y=0; s->mb_y<s->mb_height; s->mb_y++)
-    {
-        for (s->mb_x=0; s->mb_x<s->mb_width; s->mb_x++)
-        {
-            if (v->ac_pred_plane.is_raw)
-                s->ac_pred = get_bits(gb, 1);
-            else
-                s->ac_pred = v->ac_pred_plane.data[mb_offset];
-            if (v->condover == 3 && v->over_flags_plane.is_raw)
-                over_flags_mb = get_bits(gb, 1);
-            GET_MQUANT();
+    v->s.esc3_level_length = 0;
 
-            /* TODO: lots */
-        }
-        mb_offset++;
+    switch(v->s.pict_type) {
+    case I_TYPE:
+        vc1_decode_i_blocks(v);
+        break;
+    case P_TYPE:
+        vc1_decode_p_blocks(v);
+        break;
     }
-    return 0;
 }
-/** @} */ //End for group adv_mb
-#endif
+
 
 /** Initialize a VC1/WMV3 decoder
  * @todo TODO: Handle VC-1 IDUs (Transport level?)
@@ -2356,7 +2476,9 @@
     if (vc1_init_common(v) < 0) return -1;
 
     av_log(avctx, AV_LOG_INFO, "This decoder is not supposed to produce picture. Dont report this as a bug!\n");
+    av_log(avctx, AV_LOG_INFO, "If you see a picture, don't believe your eyes.\n");
 
+    avctx->flags |= CODEC_FLAG_EMU_EDGE;
     avctx->coded_width = avctx->width;
     avctx->coded_height = avctx->height;
     if (avctx->codec_id == CODEC_ID_WMV3)
@@ -2403,7 +2525,7 @@
     v->previous_line_cbpcy = (uint8_t *)av_malloc(s->mb_stride*4);
     if (!v->previous_line_cbpcy) return -1;
 
-#if HAS_ADVANCED_PROFILE
+    /* Init coded blocks info */
     if (v->profile == PROFILE_ADVANCED)
     {
         if (alloc_bitplane(&v->over_flags_plane, s->mb_width, s->mb_height) < 0)
@@ -2411,10 +2533,10 @@
         if (alloc_bitplane(&v->ac_pred_plane, s->mb_width, s->mb_height) < 0)
             return -1;
     }
-#endif
 
     return 0;
-    }
+}
+
 
 /** Decode a VC1/WMV3 frame
  * @todo TODO: Handle VC-1 IDUs (Transport level?)
@@ -2426,77 +2548,7 @@
 {
     VC1Context *v = avctx->priv_data;
     MpegEncContext *s = &v->s;
-    int ret = FRAME_SKIPPED, len;
     AVFrame *pict = data;
-    uint8_t *tmp_buf;
-    v->s.avctx = avctx;
-
-    //buf_size = 0 -> last frame
-    if (!buf_size) return 0;
-
-    len = avpicture_get_size(avctx->pix_fmt, avctx->width,
-                             avctx->height);
-    tmp_buf = (uint8_t *)av_mallocz(len);
-    avpicture_fill((AVPicture *)pict, tmp_buf, avctx->pix_fmt,
-                   avctx->width, avctx->height);
-
-    if (avctx->codec_id == CODEC_ID_VC1)
-    {
-#if 0
-        // search for IDU's
-        // FIXME
-        uint32_t scp = 0;
-        int scs = 0, i = 0;
-
-        while (i < buf_size)
-        {
-            for (; i < buf_size && scp != 0x000001; i++)
-                scp = ((scp<<8)|buf[i])&0xffffff;
-
-            if (scp != 0x000001)
-                break; // eof ?
-
-            scs = buf[i++];
-
-            init_get_bits(gb, buf+i, (buf_size-i)*8);
-
-            switch(scs)
-            {
-            case 0x0A: //Sequence End Code
-                return 0;
-            case 0x0B: //Slice Start Code
-                av_log(avctx, AV_LOG_ERROR, "Slice coding not supported\n");
-                return -1;
-            case 0x0C: //Field start code
-                av_log(avctx, AV_LOG_ERROR, "Interlaced coding not supported\n");
-                return -1;
-            case 0x0D: //Frame start code
-                break;
-            case 0x0E: //Entry point Start Code
-                if (v->profile < PROFILE_ADVANCED)
-                    av_log(avctx, AV_LOG_ERROR,
-                           "Found an entry point in profile %i\n", v->profile);
-                advanced_entry_point_process(avctx, gb);
-                break;
-            case 0x0F: //Sequence header Start Code
-                decode_sequence_header(avctx, gb);
-                break;
-            default:
-                av_log(avctx, AV_LOG_ERROR,
-                       "Unsupported IDU suffix %lX\n", scs);
-            }
-
-            i += get_bits_count(gb)*8;
-        }
-#else
-        av_abort();
-#endif
-    }
-    else
-        init_get_bits(&v->s.gb, buf, buf_size*8);
-
-    s->flags= avctx->flags;
-    s->flags2= avctx->flags2;
 
     /* no supplementary picture */
     if (buf_size == 0) {
@@ -2511,56 +2563,39 @@
         return 0;
     }
 
-    //No IDU - we mimic ff_h263_decode_frame
-    s->bitstream_buffer_size=0;
-
-    if (!s->context_initialized) {
-        if (MPV_common_init(s) < 0) //we need the idct permutaton for reading a custom matrix
-            return -1;
-    }
-
     //we need to set current_picture_ptr before reading the header, otherwise we cant store anyting im there
     if(s->current_picture_ptr==NULL || s->current_picture_ptr->data[0]){
-        s->current_picture_ptr= &s->picture[ff_find_unused_picture(s, 0)];
-    }
-#if HAS_ADVANCED_PROFILE
-    if (v->profile == PROFILE_ADVANCED)
-        ret= advanced_decode_picture_primary_header(v);
-    else
-#endif
-        ret= standard_decode_picture_primary_header(v);
-    if (ret == FRAME_SKIPPED) return buf_size;
-    /* skip if the header was thrashed */
-    if (ret < 0){
-        av_log(s->avctx, AV_LOG_ERROR, "header damaged\n");
-        return -1;
+        int i= ff_find_unused_picture(s, 0);
+        s->current_picture_ptr= &s->picture[i];
     }
 
-    //No bug workaround yet, no DCT conformance
+    avctx->has_b_frames= !s->low_delay;
 
-    //WMV9 does have resized images
-    if (v->profile < PROFILE_ADVANCED && v->multires){
-        //Parse context stuff in here, don't know how appliable it is
-    }
-    //Not sure about context initialization
+    init_get_bits(&s->gb, buf, buf_size*8);
+    // do parse frame header
+    if(vc1_parse_frame_header(v, &s->gb) == -1)
+        return -1;
+
+    if(s->pict_type != I_TYPE && s->pict_type != P_TYPE)return -1;
 
     // for hurry_up==5
     s->current_picture.pict_type= s->pict_type;
     s->current_picture.key_frame= s->pict_type == I_TYPE;
 
-    /* skip b frames if we dont have reference frames */
-    if(s->last_picture_ptr==NULL && (s->pict_type==B_TYPE || s->dropable))
-        return buf_size; //FIXME simulating all buffer consumed
+    /* skip B-frames if we don't have reference frames */
+    if(s->last_picture_ptr==NULL && (s->pict_type==B_TYPE || s->dropable)) return -1;//buf_size;
     /* skip b frames if we are in a hurry */
-    if(avctx->hurry_up && s->pict_type==B_TYPE)
-        return buf_size; //FIXME simulating all buffer consumed
+    if(avctx->hurry_up && s->pict_type==B_TYPE) return -1;//buf_size;
+    if(   (avctx->skip_frame >= AVDISCARD_NONREF && s->pict_type==B_TYPE)
+       || (avctx->skip_frame >= AVDISCARD_NONKEY && s->pict_type!=I_TYPE)
+       ||  avctx->skip_frame >= AVDISCARD_ALL)
+        return buf_size;
     /* skip everything if we are in a hurry>=5 */
-    if(avctx->hurry_up>=5)
-        return buf_size; //FIXME simulating all buffer consumed
+    if(avctx->hurry_up>=5) return -1;//buf_size;
 
     if(s->next_p_frame_damaged){
         if(s->pict_type==B_TYPE)
-            return buf_size; //FIXME simulating all buffer consumed
+            return buf_size;
         else
             s->next_p_frame_damaged=0;
     }
@@ -2570,43 +2605,17 @@
 
     ff_er_frame_start(s);
 
-    //wmv9 may or may not have skip bits
-#if HAS_ADVANCED_PROFILE
-    if (v->profile == PROFILE_ADVANCED)
-        ret= advanced_decode_picture_secondary_header(v);
-    else
-#endif
-        ret = standard_decode_picture_secondary_header(v);
-    if (ret<0) return FRAME_SKIPPED; //FIXME Non fatal for now
-
-    //We consider the image coded in only one slice
-#if HAS_ADVANCED_PROFILE
-    if (v->profile == PROFILE_ADVANCED)
-    {
-        switch(s->pict_type)
-        {
-            case I_TYPE: ret = advanced_decode_i_mbs(v); break;
-            case P_TYPE: ret = decode_p_mbs(v); break;
-            case B_TYPE:
-            case BI_TYPE: ret = decode_b_mbs(v); break;
-            default: ret = FRAME_SKIPPED;
-        }
-        if (ret == FRAME_SKIPPED) return buf_size; //We ignore for now failures
-    }
-    else
-#endif
-    {
-        ret = standard_decode_mbs(v);
-        if (ret == FRAME_SKIPPED) return buf_size;
-    }
-
+    v->bits = buf_size * 8;
+    vc1_decode_blocks(v);
+//av_log(s->avctx, AV_LOG_INFO, "Consumed %i/%i bits\n", get_bits_count(&s->gb), buf_size*8);
+//  if(get_bits_count(&s->gb) > buf_size * 8)
+//      return -1;
     ff_er_frame_end(s);
 
     MPV_frame_end(s);
 
-    assert(s->current_picture.pict_type == s->current_picture_ptr->pict_type);
-    assert(s->current_picture.pict_type == s->pict_type);
-
+assert(s->current_picture.pict_type == s->current_picture_ptr->pict_type);
+assert(s->current_picture.pict_type == s->pict_type);
     if (s->pict_type == B_TYPE || s->low_delay) {
         *pict= *(AVFrame*)s->current_picture_ptr;
     } else if (s->last_picture_ptr != NULL) {
@@ -2622,14 +2631,10 @@
     /* we substract 1 because it is added on utils.c    */
     avctx->frame_number = s->picture_number - 1;
 
-    av_log(avctx, AV_LOG_DEBUG, "Consumed %i/%i bits\n",
-           get_bits_count(&s->gb), buf_size*8);
-
-    /* Fake consumption of all data */
-    *data_size = len;
-    return buf_size; //Number of bytes consumed
+    return buf_size;
 }
 
+
 /** Close a VC1/WMV3 decoder
  * @warning Initial try at using MpegEncContext stuff
  */
@@ -2637,10 +2642,8 @@
 {
     VC1Context *v = avctx->priv_data;
 
-#if HAS_ADVANCED_PROFILE
     av_freep(&v->hrd_rate);
     av_freep(&v->hrd_buffer);
-#endif
     MPV_common_end(&v->s);
     free_bitplane(&v->mv_type_mb_plane);
     free_bitplane(&v->skip_mb_plane);
@@ -2648,6 +2651,7 @@
     return 0;
 }
 
+
 AVCodec vc1_decoder = {
     "vc1",
     CODEC_TYPE_VIDEO,

Added: trunk/libavcodec/vc1acdata.h
==============================================================================
--- (empty file)
+++ trunk/libavcodec/vc1acdata.h	Tue Jun 27 05:11:51 2006
@@ -0,0 +1,564 @@
+#define AC_MODES 8
+
+static const int vc1_ac_sizes[AC_MODES] = {
+    186, 169, 133, 149, 103, 103, 163, 175
+};
+
+static const uint32_t vc1_ac_tables[AC_MODES][186][2] = {
+{
+{ 0x0001,  2}, { 0x0005,  3}, { 0x000D,  4}, { 0x0012,  5}, { 0x000E,  6}, { 0x0015,  7},
+{ 0x0013,  8}, { 0x003F,  8}, { 0x004B,  9}, { 0x011F,  9}, { 0x00B8, 10}, { 0x03E3, 10},
+{ 0x0172, 11}, { 0x024D, 12}, { 0x03DA, 12}, { 0x02DD, 13}, { 0x1F55, 13}, { 0x05B9, 14},
+{ 0x3EAE, 14}, { 0x0000,  4}, { 0x0010,  5}, { 0x0008,  7}, { 0x0020,  8}, { 0x0029,  9},
+{ 0x01F4,  9}, { 0x0233, 10}, { 0x01E0, 11}, { 0x012A, 12}, { 0x03DD, 12}, { 0x050A, 13},
+{ 0x1F29, 13}, { 0x0A42, 14}, { 0x1272, 15}, { 0x1737, 15}, { 0x0003,  5}, { 0x0011,  7},
+{ 0x00C4,  8}, { 0x004B, 10}, { 0x00B4, 11}, { 0x07D4, 11}, { 0x0345, 12}, { 0x02D7, 13},
+{ 0x07BF, 13}, { 0x0938, 14}, { 0x0BBB, 14}, { 0x095E, 15}, { 0x0013,  5}, { 0x0078,  7},
+{ 0x0069,  9}, { 0x0232, 10}, { 0x0461, 11}, { 0x03EC, 12}, { 0x0520, 13}, { 0x1F2A, 13},
+{ 0x3E50, 14}, { 0x3E51, 14}, { 0x1486, 15}, { 0x000C,  6}, { 0x0024,  9}, { 0x0094, 11},
+{ 0x08C0, 12}, { 0x0F09, 14}, { 0x1EF0, 15}, { 0x003D,  6}, { 0x0053,  9}, { 0x01A0, 11},
+{ 0x02D6, 13}, { 0x0F08, 14}, { 0x0013,  7}, { 0x007C,  9}, { 0x07C1, 11}, { 0x04AC, 14},
+{ 0x001B,  7}, { 0x00A0, 10}, { 0x0344, 12}, { 0x0F79, 14}, { 0x0079,  7}, { 0x03E1, 10},
+{ 0x02D4, 13}, { 0x2306, 14}, { 0x0021,  8}, { 0x023C, 10}, { 0x0FAE, 12}, { 0x23DE, 14},
+{ 0x0035,  8}, { 0x0175, 11}, { 0x07B3, 13}, { 0x00C5,  8}, { 0x0174, 11}, { 0x0785, 13},
+{ 0x0048,  9}, { 0x01A3, 11}, { 0x049E, 13}, { 0x002C,  9}, { 0x00FA, 10}, { 0x07D6, 11},
+{ 0x0092, 10}, { 0x05CC, 13}, { 0x1EF1, 15}, { 0x00A3, 10}, { 0x03ED, 12}, { 0x093E, 14},
+{ 0x01E2, 11}, { 0x1273, 15}, { 0x07C4, 11}, { 0x1487, 15}, { 0x0291, 12}, { 0x0293, 12},
+{ 0x0F8A, 12}, { 0x0509, 13}, { 0x0508, 13}, { 0x078D, 13}, { 0x07BE, 13}, { 0x078C, 13},
+{ 0x04AE, 14}, { 0x0BBA, 14}, { 0x2307, 14}, { 0x0B9A, 14}, { 0x1736, 15}, { 0x000E,  4},
+{ 0x0045,  7}, { 0x01F3,  9}, { 0x047A, 11}, { 0x05DC, 13}, { 0x23DF, 14}, { 0x0019,  5},
+{ 0x0028,  9}, { 0x0176, 11}, { 0x049D, 13}, { 0x23DD, 14}, { 0x0030,  6}, { 0x00A2, 10},
+{ 0x02EF, 12}, { 0x05B8, 14}, { 0x003F,  6}, { 0x00A5, 10}, { 0x03DB, 12}, { 0x093F, 14},
+{ 0x0044,  7}, { 0x07CB, 11}, { 0x095F, 15}, { 0x0063,  7}, { 0x03C3, 12}, { 0x0015,  8},
+{ 0x08F6, 12}, { 0x0017,  8}, { 0x0498, 13}, { 0x002C,  8}, { 0x07B2, 13}, { 0x002F,  8},
+{ 0x1F54, 13}, { 0x008D,  8}, { 0x07BD, 13}, { 0x008E,  8}, { 0x1182, 13}, { 0x00FB,  8},
+{ 0x050B, 13}, { 0x002D,  8}, { 0x07C0, 11}, { 0x0079,  9}, { 0x1F5F, 13}, { 0x007A,  9},
+{ 0x1F56, 13}, { 0x0231, 10}, { 0x03E4, 10}, { 0x01A1, 11}, { 0x0143, 11}, { 0x01F7, 11},
+{ 0x016F, 12}, { 0x0292, 12}, { 0x02E7, 12}, { 0x016C, 12}, { 0x016D, 12}, { 0x03DC, 12},
+{ 0x0F8B, 12}, { 0x0499, 13}, { 0x03D8, 12}, { 0x078E, 13}, { 0x02D5, 13}, { 0x1F5E, 13},
+{ 0x1F2B, 13}, { 0x078F, 13}, { 0x04AD, 14}, { 0x3EAF, 14}, { 0x23DC, 14}, { 0x004A,  9}
+},
+{
+{ 0x0000,  3}, { 0x0003,  4}, { 0x000B,  5}, { 0x0014,  6}, { 0x003F,  6}, { 0x005D,  7},
+{ 0x00A2,  8}, { 0x00AC,  9}, { 0x016E,  9}, { 0x020A, 10}, { 0x02E2, 10}, { 0x0432, 11},
+{ 0x05C9, 11}, { 0x0827, 12}, { 0x0B54, 12}, { 0x04E6, 13}, { 0x105F, 13}, { 0x172A, 13},
+{ 0x20B2, 14}, { 0x2D4E, 14}, { 0x39F0, 14}, { 0x4175, 15}, { 0x5A9E, 15}, { 0x0004,  4},
+{ 0x001E,  5}, { 0x0042,  7}, { 0x00B6,  8}, { 0x0173,  9}, { 0x0395, 10}, { 0x072E, 11},
+{ 0x0B94, 12}, { 0x16A4, 13}, { 0x20B3, 14}, { 0x2E45, 14}, { 0x0005,  5}, { 0x0040,  7},
+{ 0x0049,  9}, { 0x028F, 10}, { 0x05CB, 11}, { 0x048A, 13}, { 0x09DD, 14}, { 0x73E2, 15},
+{ 0x0018,  5}, { 0x0025,  8}, { 0x008A, 10}, { 0x051B, 11}, { 0x0E5F, 12}, { 0x09C9, 14},
+{ 0x139C, 15}, { 0x0029,  6}, { 0x004F,  9}, { 0x0412, 11}, { 0x048D, 13}, { 0x2E41, 14},
+{ 0x0038,  6}, { 0x010E,  9}, { 0x05A8, 11}, { 0x105C, 13}, { 0x39F2, 14}, { 0x0058,  7},
+{ 0x021F, 10}, { 0x0E7E, 12}, { 0x39FF, 14}, { 0x0023,  8}, { 0x02E3, 10}, { 0x04E5, 13},
+{ 0x2E40, 14}, { 0x00A1,  8}, { 0x05BE, 11}, { 0x09C8, 14}, { 0x0083,  8}, { 0x013A, 11},
+{ 0x1721, 13}, { 0x0044,  9}, { 0x0276, 12}, { 0x39F6, 14}, { 0x008B, 10}, { 0x04EF, 13},
+{ 0x5A9B, 15}, { 0x0208, 10}, { 0x1CFE, 13}, { 0x0399, 10}, { 0x1CB4, 13}, { 0x039E, 10},
+{ 0x39F3, 14}, { 0x05AB, 11}, { 0x73E3, 15}, { 0x0737, 11}, { 0x5A9F, 15}, { 0x082D, 12},
+{ 0x0E69, 12}, { 0x0E68, 12}, { 0x0433, 11}, { 0x0B7B, 12}, { 0x2DF8, 14}, { 0x2E56, 14},
+{ 0x2E57, 14}, { 0x39F7, 14}, { 0x51A5, 15}, { 0x0003,  3}, { 0x002A,  6}, { 0x00E4,  8},
+{ 0x028E, 10}, { 0x0735, 11}, { 0x1058, 13}, { 0x1CFA, 13}, { 0x2DF9, 14}, { 0x4174, 15},
+{ 0x0009,  4}, { 0x0054,  8}, { 0x0398, 10}, { 0x048B, 13}, { 0x139D, 15}, { 0x000D,  4},
+{ 0x00AD,  9}, { 0x0826, 12}, { 0x2D4C, 14}, { 0x0011,  5}, { 0x016B,  9}, { 0x0B7F, 12},
+{ 0x51A4, 15}, { 0x0019,  5}, { 0x021B, 10}, { 0x16FD, 13}, { 0x001D,  5}, { 0x0394, 10},
+{ 0x28D3, 14}, { 0x002B,  6}, { 0x05BC, 11}, { 0x5A9A, 15}, { 0x002F,  6}, { 0x0247, 12},
+{ 0x0010,  7}, { 0x0A35, 12}, { 0x003E,  6}, { 0x0B7A, 12}, { 0x0059,  7}, { 0x105E, 13},
+{ 0x0026,  8}, { 0x09CF, 14}, { 0x0055,  8}, { 0x1CB5, 13}, { 0x0057,  8}, { 0x0E5B, 12},
+{ 0x00A0,  8}, { 0x1468, 13}, { 0x0170,  9}, { 0x0090, 10}, { 0x01CE,  9}, { 0x021A, 10},
+{ 0x0218, 10}, { 0x0168,  9}, { 0x021E, 10}, { 0x0244, 12}, { 0x0736, 11}, { 0x0138, 11},
+{ 0x0519, 11}, { 0x0E5E, 12}, { 0x072C, 11}, { 0x0B55, 12}, { 0x09DC, 14}, { 0x20BB, 14},
+{ 0x048C, 13}, { 0x1723, 13}, { 0x2E44, 14}, { 0x16A5, 13}, { 0x0518, 11}, { 0x39FE, 14},
+{ 0x0169,  9}
+},
+{
+{ 0x0001,  2}, { 0x0006,  3}, { 0x000F,  4}, { 0x0016,  5}, { 0x0020,  6}, { 0x0018,  7},
+{ 0x0008,  8}, { 0x009A,  8}, { 0x0056,  9}, { 0x013E,  9}, { 0x00F0, 10}, { 0x03A5, 10},
+{ 0x0077, 11}, { 0x01EF, 11}, { 0x009A, 12}, { 0x005D, 13}, { 0x0001,  4}, { 0x0011,  5},
+{ 0x0002,  7}, { 0x000B,  8}, { 0x0012,  9}, { 0x01D6,  9}, { 0x027E, 10}, { 0x0191, 11},
+{ 0x00EA, 12}, { 0x03DC, 12}, { 0x013B, 13}, { 0x0004,  5}, { 0x0014,  7}, { 0x009E,  8},
+{ 0x0009, 10}, { 0x01AC, 11}, { 0x01E2, 11}, { 0x03CA, 12}, { 0x005F, 13}, { 0x0017,  5},
+{ 0x004E,  7}, { 0x005E,  9}, { 0x00F3, 10}, { 0x01AD, 11}, { 0x00EC, 12}, { 0x05F0, 13},
+{ 0x000E,  6}, { 0x00E1,  8}, { 0x03A4, 10}, { 0x009C, 12}, { 0x013D, 13}, { 0x003B,  6},
+{ 0x001C,  9}, { 0x0014, 11}, { 0x09BE, 12}, { 0x0006,  7}, { 0x007A,  9}, { 0x0190, 11},
+{ 0x0137, 13}, { 0x001B,  7}, { 0x0008, 10}, { 0x075C, 11}, { 0x0071,  7}, { 0x00D7, 10},
+{ 0x09BF, 12}, { 0x0007,  8}, { 0x00AF, 10}, { 0x04CC, 11}, { 0x0034,  8}, { 0x0265, 10},
+{ 0x009F, 12}, { 0x00E0,  8}, { 0x0016, 11}, { 0x0327, 12}, { 0x0015,  9}, { 0x017D, 11},
+{ 0x0EBB, 12}, { 0x0014,  9}, { 0x00F6, 10}, { 0x01E4, 11}, { 0x00CB, 10}, { 0x099D, 12},
+{ 0x00CA, 10}, { 0x02FC, 12}, { 0x017F, 11}, { 0x04CD, 11}, { 0x02FD, 12}, { 0x04FE, 11},
+{ 0x013A, 13}, { 0x000A,  4}, { 0x0042,  7}, { 0x01D3,  9}, { 0x04DD, 11}, { 0x0012,  5},
+{ 0x00E8,  8}, { 0x004C, 11}, { 0x0136, 13}, { 0x0039,  6}, { 0x0264, 10}, { 0x0EBA, 12},
+{ 0x0000,  7}, { 0x00AE, 10}, { 0x099C, 12}, { 0x001F,  7}, { 0x04DE, 11}, { 0x0043,  7},
+{ 0x04DC, 11}, { 0x0003,  8}, { 0x03CB, 12}, { 0x0006,  8}, { 0x099E, 12}, { 0x002A,  8},
+{ 0x05F1, 13}, { 0x000F,  8}, { 0x09FE, 12}, { 0x0033,  8}, { 0x09FF, 12}, { 0x0098,  8},
+{ 0x099F, 12}, { 0x00EA,  8}, { 0x013C, 13}, { 0x002E,  8}, { 0x0192, 11}, { 0x0136,  9},
+{ 0x006A,  9}, { 0x0015, 11}, { 0x03AF, 10}, { 0x01E3, 11}, { 0x0074, 11}, { 0x00EB, 12},
+{ 0x02F9, 12}, { 0x005C, 13}, { 0x00ED, 12}, { 0x03DD, 12}, { 0x0326, 12}, { 0x005E, 13},
+{ 0x0016,  7}
+},
+{
+{ 0x0004,  3}, { 0x0014,  5}, { 0x0017,  7}, { 0x007F,  8}, { 0x0154,  9}, { 0x01F2, 10},
+{ 0x00BF, 11}, { 0x0065, 12}, { 0x0AAA, 12}, { 0x0630, 13}, { 0x1597, 13}, { 0x03B7, 14},
+{ 0x2B22, 14}, { 0x0BE6, 15}, { 0x000B,  4}, { 0x0037,  7}, { 0x0062,  9}, { 0x0007, 11},
+{ 0x0166, 12}, { 0x00CE, 13}, { 0x1590, 13}, { 0x05F6, 14}, { 0x0BE7, 15}, { 0x0007,  5},
+{ 0x006D,  8}, { 0x0003, 11}, { 0x031F, 12}, { 0x05F2, 14}, { 0x0002,  6}, { 0x0061,  9},
+{ 0x0055, 12}, { 0x01DF, 14}, { 0x001A,  6}, { 0x001E, 10}, { 0x0AC9, 12}, { 0x2B23, 14},
+{ 0x001E,  6}, { 0x001F, 10}, { 0x0AC3, 12}, { 0x2B2B, 14}, { 0x0006,  7}, { 0x0004, 11},
+{ 0x02F8, 13}, { 0x0019,  7}, { 0x0006, 11}, { 0x063D, 13}, { 0x0057,  7}, { 0x0182, 11},
+{ 0x2AA2, 14}, { 0x0004,  8}, { 0x0180, 11}, { 0x059C, 14}, { 0x007D,  8}, { 0x0164, 12},
+{ 0x076D, 15}, { 0x0002,  9}, { 0x018D, 11}, { 0x1581, 13}, { 0x00AD,  8}, { 0x0060, 12},
+{ 0x0C67, 14}, { 0x001C,  9}, { 0x00EE, 13}, { 0x0003,  9}, { 0x02CF, 13}, { 0x00D9,  9},
+{ 0x1580, 13}, { 0x0002, 11}, { 0x0183, 11}, { 0x0057, 12}, { 0x0061, 12}, { 0x0031, 11},
+{ 0x0066, 12}, { 0x0631, 13}, { 0x0632, 13}, { 0x00AC, 13}, { 0x031D, 12}, { 0x0076, 12},
+{ 0x003A, 11}, { 0x0165, 12}, { 0x0C66, 14}, { 0x0003,  2}, { 0x0054,  7}, { 0x02AB, 10},
+{ 0x0016, 13}, { 0x05F7, 14}, { 0x0005,  4}, { 0x00F8,  9}, { 0x0AA9, 12}, { 0x005F, 15},
+{ 0x0004,  4}, { 0x001C, 10}, { 0x1550, 13}, { 0x0004,  5}, { 0x0077, 11}, { 0x076C, 15},
+{ 0x000E,  5}, { 0x000A, 12}, { 0x000C,  5}, { 0x0562, 11}, { 0x0004,  6}, { 0x031C, 12},
+{ 0x0006,  6}, { 0x00C8, 13}, { 0x000D,  6}, { 0x01DA, 13}, { 0x0007,  6}, { 0x00C9, 13},
+{ 0x0001,  7}, { 0x002E, 14}, { 0x0014,  7}, { 0x1596, 13}, { 0x000A,  7}, { 0x0AC2, 12},
+{ 0x0016,  7}, { 0x015B, 14}, { 0x0015,  7}, { 0x015A, 14}, { 0x000F,  8}, { 0x005E, 15},
+{ 0x007E,  8}, { 0x00AB,  8}, { 0x002D,  9}, { 0x00D8,  9}, { 0x000B,  9}, { 0x0014, 10},
+{ 0x02B3, 10}, { 0x01F3, 10}, { 0x003A, 10}, { 0x0000, 10}, { 0x0058, 10}, { 0x002E,  9},
+{ 0x005E, 10}, { 0x0563, 11}, { 0x00EC, 12}, { 0x0054, 12}, { 0x0AC1, 12}, { 0x1556, 13},
+{ 0x02FA, 13}, { 0x0181, 11}, { 0x1557, 13}, { 0x059D, 14}, { 0x2AA3, 14}, { 0x2B2A, 14},
+{ 0x01DE, 14}, { 0x063C, 13}, { 0x00CF, 13}, { 0x1594, 13}, { 0x000D,  9}
+},
+{
+{ 0x0002,  2}, { 0x0006,  3}, { 0x000F,  4}, { 0x000D,  5}, { 0x000C,  5}, { 0x0015,  6},
+{ 0x0013,  6}, { 0x0012,  6}, { 0x0017,  7}, { 0x001F,  8}, { 0x001E,  8}, { 0x001D,  8},
+{ 0x0025,  9}, { 0x0024,  9}, { 0x0023,  9}, { 0x0021,  9}, { 0x0021, 10}, { 0x0020, 10},
+{ 0x000F, 10}, { 0x000E, 10}, { 0x0007, 11}, { 0x0006, 11}, { 0x0020, 11}, { 0x0021, 11},
+{ 0x0050, 12}, { 0x0051, 12}, { 0x0052, 12}, { 0x000E,  4}, { 0x0014,  6}, { 0x0016,  7},
+{ 0x001C,  8}, { 0x0020,  9}, { 0x001F,  9}, { 0x000D, 10}, { 0x0022, 11}, { 0x0053, 12},
+{ 0x0055, 12}, { 0x000B,  5}, { 0x0015,  7}, { 0x001E,  9}, { 0x000C, 10}, { 0x0056, 12},
+{ 0x0011,  6}, { 0x001B,  8}, { 0x001D,  9}, { 0x000B, 10}, { 0x0010,  6}, { 0x0022,  9},
+{ 0x000A, 10}, { 0x000D,  6}, { 0x001C,  9}, { 0x0008, 10}, { 0x0012,  7}, { 0x001B,  9},
+{ 0x0054, 12}, { 0x0014,  7}, { 0x001A,  9}, { 0x0057, 12}, { 0x0019,  8}, { 0x0009, 10},
+{ 0x0018,  8}, { 0x0023, 11}, { 0x0017,  8}, { 0x0019,  9}, { 0x0018,  9}, { 0x0007, 10},
+{ 0x0058, 12}, { 0x0007,  4}, { 0x000C,  6}, { 0x0016,  8}, { 0x0017,  9}, { 0x0006, 10},
+{ 0x0005, 11}, { 0x0004, 11}, { 0x0059, 12}, { 0x000F,  6}, { 0x0016,  9}, { 0x0005, 10},
+{ 0x000E,  6}, { 0x0004, 10}, { 0x0011,  7}, { 0x0024, 11}, { 0x0010,  7}, { 0x0025, 11},
+{ 0x0013,  7}, { 0x005A, 12}, { 0x0015,  8}, { 0x005B, 12}, { 0x0014,  8}, { 0x0013,  8},
+{ 0x001A,  8}, { 0x0015,  9}, { 0x0014,  9}, { 0x0013,  9}, { 0x0012,  9}, { 0x0011,  9},
+{ 0x0026, 11}, { 0x0027, 11}, { 0x005C, 12}, { 0x005D, 12}, { 0x005E, 12}, { 0x005F, 12},
+{ 0x0003,  7}
+},
+{
+{ 0x0002,  2}, { 0x000F,  4}, { 0x0015,  6}, { 0x0017,  7}, { 0x001F,  8}, { 0x0025,  9},
+{ 0x0024,  9}, { 0x0021, 10}, { 0x0020, 10}, { 0x0007, 11}, { 0x0006, 11}, { 0x0020, 11},
+{ 0x0006,  3}, { 0x0014,  6}, { 0x001E,  8}, { 0x000F, 10}, { 0x0021, 11}, { 0x0050, 12},
+{ 0x000E,  4}, { 0x001D,  8}, { 0x000E, 10}, { 0x0051, 12}, { 0x000D,  5}, { 0x0023,  9},
+{ 0x000D, 10}, { 0x000C,  5}, { 0x0022,  9}, { 0x0052, 12}, { 0x000B,  5}, { 0x000C, 10},
+{ 0x0053, 12}, { 0x0013,  6}, { 0x000B, 10}, { 0x0054, 12}, { 0x0012,  6}, { 0x000A, 10},
+{ 0x0011,  6}, { 0x0009, 10}, { 0x0010,  6}, { 0x0008, 10}, { 0x0016,  7}, { 0x0055, 12},
+{ 0x0015,  7}, { 0x0014,  7}, { 0x001C,  8}, { 0x001B,  8}, { 0x0021,  9}, { 0x0020,  9},
+{ 0x001F,  9}, { 0x001E,  9}, { 0x001D,  9}, { 0x001C,  9}, { 0x001B,  9}, { 0x001A,  9},
+{ 0x0022, 11}, { 0x0023, 11}, { 0x0056, 12}, { 0x0057, 12}, { 0x0007,  4}, { 0x0019,  9},
+{ 0x0005, 11}, { 0x000F,  6}, { 0x0004, 11}, { 0x000E,  6}, { 0x000D,  6}, { 0x000C,  6},
+{ 0x0013,  7}, { 0x0012,  7}, { 0x0011,  7}, { 0x0010,  7}, { 0x001A,  8}, { 0x0019,  8},
+{ 0x0018,  8}, { 0x0017,  8}, { 0x0016,  8}, { 0x0015,  8}, { 0x0014,  8}, { 0x0013,  8},
+{ 0x0018,  9}, { 0x0017,  9}, { 0x0016,  9}, { 0x0015,  9}, { 0x0014,  9}, { 0x0013,  9},
+{ 0x0012,  9}, { 0x0011,  9}, { 0x0007, 10}, { 0x0006, 10}, { 0x0005, 10}, { 0x0004, 10},
+{ 0x0024, 11}, { 0x0025, 11}, { 0x0026, 11}, { 0x0027, 11}, { 0x0058, 12}, { 0x0059, 12},
+{ 0x005A, 12}, { 0x005B, 12}, { 0x005C, 12}, { 0x005D, 12}, { 0x005E, 12}, { 0x005F, 12},
+{ 0x0003,  7}
+},
+{
+{ 0x0000,  2}, { 0x0003,  3}, { 0x000D,  4}, { 0x0005,  4}, { 0x001C,  5}, { 0x0016,  5},
+{ 0x003F,  6}, { 0x003A,  6}, { 0x002E,  6}, { 0x0022,  6}, { 0x007B,  7}, { 0x0067,  7},
+{ 0x005F,  7}, { 0x0047,  7}, { 0x0026,  7}, { 0x00EF,  8}, { 0x00CD,  8}, { 0x00C1,  8},
+{ 0x00A9,  8}, { 0x004F,  8}, { 0x01F2,  9}, { 0x01DD,  9}, { 0x0199,  9}, { 0x0185,  9},
+{ 0x015D,  9}, { 0x011B,  9}, { 0x03EF, 10}, { 0x03E1, 10}, { 0x03C8, 10}, { 0x0331, 10},
+{ 0x0303, 10}, { 0x02F1, 10}, { 0x02A0, 10}, { 0x0233, 10}, { 0x0126, 10}, { 0x07C0, 11},
+{ 0x076F, 11}, { 0x076C, 11}, { 0x0661, 11}, { 0x0604, 11}, { 0x0572, 11}, { 0x0551, 11},
+{ 0x046A, 11}, { 0x0274, 11}, { 0x0F27, 12}, { 0x0F24, 12}, { 0x0EDB, 12}, { 0x0C8E, 12},
+{ 0x0C0B, 12}, { 0x0C0A, 12}, { 0x0AE3, 12}, { 0x08D6, 12}, { 0x0490, 12}, { 0x0495, 12},
+{ 0x1F19, 13}, { 0x1DB5, 13}, { 0x0009,  4}, { 0x0010,  5}, { 0x0029,  6}, { 0x0062,  7},
+{ 0x00F3,  8}, { 0x00AD,  8}, { 0x01E5,  9}, { 0x0179,  9}, { 0x009C,  9}, { 0x03B1, 10},
+{ 0x02AE, 10}, { 0x0127, 10}, { 0x076E, 11}, { 0x0570, 11}, { 0x0275, 11}, { 0x0F25, 12},
+{ 0x0EC0, 12}, { 0x0AA0, 12}, { 0x08D7, 12}, { 0x1E4C, 13}, { 0x0008,  5}, { 0x0063,  7},
+{ 0x00AF,  8}, { 0x017B,  9}, { 0x03B3, 10}, { 0x07DD, 11}, { 0x0640, 11}, { 0x0F8D, 12},
+{ 0x0BC1, 12}, { 0x0491, 12}, { 0x0028,  6}, { 0x00C3,  8}, { 0x0151,  9}, { 0x02A1, 10},
+{ 0x0573, 11}, { 0x0EC3, 12}, { 0x1F35, 13}, { 0x0065,  7}, { 0x01DA,  9}, { 0x02AF, 10},
+{ 0x0277, 11}, { 0x08C9, 12}, { 0x1781, 13}, { 0x0025,  7}, { 0x0118,  9}, { 0x0646, 11},
+{ 0x0AA6, 12}, { 0x1780, 13}, { 0x00C9,  8}, { 0x0321, 10}, { 0x0F9B, 12}, { 0x191E, 13},
+{ 0x0048,  8}, { 0x07CC, 11}, { 0x0AA1, 12}, { 0x0180,  9}, { 0x0465, 11}, { 0x1905, 13},
+{ 0x03E2, 10}, { 0x0EC1, 12}, { 0x3C9B, 14}, { 0x02F4, 10}, { 0x08C8, 12}, { 0x07C1, 11},
+{ 0x0928, 13}, { 0x05E1, 11}, { 0x320D, 14}, { 0x0EC2, 12}, { 0x6418, 15}, { 0x1F34, 13},
+{ 0x0078,  7}, { 0x0155,  9}, { 0x0552, 11}, { 0x191F, 13}, { 0x00FA,  8}, { 0x07DC, 11},
+{ 0x1907, 13}, { 0x00AC,  8}, { 0x0249, 11}, { 0x13B1, 14}, { 0x01F6,  9}, { 0x0AE2, 12},
+{ 0x01DC,  9}, { 0x04ED, 12}, { 0x0184,  9}, { 0x1904, 13}, { 0x0156,  9}, { 0x09D9, 13},
+{ 0x03E7, 10}, { 0x0929, 13}, { 0x03B2, 10}, { 0x3B68, 14}, { 0x02F5, 10}, { 0x13B0, 14},
+{ 0x0322, 10}, { 0x3B69, 14}, { 0x0234, 10}, { 0x7935, 15}, { 0x07C7, 11}, { 0xC833, 16},
+{ 0x0660, 11}, { 0x7934, 15}, { 0x024B, 11}, { 0xC832, 16}, { 0x0AA7, 12}, { 0x1F18, 13},
+{ 0x007A,  7}
+},
+{
+{ 0x0002,  2}, { 0x0000,  3}, { 0x001E,  5}, { 0x0004,  5}, { 0x0012,  6}, { 0x0070,  7},
+{ 0x001A,  7}, { 0x005F,  8}, { 0x0047,  8}, { 0x01D3,  9}, { 0x00B5,  9}, { 0x0057,  9},
+{ 0x03B5, 10}, { 0x016D, 10}, { 0x0162, 10}, { 0x07CE, 11}, { 0x0719, 11}, { 0x0691, 11},
+{ 0x02C6, 11}, { 0x0156, 11}, { 0x0F92, 12}, { 0x0D2E, 12}, { 0x0D20, 12}, { 0x059E, 12},
+{ 0x0468, 12}, { 0x02A6, 12}, { 0x1DA2, 13}, { 0x1C60, 13}, { 0x1A43, 13}, { 0x0B1D, 13},
+{ 0x08C0, 13}, { 0x055D, 13}, { 0x0003,  3}, { 0x000A,  5}, { 0x0077,  7}, { 0x00E5,  8},
+{ 0x01D9,  9}, { 0x03E5, 10}, { 0x0166, 10}, { 0x0694, 11}, { 0x0152, 11}, { 0x059F, 12},
+{ 0x1F3C, 13}, { 0x1A4B, 13}, { 0x055E, 13}, { 0x000C,  4}, { 0x007D,  7}, { 0x0044,  8},
+{ 0x03E0, 10}, { 0x0769, 11}, { 0x0E31, 12}, { 0x1F26, 13}, { 0x055C, 13}, { 0x001B,  5},
+{ 0x00E2,  8}, { 0x03A5, 10}, { 0x02C9, 11}, { 0x1F23, 13}, { 0x3B47, 14}, { 0x0007,  5},
+{ 0x01D8,  9}, { 0x02D8, 11}, { 0x1F27, 13}, { 0x3494, 14}, { 0x0035,  6}, { 0x03E1, 10},
+{ 0x059C, 12}, { 0x38C3, 14}, { 0x000C,  6}, { 0x0165, 10}, { 0x1D23, 13}, { 0x1638, 14},
+{ 0x0068,  7}, { 0x0693, 11}, { 0x3A45, 14}, { 0x0020,  7}, { 0x0F90, 12}, { 0x7CF6, 15},
+{ 0x00E8,  8}, { 0x058F, 12}, { 0x2CEF, 15}, { 0x0045,  8}, { 0x0B3A, 13}, { 0x01F1,  9},
+{ 0x3B46, 14}, { 0x01A7,  9}, { 0x1676, 14}, { 0x0056,  9}, { 0x692A, 15}, { 0x038D, 10},
+{ 0xE309, 16}, { 0x00AA, 10}, { 0x1C611, 17}, { 0x02DF, 11}, { 0xB3B9, 17}, { 0x02C8, 11},
+{ 0x38C20, 18}, { 0x01B0, 11}, { 0x16390, 18}, { 0x0F9F, 12}, { 0x16771, 18}, { 0x0ED0, 12},
+{ 0x71843, 19}, { 0x0D2A, 12}, { 0xF9E8C, 20}, { 0x0461, 12}, { 0xF9E8E, 20}, { 0x0B67, 13},
+{ 0x055F, 13}, { 0x003F,  6}, { 0x006D,  9}, { 0x0E90, 12}, { 0x054E, 13}, { 0x0013,  6},
+{ 0x0119, 10}, { 0x0B66, 13}, { 0x000B,  6}, { 0x0235, 11}, { 0x7CF5, 15}, { 0x0075,  7},
+{ 0x0D24, 12}, { 0xF9E9, 16}, { 0x002E,  7}, { 0x1F22, 13}, { 0x0021,  7}, { 0x054F, 13},
+{ 0x0014,  7}, { 0x3A44, 14}, { 0x00E4,  8}, { 0x7CF7, 15}, { 0x005E,  8}, { 0x7185, 15},
+{ 0x0037,  8}, { 0x2C73, 15}, { 0x01DB,  9}, { 0x59DD, 16}, { 0x01C7,  9}, { 0x692B, 15},
+{ 0x01A6,  9}, { 0x58E5, 16}, { 0x00B4,  9}, { 0x1F3D0, 17}, { 0x00B0,  9}, { 0xB1C9, 17},
+{ 0x03E6, 10}, { 0x16770, 18}, { 0x016E, 10}, { 0x3E7A2, 18}, { 0x011B, 10}, { 0xF9E8D, 20},
+{ 0x00D9, 10}, { 0xF9E8F, 20}, { 0x00A8, 10}, { 0x2C723, 19}, { 0x0749, 11}, { 0xE3084, 20},
+{ 0x0696, 11}, { 0x58E45, 20}, { 0x02DE, 11}, { 0xB1C88, 21}, { 0x0231, 11}, { 0x1C610A, 21},
+{ 0x01B1, 11}, { 0x71842D, 23}, { 0x0D2B, 12}, { 0x38C217, 22}, { 0x0D2F, 12}, { 0x163913, 22},
+{ 0x05B2, 12}, { 0x163912, 22}, { 0x0469, 12}, { 0x71842C, 23}, { 0x1A42, 13}, { 0x08C1, 13},
+{ 0x0073,  7}
+}
+};
+
+/* which indexes point to last=1 entries in tables */
+static const int vc1_last_decode_table[AC_MODES] = {
+    119, 99, 85, 81, 67, 58, 126, 109
+};
+
+static const uint8_t vc1_index_decode_table[AC_MODES][185][2] = {
+{
+{  0,  1}, {  0,  2}, {  0,  3}, {  0,  4}, {  0,  5}, {  0,  6}, {  0,  7}, {  0,  8},
+{  0,  9}, {  0, 10}, {  0, 11}, {  0, 12}, {  0, 13}, {  0, 14}, {  0, 15}, {  0, 16},
+{  0, 17}, {  0, 18}, {  0, 19}, {  1,  1}, {  1,  2}, {  1,  3}, {  1,  4}, {  1,  5},
+{  1,  6}, {  1,  7}, {  1,  8}, {  1,  9}, {  1, 10}, {  1, 11}, {  1, 12}, {  1, 13},
+{  1, 14}, {  1, 15}, {  2,  1}, {  2,  2}, {  2,  3}, {  2,  4}, {  2,  5}, {  2,  6},
+{  2,  7}, {  2,  8}, {  2,  9}, {  2, 10}, {  2, 11}, {  2, 12}, {  3,  1}, {  3,  2},
+{  3,  3}, {  3,  4}, {  3,  5}, {  3,  6}, {  3,  7}, {  3,  8}, {  3,  9}, {  3, 10},
+{  3, 11}, {  4,  1}, {  4,  2}, {  4,  3}, {  4,  4}, {  4,  5}, {  4,  6}, {  5,  1},
+{  5,  2}, {  5,  3}, {  5,  4}, {  5,  5}, {  6,  1}, {  6,  2}, {  6,  3}, {  6,  4},
+{  7,  1}, {  7,  2}, {  7,  3}, {  7,  4}, {  8,  1}, {  8,  2}, {  8,  3}, {  8,  4},
+{  9,  1}, {  9,  2}, {  9,  3}, {  9,  4}, { 10,  1}, { 10,  2}, { 10,  3}, { 11,  1},
+{ 11,  2}, { 11,  3}, { 12,  1}, { 12,  2}, { 12,  3}, { 13,  1}, { 13,  2}, { 13,  3},
+{ 14,  1}, { 14,  2}, { 14,  3}, { 15,  1}, { 15,  2}, { 15,  3}, { 16,  1}, { 16,  2},
+{ 17,  1}, { 17,  2}, { 18,  1}, { 19,  1}, { 20,  1}, { 21,  1}, { 22,  1}, { 23,  1},
+{ 24,  1}, { 25,  1}, { 26,  1}, { 27,  1}, { 28,  1}, { 29,  1}, { 30,  1}, {  0,  1},
+{  0,  2}, {  0,  3}, {  0,  4}, {  0,  5}, {  0,  6}, {  1,  1}, {  1,  2}, {  1,  3},
+{  1,  4}, {  1,  5}, {  2,  1}, {  2,  2}, {  2,  3}, {  2,  4}, {  3,  1}, {  3,  2},
+{  3,  3}, {  3,  4}, {  4,  1}, {  4,  2}, {  4,  3}, {  5,  1}, {  5,  2}, {  6,  1},
+{  6,  2}, {  7,  1}, {  7,  2}, {  8,  1}, {  8,  2}, {  9,  1}, {  9,  2}, { 10,  1},
+{ 10,  2}, { 11,  1}, { 11,  2}, { 12,  1}, { 12,  2}, { 13,  1}, { 13,  2}, { 14,  1},
+{ 14,  2}, { 15,  1}, { 15,  2}, { 16,  1}, { 17,  1}, { 18,  1}, { 19,  1}, { 20,  1},
+{ 21,  1}, { 22,  1}, { 23,  1}, { 24,  1}, { 25,  1}, { 26,  1}, { 27,  1}, { 28,  1},
+{ 29,  1}, { 30,  1}, { 31,  1}, { 32,  1}, { 33,  1}, { 34,  1}, { 35,  1}, { 36,  1},
+{ 37,  1}
+},
+{
+{  0,  1}, {  0,  2}, {  0,  3}, {  0,  4}, {  0,  5}, {  0,  6}, {  0,  7}, {  0,  8},
+{  0,  9}, {  0, 10}, {  0, 11}, {  0, 12}, {  0, 13}, {  0, 14}, {  0, 15}, {  0, 16},
+{  0, 17}, {  0, 18}, {  0, 19}, {  0, 20}, {  0, 21}, {  0, 22}, {  0, 23}, {  1,  1},
+{  1,  2}, {  1,  3}, {  1,  4}, {  1,  5}, {  1,  6}, {  1,  7}, {  1,  8}, {  1,  9},
+{  1, 10}, {  1, 11}, {  2,  1}, {  2,  2}, {  2,  3}, {  2,  4}, {  2,  5}, {  2,  6},
+{  2,  7}, {  2,  8}, {  3,  1}, {  3,  2}, {  3,  3}, {  3,  4}, {  3,  5}, {  3,  6},
+{  3,  7}, {  4,  1}, {  4,  2}, {  4,  3}, {  4,  4}, {  4,  5}, {  5,  1}, {  5,  2},
+{  5,  3}, {  5,  4}, {  5,  5}, {  6,  1}, {  6,  2}, {  6,  3}, {  6,  4}, {  7,  1},
+{  7,  2}, {  7,  3}, {  7,  4}, {  8,  1}, {  8,  2}, {  8,  3}, {  9,  1}, {  9,  2},
+{  9,  3}, { 10,  1}, { 10,  2}, { 10,  3}, { 11,  1}, { 11,  2}, { 11,  3}, { 12,  1},
+{ 12,  2}, { 13,  1}, { 13,  2}, { 14,  1}, { 14,  2}, { 15,  1}, { 15,  2}, { 16,  1},
+{ 16,  2}, { 17,  1}, { 18,  1}, { 19,  1}, { 20,  1}, { 21,  1}, { 22,  1}, { 23,  1},
+{ 24,  1}, { 25,  1}, { 26,  1}, {  0,  1}, {  0,  2}, {  0,  3}, {  0,  4}, {  0,  5},
+{  0,  6}, {  0,  7}, {  0,  8}, {  0,  9}, {  1,  1}, {  1,  2}, {  1,  3}, {  1,  4},
+{  1,  5}, {  2,  1}, {  2,  2}, {  2,  3}, {  2,  4}, {  3,  1}, {  3,  2}, {  3,  3},
+{  3,  4}, {  4,  1}, {  4,  2}, {  4,  3}, {  5,  1}, {  5,  2}, {  5,  3}, {  6,  1},
+{  6,  2}, {  6,  3}, {  7,  1}, {  7,  2}, {  8,  1}, {  8,  2}, {  9,  1}, {  9,  2},
+{ 10,  1}, { 10,  2}, { 11,  1}, { 11,  2}, { 12,  1}, { 12,  2}, { 13,  1}, { 13,  2},
+{ 14,  1}, { 14,  2}, { 15,  1}, { 16,  1}, { 17,  1}, { 18,  1}, { 19,  1}, { 20,  1},
+{ 21,  1}, { 22,  1}, { 23,  1}, { 24,  1}, { 25,  1}, { 26,  1}, { 27,  1}, { 28,  1},
+{ 29,  1}, { 30,  1}, { 31,  1}, { 32,  1}, { 33,  1}, { 34,  1}, { 35,  1}, { 36,  1}
+},
+{
+{  0,  1}, {  0,  2}, {  0,  3}, {  0,  4}, {  0,  5}, {  0,  6}, {  0,  7}, {  0,  8},
+{  0,  9}, {  0, 10}, {  0, 11}, {  0, 12}, {  0, 13}, {  0, 14}, {  0, 15}, {  0, 16},
+{  1,  1}, {  1,  2}, {  1,  3}, {  1,  4}, {  1,  5}, {  1,  6}, {  1,  7}, {  1,  8},
+{  1,  9}, {  1, 10}, {  1, 11}, {  2,  1}, {  2,  2}, {  2,  3}, {  2,  4}, {  2,  5},
+{  2,  6}, {  2,  7}, {  2,  8}, {  3,  1}, {  3,  2}, {  3,  3}, {  3,  4}, {  3,  5},
+{  3,  6}, {  3,  7}, {  4,  1}, {  4,  2}, {  4,  3}, {  4,  4}, {  4,  5}, {  5,  1},
+{  5,  2}, {  5,  3}, {  5,  4}, {  6,  1}, {  6,  2}, {  6,  3}, {  6,  4}, {  7,  1},
+{  7,  2}, {  7,  3}, {  8,  1}, {  8,  2}, {  8,  3}, {  9,  1}, {  9,  2}, {  9,  3},
+{ 10,  1}, { 10,  2}, { 10,  3}, { 11,  1}, { 11,  2}, { 11,  3}, { 12,  1}, { 12,  2},
+{ 12,  3}, { 13,  1}, { 13,  2}, { 13,  3}, { 14,  1}, { 14,  2}, { 15,  1}, { 15,  2},
+{ 16,  1}, { 17,  1}, { 18,  1}, { 19,  1}, { 20,  1}, {  0,  1}, {  0,  2}, {  0,  3},
+{  0,  4}, {  1,  1}, {  1,  2}, {  1,  3}, {  1,  4}, {  2,  1}, {  2,  2}, {  2,  3},
+{  3,  1}, {  3,  2}, {  3,  3}, {  4,  1}, {  4,  2}, {  5,  1}, {  5,  2}, {  6,  1},
+{  6,  2}, {  7,  1}, {  7,  2}, {  8,  1}, {  8,  2}, {  9,  1}, {  9,  2}, { 10,  1},
+{ 10,  2}, { 11,  1}, { 11,  2}, { 12,  1}, { 12,  2}, { 13,  1}, { 13,  2}, { 14,  1},
+{ 15,  1}, { 16,  1}, { 17,  1}, { 18,  1}, { 19,  1}, { 20,  1}, { 21,  1}, { 22,  1},
+{ 23,  1}, { 24,  1}, { 25,  1}, { 26,  1}
+},
+{
+{  0,  1}, {  0,  2}, {  0,  3}, {  0,  4}, {  0,  5}, {  0,  6}, {  0,  7}, {  0,  8},
+{  0,  9}, {  0, 10}, {  0, 11}, {  0, 12}, {  0, 13}, {  0, 14}, {  1,  1}, {  1,  2},
+{  1,  3}, {  1,  4}, {  1,  5}, {  1,  6}, {  1,  7}, {  1,  8}, {  1,  9}, {  2,  1},
+{  2,  2}, {  2,  3}, {  2,  4}, {  2,  5}, {  3,  1}, {  3,  2}, {  3,  3}, {  3,  4},
+{  4,  1}, {  4,  2}, {  4,  3}, {  4,  4}, {  5,  1}, {  5,  2}, {  5,  3}, {  5,  4},
+{  6,  1}, {  6,  2}, {  6,  3}, {  7,  1}, {  7,  2}, {  7,  3}, {  8,  1}, {  8,  2},
+{  8,  3}, {  9,  1}, {  9,  2}, {  9,  3}, { 10,  1}, { 10,  2}, { 10,  3}, { 11,  1},
+{ 11,  2}, { 11,  3}, { 12,  1}, { 12,  2}, { 12,  3}, { 13,  1}, { 13,  2}, { 14,  1},
+{ 14,  2}, { 15,  1}, { 15,  2}, { 16,  1}, { 17,  1}, { 18,  1}, { 19,  1}, { 20,  1},
+{ 21,  1}, { 22,  1}, { 23,  1}, { 24,  1}, { 25,  1}, { 26,  1}, { 27,  1}, { 28,  1},
+{ 29,  1}, {  0,  1}, {  0,  2}, {  0,  3}, {  0,  4}, {  0,  5}, {  1,  1}, {  1,  2},
+{  1,  3}, {  1,  4}, {  2,  1}, {  2,  2}, {  2,  3}, {  3,  1}, {  3,  2}, {  3,  3},
+{  4,  1}, {  4,  2}, {  5,  1}, {  5,  2}, {  6,  1}, {  6,  2}, {  7,  1}, {  7,  2},
+{  8,  1}, {  8,  2}, {  9,  1}, {  9,  2}, { 10,  1}, { 10,  2}, { 11,  1}, { 11,  2},
+{ 12,  1}, { 12,  2}, { 13,  1}, { 13,  2}, { 14,  1}, { 14,  2}, { 15,  1}, { 15,  2},
+{ 16,  1}, { 17,  1}, { 18,  1}, { 19,  1}, { 20,  1}, { 21,  1}, { 22,  1}, { 23,  1},
+{ 24,  1}, { 25,  1}, { 26,  1}, { 27,  1}, { 28,  1}, { 29,  1}, { 30,  1}, { 31,  1},
+{ 32,  1}, { 33,  1}, { 34,  1}, { 35,  1}, { 36,  1}, { 37,  1}, { 38,  1}, { 39,  1},
+{ 40,  1}, { 41,  1}, { 42,  1}, { 43,  1}
+},
+{
+{  0,  1}, {  0,  2}, {  0,  3}, {  0,  4}, {  0,  5}, {  0,  6}, {  0,  7}, {  0,  8},
+{  0,  9}, {  0, 10}, {  0, 11}, {  0, 12}, {  0, 13}, {  0, 14}, {  0, 15}, {  0, 16},
+{  0, 17}, {  0, 18}, {  0, 19}, {  0, 20}, {  0, 21}, {  0, 22}, {  0, 23}, {  0, 24},
+{  0, 25}, {  0, 26}, {  0, 27}, {  1,  1}, {  1,  2}, {  1,  3}, {  1,  4}, {  1,  5},
+{  1,  6}, {  1,  7}, {  1,  8}, {  1,  9}, {  1, 10}, {  2,  1}, {  2,  2}, {  2,  3},
+{  2,  4}, {  2,  5}, {  3,  1}, {  3,  2}, {  3,  3}, {  3,  4}, {  4,  1}, {  4,  2},
+{  4,  3}, {  5,  1}, {  5,  2}, {  5,  3}, {  6,  1}, {  6,  2}, {  6,  3}, {  7,  1},
+{  7,  2}, {  7,  3}, {  8,  1}, {  8,  2}, {  9,  1}, {  9,  2}, { 10,  1}, { 11,  1},
+{ 12,  1}, { 13,  1}, { 14,  1}, {  0,  1}, {  0,  2}, {  0,  3}, {  0,  4}, {  0,  5},
+{  0,  6}, {  0,  7}, {  0,  8}, {  1,  1}, {  1,  2}, {  1,  3}, {  2,  1}, {  2,  2},
+{  3,  1}, {  3,  2}, {  4,  1}, {  4,  2}, {  5,  1}, {  5,  2}, {  6,  1}, {  6,  2},
+{  7,  1}, {  8,  1}, {  9,  1}, { 10,  1}, { 11,  1}, { 12,  1}, { 13,  1}, { 14,  1},
+{ 15,  1}, { 16,  1}, { 17,  1}, { 18,  1}, { 19,  1}, { 20,  1}
+},
+{
+{  0,  1}, {  0,  2}, {  0,  3}, {  0,  4}, {  0,  5}, {  0,  6}, {  0,  7}, {  0,  8},
+{  0,  9}, {  0, 10}, {  0, 11}, {  0, 12}, {  1,  1}, {  1,  2}, {  1,  3}, {  1,  4},
+{  1,  5}, {  1,  6}, {  2,  1}, {  2,  2}, {  2,  3}, {  2,  4}, {  3,  1}, {  3,  2},
+{  3,  3}, {  4,  1}, {  4,  2}, {  4,  3}, {  5,  1}, {  5,  2}, {  5,  3}, {  6,  1},
+{  6,  2}, {  6,  3}, {  7,  1}, {  7,  2}, {  8,  1}, {  8,  2}, {  9,  1}, {  9,  2},
+{ 10,  1}, { 10,  2}, { 11,  1}, { 12,  1}, { 13,  1}, { 14,  1}, { 15,  1}, { 16,  1},
+{ 17,  1}, { 18,  1}, { 19,  1}, { 20,  1}, { 21,  1}, { 22,  1}, { 23,  1}, { 24,  1},
+{ 25,  1}, { 26,  1}, {  0,  1}, {  0,  2}, {  0,  3}, {  1,  1}, {  1,  2}, {  2,  1},
+{  3,  1}, {  4,  1}, {  5,  1}, {  6,  1}, {  7,  1}, {  8,  1}, {  9,  1}, { 10,  1},
+{ 11,  1}, { 12,  1}, { 13,  1}, { 14,  1}, { 15,  1}, { 16,  1}, { 17,  1}, { 18,  1},
+{ 19,  1}, { 20,  1}, { 21,  1}, { 22,  1}, { 23,  1}, { 24,  1}, { 25,  1}, { 26,  1},
+{ 27,  1}, { 28,  1}, { 29,  1}, { 30,  1}, { 31,  1}, { 32,  1}, { 33,  1}, { 34,  1},
+{ 35,  1}, { 36,  1}, { 37,  1}, { 38,  1}, { 39,  1}, { 40,  1}
+},
+{
+{  0,  1}, {  0,  2}, {  0,  3}, {  0,  4}, {  0,  5}, {  0,  6}, {  0,  7}, {  0,  8},
+{  0,  9}, {  0, 10}, {  0, 11}, {  0, 12}, {  0, 13}, {  0, 14}, {  0, 15}, {  0, 16},
+{  0, 17}, {  0, 18}, {  0, 19}, {  0, 20}, {  0, 21}, {  0, 22}, {  0, 23}, {  0, 24},
+{  0, 25}, {  0, 26}, {  0, 27}, {  0, 28}, {  0, 29}, {  0, 30}, {  0, 31}, {  0, 32},
+{  0, 33}, {  0, 34}, {  0, 35}, {  0, 36}, {  0, 37}, {  0, 38}, {  0, 39}, {  0, 40},
+{  0, 41}, {  0, 42}, {  0, 43}, {  0, 44}, {  0, 45}, {  0, 46}, {  0, 47}, {  0, 48},
+{  0, 49}, {  0, 50}, {  0, 51}, {  0, 52}, {  0, 53}, {  0, 54}, {  0, 55}, {  0, 56},
+{  1,  1}, {  1,  2}, {  1,  3}, {  1,  4}, {  1,  5}, {  1,  6}, {  1,  7}, {  1,  8},
+{  1,  9}, {  1, 10}, {  1, 11}, {  1, 12}, {  1, 13}, {  1, 14}, {  1, 15}, {  1, 16},
+{  1, 17}, {  1, 18}, {  1, 19}, {  1, 20}, {  2,  1}, {  2,  2}, {  2,  3}, {  2,  4},
+{  2,  5}, {  2,  6}, {  2,  7}, {  2,  8}, {  2,  9}, {  2, 10}, {  3,  1}, {  3,  2},
+{  3,  3}, {  3,  4}, {  3,  5}, {  3,  6}, {  3,  7}, {  4,  1}, {  4,  2}, {  4,  3},
+{  4,  4}, {  4,  5}, {  4,  6}, {  5,  1}, {  5,  2}, {  5,  3}, {  5,  4}, {  5,  5},
+{  6,  1}, {  6,  2}, {  6,  3}, {  6,  4}, {  7,  1}, {  7,  2}, {  7,  3}, {  8,  1},
+{  8,  2}, {  8,  3}, {  9,  1}, {  9,  2}, {  9,  3}, { 10,  1}, { 10,  2}, { 11,  1},
+{ 11,  2}, { 12,  1}, { 12,  2}, { 13,  1}, { 13,  2}, { 14,  1}, {  0,  1}, {  0,  2},
+{  0,  3}, {  0,  4}, {  1,  1}, {  1,  2}, {  1,  3}, {  2,  1}, {  2,  2}, {  2,  3},
+{  3,  1}, {  3,  2}, {  4,  1}, {  4,  2}, {  5,  1}, {  5,  2}, {  6,  1}, {  6,  2},
+{  7,  1}, {  7,  2}, {  8,  1}, {  8,  2}, {  9,  1}, {  9,  2}, { 10,  1}, { 10,  2},
+{ 11,  1}, { 11,  2}, { 12,  1}, { 12,  2}, { 13,  1}, { 13,  2}, { 14,  1}, { 14,  2},
+{ 15,  1}, { 16,  1}
+},
+{
+{  0,  1}, {  0,  2}, {  0,  3}, {  0,  4}, {  0,  5}, {  0,  6}, {  0,  7}, {  0,  8},
+{  0,  9}, {  0, 10}, {  0, 11}, {  0, 12}, {  0, 13}, {  0, 14}, {  0, 15}, {  0, 16},
+{  0, 17}, {  0, 18}, {  0, 19}, {  0, 20}, {  0, 21}, {  0, 22}, {  0, 23}, {  0, 24},
+{  0, 25}, {  0, 26}, {  0, 27}, {  0, 28}, {  0, 29}, {  0, 30}, {  0, 31}, {  0, 32},
+{  1,  1}, {  1,  2}, {  1,  3}, {  1,  4}, {  1,  5}, {  1,  6}, {  1,  7}, {  1,  8},
+{  1,  9}, {  1, 10}, {  1, 11}, {  1, 12}, {  1, 13}, {  2,  1}, {  2,  2}, {  2,  3},
+{  2,  4}, {  2,  5}, {  2,  6}, {  2,  7}, {  2,  8}, {  3,  1}, {  3,  2}, {  3,  3},
+{  3,  4}, {  3,  5}, {  3,  6}, {  4,  1}, {  4,  2}, {  4,  3}, {  4,  4}, {  4,  5},
+{  5,  1}, {  5,  2}, {  5,  3}, {  5,  4}, {  6,  1}, {  6,  2}, {  6,  3}, {  6,  4},
+{  7,  1}, {  7,  2}, {  7,  3}, {  8,  1}, {  8,  2}, {  8,  3}, {  9,  1}, {  9,  2},
+{  9,  3}, { 10,  1}, { 10,  2}, { 11,  1}, { 11,  2}, { 12,  1}, { 12,  2}, { 13,  1},
+{ 13,  2}, { 14,  1}, { 14,  2}, { 15,  1}, { 15,  2}, { 16,  1}, { 16,  2}, { 17,  1},
+{ 17,  2}, { 18,  1}, { 18,  2}, { 19,  1}, { 19,  2}, { 20,  1}, { 20,  2}, { 21,  1},
+{ 21,  2}, { 22,  1}, { 22,  2}, { 23,  1}, { 24,  1}, {  0,  1}, {  0,  2}, {  0,  3},
+{  0,  4}, {  1,  1}, {  1,  2}, {  1,  3}, {  2,  1}, {  2,  2}, {  2,  3}, {  3,  1},
+{  3,  2}, {  3,  3}, {  4,  1}, {  4,  2}, {  5,  1}, {  5,  2}, {  6,  1}, {  6,  2},
+{  7,  1}, {  7,  2}, {  8,  1}, {  8,  2}, {  9,  1}, {  9,  2}, { 10,  1}, { 10,  2},
+{ 11,  1}, { 11,  2}, { 12,  1}, { 12,  2}, { 13,  1}, { 13,  2}, { 14,  1}, { 14,  2},
+{ 15,  1}, { 15,  2}, { 16,  1}, { 16,  2}, { 17,  1}, { 17,  2}, { 18,  1}, { 18,  2},
+{ 19,  1}, { 19,  2}, { 20,  1}, { 20,  2}, { 21,  1}, { 21,  2}, { 22,  1}, { 22,  2},
+{ 23,  1}, { 23,  2}, { 24,  1}, { 24,  2}, { 25,  1}, { 25,  2}, { 26,  1}, { 26,  2},
+{ 27,  1}, { 27,  2}, { 28,  1}, { 28,  2}, { 29,  1}, { 30,  1}
+}
+};
+
+static const uint8_t vc1_delta_level_table[AC_MODES][31] = {
+{
+      19,    15,    12,    11,     6,     5,     4,     4,     4,     4,
+       3,     3,     3,     3,     3,     3,     2,     2,     1,     1,
+       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
+       1
+},
+{
+      23,    11,     8,     7,     5,     5,     4,     4,     3,     3,
+       3,     3,     2,     2,     2,     2,     2,     1,     1,     1,
+       1,     1,     1,     1,     1,     1,     1
+},
+{
+      16,    11,     8,     7,     5,     4,     4,     3,     3,     3,
+       3,     3,     3,     3,     2,     2,     1,     1,     1,     1,
+       1
+},
+{
+      14,     9,     5,     4,     4,     4,     3,     3,     3,     3,
+       3,     3,     3,     2,     2,     2,     1,     1,     1,     1,
+       1,     1,     1,     1,     1,     1,     1,     1,     1,
+       1
+},
+{
+      27,    10,     5,     4,     3,     3,     3,     3,     2,     2,
+       1,     1,     1,     1,     1
+},
+{
+      12,     6,     4,     3,     3,     3,     3,     2,     2,     2,
+       2,     1,     1,     1,     1,     1,     1,     1,     1,     1,
+       1,     1,     1,     1,     1,     1,     1
+},
+{
+      56,    20,    10,     7,     6,     5,     4,     3,     3,     3,
+       2,     2,     2,     2,     1
+},
+{
+      32,    13,     8,     6,     5,     4,     4,     3,     3,     3,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     1,     1
+}
+};
+
+static const uint8_t vc1_last_delta_level_table[AC_MODES][44] = {
+{
+       6,     5,     4,     4,     3,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     1,     1,     1,     1,
+       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
+       1,     1,     1,     1,     1,     1,     1,     1
+},
+{
+       9,     5,     4,     4,     3,     3,     3,     2,     2,     2,
+       2,     2,     2,     2,     2,     1,     1,     1,     1,     1,
+       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
+       1,     1,     1,     1,     1,     1,     1
+},
+{
+       4,     4,     3,     3,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     1,     1,     1,     1,     1,     1,
+       1,     1,     1,     1,     1,     1,     1
+},
+{
+       5,     4,     3,     3,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     1,     1,     1,     1,
+       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
+       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
+       1,     1,     1,     1
+},
+{
+       8,     3,     2,     2,     2,     2,     2,     1,     1,     1,
+       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
+       1
+},
+{
+       3,     2,     1,     1,     1,     1,     1,     1,     1,     1,
+       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
+       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
+       1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
+       1
+},
+{
+       4,     3,     3,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     1,     1
+},
+{
+       4,     3,     3,     3,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,     2,     1,
+       1
+}
+};
+
+static const uint8_t vc1_delta_run_table[AC_MODES][57] = {
+{
+      -1,    30,    17,    15,     9,     5,     4,     3,     3,     3,
+       3,     3,     2,     1,     1,     1,     0,     0,     0,
+       0
+},
+{
+      -1,    26,    16,    11,     7,     5,     3,     3,     2,     1,
+       1,     1,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0
+},
+{
+      -1,    20,    15,    13,     6,     4,     3,     3,     2,     1,
+       1,     1,     0,     0,     0,     0,     0
+},
+{
+      -1,    29,    15,    12,     5,     2,     1,     1,     1,     1,
+       0,     0,     0,     0,     0
+},
+{
+      -1,    14,     9,     7,     3,     2,     1,     1,     1,     1,
+       1,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0
+},
+{
+      -1,    26,    10,     6,     2,     1,     1,     0,     0,     0,
+       0,     0,     0
+},
+{
+      -1,    14,    13,     9,     6,     5,     4,     3,     2,     2,
+       2,     1,     1,     1,     1,     1,     1,     1,     1,     1,
+       1,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0
+},
+{
+      -1,    24,    22,     9,     6,     4,     3,     2,     2,     1,
+       1,     1,     1,     1,     0,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
+       0,     0,     0
+}
+};
+
+static const uint8_t vc1_last_delta_run_table[AC_MODES][10] = {
+{
+      -1,    37,    15,     4,     3,     1,     0
+},
+{
+      -1,    36,    14,     6,     3,     1,     0,     0,     0,
+       0
+},
+{
+      -1,    26,    13,     3,     1
+},
+{
+      -1,    43,    15,     3,     1,     0
+},
+{
+      -1,    20,     6,     1,     0,     0,     0,     0,     0
+},
+{
+      -1,    40,     1,     0
+},
+{
+      -1,    16,    14,     2,     0
+},
+{
+      -1,    30,    28,     3,     0
+}
+};

Modified: trunk/libavcodec/vc1data.h
==============================================================================
--- trunk/libavcodec/vc1data.h	(original)
+++ trunk/libavcodec/vc1data.h	Tue Jun 27 05:11:51 2006
@@ -1,6 +1,6 @@
 /**
  * @file vc1data.h
- * VC1 tables.
+ * VC-1 tables.
  */
 
 #ifndef VC1DATA_H
@@ -167,10 +167,65 @@
 };
 
 const uint8_t wmv3_dc_scale_table[32]={
-    0, 4, 6, 8, 8, 8, 9, 9,10,10,11,11,12,12,13,13,14,14,15,15,16,16,17,17,18,18,19,19,20,20,21,21
+    0, 2, 4, 8, 8, 8, 9, 9,10,10,11,11,12,12,13,13,14,14,15,15,16,16,17,17,18,18,19,19,20,20,21,21
 };
 
 /* P-Picture CBPCY VLC tables */
+#if 1 // Looks like original tables are not conforming to standard at all. Are they used for old WMV?
+static const uint16_t vc1_cbpcy_p_codes[4][64] = {
+  {
+      0,   6,  15,  13,  13,  11,   3,  13,   5,   8,  49,  10,  12, 114, 102, 119,
+      1,  54,  96,   8,  10, 111,   5,  15,  12,  10,   2,  12,  13, 115,  53,  63,
+      1,   7,   1,   7,  14,  12,   4,  14,   1,   9,  97,  11,   7,  58,  52,  62,
+      4, 103,   1,   9,  11,  56, 101, 118,   4, 110, 100,  30,   2,   5,   4,   3
+  },
+  {
+      0,   9,   1,  18,   5,  14, 237,  26,   3, 121,   3,  22,  13,  16,   6,  30,
+      2,  10,   1,  20,  12, 241,   5,  28,  16,  12,   3,  24,  28, 124, 239, 247,
+      1, 240,   1,  19,  18,  15,   4,  27,   1, 122,   2,  23,   1,  17,   7,  31,
+      1,  11,   2,  21,  19, 246, 238,  29,  17,  13, 236,  25,  58,  63,   8, 125
+  },
+  {
+      0, 201,  25, 231,   5, 221,   1,   3,   2, 414,   2, 241,  16, 225, 195, 492,
+      2, 412,   1, 240,   7, 224,  98, 245,   1, 220,  96,   5,   9, 230, 101, 247,
+      1, 102,   1, 415,  24,   3,   2, 244,   3,  54,   3, 484,  17, 114, 200, 493,
+      3, 413,   1,   4,  13, 113,  99, 485,   4, 111, 194, 243,   5,  29,  26,  31
+  },
+  {
+      0,  28,  12,  44,   3,  36,  20,  52,   2,  32,  16,  48,   8,  40,  24,  28,
+      1,  30,  14,  46,   6,  38,  22,  54,   3,  34,  18,  50,  10,  42,  26,  30,
+      1,  29,  13,  45,   5,  37,  21,  53,   2,  33,  17,  49,   9,  41,  25,  29,
+      1,  31,  15,  47,   7,  39,  23,  55,   4,  35,  19,  51,  11,  43,  27,  31
+   }
+};
+
+static const uint8_t vc1_cbpcy_p_bits[4][64] = {
+  {
+    13,  13,   7,  13,   7,  13,  13,  12,   6,  13,   7,  12,   6,   8,   8,   8,
+     5,   7,   8,  12,   6,   8,  13,  12,   7,  13,  13,  12,   6,   8,   7,   7,
+     6,  13,   8,  12,   7,  13,  13,  12,   7,  13,   8,  12,   5,   7,   7,   7,
+     6,   8,  13,  12,   6,   7,   8,   8,   5,   8,   8,   6,   3,   3,   3,   2
+  },
+  {
+    14,  13,   8,  13,   3,  13,   8,  13,   3,   7,   8,  13,   4,  13,  13,  13,
+     3,  13,  13,  13,   4,   8,  13,  13,   5,  13,  13,  13,   5,   7,   8,   8,
+     3,   8,  14,  13,   5,  13,  13,  13,   4,   7,  13,  13,   6,  13,  13,  13,
+     5,  13,   8,  13,   5,   8,   8,  13,   5,  13,   8,  13,   6,   6,  13,   7
+  },
+  {
+    13,   8,   6,   8,   4,   8,  13,  12,   4,   9,   8,   8,   5,   8,   8,   9,
+     5,   9,  10,   8,   4,   8,   7,   8,   6,   8,   7,  13,   4,   8,   7,   8,
+     5,   7,   8,   9,   6,  13,  13,   8,   4,   6,   8,   9,   5,   7,   8,   9,
+     5,   9,   9,  13,   5,   7,   7,   9,   4,   7,   8,   8,   3,   5,   5,   5
+  },
+  {
+     9,   9,   9,   9,   2,   9,   9,   9,   2,   9,   9,   9,   9,   9,   9,   8,
+     3,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   8,
+     2,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   8,
+     9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   9,   8
+  }
+};
+#else
 static const uint16_t vc1_cbpcy_p_codes[4][64] = {
   {
       0,   1,   1,   4,   5,   1,  12,   4,  13,  14,  10,  11,  12,   7,  13,   2,
@@ -223,6 +278,7 @@
      9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  9,  8,  8,  8,  8
   }
 };
+#endif
 
 /* MacroBlock Transform Type: 7.1.3.11, p89
  * 8x8:B
@@ -402,5 +458,153 @@
 /* DC differentials low+hi-mo, p217 are the same as in msmpeg4data .h */
 
 /* Scantables/ZZ scan are at 11.9 (p262) and 8.1.1.12 (p10) */
-
+static const int8_t vc1_normal_zz[64] = {
+       0,     8,     1,     2,     9,    16,    24,    17,
+      10,     3,     4,    11,    18,    25,    32,    40,
+      33,    48,    26,    19,    12,     5,     6,    13,
+      20,    27,    34,    41,    56,    49,    57,    42,
+      35,    28,    21,    14,     7,    15,    22,    29,
+      36,    43,    50,    58,    51,    59,    44,    37,
+      30,    23,    31,    38,    45,    52,    60,    53,
+      61,    46,    39,    47,    54,    62,    55,    63
+};
+
+static const int8_t vc1_horizontal_zz [64] = /* Table 227 */
+{
+       0,     1,     8,     2,     3,     9,    16,    24,
+      17,    10,     4,     5,    11,    18,    25,    32,
+      40,    48,    33,    26,    19,    12,     6,     7,
+      13,    20,    27,    34,    41,    56,    49,    57,
+      42,    35,    28,    21,    14,    15,    22,    29,
+      36,    43,    50,    58,    51,    44,    37,    30,
+      23,    31,    38,    45,    52,    59,    60,    53,
+      46,    39,    47,    54,    61,    62,    55,    63
+};
+
+static const int8_t vc1_vertical_zz [64] = /* Table 228 */
+{
+       0,     8,    16,     1,    24,    32,    40,     9,
+       2,     3,    10,    17,    25,    48,    56,    41,
+      33,    26,    18,    11,     4,     5,    12,    19,
+      27,    34,    49,    57,    50,    42,    35,    28,
+      20,    13,     6,     7,    14,    21,    29,    36,
+      43,    51,    58,    59,    52,    44,    37,    30,
+      22,    15,    23,    31,    38,    45,    60,    53,
+      46,    39,    47,    54,    61,    62,    55,    63
+};
+
+static const int8_t vc1_simple_progressive_8x8_zz [64] =
+/* Table 229 */
+{
+       0,     8,     1,     2,     9,    16,    24,    17,
+      10,     3,     4,    11,    18,    25,    32,    40,
+      48,    56,    41,    33,    26,    19,    12,     5,
+       6,    13,    20,    27,    34,    49,    57,    58,
+      50,    42,    35,    28,    21,    14,     7,    15,
+      22,    29,    36,    43,    51,    59,    60,    52,
+      44,    37,    30,    23,    31,    38,    45,    53,
+      61,    62,    54,    46,    39,    47,    55,    63
+};
+
+static const int8_t vc1_simple_progressive_8x4_zz [32] = /* Table 230 */
+{
+       0,     1,     2,     8,     3,     9,    10,    16,
+       4,    11,    17,    24,    18,    12,     5,    19,
+      25,    13,    20,    26,    27,     6,    21,    28,
+      14,    22,    29,     7,    30,    15,    23,    31
+};
+
+static const int8_t vc1_simple_progressive_4x8_zz [32] = /* Table 231 */
+{
+       0,     8,     1,    16,
+       9,    24,    17,     2,
+      32,    10,    25,    40,
+      18,    48,    33,    26,
+      56,    41,    34,     3,
+      49,    57,    11,    42,
+      19,    50,    27,    58,
+      35,    43,    51,    59
+};
+
+/* Table 232 */
+static const int8_t vc1_simple_progressive_4x4_zz [16] =
+{
+       0,     8,    16,     1,
+       9,    24,    17,     2,
+      10,    18,    25,     3,
+      11,    26,    19,    27
+};
+
+static const int8_t vc1_adv_progressive_8x4_zz [32] = /* Table 233 */
+{
+       0,     8,     1,    16,     2,     9,    10,     3,
+      24,    17,     4,    11,    18,    12,     5,    19,
+      25,    13,    20,    26,    27,     6,    21,    28,
+      14,    22,    29,     7,    30,    15,    23,    31
+};
+
+static const int8_t vc1_adv_progressive_4x8_zz [32] = /* Table 234 */
+{
+       0,     1,     8,     2,
+       9,    16,    17,    24,
+      10,    32,    25,    18,
+      40,     3,    33,    26,
+      48,    11,    56,    41,
+      34,    49,    57,    42,
+      19,    50,    27,    58,
+      35,    43,    51,    59
+};
+
+static const int8_t vc1_adv_interlaced_8x8_zz [64] = /* Table 235 */
+{
+       0,     8,     1,    16,    24,     9,     2,    32,
+      40,    48,    56,    17,    10,     3,    25,    18,
+      11,     4,    33,    41,    49,    57,    26,    34,
+      42,    50,    58,    19,    12,     5,    27,    20,
+      13,     6,    35,    28,    21,    14,     7,    15,
+      22,    29,    36,    43,    51,    59,    60,    52,
+      44,    37,    30,    23,    31,    38,    45,    53,
+      61,    62,    54,    46,    39,    47,    55,    63
+};
+
+static const int8_t vc1_adv_interlaced_8x4_zz [32] = /* Table 236 */
+{
+       0,     8,    16,    24,     1,     9,     2,    17,
+      25,    10,     3,    18,    26,     4,    11,    19,
+      12,     5,    13,    20,    27,     6,    21,    28,
+      14,    22,    29,     7,    30,    15,    23,    31
+};
+
+static const int8_t vc1_adv_interlaced_4x8_zz [32] = /* Table 237 */
+{
+       0,     1,     2,     8,
+      16,     9,    24,    17,
+      10,     3,    32,    40,
+      48,    56,    25,    18,
+      33,    26,    41,    34,
+      49,    57,    11,    42,
+      19,    50,    27,    58,
+      35,    43,    51,    59
+};
+
+static const int8_t vc1_adv_interlaced_4x4_zz [16] = /* Table 238 */
+{
+       0,     8,    16,    24,
+       1,     9,    17,     2,
+      25,    10,    18,     3,
+      26,    11,    19,    27
+};
+
+
+/* DQScale as specified in 8.1.3.9 - almost identical to 0x40000/i */
+static const int32_t vc1_dqscale[63] = {
+0x40000, 0x20000, 0x15555, 0x10000, 0xCCCD, 0xAAAB, 0x9249, 0x8000,
+    0x71C7, 0x6666, 0x5D17, 0x5555, 0x4EC5, 0x4925, 0x4444, 0x4000,
+    0x3C3C, 0x38E4, 0x35E5, 0x3333, 0x30C3, 0x2E8C, 0x2C86, 0x2AAB,
+    0x28F6, 0x2762, 0x25ED, 0x2492, 0x234F, 0x2222, 0x2108, 0x2000,
+    0x1F08, 0x1E1E, 0x1D42, 0x1C72, 0x1BAD, 0x1AF3, 0x1A42, 0x199A,
+    0x18FA, 0x1862, 0x17D0, 0x1746, 0x16C1, 0x1643, 0x15CA, 0x1555,
+    0x14E6, 0x147B, 0x1414, 0x13B1, 0x1352, 0x12F7, 0x129E, 0x1249,
+    0x11F7, 0x11A8, 0x115B, 0x1111, 0x10C9, 0x1084, 0x1000
+};
 #endif /* VC1DATA_H */




More information about the ffmpeg-cvslog mailing list