changeset 1938:e2501e6e7ff7 libavcodec

unify table indexing (motion_val,dc_val,ac_val,coded_block changed) minor +-1 bugfix
author michael
date Fri, 16 Apr 2004 01:01:45 +0000
parents 4d91a9342d95
children 71fe2180024c
files error_resilience.c h263.c motion_est.c mpeg12.c mpegvideo.c mpegvideo.h msmpeg4.c rv10.c wmv2.c
diffstat 9 files changed, 135 insertions(+), 185 deletions(-) [+]
line wrap: on
line diff
--- a/error_resilience.c	Wed Apr 14 13:13:31 2004 +0000
+++ b/error_resilience.c	Fri Apr 16 01:01:45 2004 +0000
@@ -45,7 +45,7 @@
 {
     int dc, dcu, dcv, y, i;
     for(i=0; i<4; i++){
-        dc= s->dc_val[0][mb_x*2+1 + (i&1) + (mb_y*2+1 + (i>>1))*(s->mb_width*2+2)];
+        dc= s->dc_val[0][mb_x*2 + (i&1) + (mb_y*2 + (i>>1))*s->b8_stride];
         if(dc<0) dc=0;
         else if(dc>2040) dc=2040;
         for(y=0; y<8; y++){
@@ -55,8 +55,8 @@
             }
         }
     }
-    dcu = s->dc_val[1][mb_x+1 + (mb_y+1)*(s->mb_width+2)];
-    dcv = s->dc_val[2][mb_x+1 + (mb_y+1)*(s->mb_width+2)];
+    dcu = s->dc_val[1][mb_x + mb_y*s->mb_stride];
+    dcv = s->dc_val[2][mb_x + mb_y*s->mb_stride];
     if     (dcu<0   ) dcu=0;
     else if(dcu>2040) dcu=2040;
     if     (dcv<0   ) dcv=0;
@@ -209,8 +209,8 @@
             int left_damage =  left_status&(DC_ERROR|AC_ERROR|MV_ERROR);
             int right_damage= right_status&(DC_ERROR|AC_ERROR|MV_ERROR);
             int offset= b_x*8 + b_y*stride*8;
-            int16_t *left_mv=  s->current_picture.motion_val[0][s->block_wrap[0]*((b_y<<(1-is_luma)) + 1) + ( b_x   <<(1-is_luma))];
-            int16_t *right_mv= s->current_picture.motion_val[0][s->block_wrap[0]*((b_y<<(1-is_luma)) + 1) + ((b_x+1)<<(1-is_luma))];
+            int16_t *left_mv=  s->current_picture.motion_val[0][s->b8_stride*(b_y<<(1-is_luma)) + ( b_x   <<(1-is_luma))];
+            int16_t *right_mv= s->current_picture.motion_val[0][s->b8_stride*(b_y<<(1-is_luma)) + ((b_x+1)<<(1-is_luma))];
             
             if(!(left_damage||right_damage)) continue; // both undamaged
             
@@ -269,8 +269,8 @@
             int top_damage =      top_status&(DC_ERROR|AC_ERROR|MV_ERROR);
             int bottom_damage= bottom_status&(DC_ERROR|AC_ERROR|MV_ERROR);
             int offset= b_x*8 + b_y*stride*8;
-            int16_t *top_mv=    s->current_picture.motion_val[0][s->block_wrap[0]*(( b_y   <<(1-is_luma)) + 1) + (b_x<<(1-is_luma))];
-            int16_t *bottom_mv= s->current_picture.motion_val[0][s->block_wrap[0]*(((b_y+1)<<(1-is_luma)) + 1) + (b_x<<(1-is_luma))];
+            int16_t *top_mv=    s->current_picture.motion_val[0][s->b8_stride*( b_y   <<(1-is_luma)) + (b_x<<(1-is_luma))];
+            int16_t *bottom_mv= s->current_picture.motion_val[0][s->b8_stride*((b_y+1)<<(1-is_luma)) + (b_x<<(1-is_luma))];
             
             if(!(top_damage||bottom_damage)) continue; // both undamaged
             
@@ -378,8 +378,8 @@
                     int j;
                     int best_score=256*256*256*64;
                     int best_pred=0;
-                    const int mot_stride= mb_width*2+2;
-                    const int mot_index= mb_x*2 + 1 + (mb_y*2+1)*mot_stride;
+                    const int mot_stride= s->b8_stride;
+                    const int mot_index= mb_x*2 + mb_y*2*mot_stride;
                     int prev_x= s->current_picture.motion_val[0][mot_index][0];
                     int prev_y= s->current_picture.motion_val[0][mot_index][1];
 
