From: Jingning Han Date: Sat, 5 Sep 2015 01:16:39 +0000 (-0700) Subject: Exercise internal frame resizing X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=fb27ffbb069034a9f291a1337b285acb68226581;p=libvpx Exercise internal frame resizing This commit enables the encoder to exercise internal frame resizing and to use scaled reference frame for sub8x8 block motion compensated prediction. Change-Id: I42703da4a4b075c6aefe9a9f687374af65c3c73f --- diff --git a/configure b/configure index e9d0b8bb0..369431877 100755 --- a/configure +++ b/configure @@ -252,6 +252,7 @@ EXPERIMENT_LIST=" spatial_svc fp_mb_stats full_buffer_test + internal_resize emulate_hardware " CONFIG_LIST=" diff --git a/vp9/common/vp9_reconinter.c b/vp9/common/vp9_reconinter.c index 11eaf2e2d..e5d548b7a 100644 --- a/vp9/common/vp9_reconinter.c +++ b/vp9/common/vp9_reconinter.c @@ -168,9 +168,9 @@ MV average_split_mvs(const struct macroblockd_plane *pd, } void build_inter_predictors(MACROBLOCKD *xd, int plane, int block, - int bw, int bh, - int x, int y, int w, int h, - int mi_x, int mi_y) { + int bw, int bh, + int x, int y, int w, int h, + int mi_x, int mi_y) { struct macroblockd_plane *const pd = &xd->plane[plane]; const MODE_INFO *mi = xd->mi[0]; const int is_compound = has_second_ref(&mi->mbmi); @@ -201,7 +201,20 @@ void build_inter_predictors(MACROBLOCKD *xd, int plane, int block, const int is_scaled = vp9_is_scaled(sf); if (is_scaled) { - pre = pre_buf->buf + scaled_buffer_offset(x, y, pre_buf->stride, sf); + // Co-ordinate of containing block to pixel precision. + int x_start = (-xd->mb_to_left_edge >> (3 + pd->subsampling_x)); + int y_start = (-xd->mb_to_top_edge >> (3 + pd->subsampling_y)); + + if (plane == 0) + pre_buf->buf = xd->block_refs[ref]->buf->y_buffer; + else if (plane == 1) + pre_buf->buf = xd->block_refs[ref]->buf->u_buffer; + else + pre_buf->buf = xd->block_refs[ref]->buf->v_buffer; + + pre_buf->buf += scaled_buffer_offset(x_start + x, y_start + y, + pre_buf->stride, sf); + pre = pre_buf->buf; scaled_mv = vp9_scale_mv(&mv_q4, mi_x + x, mi_y + y, sf); xs = sf->x_step_q4; ys = sf->y_step_q4; diff --git a/vp9/decoder/vp9_decodeframe.c b/vp9/decoder/vp9_decodeframe.c index 8ad9e0656..38cd9529a 100644 --- a/vp9/decoder/vp9_decodeframe.c +++ b/vp9/decoder/vp9_decodeframe.c @@ -775,11 +775,11 @@ static void decode_block(VP9Decoder *const pbi, MACROBLOCKD *const xd, if (!less8x8 && eobtotal == 0) mbmi->skip = 1; // skip loopfilter } - } #if CONFIG_INTERNAL_STATS pbi->sub8x8_inter += less8x8; #endif + } xd->corrupted |= vp9_reader_has_error(r); } @@ -2061,6 +2061,7 @@ void vp9_decode_frame(VP9Decoder *pbi, if (pbi->frame_parallel_decode && cm->frame_parallel_decoding_mode) { VP9Worker *const worker = pbi->frame_worker_owner; FrameWorkerData *const frame_worker_data = worker->data1; + if (cm->refresh_frame_context) { context_updated = 1; cm->frame_contexts[cm->frame_context_idx] = *cm->fc; diff --git a/vp9/encoder/vp9_encoder.c b/vp9/encoder/vp9_encoder.c index 6d4124052..a9dc13a5c 100644 --- a/vp9/encoder/vp9_encoder.c +++ b/vp9/encoder/vp9_encoder.c @@ -3071,6 +3071,17 @@ static void set_frame_size(VP9_COMP *cpi) { VP9EncoderConfig *const oxcf = &cpi->oxcf; MACROBLOCKD *const xd = &cpi->td.mb.e_mbd; +#if CONFIG_INTERNAL_RESIZE + if (oxcf->pass == 2 && oxcf->resize_mode == RESIZE_DYNAMIC) { + if ((cm->current_video_frame % 5) == 2) { + cpi->resize_pending = 1; + cpi->rc.frame_size_selector = (cm->current_video_frame / 5) & 0x01; + } else { + cpi->resize_pending = 0; + } + } +#endif + if (oxcf->pass == 2 && oxcf->rc_mode == VPX_VBR && ((oxcf->resize_mode == RESIZE_FIXED && cm->current_video_frame == 0) || @@ -3083,6 +3094,11 @@ static void set_frame_size(VP9_COMP *cpi) { oxcf->scaled_frame_height); } +#if CONFIG_INTERNAL_RESIZE + fprintf(stderr, "%d %d\n", oxcf->scaled_frame_width, + oxcf->scaled_frame_height); +#endif + if (oxcf->pass == 0 && oxcf->rc_mode == VPX_CBR && !cpi->use_svc && diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c index 162d4de5f..4264e6f2b 100644 --- a/vp9/encoder/vp9_rdopt.c +++ b/vp9/encoder/vp9_rdopt.c @@ -3803,6 +3803,13 @@ void vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi, int64_t total_sse = INT_MAX; int early_term = 0; + struct buf_2d backup_yv12[2][MAX_MB_PLANE]; + const YV12_BUFFER_CONFIG *scaled_ref_frame[2] = { + vp9_get_scaled_ref_frame(cpi, vp9_ref_order[ref_index].ref_frame[0]), + vp9_get_scaled_ref_frame(cpi, vp9_ref_order[ref_index].ref_frame[1]) + }; + int ref; + ref_frame = vp9_ref_order[ref_index].ref_frame[0]; second_ref_frame = vp9_ref_order[ref_index].ref_frame[1]; @@ -3858,16 +3865,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) @@ -3946,6 +3943,19 @@ void vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi, int pred_exists = 0; int uv_skippable; + for (ref = 0; ref < 2; ++ref) { + 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]; @@ -4079,8 +4089,17 @@ void vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi, BLOCK_8X8); memset(x->skip_txfm, 0, 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]) { + // 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]; + } + } continue; + } rate2 += rate_uv; distortion2 += distortion_uv; @@ -4089,6 +4108,15 @@ void vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi, } } + 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) rate2 += compmode_cost; diff --git a/vp9/encoder/vp9_speed_features.c b/vp9/encoder/vp9_speed_features.c index 6c6c4ed30..7d548d17e 100644 --- a/vp9/encoder/vp9_speed_features.c +++ b/vp9/encoder/vp9_speed_features.c @@ -48,8 +48,9 @@ static void set_good_speed_feature_framesize_dependent(VP9_COMP *cpi, if (speed >= 1) { if (MIN(cm->width, cm->height) >= 720) { - sf->disable_split_mask = cm->show_frame ? DISABLE_ALL_SPLIT - : DISABLE_ALL_INTER_SPLIT; +// sf->disable_split_mask = cm->show_frame ? DISABLE_ALL_SPLIT +// : DISABLE_ALL_INTER_SPLIT; +// sf->disable_split_mask = DISABLE_COMPOUND_SPLIT; sf->partition_search_breakout_dist_thr = (1 << 23); } else { sf->disable_split_mask = DISABLE_COMPOUND_SPLIT;