diff options
author | Kostya Shishkov <kostya.shishkov@gmail.com> | 2008-04-26 13:09:36 +0000 |
---|---|---|
committer | Kostya Shishkov <kostya.shishkov@gmail.com> | 2008-04-26 13:09:36 +0000 |
commit | 86c90cc7a67497f145117c9ae5e4e81279540cce (patch) | |
tree | 9e93161c3218eb011f359b3183f56dce3489449b /libavcodec/rv34.c | |
parent | ec39f7d8558af7d22c455eccb9ac32539d0accdd (diff) | |
download | ffmpeg-streaming-86c90cc7a67497f145117c9ae5e4e81279540cce.zip ffmpeg-streaming-86c90cc7a67497f145117c9ae5e4e81279540cce.tar.gz |
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
Diffstat (limited to 'libavcodec/rv34.c')
-rw-r--r-- | libavcodec/rv34.c | 36 |
1 files changed, 32 insertions, 4 deletions
diff --git a/libavcodec/rv34.c b/libavcodec/rv34.c index 7749637..68aaded 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: |