From e5ec68699e418b5c6044195fb998ee5287f2bb6f Mon Sep 17 00:00:00 2001 From: Kostya Shishkov Date: Wed, 10 Aug 2011 11:26:24 +0200 Subject: [PATCH] RV3/4: calculate B-frame motion weights once per frame Signed-off-by: Ronald S. Bultje --- libavcodec/rv34.c | 17 ++++++++++++----- libavcodec/rv34.h | 1 + 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/libavcodec/rv34.c b/libavcodec/rv34.c index f8192a8..58e4552 100644 --- a/libavcodec/rv34.c +++ b/libavcodec/rv34.c @@ -568,12 +568,8 @@ static void rv34_pred_mv(RV34DecContext *r, int block_type, int subblock_no, int */ static int calc_add_mv(RV34DecContext *r, int dir, int val) { - int refdist = GET_PTS_DIFF(r->next_pts, r->last_pts); - int dist = dir ? -GET_PTS_DIFF(r->next_pts, r->cur_pts) : GET_PTS_DIFF(r->cur_pts, r->last_pts); - int mul; + int mul = dir ? -r->weight2 : r->weight1; - if(!refdist) return 0; - mul = (dist << 14) / refdist; return (val * mul + 0x2000) >> 14; } @@ -1273,6 +1269,17 @@ static int rv34_decode_slice(RV34DecContext *r, int end, const uint8_t* buf, int if(s->pict_type != AV_PICTURE_TYPE_B){ r->last_pts = r->next_pts; r->next_pts = r->cur_pts; + }else{ + int refdist = GET_PTS_DIFF(r->next_pts, r->last_pts); + int dist0 = GET_PTS_DIFF(r->cur_pts, r->last_pts); + int dist1 = GET_PTS_DIFF(r->next_pts, r->cur_pts); + + if(!refdist){ + r->weight1 = r->weight2 = 8192; + }else{ + r->weight1 = (dist0 << 14) / refdist; + r->weight2 = (dist1 << 14) / refdist; + } } s->mb_x = s->mb_y = 0; } diff --git a/libavcodec/rv34.h b/libavcodec/rv34.h index 811afb4..ef19813 100644 --- a/libavcodec/rv34.h +++ b/libavcodec/rv34.h @@ -107,6 +107,7 @@ typedef struct RV34DecContext{ int rpr; ///< one field size in RV30 slice header int cur_pts, last_pts, next_pts; + int weight1, weight2; ///< B frame distance fractions (0.14) used in motion compensation uint16_t *cbp_luma; ///< CBP values for luma subblocks uint8_t *cbp_chroma; ///< CBP values for chroma subblocks -- 2.7.4