diff options
author | Tero Rintaluoma <teror@google.com> | 2013-06-10 10:23:04 +0300 |
---|---|---|
committer | John Koleszar <jkoleszar@google.com> | 2013-06-10 08:07:55 -0700 |
commit | 86bb6df00515ab2263b41e506cdf55d90d76598f (patch) | |
tree | 778c54d301025db0ecf90cd6d2ee3da4eb1c74ca /vp9/encoder | |
parent | 4852a8023d0e8562fba338f20a064b40304f7858 (diff) | |
download | libvpx-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.c | 29 |
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; |