changeset 3367:8c7b8ffc2485 libavcodec

Some optimization and fixes - mostly reworked MC and bitplanes.
author kostya
date Thu, 29 Jun 2006 11:05:33 +0000
parents c59aa4cdf042
children 19620d64a239
files vc1.c
diffstat 1 files changed, 215 insertions(+), 241 deletions(-) [+]
line wrap: on
line diff
--- a/vc1.c	Thu Jun 29 11:02:33 2006 +0000
+++ b/vc1.c	Thu Jun 29 11:05:33 2006 +0000
@@ -203,30 +203,6 @@
     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
- * @fixme For now, stride=width
- * @warning Data are bits, either 1 or 0
- */
-typedef struct BitPlane {
-    uint8_t *data;      ///< Data buffer
-    int width;          ///< Width of the buffer
-    int stride;         ///< Stride of the buffer
-    int height;         ///< Plane height
-    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
@@ -334,9 +310,11 @@
     uint8_t *previous_line_cbpcy; ///< To use for predicted CBPCY
     VLC *cbpcy_vlc;               ///< CBPCY VLC table
     int tt_index;                 ///< Index for Transform Type tables
-    BitPlane mv_type_mb_plane;    ///< bitplane for mv_type == (4MV)
-    BitPlane skip_mb_plane;       ///< bitplane for skipped MBs
-    BitPlane direct_mb_plane;     ///< bitplane for "direct" MBs
+    uint8_t* mv_type_mb_plane;    ///< bitplane for mv_type == (4MV)
+    uint8_t* skip_mb_plane;       ///< bitplane for skipped MBs
+//    BitPlane direct_mb_plane;     ///< bitplane for "direct" MBs
+    int mv_type_is_raw;           ///< mv type mb plane is not coded
+    int skip_is_raw;              ///< skip mb plane is not coded
 
     /** Frame decoding info for S/M profiles only */
     //@{
@@ -359,8 +337,8 @@
     int hrd_num_leaky_buckets;
     uint8_t bit_rate_exponent;
     uint8_t buffer_size_exponent;
-    BitPlane ac_pred_plane;       ///< AC prediction flags bitplane
-    BitPlane over_flags_plane;    ///< Overflags bitplane
+//    BitPlane ac_pred_plane;       ///< AC prediction flags bitplane
+//    BitPlane over_flags_plane;    ///< Overflags bitplane
     uint8_t condover;
     uint16_t *hrd_rate, *hrd_buffer;
     uint8_t *hrd_fullness;
@@ -436,11 +414,6 @@
     static int done = 0;
     int i = 0;
 
-    /* Set the bit planes */
-    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 };
-    v->ac_pred_plane = v->over_flags_plane = (struct BitPlane) { NULL, 0, 0, 0 };
     v->hrd_rate = v->hrd_buffer = NULL;
 
     /* VLC tables */
@@ -521,33 +494,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
@@ -595,53 +541,57 @@
  * @fixme FIXME: Optimize
  * @todo TODO: Decide if a struct is needed
  */
