Mercurial > libavcodec.hg
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: