summaryrefslogtreecommitdiff
path: root/vp9/encoder
diff options
context:
space:
mode:
authorTero Rintaluoma <teror@google.com>2013-06-10 10:23:04 +0300
committerJohn Koleszar <jkoleszar@google.com>2013-06-10 08:07:55 -0700
commit86bb6df00515ab2263b41e506cdf55d90d76598f (patch)
tree778c54d301025db0ecf90cd6d2ee3da4eb1c74ca /vp9/encoder
parent4852a8023d0e8562fba338f20a064b40304f7858 (diff)
downloadlibvpx-86bb6df00515ab2263b41e506cdf55d90d76598f.tar
libvpx-86bb6df00515ab2263b41e506cdf55d90d76598f.tar.gz
libvpx-86bb6df00515ab2263b41e506cdf55d90d76598f.tar.bz2
libvpx-86bb6df00515ab2263b41e506cdf55d90d76598f.zip
Fixed point reference picture scaling
Fixed point scaling factors are calculated once for each reference frame by using integer division. Otherwise fixed point scaling routines are used in all scaling calculations. This makes it possible to calculate fixed point scaling factors on device driver software and pass them to hardware and thus avoid division on hardware. TODO: - Missing check for maximum frame dimensions (currently scaling uses 14 bits) - Missing check for maximum scaling ratio (upscaling 16:1, downscaling 2:1) Problems: - Straightforward fixed point implementation can cause error +-1 compared to integer division (i.e. in x_step_q4). Should only be an issue for frames larger than 16k. Change-Id: I3cf4dabd610a4dc18da3bdb31ae244ebaf5d579c
Diffstat (limited to 'vp9/encoder')
-rw-r--r--vp9/encoder/vp9_rdopt.c29
1 files changed, 15 insertions, 14 deletions
diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c
index 6150746e2..06f571aaa 100644
--- a/vp9/encoder/vp9_rdopt.c
+++ b/vp9/encoder/vp9_rdopt.c
@@ -1755,12 +1755,13 @@ static void setup_buffer_inter(VP9_COMP *cpi, MACROBLOCK *x,
// set up scaling factors
scale[frame_type] = cpi->common.active_ref_scale[frame_type - 1];
+
scale[frame_type].x_offset_q4 =
- (mi_col * MI_SIZE * scale[frame_type].x_num /
- scale[frame_type].x_den) & 0xf;
+ ROUND_POWER_OF_TWO(mi_col * MI_SIZE * scale[frame_type].x_scale_fp,
+ VP9_REF_SCALE_SHIFT) & 0xf;
scale[frame_type].y_offset_q4 =
- (mi_row * MI_SIZE * scale[frame_type].y_num /
- scale[frame_type].y_den) & 0xf;
+ ROUND_POWER_OF_TWO(mi_row * MI_SIZE * scale[frame_type].y_scale_fp,
+ VP9_REF_SCALE_SHIFT) & 0xf;
// TODO(jkoleszar): Is the UV buffer ever used here? If so, need to make this
// use the UV scaling factors.
@@ -1783,8 +1784,8 @@ static void setup_buffer_inter(VP9_COMP *cpi, MACROBLOCK *x,
// Further refinement that is encode side only to test the top few candidates
// in full and choose the best as the centre point for subsequent searches.
// The current implementation doesn't support scaling.
- if (scale[frame_type].x_num == scale[frame_type].x_den &&
- scale[frame_type].y_num == scale[frame_type].y_den)
+ if (scale[frame_type].x_scale_fp == (1 << VP9_REF_SCALE_SHIFT) &&
+ scale[frame_type].y_scale_fp == (1 << VP9_REF_SCALE_SHIFT))
mv_pred(cpi, x, yv12_mb[frame_type][0].buf, yv12->y_stride,
frame_type, block_size);
}
@@ -2612,18 +2613,18 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
// TODO(jingning, jkoleszar): scaling reference frame not supported for
// SPLITMV.
if (mbmi->ref_frame[0] > 0 &&
- (scale_factor[mbmi->ref_frame[0]].x_num !=
- scale_factor[mbmi->ref_frame[0]].x_den ||
- scale_factor[mbmi->ref_frame[0]].y_num !=
- scale_factor[mbmi->ref_frame[0]].y_den) &&
+ (scale_factor[mbmi->ref_frame[0]].x_scale_fp !=
+ (1 << VP9_REF_SCALE_SHIFT) ||
+ scale_factor[mbmi->ref_frame[0]].y_scale_fp !=
+ (1 << VP9_REF_SCALE_SHIFT)) &&
this_mode == SPLITMV)
continue;
if (mbmi->ref_frame[1] > 0 &&
- (scale_factor[mbmi->ref_frame[1]].x_num !=
- scale_factor[mbmi->ref_frame[1]].x_den ||
- scale_factor[mbmi->ref_frame[1]].y_num !=
- scale_factor[mbmi->ref_frame[1]].y_den) &&
+ (scale_factor[mbmi->ref_frame[1]].x_scale_fp !=
+ (1 << VP9_REF_SCALE_SHIFT) ||
+ scale_factor[mbmi->ref_frame[1]].y_scale_fp !=
+ (1 << VP9_REF_SCALE_SHIFT)) &&
this_mode == SPLITMV)
continue;