| Index: source/libvpx/vp9/encoder/vp9_rdopt.c
|
| diff --git a/source/libvpx/vp9/encoder/vp9_rdopt.c b/source/libvpx/vp9/encoder/vp9_rdopt.c
|
| index 038d1e11e301bc91a0e4f993b6c202ee73b4ff17..3c84a7753789930ea5f210441f8672cc70750a33 100644
|
| --- a/source/libvpx/vp9/encoder/vp9_rdopt.c
|
| +++ b/source/libvpx/vp9/encoder/vp9_rdopt.c
|
| @@ -14,6 +14,7 @@
|
| #include "./vp9_rtcd.h"
|
| #include "./vpx_dsp_rtcd.h"
|
|
|
| +#include "vpx_dsp/vpx_dsp_common.h"
|
| #include "vpx_mem/vpx_mem.h"
|
| #include "vpx_ports/mem.h"
|
| #include "vpx_ports/system_state.h"
|
| @@ -3785,6 +3786,7 @@ void vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi,
|
| int this_skip2 = 0;
|
| int64_t total_sse = INT_MAX;
|
| int early_term = 0;
|
| + struct buf_2d backup_yv12[2][MAX_MB_PLANE];
|
|
|
| ref_frame = vp9_ref_order[ref_index].ref_frame[0];
|
| second_ref_frame = vp9_ref_order[ref_index].ref_frame[1];
|
| @@ -3842,16 +3844,6 @@ void vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi,
|
| continue;
|
| }
|
|
|
| - // TODO(jingning, jkoleszar): scaling reference frame not supported for
|
| - // sub8x8 blocks.
|
| - if (ref_frame > INTRA_FRAME &&
|
| - vp9_is_scaled(&cm->frame_refs[ref_frame - 1].sf))
|
| - continue;
|
| -
|
| - if (second_ref_frame > INTRA_FRAME &&
|
| - vp9_is_scaled(&cm->frame_refs[second_ref_frame - 1].sf))
|
| - continue;
|
| -
|
| if (comp_pred)
|
| mode_excluded = cm->reference_mode == SINGLE_REFERENCE;
|
| else if (ref_frame != INTRA_FRAME)
|
| @@ -3930,6 +3922,25 @@ void vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi,
|
| int pred_exists = 0;
|
| int uv_skippable;
|
|
|
| + YV12_BUFFER_CONFIG *scaled_ref_frame[2] = {NULL, NULL};
|
| + int ref;
|
| +
|
| + for (ref = 0; ref < 2; ++ref) {
|
| + scaled_ref_frame[ref] = mbmi->ref_frame[ref] > INTRA_FRAME ?
|
| + vp9_get_scaled_ref_frame(cpi, mbmi->ref_frame[ref]) : NULL;
|
| +
|
| + if (scaled_ref_frame[ref]) {
|
| + int i;
|
| + // Swap out the reference frame for a version that's been scaled to
|
| + // match the resolution of the current frame, allowing the existing
|
| + // motion search code to be used without additional modifications.
|
| + for (i = 0; i < MAX_MB_PLANE; i++)
|
| + backup_yv12[ref][i] = xd->plane[i].pre[ref];
|
| + vp9_setup_pre_planes(xd, ref, scaled_ref_frame[ref], mi_row, mi_col,
|
| + NULL);
|
| + }
|
| + }
|
| +
|
| this_rd_thresh = (ref_frame == LAST_FRAME) ?
|
| rd_opt->threshes[segment_id][bsize][THR_LAST] :
|
| rd_opt->threshes[segment_id][bsize][THR_ALTR];
|
| @@ -4063,14 +4074,31 @@ void vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi,
|
| BLOCK_8X8);
|
| memset(x->skip_txfm, SKIP_TXFM_NONE, sizeof(x->skip_txfm));
|
| if (!super_block_uvrd(cpi, x, &rate_uv, &distortion_uv, &uv_skippable,
|
| - &uv_sse, BLOCK_8X8, tmp_best_rdu))
|
| + &uv_sse, BLOCK_8X8, tmp_best_rdu)) {
|
| + for (ref = 0; ref < 2; ++ref) {
|
| + if (scaled_ref_frame[ref]) {
|
| + int i;
|
| + for (i = 0; i < MAX_MB_PLANE; ++i)
|
| + xd->plane[i].pre[ref] = backup_yv12[ref][i];
|
| + }
|
| + }
|
| continue;
|
| + }
|
|
|
| rate2 += rate_uv;
|
| distortion2 += distortion_uv;
|
| skippable = skippable && uv_skippable;
|
| total_sse += uv_sse;
|
| }
|
| +
|
| + for (ref = 0; ref < 2; ++ref) {
|
| + if (scaled_ref_frame[ref]) {
|
| + // Restore the prediction frame pointers to their unscaled versions.
|
| + int i;
|
| + for (i = 0; i < MAX_MB_PLANE; ++i)
|
| + xd->plane[i].pre[ref] = backup_yv12[ref][i];
|
| + }
|
| + }
|
| }
|
|
|
| if (cm->reference_mode == REFERENCE_MODE_SELECT)
|
|
|