@@ -672,14 +672,14 @@
     av_log(s->avctx, AV_LOG_INFO, "concealing errors\n");
     
     if(s->current_picture.motion_val[0] == NULL){
-        int size = (2 * s->mb_width + 2) * (2 * s->mb_height + 2);
+        int size = s->b8_stride * 2 * s->mb_height;
         Picture *pic= s->current_picture_ptr;
         
         av_log(s->avctx, AV_LOG_ERROR, "Warning MVs not available\n");
             
         for(i=0; i<2; i++){
-            pic->motion_val_base[i]= av_mallocz((size+1) * 2 * sizeof(uint16_t)); //FIXME size
-            pic->motion_val[i]= pic->motion_val_base[i]+1;
+            pic->motion_val_base[i]= av_mallocz((size+2) * 2 * sizeof(uint16_t));
+            pic->motion_val[i]= pic->motion_val_base[i]+2;
         }
         pic->motion_subsample_log2= 3;
         s->current_picture= *s->current_picture_ptr;
@@ -845,17 +845,17 @@
             s->mb_intra=0;
             s->mb_skiped=0;
             if(IS_8X8(mb_type)){
-                int mb_index= mb_x*2+1 + (mb_y*2+1)*s->block_wrap[0];
+                int mb_index= mb_x*2 + mb_y*2*s->b8_stride;
                 int j;
                 s->mv_type = MV_TYPE_8X8;
                 for(j=0; j<4; j++){
-                    s->mv[0][j][0] = s->current_picture.motion_val[0][ mb_index + (j&1) + (j>>1)*s->block_wrap[0] ][0];
-                    s->mv[0][j][1] = s->current_picture.motion_val[0][ mb_index + (j&1) + (j>>1)*s->block_wrap[0] ][1];
+                    s->mv[0][j][0] = s->current_picture.motion_val[0][ mb_index + (j&1) + (j>>1)*s->b8_stride ][0];
+                    s->mv[0][j][1] = s->current_picture.motion_val[0][ mb_index + (j&1) + (j>>1)*s->b8_stride ][1];
                 }
             }else{
                 s->mv_type = MV_TYPE_16X16;
-                s->mv[0][0][0] = s->current_picture.motion_val[0][ mb_x*2+1 + (mb_y*2+1)*s->block_wrap[0] ][0];
-                s->mv[0][0][1] = s->current_picture.motion_val[0][ mb_x*2+1 + (mb_y*2+1)*s->block_wrap[0] ][1];
+                s->mv[0][0][0] = s->current_picture.motion_val[0][ mb_x*2 + mb_y*2*s->b8_stride ][0];
+                s->mv[0][0][1] = s->current_picture.motion_val[0][ mb_x*2 + mb_y*2*s->b8_stride ][1];
             }
         
 	    s->dsp.clear_blocks(s->block[0]);
@@ -870,7 +870,7 @@
     if(s->pict_type==B_TYPE){
         for(mb_y=0; mb_y<s->mb_height; mb_y++){
             for(mb_x=0; mb_x<s->mb_width; mb_x++){
-                int xy= mb_x*2+1 + (mb_y*2+1)*s->block_wrap[0];
+                int xy= mb_x*2 + mb_y*2*s->b8_stride;
                 const int mb_xy= mb_x + mb_y * s->mb_stride;
                 const int mb_type= s->current_picture.mb_type[mb_xy];
                 error= s->error_status_table[mb_xy];
@@ -930,7 +930,7 @@
             dest_cb= s->current_picture.data[1] + mb_x*8  + mb_y*8 *s->uvlinesize;
             dest_cr= s->current_picture.data[2] + mb_x*8  + mb_y*8 *s->uvlinesize;
            
-            dc_ptr= &s->dc_val[0][mb_x*2+1 + (mb_y*2+1)*(s->mb_width*2+2)];
+            dc_ptr= &s->dc_val[0][mb_x*2 + mb_y*2*s->b8_stride];
             for(n=0; n<4; n++){
                 dc=0;
                 for(y=0; y<8; y++){
@@ -939,7 +939,7 @@
                        dc+= dest_y[x + (n&1)*8 + (y + (n>>1)*8)*s->linesize];
                     }
                 }
-                dc_ptr[(n&1) + (n>>1)*(s->mb_width*2+2)]= (dc+4)>>3;
+                dc_ptr[(n&1) + (n>>1)*s->b8_stride]= (dc+4)>>3;
             }
 
             dcu=dcv=0;
@@ -950,18 +950,18 @@
                     dcv+=dest_cr[x + y*(s->uvlinesize)];
                 }
             }
-            s->dc_val[1][mb_x+1 + (mb_y+1)*(s->mb_width+2)]= (dcu+4)>>3;
-            s->dc_val[2][mb_x+1 + (mb_y+1)*(s->mb_width+2)]= (dcv+4)>>3;   
+            s->dc_val[1][mb_x + mb_y*s->mb_stride]= (dcu+4)>>3;
+            s->dc_val[2][mb_x + mb_y*s->mb_stride]= (dcv+4)>>3;   
         }
     }
 #if 1
     /* guess DC for damaged blocks */
-    guess_dc(s, s->dc_val[0] + s->mb_width*2+3, s->mb_width*2, s->mb_height*2, s->mb_width*2+2, 1);
-    guess_dc(s, s->dc_val[1] + s->mb_width  +3, s->mb_width  , s->mb_height  , s->mb_width  +2, 0);
-    guess_dc(s, s->dc_val[2] + s->mb_width  +3, s->mb_width  , s->mb_height  , s->mb_width  +2, 0);
+    guess_dc(s, s->dc_val[0], s->mb_width*2, s->mb_height*2, s->b8_stride, 1);
+    guess_dc(s, s->dc_val[1], s->mb_width  , s->mb_height  , s->mb_stride, 0);
+    guess_dc(s, s->dc_val[2], s->mb_width  , s->mb_height  , s->mb_stride, 0);
 #endif   
     /* filter luma DC */
-    filter181(s->dc_val[0] + s->mb_width*2+3, s->mb_width*2, s->mb_height*2, s->mb_width*2+2);
+    filter181(s->dc_val[0], s->mb_width*2, s->mb_height*2, s->b8_stride);
     
 #if 1
     /* render DC only intra */
--- a/h263.c	Wed Apr 14 13:13:31 2004 +0000
+++ b/h263.c	Fri Apr 16 01:01:45 2004 +0000
@@ -610,7 +610,7 @@
 void ff_h263_update_motion_val(MpegEncContext * s){
     const int mb_xy = s->mb_y * s->mb_stride + s->mb_x;
                //FIXME a lot of thet is only needed for !low_delay
-    const int wrap = s->block_wrap[0];
+    const int wrap = s->b8_stride;
     const int xy = s->block_index[0];
     
     s->current_picture.mbskip_table[mb_xy]= s->mb_skiped; 
@@ -985,7 +985,7 @@
                 }
 
                 /* motion vectors: 16x16 mode */
-                h263_pred_motion(s, 0, &pred_x, &pred_y);
+                h263_pred_motion(s, 0, 0, &pred_x, &pred_y);
             
                 h263_encode_motion(s, motion_x - pred_x, s->f_code);
                 h263_encode_motion(s, motion_y - pred_y, s->f_code);
@@ -1009,7 +1009,7 @@
                 }
 
                 /* motion vectors: 16x8 interlaced mode */
-                h263_pred_motion(s, 0, &pred_x, &pred_y);
+                h263_pred_motion(s, 0, 0, &pred_x, &pred_y);
                 pred_y /=2;
                 
                 put_bits(&s->pb, 1, s->field_select[0][0]);
@@ -1037,7 +1037,7 @@
 
                 for(i=0; i<4; i++){
                     /* motion vectors: 8x8 mode*/
-                    h263_pred_motion(s, i, &pred_x, &pred_y);
+                    h263_pred_motion(s, i, 0, &pred_x, &pred_y);
 
                     h263_encode_motion(s, s->current_picture.motion_val[0][ s->block_index[i] ][0] - pred_x, s->f_code);
                     h263_encode_motion(s, s->current_picture.motion_val[0][ s->block_index[i] ][1] - pred_y, s->f_code);
@@ -1185,7 +1185,7 @@
             }
 
             /* motion vectors: 16x16 mode */
-            h263_pred_motion(s, 0, &pred_x, &pred_y);
+            h263_pred_motion(s, 0, 0, &pred_x, &pred_y);
             
             if (!s->umvplus) {  
                 h263_encode_motion(s, motion_x - pred_x, 1);
@@ -1212,7 +1212,7 @@
 
             for(i=0; i<4; i++){
                 /* motion vectors: 8x8 mode*/
-                h263_pred_motion(s, i, &pred_x, &pred_y);
+                h263_pred_motion(s, i, 0, &pred_x, &pred_y);
 
                 motion_x= s->current_picture.motion_val[0][ s->block_index[i] ][0];
                 motion_y= s->current_picture.motion_val[0][ s->block_index[i] ][1];
@@ -1435,16 +1435,16 @@
 
     /* find prediction */
     if (n < 4) {
-        x = 2 * s->mb_x + 1 + (n & 1);
-        y = 2 * s->mb_y + 1 + ((n & 2) >> 1);
-        wrap = s->mb_width * 2 + 2;
+        x = 2 * s->mb_x + (n & 1);
+        y = 2 * s->mb_y + ((n & 2) >> 1);
+        wrap = s->b8_stride;
         dc_val = s->dc_val[0];
         ac_val = s->ac_val[0][0];
         scale = s->y_dc_scale;
     } else {
-        x = s->mb_x + 1;
-        y = s->mb_y + 1;
-        wrap = s->mb_width + 2;
+        x = s->mb_x;
+        y = s->mb_y;
+        wrap = s->mb_stride;
         dc_val = s->dc_val[n - 4 + 1];
         ac_val = s->ac_val[n - 4 + 1][0];
         scale = s->c_dc_scale;
@@ -1482,16 +1482,16 @@
 
     /* find prediction */
     if (n < 4) {
-        x = 2 * s->mb_x + 1 + (n & 1);
-        y = 2 * s->mb_y + 1 + (n>> 1);
-        wrap = s->mb_width * 2 + 2;
+        x = 2 * s->mb_x + (n & 1);
+        y = 2 * s->mb_y + (n>> 1);
+        wrap = s->b8_stride;
         dc_val = s->dc_val[0];
         ac_val = s->ac_val[0][0];
         scale = s->y_dc_scale;
     } else {
-        x = s->mb_x + 1;
-        y = s->mb_y + 1;
-        wrap = s->mb_width + 2;
+        x = s->mb_x;
+        y = s->mb_y;
+        wrap = s->mb_stride;
         dc_val = s->dc_val[n - 4 + 1];
         ac_val = s->ac_val[n - 4 + 1][0];
         scale = s->c_dc_scale;
@@ -1562,78 +1562,15 @@
         ac_val1[8 + i] = block[s->dsp.idct_permutation[i   ]];
 }
 
-int16_t *h263_pred_motion(MpegEncContext * s, int block, 
+int16_t *h263_pred_motion(MpegEncContext * s, int block, int dir,
                         int *px, int *py)
 {
-    int xy, wrap;
-    int16_t *A, *B, *C, *mot_val;
-    static const int off[4]= {2, 1, 1, -1};
-
-    wrap = s->block_wrap[0];
-    xy = s->block_index[block];
-
-    mot_val = s->current_picture.motion_val[0][xy];
-
-    A = s->current_picture.motion_val[0][xy - 1];
-    /* special case for first (slice) line */
-    if (s->first_slice_line && block<3) {
-        // we cant just change some MVs to simulate that as we need them for the B frames (and ME)
-        // and if we ever support non rectangular objects than we need to do a few ifs here anyway :(
-        if(block==0){ //most common case
-            if(s->mb_x  == s->resync_mb_x){ //rare
-                *px= *py = 0;
-            }else if(s->mb_x + 1 == s->resync_mb_x && s->h263_pred){ //rare
-                C = s->current_picture.motion_val[0][xy + off[block] - wrap];
-                if(s->mb_x==0){
-                    *px = C[0];
-                    *py = C[1];
-                }else{
-                    *px = mid_pred(A[0], 0, C[0]);
-                    *py = mid_pred(A[1], 0, C[1]);
-                }
-            }else{
-                *px = A[0];
-                *py = A[1];
-            }
-        }else if(block==1){
-            if(s->mb_x + 1 == s->resync_mb_x && s->h263_pred){ //rare
-                C = s->current_picture.motion_val[0][xy + off[block] - wrap];
-                *px = mid_pred(A[0], 0, C[0]);
-                *py = mid_pred(A[1], 0, C[1]);
-            }else{
-                *px = A[0];
-                *py = A[1];
-            }
-        }else{ /* block==2*/
-            B = s->current_picture.motion_val[0][xy - wrap];
-            C = s->current_picture.motion_val[0][xy + off[block] - wrap];
-            if(s->mb_x == s->resync_mb_x) //rare
-                A[0]=A[1]=0;
-    
-            *px = mid_pred(A[0], B[0], C[0]);
-            *py = mid_pred(A[1], B[1], C[1]);
-        }
-    } else {
-        B = s->current_picture.motion_val[0][xy - wrap];
-        C = s->current_picture.motion_val[0][xy + off[block] - wrap];
-        *px = mid_pred(A[0], B[0], C[0]);
-        *py = mid_pred(A[1], B[1], C[1]);
-    }
-    return mot_val;
-}
-
-// identical to above but with s->current_picture->motion_val, the above one will be removed, and this renamed to it
-int16_t *h263_pred_motion2(MpegEncContext * s, int block, int dir,
-                        int *px, int *py)
-{
-    int xy, wrap;
+    int wrap;
     int16_t *A, *B, *C, (*mot_val)[2];
     static const int off[4]= {2, 1, 1, -1};
 
     wrap = s->b8_stride;
-    xy = 2*(s->mb_x + s->mb_y * wrap);
-
-    mot_val = s->current_picture.motion_val[dir] + xy;
+    mot_val = s->current_picture.motion_val[dir] + s->block_index[block];
 
     A = mot_val[ - 1];
     /* special case for first (slice) line */
@@ -3198,10 +3135,10 @@
 {
     int c_wrap, c_xy, l_wrap, l_xy;
 
-    l_wrap= s->block_wrap[0];
-    l_xy= s->mb_y*l_wrap*2 + s->mb_x*2;
-    c_wrap= s->block_wrap[4];
-    c_xy= s->mb_y*c_wrap + s->mb_x;
+    l_wrap= s->b8_stride;
+    l_xy= (2*s->mb_y-1)*l_wrap + s->mb_x*2 - 1;
+    c_wrap= s->mb_stride;
+    c_xy= (s->mb_y-1)*c_wrap + s->mb_x - 1;
 
 #if 0
     /* clean DC */
@@ -3374,7 +3311,7 @@
             }else{ /* P/S_TYPE */
                 int mx, my, pred_x, pred_y, bits;
                 int16_t * const mot_val= s->current_picture.motion_val[0][s->block_index[0]];
-                const int stride= s->block_wrap[0]*2;
+                const int stride= s->b8_stride*2;
 
 try_again:
                 bits= show_bits(&s->gb, 17);
@@ -3432,7 +3369,7 @@
                     if ((cbpc & 16) == 0) {
                         /* 16x16 motion prediction */
 
-                        h263_pred_motion(s, 0, &pred_x, &pred_y);
+                        h263_pred_motion(s, 0, 0, &pred_x, &pred_y);
                         if(!s->mcsel){
                             mx = h263_decode_motion(s, pred_x, s->f_code);
                             if (mx >= 0xffff)
@@ -3456,7 +3393,7 @@
                         int i;
                         s->current_picture.mb_type[xy]= MB_TYPE_8x8 | MB_TYPE_L0;
                         for(i=0;i<4;i++) {
-                            int16_t *mot_val= h263_pred_motion(s, i, &pred_x, &pred_y);
+                            int16_t *mot_val= h263_pred_motion(s, i, 0, &pred_x, &pred_y);
                             mx = h263_decode_motion(s, pred_x, s->f_code);
                             if (mx >= 0xffff)
                                 return -1;
@@ -3710,7 +3647,7 @@
     int cbpc, i, pred_x, pred_y, mx, my;
     int16_t *mot_val;
     const int xy= s->mb_x + 1 + s->mb_y * s->mb_stride;
-    const int stride= s->block_wrap[0]*2;
+    const int stride= s->b8_stride*2;
     
     for(i=0; i<4; i++)
         s->block_index[i]+= 2;
@@ -3750,7 +3687,7 @@
         if ((cbpc & 16) == 0) {
                 s->current_picture.mb_type[xy]= MB_TYPE_16x16 | MB_TYPE_L0; 
                 /* 16x16 motion prediction */
-                mot_val= h263_pred_motion(s, 0, &pred_x, &pred_y);
+                mot_val= h263_pred_motion(s, 0, 0, &pred_x, &pred_y);
                 if (s->umvplus)
                    mx = h263p_decode_umotion(s, pred_x);
                 else
@@ -3768,7 +3705,7 @@
         } else {
             s->current_picture.mb_type[xy]= MB_TYPE_8x8 | MB_TYPE_L0; 
             for(i=0;i<4;i++) {
-                mot_val = h263_pred_motion(s, i, &pred_x, &pred_y);
+                mot_val = h263_pred_motion(s, i, 0, &pred_x, &pred_y);
                 if (s->umvplus)
                   mx = h263p_decode_umotion(s, pred_x);
                 else
@@ -3860,7 +3797,7 @@
             s->current_picture.mb_type[xy]= MB_TYPE_16x16 | MB_TYPE_L0; 
             /* 16x16 motion prediction */
             s->mv_type = MV_TYPE_16X16;
-            h263_pred_motion(s, 0, &pred_x, &pred_y);
+            h263_pred_motion(s, 0, 0, &pred_x, &pred_y);
             if (s->umvplus)
                mx = h263p_decode_umotion(s, pred_x);
             else
@@ -3885,7 +3822,7 @@
             s->current_picture.mb_type[xy]= MB_TYPE_8x8 | MB_TYPE_L0; 
             s->mv_type = MV_TYPE_8X8;
             for(i=0;i<4;i++) {
-                mot_val = h263_pred_motion(s, i, &pred_x, &pred_y);
+                mot_val = h263_pred_motion(s, i, 0, &pred_x, &pred_y);
                 if (s->umvplus)
                   mx = h263p_decode_umotion(s, pred_x);
                 else
@@ -3979,7 +3916,7 @@
 //FIXME UMV
 
             if(USES_LIST(mb_type, 0)){
-                int16_t *mot_val= h263_pred_motion2(s, 0, 0, &mx, &my);
+                int16_t *mot_val= h263_pred_motion(s, 0, 0, &mx, &my);
                 s->mv_dir = MV_DIR_FORWARD;
 
                 mx = h263_decode_motion(s, mx, 1);
@@ -3992,7 +3929,7 @@
             }
     
             if(USES_LIST(mb_type, 1)){
-                int16_t *mot_val= h263_pred_motion2(s, 0, 1, &mx, &my);
+                int16_t *mot_val= h263_pred_motion(s, 0, 1, &mx, &my);
                 s->mv_dir |= MV_DIR_BACKWARD;
                 
                 mx = h263_decode_motion(s, mx, 1);
@@ -4147,7 +4084,7 @@
                 s->field_select[0][0]= get_bits1(&s->gb);
                 s->field_select[0][1]= get_bits1(&s->gb);
 
-                h263_pred_motion(s, 0, &pred_x, &pred_y);
+                h263_pred_motion(s, 0, 0, &pred_x, &pred_y);
                 
                 for(i=0; i<2; i++){
                     mx = h263_decode_motion(s, pred_x, s->f_code);
@@ -4165,7 +4102,7 @@
                 s->current_picture.mb_type[xy]= MB_TYPE_16x16 | MB_TYPE_L0; 
                 /* 16x16 motion prediction */
                 s->mv_type = MV_TYPE_16X16;
-                h263_pred_motion(s, 0, &pred_x, &pred_y);
+                h263_pred_motion(s, 0, 0, &pred_x, &pred_y);
                 mx = h263_decode_motion(s, pred_x, s->f_code);
             
                 if (mx >= 0xffff)
@@ -4182,7 +4119,7 @@
             s->current_picture.mb_type[xy]= MB_TYPE_8x8 | MB_TYPE_L0; 
             s->mv_type = MV_TYPE_8X8;
             for(i=0;i<4;i++) {
-                mot_val = h263_pred_motion(s, i, &pred_x, &pred_y);
+                mot_val = h263_pred_motion(s, i, 0, &pred_x, &pred_y);
                 mx = h263_decode_motion(s, pred_x, s->f_code);
                 if (mx >= 0xffff)
                     return -1;
--- a/motion_est.c	Wed Apr 14 13:13:31 2004 +0000
+++ b/motion_est.c	Fri Apr 16 01:01:45 2004 +0000
@@ -733,7 +733,7 @@
         s->current_picture.motion_val[0][mot_xy+1][0]= mx;
         s->current_picture.motion_val[0][mot_xy+1][1]= my;
 
-        mot_xy += s->block_wrap[0];
+        mot_xy += s->b8_stride;
         s->current_picture.motion_val[0][mot_xy  ][0]= mx;
         s->current_picture.motion_val[0][mot_xy  ][1]= my;
         s->current_picture.motion_val[0][mot_xy+1][0]= mx;
@@ -780,7 +780,7 @@
         int pred_x4, pred_y4;
         int dmin4;
         static const int off[4]= {2, 1, 1, -1};
-        const int mot_stride = s->block_wrap[0];
+        const int mot_stride = s->b8_stride;
         const int mot_xy = s->block_index[block];
         const int block_x= (block&1);
         const int block_y= (block>>1);
@@ -1102,7 +1102,7 @@
     case ME_X1:
     case ME_EPZS:
        {
-            const int mot_stride = s->block_wrap[0];
+            const int mot_stride = s->b8_stride;
             const int mot_xy = s->block_index[0];
 
             P_LEFT[0]       = s->current_picture.motion_val[0][mot_xy - 1][0];
@@ -1252,7 +1252,7 @@
                 int mean;
                 
                 if(s->out_format == FMT_H263){
-                    mean= (s->dc_val[i][mb_x + (mb_y+1)*(s->mb_width+2)] + 4)>>3; //FIXME not exact but simple ;)
+                    mean= (s->dc_val[i][mb_x + mb_y*s->b8_stride] + 4)>>3; //FIXME not exact but simple ;)
                 }else{
                     mean= (s->last_dc[i] + 4)>>3;
                 }
@@ -1809,11 +1809,11 @@
     
 //printf("%d no:%d %d//\n", clip, noclip, f_code);
     if(s->flags&CODEC_FLAG_4MV){
-        const int wrap= 2+ s->mb_width*2;
+        const int wrap= s->b8_stride;
 
         /* clip / convert to intra 8x8 type MVs */
         for(y=0; y<s->mb_height; y++){
-            int xy= (y*2 + 1)*wrap + 1;
+            int xy= y*2*wrap;
             int i= y*s->mb_stride;
             int x;
 
--- a/mpeg12.c	Wed Apr 14 13:13:31 2004 +0000
+++ b/mpeg12.c	Fri Apr 16 01:01:45 2004 +0000
@@ -2324,8 +2324,8 @@
             return -1;
 
         if(s->current_picture.motion_val[0] && !s->encoding){ //note motion_val is normally NULL unless we want to extract the MVs
-            const int wrap = field_pic ? 2*s->block_wrap[0] : s->block_wrap[0];
-            int xy = s->mb_x*2 + 1 + (s->mb_y*2 +1)*wrap;
+            const int wrap = field_pic ? 2*s->b8_stride : s->b8_stride;
+            int xy = s->mb_x*2 + s->mb_y*2*wrap;
             int motion_x, motion_y, dir, i;
             if(field_pic && !s->first_field)
                 xy += wrap/2;
--- a/mpegvideo.c	Wed Apr 14 13:13:31 2004 +0000
+++ b/mpegvideo.c	Fri Apr 16 01:01:45 2004 +0000
@@ -275,7 +275,9 @@
     dst->type= FF_BUFFER_TYPE_COPY;
 }
 
-static void copy_picture_attributes(AVFrame *dst, AVFrame *src){
+static void copy_picture_attributes(MpegEncContext *s, AVFrame *dst, AVFrame *src){
+    int i;
+
     dst->pict_type              = src->pict_type;
     dst->quality                = src->quality;
     dst->coded_picture_number   = src->coded_picture_number;
@@ -284,6 +286,18 @@
     dst->pts                    = src->pts;
     dst->interlaced_frame       = src->interlaced_frame;
     dst->top_field_first        = src->top_field_first;
+
+    if(src->motion_val[0] && src->motion_val[0] != dst->motion_val[0]){
+        if(src->motion_subsample_log2 != dst->motion_subsample_log2)
+            av_log(s->avctx, AV_LOG_ERROR, "AVFrame.motion_subsample_log2 doesnt match!\n");
+        else{
+            int stride= ((16*s->mb_width )>>src->motion_subsample_log2) + 1;
+            int height= ((16*s->mb_height)>>src->motion_subsample_log2);
+
+            for(i=0; i<2; i++)
+                memcpy(dst->motion_val[i], src->motion_val[i], stride*height*sizeof(int16_t));
+        }
+    }
 }
 
 /**
@@ -347,7 +361,7 @@
             pic->motion_subsample_log2= 2;
         }else if(s->out_format == FMT_H263 || s->encoding || (s->avctx->debug&FF_DEBUG_MV) || (s->avctx->debug_mv)){
             for(i=0; i<2; i++){
-                CHECKED_ALLOCZ(pic->motion_val_base[i], 2 * (b8_array_size+2) * sizeof(int16_t)*2) //FIXME
+                CHECKED_ALLOCZ(pic->motion_val_base[i], 2 * (b8_array_size+2) * sizeof(int16_t))
                 pic->motion_val[i]= pic->motion_val_base[i]+2;
             }
             pic->motion_subsample_log2= 3;
@@ -591,12 +605,12 @@
     s->block_wrap[0]=
     s->block_wrap[1]=
     s->block_wrap[2]=
-    s->block_wrap[3]= s->mb_width*2 + 2;
+    s->block_wrap[3]= s->b8_stride;
     s->block_wrap[4]=
-    s->block_wrap[5]= s->mb_width + 2;
+    s->block_wrap[5]= s->mb_stride;
  
-    y_size = (2 * s->mb_width + 2) * (2 * s->mb_height + 2);
-    c_size = (s->mb_width + 2) * (s->mb_height + 2);
+    y_size = s->b8_stride * (2 * s->mb_height + 1);
+    c_size = s->mb_stride * (s->mb_height + 1);
     yc_size = y_size + 2 * c_size;
     
     /* convert fourcc to upper case */
@@ -678,12 +692,14 @@
     }
     if (s->out_format == FMT_H263) {
         /* ac values */
-        CHECKED_ALLOCZ(s->ac_val[0], yc_size * sizeof(int16_t) * 16);
-        s->ac_val[1] = s->ac_val[0] + y_size;
+        CHECKED_ALLOCZ(s->ac_val_base, yc_size * sizeof(int16_t) * 16);
+        s->ac_val[0] = s->ac_val_base + s->b8_stride + 1;
+        s->ac_val[1] = s->ac_val_base + y_size + s->mb_stride + 1;
         s->ac_val[2] = s->ac_val[1] + c_size;
         
         /* cbp values */
-        CHECKED_ALLOCZ(s->coded_block, y_size);
+        CHECKED_ALLOCZ(s->coded_block_base, y_size);
+        s->coded_block= s->coded_block_base + s->b8_stride + 1;
         
         /* divx501 bitstream reorder buffer */
         CHECKED_ALLOCZ(s->bitstream_buffer, BITSTREAM_BUFFER_SIZE);
@@ -696,11 +712,12 @@
     if (s->h263_pred || s->h263_plus || !s->encoding) {
         /* dc values */
         //MN: we need these for error resilience of intra-frames
-        CHECKED_ALLOCZ(s->dc_val[0], yc_size * sizeof(int16_t));
-        s->dc_val[1] = s->dc_val[0] + y_size;
+        CHECKED_ALLOCZ(s->dc_val_base, yc_size * sizeof(int16_t));
+        s->dc_val[0] = s->dc_val_base + s->b8_stride + 1;
+        s->dc_val[1] = s->dc_val_base + y_size + s->mb_stride + 1;
         s->dc_val[2] = s->dc_val[1] + c_size;
         for(i=0;i<yc_size;i++)
-            s->dc_val[0][i] = 1024;
+            s->dc_val_base[i] = 1024;
     }
 
     /* which mb is a intra block */
@@ -781,9 +798,9 @@
         av_freep(&s->p_field_select_table[i]);
     }
     
-    av_freep(&s->dc_val[0]);
-    av_freep(&s->ac_val[0]);
-    av_freep(&s->coded_block);
+    av_freep(&s->dc_val_base);
+    av_freep(&s->ac_val_base);
+    av_freep(&s->coded_block_base);
     av_freep(&s->mbintra_table);
     av_freep(&s->cbp_table);
     av_freep(&s->pred_dir_table);
@@ -1684,12 +1701,13 @@
                     if(!USES_LIST(pict->mb_type[mb_index], direction))
                         continue;
 
+                    //FIXME for h264
                     if(IS_8X8(pict->mb_type[mb_index])){
                       int i;
                       for(i=0; i<4; i++){
                         int sx= mb_x*16 + 4 + 8*(i&1);
                         int sy= mb_y*16 + 4 + 8*(i>>1);
-                        int xy= 1 + mb_x*2 + (i&1) + (mb_y*2 + 1 + (i>>1))*(s->mb_width*2 + 2);
+                        int xy= mb_x*2 + (i&1) + (mb_y*2 + (i>>1))*s->b8_stride;
                         int mx= (pict->motion_val[direction][xy][0]>>shift) + sx;
                         int my= (pict->motion_val[direction][xy][1]>>shift) + sy;
                         draw_arrow(ptr, sx, sy, mx, my, s->width, s->height, s->linesize, 100);
@@ -1699,7 +1717,7 @@
                       for(i=0; i<2; i++){
                         int sx=mb_x*16 + 8;
                         int sy=mb_y*16 + 4 + 8*i;
-                        int xy=1 + mb_x*2 + (mb_y*2 + 1 + i)*(s->mb_width*2 + 2);
+                        int xy= mb_x*2 + (mb_y*2 + i)*s->b8_stride;
                         int mx=(pict->motion_val[direction][xy][0]>>shift) + sx;
                         int my=(pict->motion_val[direction][xy][1]>>shift) + sy;
                         draw_arrow(ptr, sx, sy, mx, my, s->width, s->height, s->linesize, 100);
@@ -1707,7 +1725,7 @@
                     }else{
                       int sx= mb_x*16 + 8;
                       int sy= mb_y*16 + 8;
-                      int xy= 1 + mb_x*2 + (mb_y*2 + 1)*(s->mb_width*2 + 2);
+                      int xy= mb_x*2 + mb_y*2*s->b8_stride;
                       int mx= (pict->motion_val[direction][xy][0]>>shift) + sx;
                       int my= (pict->motion_val[direction][xy][1]>>shift) + sy;
                       draw_arrow(ptr, sx, sy, mx, my, s->width, s->height, s->linesize, 100);
@@ -1884,7 +1902,7 @@
             }
         }
     }
-    copy_picture_attributes(pic, pic_arg);
+    copy_picture_attributes(s, pic, pic_arg);
     
     pic->display_picture_number= s->input_picture_number++;
     if(pic->pts != AV_NOPTS_VALUE){ 
@@ -2013,7 +2031,7 @@
                 s->reordered_input_picture[0]->data[i]= NULL;
             s->reordered_input_picture[0]->type= 0;
             
-            copy_picture_attributes((AVFrame*)pic, (AVFrame*)s->reordered_input_picture[0]);
+            copy_picture_attributes(s, (AVFrame*)pic, (AVFrame*)s->reordered_input_picture[0]);
             pic->reference              = s->reordered_input_picture[0]->reference;
             
             alloc_picture(s, pic, 0);
@@ -2746,8 +2764,8 @@
     if(s->obmc && s->pict_type != B_TYPE){
         int16_t mv_cache[4][4][2];
         const int xy= s->mb_x + s->mb_y*s->mb_stride;
-        const int mot_stride= s->mb_width*2 + 2;
-        const int mot_xy= 1 + mb_x*2 + (mb_y*2 + 1)*mot_stride;
+        const int mot_stride= s->b8_stride;
+        const int mot_xy= mb_x*2 + mb_y*2*mot_stride;
 
         assert(!s->mb_skiped);
                 
@@ -3003,7 +3021,7 @@
  */
 void ff_clean_intra_table_entries(MpegEncContext *s)
 {
-    int wrap = s->block_wrap[0];
+    int wrap = s->b8_stride;
     int xy = s->block_index[0];
     
     s->dc_val[0][xy           ] = 
@@ -3020,15 +3038,15 @@
         s->coded_block[xy + 1 + wrap] = 0;
     }
     /* chroma */
-    wrap = s->block_wrap[4];
-    xy = s->mb_x + 1 + (s->mb_y + 1) * wrap;
+    wrap = s->mb_stride;
+    xy = s->mb_x + s->mb_y * wrap;
     s->dc_val[1][xy] =
     s->dc_val[2][xy] = 1024;
     /* ac pred */
     memset(s->ac_val[1][xy], 0, 16 * sizeof(int16_t));
     memset(s->ac_val[2][xy], 0, 16 * sizeof(int16_t));
     
-    s->mbintra_table[s->mb_x + s->mb_y*s->mb_stride]= 0;
+    s->mbintra_table[xy]= 0;
 }
 
 /* generic function called after a macroblock has been parsed by the
@@ -3348,12 +3366,12 @@
     const int linesize= s->current_picture.linesize[0]; //not s->linesize as this woulnd be wrong for field pics
     const int uvlinesize= s->current_picture.linesize[1];
         
-    s->block_index[0]= s->block_wrap[0]*(s->mb_y*2 + 1) - 1 + s->mb_x*2;
-    s->block_index[1]= s->block_wrap[0]*(s->mb_y*2 + 1)     + s->mb_x*2;
-    s->block_index[2]= s->block_wrap[0]*(s->mb_y*2 + 2) - 1 + s->mb_x*2;
-    s->block_index[3]= s->block_wrap[0]*(s->mb_y*2 + 2)     + s->mb_x*2;
-    s->block_index[4]= s->block_wrap[4]*(s->mb_y + 1)                    + s->block_wrap[0]*(s->mb_height*2 + 2) + s->mb_x;
-    s->block_index[5]= s->block_wrap[4]*(s->mb_y + 1 + s->mb_height + 2) + s->block_wrap[0]*(s->mb_height*2 + 2) + s->mb_x;
+    s->block_index[0]= s->b8_stride*(s->mb_y*2    ) - 2 + s->mb_x*2;
+    s->block_index[1]= s->b8_stride*(s->mb_y*2    ) - 1 + s->mb_x*2;
+    s->block_index[2]= s->b8_stride*(s->mb_y*2 + 1) - 2 + s->mb_x*2;
+    s->block_index[3]= s->b8_stride*(s->mb_y*2 + 1) - 1 + s->mb_x*2;
+    s->block_index[4]= s->mb_stride*(s->mb_y + 1)                + s->b8_stride*s->mb_height*2 + s->mb_x - 1;
+    s->block_index[5]= s->mb_stride*(s->mb_y + s->mb_height + 2) + s->b8_stride*s->mb_height*2 + s->mb_x - 1;
     
     if(s->pict_type==B_TYPE && s->avctx->draw_horiz_band && s->picture_structure==PICT_FRAME){
         s->dest[0] = s->current_picture.data[0] + s->mb_x * 16 - 16;
--- a/mpegvideo.h	Wed Apr 14 13:13:31 2004 +0000
+++ b/mpegvideo.h	Fri Apr 16 01:01:45 2004 +0000
@@ -321,13 +321,16 @@
     Picture *current_picture_ptr;  ///< pointer to the current picture
     uint8_t *visualization_buffer[3]; //< temporary buffer vor MV visualization
     int last_dc[3];                ///< last DC values for MPEG1 
+    int16_t *dc_val_base;
     int16_t *dc_val[3];            ///< used for mpeg4 DC prediction, all 3 arrays must be continuous 
     int16_t dc_cache[4*5];
     int y_dc_scale, c_dc_scale;
     uint8_t *y_dc_scale_table;     ///< qscale -> y_dc_scale table 
     uint8_t *c_dc_scale_table;     ///< qscale -> c_dc_scale table 
     const uint8_t *chroma_qscale_table;  ///< qscale -> chroma_qscale (h263)
+    uint8_t *coded_block_base;
     uint8_t *coded_block;          ///< used for coded block pattern prediction (msmpeg4v3, wmv1)
+    int16_t (*ac_val_base)[16];
     int16_t (*ac_val[3])[16];      ///< used for for mpeg4 AC prediction, all 3 arrays must be continuous 
     int ac_pred;
     uint8_t *prev_pict_types;     ///< previous picture types in bitstream order, used for mb skip 
@@ -857,7 +860,7 @@
 void h263_encode_picture_header(MpegEncContext *s, int picture_number);
 void ff_flv_encode_picture_header(MpegEncContext *s, int picture_number);
 void h263_encode_gob_header(MpegEncContext * s, int mb_line);
-int16_t *h263_pred_motion(MpegEncContext * s, int block, 
+int16_t *h263_pred_motion(MpegEncContext * s, int block, int dir,
                         int *px, int *py);
 void mpeg4_pred_ac(MpegEncContext * s, DCTELEM *block, int n, 
                    int dir);
--- a/msmpeg4.c	Wed Apr 14 13:13:31 2004 +0000
+++ b/msmpeg4.c	Fri Apr 16 01:01:45 2004 +0000
@@ -449,7 +449,7 @@
     int xy, wrap, pred, a, b, c;
 
     xy = s->block_index[n];
-    wrap = s->block_wrap[0];
+    wrap = s->b8_stride;
 
     /* B C
      * A X 
@@ -567,7 +567,7 @@
 
             s->misc_bits += get_bits_diff(s);
 
-            h263_pred_motion(s, 0, &pred_x, &pred_y);
+            h263_pred_motion(s, 0, 0, &pred_x, &pred_y);
             msmpeg4v2_encode_motion(s, motion_x - pred_x);
             msmpeg4v2_encode_motion(s, motion_y - pred_y);
         }else{
@@ -578,7 +578,7 @@
             s->misc_bits += get_bits_diff(s);
 
             /* motion vector */
-            h263_pred_motion(s, 0, &pred_x, &pred_y);
+            h263_pred_motion(s, 0, 0, &pred_x, &pred_y);
             msmpeg4_encode_motion(s, motion_x - pred_x, 
                                   motion_y - pred_y);
         }
@@ -1549,7 +1549,7 @@
         cbp|= cbpy<<2;
         if(s->msmpeg4_version==1 || (cbp&3) != 3) cbp^= 0x3C;
         
-        h263_pred_motion(s, 0, &mx, &my);
+        h263_pred_motion(s, 0, 0, &mx, &my);
         mx= msmpeg4v2_decode_motion(s, mx, 1);
         my= msmpeg4v2_decode_motion(s, my, 1);
         
@@ -1637,7 +1637,7 @@
             s->rl_chroma_table_index = s->rl_table_index;
         }
         set_stat(ST_MV);
-        h263_pred_motion(s, 0, &mx, &my);
+        h263_pred_motion(s, 0, 0, &mx, &my);
         if (msmpeg4_decode_motion(s, &mx, &my) < 0)
             return -1;
         s->mv_dir = MV_DIR_FORWARD;
--- a/rv10.c	Wed Apr 14 13:13:31 2004 +0000
+++ b/rv10.c	Fri Apr 16 01:01:45 2004 +0000
@@ -564,10 +564,6 @@
             return -1;
     }
 
-    if(s->pict_type == B_TYPE){ //FIXME remove after cleaning mottion_val indexing
-        memset(s->current_picture.motion_val[0], 0, sizeof(int16_t)*2*(s->mb_width*2+2)*(s->mb_height*2+2));
-    }
-
 #ifdef DEBUG
     printf("qscale=%d\n", s->qscale);
 #endif
@@ -600,9 +596,9 @@
     s->block_wrap[0]=
     s->block_wrap[1]=
     s->block_wrap[2]=
-    s->block_wrap[3]= s->mb_width*2 + 2;
+    s->block_wrap[3]= s->b8_stride;
     s->block_wrap[4]=
-    s->block_wrap[5]= s->mb_width + 2;
+    s->block_wrap[5]= s->mb_stride;
     ff_init_block_index(s);
     /* decode each macroblock */
 
@@ -677,10 +673,6 @@
             return -1;
     }
     
-    if(s->pict_type == B_TYPE){ //FIXME remove after cleaning mottion_val indexing
-        memset(s->current_picture.motion_val[0], 0, sizeof(int16_t)*2*(s->mb_width*2+2)*(s->mb_height*2+2));
-    }
-
     if(s->mb_y>=s->mb_height){
         MPV_frame_end(s);
     
--- a/wmv2.c	Wed Apr 14 13:13:31 2004 +0000
+++ b/wmv2.c	Fri Apr 16 01:01:45 2004 +0000
@@ -216,7 +216,7 @@
                  wmv2_inter_table[w->cbp_table_index][cbp + 64][0]);
 
         /* motion vector */
-        h263_pred_motion(s, 0, &pred_x, &pred_y);
+        h263_pred_motion(s, 0, 0, &pred_x, &pred_y);
         msmpeg4_encode_motion(s, motion_x - pred_x, 
                               motion_y - pred_y);
     } else {
@@ -504,7 +504,7 @@
     int xy, wrap, diff, type;
     int16_t *A, *B, *C, *mot_val;
 
-    wrap = s->block_wrap[0];
+    wrap = s->b8_stride;
     xy = s->block_index[0];
 
     mot_val = s->current_picture.motion_val[0][xy];