-static int bitplane_decoding(BitPlane *bp, VC1Context *v)
+static int bitplane_decoding(uint8_t* data, int *raw_flag, VC1Context *v)
 {
     GetBitContext *gb = &v->s.gb;
 
     int imode, x, y, code, offset;
-    uint8_t invert, *planep = bp->data;
+    uint8_t invert, *planep = data;
+    int width, height, stride;
 
+    width = v->s.mb_width;
+    height = v->s.mb_height;
+    stride = v->s.mb_stride;
     invert = get_bits(gb, 1);
     imode = get_vlc2(gb, vc1_imode_vlc.table, VC1_IMODE_VLC_BITS, 1);
 
-    bp->is_raw = 0;
+    *raw_flag = 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
+        *raw_flag = 1; //invert ignored
         return invert;
     case IMODE_DIFF2:
     case IMODE_NORM2:
-        if ((bp->height * bp->width) & 1)
+        if ((height * width) & 1)
         {
             *planep++ = get_bits(gb, 1);
             offset = 1;
         }
         else offset = 0;
         // decode bitplane as one long line
-        for (y = offset; y < bp->height * bp->width; y += 2) {
+        for (y = offset; y < height * width; y += 2) {
             code = get_vlc2(gb, vc1_norm2_vlc.table, VC1_NORM2_VLC_BITS, 1);
             *planep++ = code & 1;
             offset++;
-            if(offset == bp->width) {
+            if(offset == width) {
                 offset = 0;
-                planep += bp->stride - bp->width;
+                planep += stride - width;
             }
             *planep++ = code >> 1;
             offset++;
-            if(offset == bp->width) {
+            if(offset == width) {
                 offset = 0;
-                planep += bp->stride - bp->width;
+                planep += stride - width;
             }
         }
         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) {
+        if(!(height % 3) && (width % 3)) { // use 2x3 decoding
+            for(y = 0; y < height; y+= 3) {
+                for(x = width & 1; x < 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");
@@ -649,17 +599,17 @@
                     }
                     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[x + 0 + stride] = (code >> 2) & 1;
+                    planep[x + 1 + stride] = (code >> 3) & 1;
+                    planep[x + 0 + stride * 2] = (code >> 4) & 1;
+                    planep[x + 1 + stride * 2] = (code >> 5) & 1;
                 }
-                planep += bp->stride * 3;
+                planep += stride * 3;
             }
-            if(bp->width & 1) decode_colskip(bp->data, 1, bp->height, bp->stride, &v->s.gb);
+            if(width & 1) decode_colskip(data, 1, height, 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) {
+            for(y = height & 1; y < height; y += 2) {
+                for(x = width % 3; x < 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");
@@ -668,22 +618,22 @@
                     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[x + 0 + stride] = (code >> 3) & 1;
+                    planep[x + 1 + stride] = (code >> 4) & 1;
+                    planep[x + 2 + stride] = (code >> 5) & 1;
                 }
-                planep += bp->stride * 2;
+                planep += 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);
+            x = width % 3;
+            if(x) decode_colskip(data  ,             x, height    , stride, &v->s.gb);
+            if(height & 1) decode_rowskip(data+x, width - x, 1, stride, &v->s.gb);
         }
         break;
     case IMODE_ROWSKIP:
-        decode_rowskip(bp->data, bp->width, bp->height, bp->stride, &v->s.gb);
+        decode_rowskip(data, width, height, stride, &v->s.gb);
         break;
     case IMODE_COLSKIP:
-        decode_colskip(bp->data, bp->width, bp->height, bp->stride, &v->s.gb);
+        decode_colskip(data, width, height, stride, &v->s.gb);
         break;
     default: break;
     }
@@ -691,28 +641,29 @@
     /* Applying diff operator */
     if (imode == IMODE_DIFF2 || imode == IMODE_DIFF6)
     {
-        planep = bp->data;
+        planep = data;
         planep[0] ^= invert;
-        for (x=1; x<bp->width; x++)
+        for (x=1; x<width; x++)
             planep[x] ^= planep[x-1];
-        for (y=1; y<bp->height; y++)
+        for (y=1; y<height; y++)
         {
-            planep += bp->stride;
-            planep[0] ^= planep[-bp->stride];
-            for (x=1; x<bp->width; x++)
+            planep += stride;
+            planep[0] ^= planep[-stride];
+            for (x=1; x<width; x++)
             {
-                if (planep[x-1] != planep[x-bp->stride]) planep[x] ^= invert;
-                else                                     planep[x] ^= planep[x-1];
+                if (planep[x-1] != planep[x-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
+        planep = data;
+        for (x=0; x<stride*height; x++) planep[x] = !planep[x]; //FIXME stride
     }
     return (imode<<1) + invert;
 }
+
 /** @} */ //Bitplane group
 
 /***********************************************************************/
@@ -886,6 +837,42 @@
 }
 
 
+static void vc1_v_overlap(uint8_t* src, int stride)
+{
+    int i;
+    int a, b, c, d;
+    for(i = 0; i < 8; i++) {
+        a = src[-2*stride];
+        b = src[-stride];
+        c = src[0];
+        d = src[stride];
+
+        src[-2*stride] = (7*a + d) >> 3;
+        src[-stride] = (-a + 7*b + c + d) >> 3;
+        src[0] = (a + b + 7*c - d) >> 3;
+        src[stride] = (a + 7*d) >> 3;
+        src++;
+    }
+}
+
+static void vc1_h_overlap(uint8_t* src, int stride)
+{
+    int i;
+    int a, b, c, d;
+    for(i = 0; i < 8; i++) {
+        a = src[-2];
+        b = src[-1];
+        c = src[0];
+        d = src[1];
+
+        src[-2] = (7*a + d) >> 3;
+        src[-1] = (-a + 7*b + c + d) >> 3;
+        src[0] = (a + b + 7*c - d) >> 3;
+        src[1] = (a + 7*d) >> 3;
+        src += stride;
+    }
+}
+
 /** Put block onto picture
  * @todo move to DSPContext
  */
@@ -910,6 +897,11 @@
     dsp->put_pixels_clamped(block[5], v->s.dest[2], vs);
 }
 
+/* clip motion vector as specified in 8.3.6.5 */
+#define CLIP_RANGE(mv, src, lim, bs)      \
+    if(mv < -bs) mv = -bs - src * bs; \
+    if(mv > lim) mv = lim - src * bs;
+
 /** Do motion compensation over 1 macroblock
  * Mostly adapted hpel_motion and qpel_motion from mpegvideo.c
  */
@@ -918,89 +910,69 @@
     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;
+    int dxy, uvdxy, mx, my, uvmx, uvmy, src_x, src_y, uvsrc_x, uvsrc_y;
 
     if(!v->s.last_picture.data[0])return;
 
-    mx = s->mv[0][0][0] >> s->mspel;
-    my = s->mv[0][0][1] >> s->mspel;
+    mx = s->mv[0][0][0];
+    my = s->mv[0][0][1];
+    uvmx = (mx + ((mx & 3) == 3)) >> 1;
+    uvmy = (my + ((my & 3) == 3)) >> 1;
     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(v->fastuvmc) { // XXX: 8.3.5.4.5 specifies something different
+        uvmx = (uvmx + 1) >> 1;
+        uvmy = (uvmy + 1) >> 1;
+    }
+
+    src_x = s->mb_x * 16 + (mx >> 2);
+    src_y = s->mb_y * 16 + (my >> 2);
+    uvsrc_x = s->mb_x * 8 + (uvmx >> 2);
+    uvsrc_y = s->mb_y * 8 + (uvmy >> 2);
+
+    CLIP_RANGE(  src_x, s->mb_x, s->mb_width  * 16, 16);
+    CLIP_RANGE(  src_y, s->mb_y, s->mb_height * 16, 16);
+    CLIP_RANGE(uvsrc_x, s->mb_x, s->mb_width  *  8,  8);
+    CLIP_RANGE(uvsrc_y, s->mb_y, s->mb_height *  8,  8);
+
+    srcY += src_y * s->linesize + src_x;
+    srcU += uvsrc_y * s->uvlinesize + uvsrc_x;
+    srcV += uvsrc_y * s->uvlinesize + uvsrc_x;
 
-        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;
+    if((unsigned)src_x > s->h_edge_pos - (mx&3) - 16
+       || (unsigned)src_y > s->v_edge_pos - (my&3) - 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;
-        }
+        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,
+                            uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1);
+        ff_emulated_edge_mc(uvbuf + 16, srcV, s->uvlinesize, 8+1, 8+1,
+                            uvsrc_x, uvsrc_y, s->h_edge_pos >> 1, s->v_edge_pos >> 1);
+        srcU = uvbuf;
+        srcV = uvbuf + 16;
+    }
+
+    if(!s->quarter_sample) { // hpel mc
+        mx >>= 1;
+        my >>= 1;
+        uvmx >>= 1;
+        uvmy >>= 1;
+        dxy = ((my & 1) << 1) | (mx & 1);
+        uvdxy = 0;
+
         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;
-        }
+        dxy = ((my & 3) << 2) | (mx & 3);
+        uvdxy = ((uvmy & 1) << 1) | (uvmx & 1);
 
         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);
     }
