changeset 6693:6f13852a9161 libavcodec

Skip blocks in B-frames reuse motion vectors from next reference frame. So if referenced blocks is 16x8, 8x16 or 8x8 partitions, skip block will have them too.
author kostya
date Sat, 26 Apr 2008 13:09:36 +0000
parents 25413354a79a
children a2319e5d8bd3
files rv34.c
diffstat 1 files changed, 32 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/rv34.c	Sat Apr 26 13:08:16 2008 +0000
+++ b/rv34.c	Sat Apr 26 13:09:36 2008 +0000
@@ -667,6 +667,22 @@
             r->s.dsp.avg_h264_chroma_pixels_tab);
 }
 
+static void rv34_mc_2mv_skip(RV34DecContext *r)
+{
+    int i, j, k;
+    for(j = 0; j < 2; j++)
+        for(i = 0; i < 2; i++){
+             rv34_mc(r, RV34_MB_P_8x8, i*8, j*8, i+j*r->s.b8_stride, 1, 1, 0, r->rv30,
+                    r->rv30 ? r->s.dsp.put_rv30_tpel_pixels_tab
+                            : r->s.dsp.put_h264_qpel_pixels_tab,
+                    r->s.dsp.put_h264_chroma_pixels_tab);
+             rv34_mc(r, RV34_MB_P_8x8, i*8, j*8, i+j*r->s.b8_stride, 1, 1, 1, r->rv30,
+                    r->rv30 ? r->s.dsp.avg_rv30_tpel_pixels_tab
+                            : r->s.dsp.avg_h264_qpel_pixels_tab,
+                    r->s.dsp.avg_h264_chroma_pixels_tab);
+        }
+}
+
 /** number of motion vectors in each macroblock type */
 static const int num_mvs[RV34_MB_TYPES] = { 0, 0, 1, 4, 1, 1, 0, 0, 2, 2, 2, 1 };
 
@@ -678,7 +694,9 @@
 {
     MpegEncContext *s = &r->s;
     GetBitContext *gb = &s->gb;
-    int i;
+    int i, j, k;
+    int mv_pos = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride;
+    int next_bt;
 
     memset(r->dmv, 0, sizeof(r->dmv));
     for(i = 0; i < num_mvs[block_type]; i++){
@@ -697,9 +715,19 @@
             break;
         }
     case RV34_MB_B_DIRECT:
-        rv34_pred_mv_b  (r, RV34_MB_B_DIRECT, 0);
-        rv34_pred_mv_b  (r, RV34_MB_B_DIRECT, 1);
-        rv34_mc_2mv     (r, RV34_MB_B_DIRECT);
+        //surprisingly, it uses motion scheme from next reference frame
+        next_bt = s->next_picture_ptr->mb_type[s->mb_x + s->mb_y * s->mb_stride];
+        for(j = 0; j < 2; j++)
+            for(i = 0; i < 2; i++)
+                for(k = 0; k < 2; k++){
+                    s->current_picture_ptr->motion_val[0][mv_pos + i + j*s->b8_stride][k] =  (s->next_picture_ptr->motion_val[0][mv_pos + i + j*s->b8_stride][k] + 1) >> 1;
+                    s->current_picture_ptr->motion_val[1][mv_pos + i + j*s->b8_stride][k] = -(s->next_picture_ptr->motion_val[0][mv_pos + i + j*s->b8_stride][k] >> 1);
+                }
+        if(IS_16X16(next_bt)) //we can use whole macroblock MC
+            rv34_mc_2mv(r, block_type);
+        else
+            rv34_mc_2mv_skip(r);
+        fill_rectangle(s->current_picture_ptr->motion_val[0][s->mb_x * 2 + s->mb_y * 2 * s->b8_stride], 2, 2, s->b8_stride, 0, 4);
         break;
     case RV34_MB_P_16x16:
     case RV34_MB_P_MIX16x16: