]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/vc1_pred.c
avformat/dashenc: Remove deprecated min_seg_duration option
[ffmpeg] / libavcodec / vc1_pred.c
index de736ec7750d739bb78681f60cc1fb3659e94df1..f70956e7392952b7161d059f564dbc305dbd91e3 100644 (file)
@@ -178,7 +178,7 @@ static av_always_inline int scaleforsame(VC1Context *v, int i, int n /* MV */,
     brfd      = FFMIN(v->brfd, 3);
     scalesame = ff_vc1_b_field_mvpred_scales[0][brfd];
 
-    n = (n * scalesame >> 8) << hpel;
+    n = (n * scalesame >> 8) * (1 << hpel);
     return n;
 }
 
@@ -191,15 +191,16 @@ static av_always_inline int scaleforopp(VC1Context *v, int n /* MV */,
     n >>= hpel;
     if (v->s.pict_type == AV_PICTURE_TYPE_B && !v->second_field && dir == 1) {
         if (dim)
-            n = scaleforopp_y(v, n, dir) << hpel;
+            n = scaleforopp_y(v, n, dir) * (1 << hpel);
         else
-            n = scaleforopp_x(v, n) << hpel;
+            n = scaleforopp_x(v, n)      * (1 << hpel);
         return n;
     }
     if (v->s.pict_type != AV_PICTURE_TYPE_B)
-        refdist = FFMIN(v->refdist, 3);
+        refdist = v->refdist;
     else
         refdist = dir ? v->brfd : v->frfd;
+    refdist = FFMIN(refdist, 3);
     scaleopp = ff_vc1_field_mvpred_scales[dir ^ v->second_field][0][refdist];
 
     n = (n * scaleopp >> 8) * (1 << hpel);
@@ -262,18 +263,23 @@ void ff_vc1_pred_mv(VC1Context *v, int n, int dmv_x, int dmv_y,
         return;
     }
 
-    C = s->current_picture.motion_val[dir][xy -    1 + v->blocks_off];
-    A = s->current_picture.motion_val[dir][xy - wrap + v->blocks_off];
+    a_valid = !s->first_slice_line || (n == 2 || n == 3);
+    b_valid = a_valid;
+    c_valid = s->mb_x || (n == 1 || n == 3);
     if (mv1) {
         if (v->field_mode && mixedmv_pic)
             off = (s->mb_x == (s->mb_width - 1)) ? -2 : 2;
         else
             off = (s->mb_x == (s->mb_width - 1)) ? -1 : 2;
+        b_valid = b_valid && s->mb_width > 1;
     } else {
         //in 4-MV mode different blocks have different B predictor position
         switch (n) {
         case 0:
-            off = (s->mb_x > 0) ? -1 : 1;
+            if (v->res_rtm_flag)
+                off = s->mb_x ? -1 : 1;
+            else
+                off = s->mb_x ? -1 : 2 * s->mb_width - wrap - 1;
             break;
         case 1:
             off = (s->mb_x == (s->mb_width - 1)) ? -1 : 1;
@@ -284,12 +290,10 @@ void ff_vc1_pred_mv(VC1Context *v, int n, int dmv_x, int dmv_y,
         case 3:
             off = -1;
         }
+        if (v->field_mode && s->mb_width == 1)
+            b_valid = b_valid && c_valid;
     }
-    B = s->current_picture.motion_val[dir][xy - wrap + off + v->blocks_off];
 
-    a_valid = !s->first_slice_line || (n == 2 || n == 3);
-    b_valid = a_valid && (s->mb_width > 1);
-    c_valid = s->mb_x || (n == 1 || n == 3);
     if (v->field_mode) {
         a_valid = a_valid && !is_intra[xy - wrap];
         b_valid = b_valid && !is_intra[xy - wrap + off];
@@ -297,6 +301,7 @@ void ff_vc1_pred_mv(VC1Context *v, int n, int dmv_x, int dmv_y,
     }
 
     if (a_valid) {
+        A = s->current_picture.motion_val[dir][xy - wrap + v->blocks_off];
         a_f = v->mv_f[dir][xy - wrap + v->blocks_off];
         num_oppfield  += a_f;
         num_samefield += 1 - a_f;
@@ -307,6 +312,7 @@ void ff_vc1_pred_mv(VC1Context *v, int n, int dmv_x, int dmv_y,
         a_f = 0;
     }
     if (b_valid) {
+        B = s->current_picture.motion_val[dir][xy - wrap + off + v->blocks_off];
         b_f = v->mv_f[dir][xy - wrap + off + v->blocks_off];
         num_oppfield  += b_f;
         num_samefield += 1 - b_f;
@@ -317,6 +323,7 @@ void ff_vc1_pred_mv(VC1Context *v, int n, int dmv_x, int dmv_y,
         b_f = 0;
     }
     if (c_valid) {
+        C = s->current_picture.motion_val[dir][xy - 1 + v->blocks_off];
         c_f = v->mv_f[dir][xy - 1 + v->blocks_off];
         num_oppfield  += c_f;
         num_samefield += 1 - c_f;