+    dsp->put_mspel_pixels_tab[uvdxy](s->dest[1], srcU, s->uvlinesize);
+    dsp->put_mspel_pixels_tab[uvdxy](s->dest[2], srcV, s->uvlinesize);
 }
 
 /**
@@ -1215,9 +1187,9 @@
             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;
+            v->s.quarter_sample = 0;
         else
-            v->s.mspel = 0;
+            v->s.quarter_sample = 1;
 
 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");
@@ -1227,12 +1199,15 @@
                  v->mv_mode2 == MV_PMODE_MIXED_MV)
                 || v->mv_mode == MV_PMODE_MIXED_MV)
         {
-            status = bitplane_decoding(&v->mv_type_mb_plane, v);
+            status = bitplane_decoding(v->mv_type_mb_plane, &v->mv_type_is_raw, 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);
+        } else {
+            v->mv_type_is_raw = 0;
+            memset(v->mv_type_mb_plane, 0, v->s.mb_stride * v->s.mb_height);
         }
-        status = bitplane_decoding(&v->skip_mb_plane, v);
+        status = bitplane_decoding(v->skip_mb_plane, &v->skip_is_raw, 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);
@@ -1327,8 +1302,8 @@
   if (!index) { _dmv_x = _dmv_y = 0; }                              \
   else if (index == 35)                                             \
   {                                                                 \
-    _dmv_x = get_bits(gb, v->k_x - s->mspel);                       \
-    _dmv_y = get_bits(gb, v->k_y - s->mspel);                       \
+    _dmv_x = get_bits(gb, v->k_x - 1 + s->quarter_sample);          \
+    _dmv_y = get_bits(gb, v->k_y - 1 + s->quarter_sample);          \
   }                                                                 \
   else if (index == 36)                                             \
   {                                                                 \
@@ -1339,8 +1314,8 @@
   else                                                              \
   {                                                                 \
     index1 = index%6;                                               \
-    if (s->mspel && index1 == 5) val = 1;                           \
-    else                         val = 0;                           \
+    if (!s->quarter_sample && index1 == 5) val = 1;                 \
+    else                                   val = 0;                 \
     if(size_table[index1] - val > 0)                                \
         val = get_bits(gb, size_table[index1] - val);               \
     else                                   val = 0;                 \
@@ -1348,8 +1323,8 @@
     _dmv_x = (sign ^ ((val>>1) + offset_table[index1])) - sign;     \
                                                                     \
     index1 = index/6;                                               \
-    if (s->mspel && index1 == 5) val = 1;                           \
-    else                         val = 0;                           \
+    if (!s->quarter_sample && index1 == 5) val = 1;                 \
+    else                                   val = 0;                 \
     if(size_table[index1] - val > 0)                                \
         val = get_bits(gb, size_table[index1] - val);               \
     else                                   val = 0;                 \
@@ -1368,8 +1343,8 @@
     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;
+    dmv_x <<= 1 - s->quarter_sample;
+    dmv_y <<= 1 - s->quarter_sample;
 
     wrap = s->b8_stride;
     xy = s->block_index[0];
@@ -1627,26 +1602,22 @@
             level = -level;
     } else {
         escape = decode210(gb);
-        if (escape == 0) {
+        if (escape != 2) {
             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(escape == 0) {
+                if(lst)
+                    level += vc1_last_delta_level_table[codingset][run];
+                else
+                    level += vc1_delta_level_table[codingset][run];
+            } else {
+                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 {
@@ -1944,7 +1915,7 @@
         }
 
         /* apply AC prediction if needed */
