aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKostya Shishkov2008-04-26 13:09:36 +0000
committerKostya Shishkov2008-04-26 13:09:36 +0000
commit86c90cc7a67497f145117c9ae5e4e81279540cce (patch)
tree9e93161c3218eb011f359b3183f56dce3489449b
parentec39f7d8558af7d22c455eccb9ac32539d0accdd (diff)
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. Originally committed as revision 12987 to svn://svn.ffmpeg.org/ffmpeg/trunk
-rw-r--r--libavcodec/rv34.c36
1 files changed, 32 insertions, 4 deletions
diff --git a/libavcodec/rv34.c b/libavcodec/rv34.c
index 7749637dc1..68aadedc43 100644
--- a/libavcodec/rv34.c
+++ b/libavcodec/rv34.c
@@ -667,6 +667,22 @@ static void rv34_mc_2mv(RV34DecContext *r, const int block_type)
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 @@ static int rv34_decode_mv(RV34DecContext *r, int block_type)
{
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 @@ static int rv34_decode_mv(RV34DecContext *r, int block_type)
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: