diff options
author | Kostya Shishkov <kostya.shishkov@gmail.com> | 2008-11-01 20:57:44 +0300 |
---|---|---|
committer | Kostya Shishkov <kostya.shishkov@gmail.com> | 2008-11-01 20:57:44 +0300 |
commit | b2153658171f16dbac19c09ad4198692400093e8 (patch) | |
tree | 07f0d407ed5770c40e2dfe67ec2c36ffcef1f0b4 /libavcodec/rv34.c | |
parent | 34b37f86ec569e5ae1da143919ca04d089c66ae8 (diff) |
Introduce RV3-specific motion vector prediction.
Now B-frames in RV3 look almost correct.
Originally committed as revision 15764 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavcodec/rv34.c')
-rw-r--r-- | libavcodec/rv34.c | 54 |
1 files changed, 53 insertions, 1 deletions
diff --git a/libavcodec/rv34.c b/libavcodec/rv34.c index 3baa471140..e21d224428 100644 --- a/libavcodec/rv34.c +++ b/libavcodec/rv34.c @@ -556,6 +556,55 @@ static void rv34_pred_mv_b(RV34DecContext *r, int block_type, int dir) fill_rectangle(cur_pic->motion_val[!dir][mv_pos], 2, 2, s->b8_stride, 0, 4); } +/** + * motion vector prediction - RV3 version + */ +static void rv34_pred_mv_rv3(RV34DecContext *r, int block_type, int dir) +{ + MpegEncContext *s = &r->s; + int mv_pos = s->mb_x * 2 + s->mb_y * 2 * s->b8_stride; + int A[2] = {0}, B[2], C[2]; + int i, j; + int mx, my; + int avail_index = avail_indexes[0]; + + if(r->avail_cache[avail_index - 1]){ + A[0] = s->current_picture_ptr->motion_val[0][mv_pos-1][0]; + A[1] = s->current_picture_ptr->motion_val[0][mv_pos-1][1]; + } + if(r->avail_cache[avail_index - 4]){ + B[0] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride][0]; + B[1] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride][1]; + }else{ + B[0] = A[0]; + B[1] = A[1]; + } + if(!r->avail_cache[avail_index - 4 + 2]){ + if(r->avail_cache[avail_index - 4] && (r->avail_cache[avail_index - 1])){ + C[0] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride-1][0]; + C[1] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride-1][1]; + }else{ + C[0] = A[0]; + C[1] = A[1]; + } + }else{ + C[0] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride+2][0]; + C[1] = s->current_picture_ptr->motion_val[0][mv_pos-s->b8_stride+2][1]; + } + mx = mid_pred(A[0], B[0], C[0]); + my = mid_pred(A[1], B[1], C[1]); + mx += r->dmv[0][0]; + my += r->dmv[0][1]; + for(j = 0; j < 2; j++){ + for(i = 0; i < 2; i++){ + s->current_picture_ptr->motion_val[0][mv_pos + i + j*s->b8_stride][0] = mx; + s->current_picture_ptr->motion_val[0][mv_pos + i + j*s->b8_stride][1] = my; + } + } + if(block_type == RV34_MB_B_BACKWARD || block_type == RV34_MB_B_FORWARD) + fill_rectangle(s->current_picture_ptr->motion_val[!dir][mv_pos], 2, 2, s->b8_stride, 0, 4); +} + static const int chroma_coeffs[3] = { 0, 3, 5 }; /** @@ -741,7 +790,10 @@ static int rv34_decode_mv(RV34DecContext *r, int block_type) case RV34_MB_B_BACKWARD: r->dmv[1][0] = r->dmv[0][0]; r->dmv[1][1] = r->dmv[0][1]; - rv34_pred_mv_b (r, block_type, block_type == RV34_MB_B_BACKWARD); + if(r->rv30) + rv34_pred_mv_rv3(r, block_type, block_type == RV34_MB_B_BACKWARD); + else + rv34_pred_mv_b (r, block_type, block_type == RV34_MB_B_BACKWARD); rv34_mc_1mv (r, block_type, 0, 0, 0, 2, 2, block_type == RV34_MB_B_BACKWARD); break; case RV34_MB_P_16x8: |