-        if(s->ac_pred) {
+        if(s->ac_pred && (v->a_avail || v->c_avail)) {
             /* scale predictors if needed*/
             int mb_pos2, q1, q2;
 
@@ -1960,7 +1931,7 @@
                 memset(ac_val + 8, 0, 8 * sizeof(ac_val[0]));
                 dc_pred_dir = 1;
             }
-            if(!q1 && q1 && q2 && q1 != q2) {
+            if(q2 && q1 != q2) {
                 q1 = q1 * 2 - 1;
                 q2 = q2 * 2 - 1;
 
@@ -2017,16 +1988,16 @@
         memset(ac_val2, 0, 16 * 2);
         if(dc_pred_dir) {//left
             ac_val -= 16;
-            if(s->ac_pred)
+            if(s->ac_pred && (v->a_avail || v->c_avail))
                 memcpy(ac_val2, ac_val, 8 * 2);
         } else {//top
             ac_val -= 16 * s->block_wrap[n];
-            if(s->ac_pred)
+            if(s->ac_pred && (v->a_avail || v->c_avail))
                 memcpy(ac_val2 + 8, ac_val + 8, 8 * 2);
         }
 
         /* apply AC prediction if needed */
-        if(s->ac_pred) {
+        if(s->ac_pred && (v->a_avail || v->c_avail)) {
             if(dc_pred_dir) { //left
                 for(k = 1; k < 8; k++) {
                     block[k << 3] = ac_val[k] * scale;
@@ -2082,7 +2053,6 @@
         ttblk = TT_4X8;
         subblkpat = 2 - (ttblk == TT_4X8_LEFT);
     }
-
     switch(ttblk) {
     case TT_8X8:
         i = 0;
@@ -2101,7 +2071,7 @@
         for(j = 0; j < 4; j++) {
             last = subblkpat & (1 << (3 - j));
             i = 0;
-            off = (j & 1) * 4 + (j & 2) * 32;
+            off = (j & 1) * 4 + (j & 2) * 16;
             while (!last) {
                 vc1_decode_ac_coeff(v, &last, &skip, &value, v->codingset2);
                 i += skip;
@@ -2110,7 +2080,8 @@
                 idx = vc1_simple_progressive_4x4_zz[i++];
                 block[idx + off] = value * scale;
             }
-            vc1_inv_trans(block + off, 4, 4);
+            if(!(subblkpat & (1 << (3 - j))))
+                vc1_inv_trans(block + off, 4, 4);
         }
         break;
     case TT_8X4:
@@ -2126,7 +2097,8 @@
                 idx = vc1_simple_progressive_8x4_zz[i++];
                 block[idx + off] = value * scale;
             }
-            if(!(subblkpat & (1 << (1 - j)))) vc1_inv_trans(block + off, 8, 4);
+            if(!(subblkpat & (1 << (1 - j))))
+                vc1_inv_trans(block + off, 8, 4);
         }
         break;
     case TT_4X8:
@@ -2142,7 +2114,8 @@
                 idx = vc1_simple_progressive_8x4_zz[i++];
                 block[idx + off] = value * scale;
             }
-            vc1_inv_trans(block + off, 4, 8);
+            if(!(subblkpat & (1 << (1 - j))))
+                vc1_inv_trans(block + off, 4, 8);
         }
         break;
     }
@@ -2158,7 +2131,7 @@
 {
     MpegEncContext *s = &v->s;
     GetBitContext *gb = &s->gb;
-    int i, j, mb_offset = s->mb_x + s->mb_y*s->mb_width; /* XXX: mb_stride */
+    int i, j;
     int mb_pos = s->mb_x + s->mb_y * s->mb_stride;
     int cbp; /* cbp decoding stuff */
     int hybrid_pred; /* Prediction types */
@@ -2174,17 +2147,22 @@
     int val, sign; /* temp values */
     int first_block = 1;
     int dst_idx, off;
+    int skipped, fourmv;
 
     mquant = v->pq; /* Loosy initialization */
 
-    if (v->mv_type_mb_plane.is_raw)
-        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);
-    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->mv_type_is_raw)
+        fourmv = get_bits1(gb);
+    else
+        fourmv = v->mv_type_mb_plane[mb_pos];
+    if (v->skip_is_raw)
+        skipped = get_bits1(gb);
+    else
+        skipped = v->skip_mb_plane[mb_pos];
+
+    if (!fourmv) /* 1MV mode */
     {
-        if (!v->skip_mb_plane.data[mb_offset])
+        if (!skipped)
         {
             GET_MVDATA(dmv_x, dmv_y);
 
@@ -2232,19 +2210,21 @@
                         v->c_avail = 1;
 
                     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));
+                    vc1_inv_trans(block[i], 8, 8);
+                    for(j = 0; j < 64; j++) block[i][j] += 128;
+                    s->dsp.put_pixels_clamped(block[i], s->dest[dst_idx] + off, s->linesize >> ((i & 4) >> 2));
                     /* TODO: proper loop filtering */
-                    if(v->a_avail)
-                        s->dsp.h263_v_loop_filter(s->dest[dst_idx] + off, s->linesize >> ((i & 4) >> 2), s->y_dc_scale);
-                    if(v->c_avail)
-                        s->dsp.h263_h_loop_filter(s->dest[dst_idx] + off, s->linesize >> ((i & 4) >> 2), s->y_dc_scale);
+                    if(v->pq >= 9 && v->overlap) {
+                        if(v->a_avail)
+                            s->dsp.h263_v_loop_filter(s->dest[dst_idx] + off, s->linesize >> ((i & 4) >> 2), s->y_dc_scale);
+                        if(v->c_avail)
+                            s->dsp.h263_h_loop_filter(s->dest[dst_idx] + off, s->linesize >> ((i & 4) >> 2), s->y_dc_scale);
+                    }
                 } 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);
+                    s->dsp.add_pixels_clamped(block[i], s->dest[dst_idx] + off, (i&4)?s->uvlinesize:s->linesize);
                 }
             }
         }
@@ -2259,7 +2239,7 @@
     } //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 */)
+        if (!skipped /* unskipped MB */)
         {
             int blk_intra[4], blk_coded[4];
             /* Get CBPCY */
@@ -2495,6 +2475,8 @@
     if (!avctx->extradata_size || !avctx->extradata) return -1;
     avctx->pix_fmt = PIX_FMT_YUV420P;
     v->s.avctx = avctx;
+    avctx->flags |= CODEC_FLAG_EMU_EDGE;
+    v->s.flags |= CODEC_FLAG_EMU_EDGE;
 
     if(ff_h263_decode_init(avctx) < 0)
         return -1;
@@ -2503,7 +2485,6 @@
     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)
@@ -2537,14 +2518,8 @@
     s->mb_height = (avctx->coded_height+15)>>4;
 
     /* Allocate mb bitplanes */
-    if (alloc_bitplane(&v->mv_type_mb_plane, s->mb_width, s->mb_height) < 0)
-        return -1;
-    if (alloc_bitplane(&v->mv_type_mb_plane, s->mb_width, s->mb_height) < 0)
-        return -1;
-    if (alloc_bitplane(&v->skip_mb_plane, s->mb_width, s->mb_height) < 0)
-        return -1;
-    if (alloc_bitplane(&v->direct_mb_plane, s->mb_width, s->mb_height) < 0)
-        return -1;
+    v->mv_type_mb_plane = av_malloc(s->mb_stride * s->mb_height);
+    v->skip_mb_plane = av_malloc(s->mb_stride * s->mb_height);
 
     /* For predictors */
     v->previous_line_cbpcy = (uint8_t *)av_malloc(s->mb_stride*4);
@@ -2553,10 +2528,10 @@
     /* Init coded blocks info */
     if (v->profile == PROFILE_ADVANCED)
     {
-        if (alloc_bitplane(&v->over_flags_plane, s->mb_width, s->mb_height) < 0)
-            return -1;
-        if (alloc_bitplane(&v->ac_pred_plane, s->mb_width, s->mb_height) < 0)
-            return -1;
+//        if (alloc_bitplane(&v->over_flags_plane, s->mb_width, s->mb_height) < 0)
+//            return -1;
+//        if (alloc_bitplane(&v->ac_pred_plane, s->mb_width, s->mb_height) < 0)
+//            return -1;
     }
 
     return 0;
@@ -2670,9 +2645,8 @@
     av_freep(&v->hrd_rate);
     av_freep(&v->hrd_buffer);
     MPV_common_end(&v->s);
-    free_bitplane(&v->mv_type_mb_plane);
-    free_bitplane(&v->skip_mb_plane);
-    free_bitplane(&v->direct_mb_plane);
+    av_freep(&v->mv_type_mb_plane);
+    av_freep(&v->skip_mb_plane);
     return 0;
 }