From 2f52decd22ca02187ccc9f5d88bd4f5bc921b47d Mon Sep 17 00:00:00 2001 From: Jingning Han Date: Fri, 10 Jan 2014 11:51:20 -0800 Subject: [PATCH] Inter-frame non-RD mode decision This commit setups a test framework for real-time coding. It enables a light motion search for non-RD mode decision purpose. Change-Id: I8bec656331539e963c2b685a70e43e0ae32a6e9d --- vp9/encoder/vp9_block.h | 1 + vp9/encoder/vp9_encodeframe.c | 159 +++++++++++++++++++++++++++++ vp9/encoder/vp9_pickmode.c | 230 ++++++++++++++++++++++++++++++++++++++++++ vp9/encoder/vp9_pickmode.h | 19 ++++ vp9/encoder/vp9_rdopt.c | 31 +++--- vp9/encoder/vp9_rdopt.h | 12 +++ vp9/vp9cx.mk | 2 + 7 files changed, 439 insertions(+), 15 deletions(-) create mode 100644 vp9/encoder/vp9_pickmode.c create mode 100644 vp9/encoder/vp9_pickmode.h diff --git a/vp9/encoder/vp9_block.h b/vp9/encoder/vp9_block.h index c011948..c1b9581 100644 --- a/vp9/encoder/vp9_block.h +++ b/vp9/encoder/vp9_block.h @@ -116,6 +116,7 @@ struct macroblock { unsigned int source_variance; unsigned int pred_sse[MAX_REF_FRAMES]; int pred_mv_sad[MAX_REF_FRAMES]; + int mode_sad[MAX_REF_FRAMES][INTER_MODES + 1]; int nmvjointcost[MV_JOINTS]; int nmvcosts[2][MV_VALS]; diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c index b0fae65..75ea64a 100644 --- a/vp9/encoder/vp9_encodeframe.c +++ b/vp9/encoder/vp9_encodeframe.c @@ -34,6 +34,7 @@ #include "vp9/encoder/vp9_encodemv.h" #include "vp9/encoder/vp9_extend.h" #include "vp9/encoder/vp9_onyx_int.h" +#include "vp9/encoder/vp9_pickmode.h" #include "vp9/encoder/vp9_rdopt.h" #include "vp9/encoder/vp9_segmentation.h" #include "vp9/encoder/vp9_tokenize.h" @@ -1038,6 +1039,132 @@ static int sb_has_motion(const VP9_COMMON *cm, MODE_INFO **prev_mi_8x8) { return 0; } +// TODO(jingning) This currently serves as a test framework for non-RD mode +// decision. To be continued on optimizing the partition type decisions. +static void pick_partition_type(VP9_COMP *cpi, + const TileInfo *const tile, + MODE_INFO **mi_8x8, TOKENEXTRA **tp, + int mi_row, int mi_col, + BLOCK_SIZE bsize, int *rate, int64_t *dist, + int do_recon) { + VP9_COMMON *const cm = &cpi->common; + MACROBLOCK *const x = &cpi->mb; + const int mi_stride = cm->mode_info_stride; + const int num_8x8_subsize = (num_8x8_blocks_wide_lookup[bsize] >> 1); + int i; + PARTITION_TYPE partition = PARTITION_NONE; + BLOCK_SIZE subsize; + BLOCK_SIZE bs_type = mi_8x8[0]->mbmi.sb_type; + int sub_rate[4] = {0}; + int64_t sub_dist[4] = {0}; + int mi_offset; + + if (mi_row >= cm->mi_rows || mi_col >= cm->mi_cols) + return; + + partition = partition_lookup[b_width_log2(bsize)][bs_type]; + subsize = get_subsize(bsize, partition); + + if (bsize < BLOCK_8X8) { + // When ab_index = 0 all sub-blocks are handled, so for ab_index != 0 + // there is nothing to be done. + if (x->ab_index != 0) { + *rate = 0; + *dist = 0; + return; + } + } else { + *(get_sb_partitioning(x, bsize)) = subsize; + } + + switch (partition) { + case PARTITION_NONE: + pick_sb_modes(cpi, tile, mi_row, mi_col, rate, dist, + bsize, get_block_context(x, bsize), INT64_MAX); + break; + case PARTITION_HORZ: + *get_sb_index(x, subsize) = 0; + pick_sb_modes(cpi, tile, mi_row, mi_col, &sub_rate[0], &sub_dist[0], + subsize, get_block_context(x, subsize), INT64_MAX); + if (bsize >= BLOCK_8X8 && mi_row + num_8x8_subsize < cm->mi_rows) { + update_state(cpi, get_block_context(x, subsize), subsize, 0); + encode_superblock(cpi, tp, 0, mi_row, mi_col, subsize); + *get_sb_index(x, subsize) = 1; + pick_sb_modes(cpi, tile, mi_row + num_8x8_subsize, mi_col, + &sub_rate[1], &sub_dist[1], subsize, + get_block_context(x, subsize), INT64_MAX); + } + *rate = sub_rate[0] + sub_rate[1]; + *dist = sub_dist[0] + sub_dist[1]; + break; + case PARTITION_VERT: + *get_sb_index(x, subsize) = 0; + pick_sb_modes(cpi, tile, mi_row, mi_col, &sub_rate[0], &sub_dist[0], + subsize, get_block_context(x, subsize), INT64_MAX); + if (bsize >= BLOCK_8X8 && mi_col + num_8x8_subsize < cm->mi_cols) { + update_state(cpi, get_block_context(x, subsize), subsize, 0); + encode_superblock(cpi, tp, 0, mi_row, mi_col, subsize); + *get_sb_index(x, subsize) = 1; + pick_sb_modes(cpi, tile, mi_row, mi_col + num_8x8_subsize, + &sub_rate[1], &sub_dist[1], subsize, + get_block_context(x, subsize), INT64_MAX); + } + *rate = sub_rate[0] + sub_rate[1]; + *dist = sub_dist[1] + sub_dist[1]; + break; + case PARTITION_SPLIT: + *get_sb_index(x, subsize) = 0; + pick_partition_type(cpi, tile, mi_8x8, tp, mi_row, mi_col, subsize, + &sub_rate[0], &sub_dist[0], 0); + + if ((mi_col + num_8x8_subsize) < cm->mi_cols) { + *get_sb_index(x, subsize) = 1; + pick_partition_type(cpi, tile, mi_8x8 + num_8x8_subsize, tp, + mi_row, mi_col + num_8x8_subsize, subsize, + &sub_rate[1], &sub_dist[1], 0); + } + + if ((mi_row + num_8x8_subsize) < cm->mi_rows) { + *get_sb_index(x, subsize) = 2; + pick_partition_type(cpi, tile, mi_8x8 + num_8x8_subsize * mi_stride, tp, + mi_row + num_8x8_subsize, mi_col, subsize, + &sub_rate[2], &sub_dist[2], 0); + } + + if ((mi_col + num_8x8_subsize) < cm->mi_cols && + (mi_row + num_8x8_subsize) < cm->mi_rows) { + *get_sb_index(x, subsize) = 3; + mi_offset = num_8x8_subsize * mi_stride + num_8x8_subsize; + pick_partition_type(cpi, tile, mi_8x8 + mi_offset, tp, + mi_row + num_8x8_subsize, mi_col + num_8x8_subsize, + subsize, &sub_rate[3], &sub_dist[3], 0); + } + + for (i = 0; i < 4; ++i) { + *rate += sub_rate[i]; + *dist += sub_dist[i]; + } + + break; + default: + assert(0); + } + + if (do_recon) { + int output_enabled = (bsize == BLOCK_64X64); + + // Check the projected output rate for this SB against it's target + // and and if necessary apply a Q delta using segmentation to get + // closer to the target. + if ((cpi->oxcf.aq_mode == COMPLEXITY_AQ) && cm->seg.update_map) { + select_in_frame_q_segment(cpi, mi_row, mi_col, + output_enabled, *rate); + } + + encode_sb(cpi, tile, tp, mi_row, mi_col, output_enabled, bsize); + } +} + static void rd_use_partition(VP9_COMP *cpi, const TileInfo *const tile, MODE_INFO **mi_8x8, @@ -1875,6 +2002,34 @@ static void rd_pick_reference_frame(VP9_COMP *cpi, const TileInfo *const tile, restore_context(cpi, mi_row, mi_col, a, l, sa, sl, BLOCK_64X64); } +static void encode_sb_row_rt(VP9_COMP *cpi, const TileInfo *const tile, + int mi_row, TOKENEXTRA **tp) { + VP9_COMMON *const cm = &cpi->common; + int mi_col; + + cpi->sf.always_this_block_size = BLOCK_8X8; + + // Initialize the left context for the new SB row + vpx_memset(&cpi->left_context, 0, sizeof(cpi->left_context)); + vpx_memset(cpi->left_seg_context, 0, sizeof(cpi->left_seg_context)); + + // Code each SB in the row + for (mi_col = tile->mi_col_start; mi_col < tile->mi_col_end; + mi_col += MI_BLOCK_SIZE) { + int dummy_rate; + int64_t dummy_dist; + const int idx_str = cm->mode_info_stride * mi_row + mi_col; + MODE_INFO **mi_8x8 = cm->mi_grid_visible + idx_str; + + vp9_zero(cpi->mb.pred_mv); + + set_offsets(cpi, tile, mi_row, mi_col, BLOCK_64X64); + set_partitioning(cpi, tile, mi_8x8, mi_row, mi_col); + pick_partition_type(cpi, tile, mi_8x8, tp, mi_row, mi_col, BLOCK_64X64, + &dummy_rate, &dummy_dist, 1); + } +} + static void encode_sb_row(VP9_COMP *cpi, const TileInfo *const tile, int mi_row, TOKENEXTRA **tp) { VP9_COMMON *const cm = &cpi->common; @@ -2101,7 +2256,11 @@ static void encode_frame_internal(VP9_COMP *cpi) { vp9_tile_init(&tile, cm, tile_row, tile_col); for (mi_row = tile.mi_row_start; mi_row < tile.mi_row_end; mi_row += 8) +#if 1 encode_sb_row(cpi, &tile, mi_row, &tp); +#else + encode_sb_row_rt(cpi, &tile, mi_row, &tp); +#endif cpi->tok_count[tile_row][tile_col] = (unsigned int)(tp - tp_old); assert(tp - cpi->tok <= get_token_alloc(cm->mb_rows, cm->mb_cols)); diff --git a/vp9/encoder/vp9_pickmode.c b/vp9/encoder/vp9_pickmode.c new file mode 100644 index 0000000..17d1f59 --- /dev/null +++ b/vp9/encoder/vp9_pickmode.c @@ -0,0 +1,230 @@ +/* + * Copyright (c) 2014 The WebM project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include +#include +#include +#include + +#include "vp9/common/vp9_pragmas.h" +#include "vp9/encoder/vp9_tokenize.h" +#include "vp9/encoder/vp9_treewriter.h" +#include "vp9/encoder/vp9_onyx_int.h" +#include "vp9/common/vp9_entropymode.h" +#include "vp9/common/vp9_reconinter.h" +#include "vp9/common/vp9_reconintra.h" +#include "vp9/common/vp9_quant_common.h" +#include "vp9/encoder/vp9_encodemb.h" +#include "vp9/encoder/vp9_quantize.h" +#include "vp9/encoder/vp9_variance.h" +#include "vp9/encoder/vp9_mcomp.h" +#include "vp9/encoder/vp9_rdopt.h" +#include "vp9/encoder/vp9_ratectrl.h" +#include "vpx_mem/vpx_mem.h" +#include "vp9/common/vp9_systemdependent.h" +#include "vp9/encoder/vp9_encodemv.h" +#include "vp9/common/vp9_seg_common.h" +#include "vp9/common/vp9_pred_common.h" +#include "vp9/common/vp9_entropy.h" +#include "./vp9_rtcd.h" +#include "vp9/common/vp9_mvref_common.h" +#include "vp9/common/vp9_common.h" + +static int full_pixel_motion_search(VP9_COMP *cpi, MACROBLOCK *x, + const TileInfo *const tile, + BLOCK_SIZE bsize, int mi_row, int mi_col, + int_mv *tmp_mv, int *rate_mv) { + MACROBLOCKD *xd = &x->e_mbd; + MB_MODE_INFO *mbmi = &xd->mi_8x8[0]->mbmi; + struct buf_2d backup_yv12[MAX_MB_PLANE] = {{0}}; + int bestsme = INT_MAX; + int further_steps, step_param; + int sadpb = x->sadperbit16; + MV mvp_full; + int ref = mbmi->ref_frame[0]; + int_mv ref_mv = mbmi->ref_mvs[ref][0]; + int i; + + int tmp_col_min = x->mv_col_min; + int tmp_col_max = x->mv_col_max; + int tmp_row_min = x->mv_row_min; + int tmp_row_max = x->mv_row_max; + + int buf_offset; + int stride = xd->plane[0].pre[0].stride; + + YV12_BUFFER_CONFIG *scaled_ref_frame = vp9_get_scaled_ref_frame(cpi, ref); + + if (scaled_ref_frame) { + 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[i] = xd->plane[i].pre[0]; + + setup_pre_planes(xd, 0, scaled_ref_frame, mi_row, mi_col, NULL); + } + + vp9_set_mv_search_range(x, &ref_mv.as_mv); + + // TODO(jingning) exploiting adaptive motion search control in non-RD + // mode decision too. + step_param = 6; + further_steps = (cpi->sf.max_step_search_steps - 1) - step_param; + + for (i = LAST_FRAME; i <= ALTREF_FRAME && cpi->common.show_frame; ++i) { + if ((x->pred_mv_sad[ref] >> 3) > x->pred_mv_sad[i]) { + tmp_mv->as_int = INVALID_MV; + + if (scaled_ref_frame) { + int i; + for (i = 0; i < MAX_MB_PLANE; i++) + xd->plane[i].pre[0] = backup_yv12[i]; + } + return INT_MAX; + } + } + + mvp_full = mbmi->ref_mvs[ref][x->mv_best_ref_index[ref]].as_mv; + + mvp_full.col >>= 3; + mvp_full.row >>= 3; + + bestsme = vp9_full_pixel_diamond(cpi, x, &mvp_full, step_param, + sadpb, further_steps, 1, + &cpi->fn_ptr[bsize], + &ref_mv.as_mv, tmp_mv); + + x->mv_col_min = tmp_col_min; + x->mv_col_max = tmp_col_max; + x->mv_row_min = tmp_row_min; + x->mv_row_max = tmp_row_max; + + if (scaled_ref_frame) { + int i; + for (i = 0; i < MAX_MB_PLANE; i++) + xd->plane[i].pre[0] = backup_yv12[i]; + } + + // TODO(jingning) This step can be merged into full pixel search step in the + // re-designed log-diamond search + buf_offset = tmp_mv->as_mv.row * stride + tmp_mv->as_mv.col; + + // Find sad for current vector. + bestsme = cpi->fn_ptr[bsize].sdf(x->plane[0].src.buf, x->plane[0].src.stride, + xd->plane[0].pre[0].buf + buf_offset, + stride, 0x7fffffff); + + // scale to 1/8 pixel resolution + tmp_mv->as_mv.row = tmp_mv->as_mv.row << 3; + tmp_mv->as_mv.col = tmp_mv->as_mv.col << 3; + + // calculate the bit cost on motion vector + *rate_mv = vp9_mv_bit_cost(&tmp_mv->as_mv, &ref_mv.as_mv, + x->nmvjointcost, x->mvcost, MV_COST_WEIGHT); + + + return bestsme; +} + +// TODO(jingning) placeholder for inter-frame non-RD mode decision. +// this needs various further optimizations. to be continued.. +int64_t vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, + const TileInfo *const tile, + int mi_row, int mi_col, + int *returnrate, + int64_t *returndistortion, + BLOCK_SIZE bsize, + PICK_MODE_CONTEXT *ctx) { + MACROBLOCKD *xd = &x->e_mbd; + MB_MODE_INFO *mbmi = &xd->mi_8x8[0]->mbmi; + const BLOCK_SIZE block_size = get_plane_block_size(bsize, &xd->plane[0]); + MB_PREDICTION_MODE this_mode; + MV_REFERENCE_FRAME ref_frame; + int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES]; + struct buf_2d yv12_mb[4][MAX_MB_PLANE]; + static const int flag_list[4] = { 0, VP9_LAST_FLAG, VP9_GOLD_FLAG, + VP9_ALT_FLAG }; + int64_t best_rd = INT64_MAX; + int64_t this_rd; + + x->skip_encode = cpi->sf.skip_encode_frame && x->q_index < QIDX_SKIP_THRESH; + + x->skip = 0; + if (cpi->active_map_enabled && x->active_ptr[0] == 0) + x->skip = 1; + + // initialize mode decisions + *returnrate = INT_MAX; + vpx_memset(mbmi, 0, sizeof(MB_MODE_INFO)); + mbmi->sb_type = bsize; + mbmi->ref_frame[0] = NONE; + mbmi->ref_frame[1] = NONE; + mbmi->tx_size = MIN(max_txsize_lookup[bsize], + tx_mode_to_biggest_tx_size[cpi->common.tx_mode]); + + for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) { + x->pred_mv_sad[ref_frame] = INT_MAX; + if (cpi->ref_frame_flags & flag_list[ref_frame]) { + vp9_setup_buffer_inter(cpi, x, tile, get_ref_frame_idx(cpi, ref_frame), + ref_frame, block_size, mi_row, mi_col, + frame_mv[NEARESTMV], frame_mv[NEARMV], yv12_mb); + } + frame_mv[NEWMV][ref_frame].as_int = INVALID_MV; + frame_mv[ZEROMV][ref_frame].as_int = 0; + } + + for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) { + int rate_mv = 0; + + if (!(cpi->ref_frame_flags & flag_list[ref_frame])) + continue; + + // Select prediction reference frames. + xd->plane[0].pre[0] = yv12_mb[ref_frame][0]; + + + x->mode_sad[ref_frame][INTER_OFFSET(NEWMV)] = + full_pixel_motion_search(cpi, x, tile, bsize, mi_row, mi_col, + &frame_mv[NEWMV][ref_frame], &rate_mv); + + if (frame_mv[NEWMV][ref_frame].as_int == INVALID_MV) + continue; + + clamp_mv2(&frame_mv[NEARESTMV][ref_frame].as_mv, xd); + clamp_mv2(&frame_mv[NEARMV][ref_frame].as_mv, xd); + + for (this_mode = NEARESTMV; this_mode <= NEWMV; ++this_mode) { + int rate = x->inter_mode_cost[mbmi->mode_context[ref_frame]] + [INTER_OFFSET(this_mode)]; + int64_t dist = x->mode_sad[ref_frame][INTER_OFFSET(this_mode)] * + x->mode_sad[ref_frame][INTER_OFFSET(this_mode)]; + this_rd = RDCOST(x->rdmult, x->rddiv, rate, dist); + + if (this_rd < best_rd) { + best_rd = this_rd; + mbmi->mode = this_mode; + mbmi->ref_frame[0] = ref_frame; + mbmi->mv[0].as_int = frame_mv[this_mode][ref_frame].as_int; + } + } + } + + // TODO(jingning) sub-pixel motion search, if NEWMV is chosen + + // TODO(jingning) intra prediction search, if the best SAD is above a certain + // threshold. + + // store mode decisions + ctx->mic = *xd->mi_8x8[0]; + + return INT64_MAX; +} diff --git a/vp9/encoder/vp9_pickmode.h b/vp9/encoder/vp9_pickmode.h new file mode 100644 index 0000000..32750fa --- /dev/null +++ b/vp9/encoder/vp9_pickmode.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2014 The WebM project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "vp9/encoder/vp9_onyx_int.h" + +int64_t vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, + const struct TileInfo *const tile, + int mi_row, int mi_col, + int *returnrate, + int64_t *returndistortion, + BLOCK_SIZE bsize, + PICK_MODE_CONTEXT *ctx); diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c index 5ba8915..fa6b362 100644 --- a/vp9/encoder/vp9_rdopt.c +++ b/vp9/encoder/vp9_rdopt.c @@ -37,8 +37,6 @@ #include "vp9/common/vp9_mvref_common.h" #include "vp9/common/vp9_common.h" -#define INVALID_MV 0x80008000 - /* Factor to weigh the rate for switchable interp filters */ #define SWITCHABLE_INTERP_RATE_FACTOR 1 @@ -113,14 +111,6 @@ const REF_DEFINITION vp9_ref_order[MAX_REFS] = { static int rd_thresh_block_size_factor[BLOCK_SIZES] = {2, 3, 3, 4, 6, 6, 8, 12, 12, 16, 24, 24, 32}; -#define RD_THRESH_MAX_FACT 64 -#define RD_THRESH_INC 1 -#define RD_THRESH_POW 1.25 -#define RD_MULT_EPB_RATIO 64 - -#define MV_COST_WEIGHT 108 -#define MV_COST_WEIGHT_SUB 120 - static int raster_block_offset(BLOCK_SIZE plane_bsize, int raster_block, int stride) { const int bw = b_width_log2(plane_bsize); @@ -2133,8 +2123,10 @@ static void mv_pred(VP9_COMP *cpi, MACROBLOCK *x, max_mv = MAX(max_mv, MAX(abs(this_mv.as_mv.row), abs(this_mv.as_mv.col)) >> 3); // only need to check zero mv once - if (!this_mv.as_int && zero_seen) + if (!this_mv.as_int && zero_seen) { + x->mode_sad[ref_frame][i] = x->mode_sad[ref_frame][INTER_OFFSET(ZEROMV)]; continue; + } zero_seen = zero_seen || !this_mv.as_int; row_offset = this_mv.as_mv.row >> 3; @@ -2145,6 +2137,9 @@ static void mv_pred(VP9_COMP *cpi, MACROBLOCK *x, this_sad = cpi->fn_ptr[block_size].sdf(src_y_ptr, x->plane[0].src.stride, ref_y_ptr, ref_y_stride, 0x7fffffff); + x->mode_sad[ref_frame][i] = this_sad; + if (this_mv.as_int == 0) + x->mode_sad[ref_frame][INTER_OFFSET(ZEROMV)] = this_sad; // Note if it is the best so far. if (this_sad < best_sad) { @@ -2153,6 +2148,12 @@ static void mv_pred(VP9_COMP *cpi, MACROBLOCK *x, } } + if (!zero_seen) + x->mode_sad[ref_frame][INTER_OFFSET(ZEROMV)] = + cpi->fn_ptr[block_size].sdf(src_y_ptr, x->plane[0].src.stride, + ref_y_buffer, ref_y_stride, + 0x7fffffff); + // Note the index of the mv that worked best in the reference list. x->mv_best_ref_index[ref_frame] = best_index; x->max_mv_context[ref_frame] = max_mv; @@ -2312,7 +2313,7 @@ void vp9_setup_buffer_inter(VP9_COMP *cpi, MACROBLOCK *x, frame_type, block_size); } -static YV12_BUFFER_CONFIG *get_scaled_ref_frame(VP9_COMP *cpi, int ref_frame) { +YV12_BUFFER_CONFIG *vp9_get_scaled_ref_frame(VP9_COMP *cpi, int ref_frame) { YV12_BUFFER_CONFIG *scaled_ref_frame = NULL; int fb = get_ref_frame_idx(cpi, ref_frame); int fb_scale = get_scale_ref_frame_idx(cpi, ref_frame); @@ -2350,7 +2351,7 @@ static void single_motion_search(VP9_COMP *cpi, MACROBLOCK *x, int tmp_row_min = x->mv_row_min; int tmp_row_max = x->mv_row_max; - YV12_BUFFER_CONFIG *scaled_ref_frame = get_scaled_ref_frame(cpi, ref); + YV12_BUFFER_CONFIG *scaled_ref_frame = vp9_get_scaled_ref_frame(cpi, ref); int_mv pred_mv[3]; pred_mv[0] = mbmi->ref_mvs[ref][0]; @@ -2498,8 +2499,8 @@ static void joint_motion_search(VP9_COMP *cpi, MACROBLOCK *x, struct buf_2d scaled_first_yv12 = xd->plane[0].pre[0]; int last_besterr[2] = {INT_MAX, INT_MAX}; YV12_BUFFER_CONFIG *const scaled_ref_frame[2] = { - get_scaled_ref_frame(cpi, mbmi->ref_frame[0]), - get_scaled_ref_frame(cpi, mbmi->ref_frame[1]) + vp9_get_scaled_ref_frame(cpi, mbmi->ref_frame[0]), + vp9_get_scaled_ref_frame(cpi, mbmi->ref_frame[1]) }; for (ref = 0; ref < 2; ++ref) { diff --git a/vp9/encoder/vp9_rdopt.h b/vp9/encoder/vp9_rdopt.h index 4b244a5..696cf6b 100644 --- a/vp9/encoder/vp9_rdopt.h +++ b/vp9/encoder/vp9_rdopt.h @@ -19,6 +19,16 @@ (((128 + ((int64_t)R) * (RM)) >> 8) + (D << DM)) #define QIDX_SKIP_THRESH 115 +#define RD_THRESH_MAX_FACT 64 +#define RD_THRESH_INC 1 +#define RD_THRESH_POW 1.25 +#define RD_MULT_EPB_RATIO 64 + +#define MV_COST_WEIGHT 108 +#define MV_COST_WEIGHT_SUB 120 + +#define INVALID_MV 0x80008000 + struct TileInfo; int vp9_compute_rd_mult(VP9_COMP *cpi, int qindex); @@ -36,6 +46,8 @@ void vp9_setup_buffer_inter(VP9_COMP *cpi, MACROBLOCK *x, int_mv frame_near_mv[MAX_REF_FRAMES], struct buf_2d yv12_mb[4][MAX_MB_PLANE]); +YV12_BUFFER_CONFIG *vp9_get_scaled_ref_frame(VP9_COMP *cpi, int ref_frame); + void vp9_rd_pick_intra_mode_sb(VP9_COMP *cpi, MACROBLOCK *x, int *r, int64_t *d, BLOCK_SIZE bsize, PICK_MODE_CONTEXT *ctx, int64_t best_rd); diff --git a/vp9/vp9cx.mk b/vp9/vp9cx.mk index 0d79346..9ea0f54 100644 --- a/vp9/vp9cx.mk +++ b/vp9/vp9cx.mk @@ -43,6 +43,7 @@ VP9_CX_SRCS-yes += encoder/vp9_psnr.h VP9_CX_SRCS-yes += encoder/vp9_quantize.h VP9_CX_SRCS-yes += encoder/vp9_ratectrl.h VP9_CX_SRCS-yes += encoder/vp9_rdopt.h +VP9_CX_SRCS-yes += encoder/vp9_pickmode.h VP9_CX_SRCS-yes += encoder/vp9_sadmxn.h VP9_CX_SRCS-yes += encoder/vp9_tokenize.h VP9_CX_SRCS-yes += encoder/vp9_treewriter.h @@ -55,6 +56,7 @@ VP9_CX_SRCS-yes += encoder/vp9_psnr.c VP9_CX_SRCS-yes += encoder/vp9_quantize.c VP9_CX_SRCS-yes += encoder/vp9_ratectrl.c VP9_CX_SRCS-yes += encoder/vp9_rdopt.c +VP9_CX_SRCS-yes += encoder/vp9_pickmode.c VP9_CX_SRCS-yes += encoder/vp9_sad_c.c VP9_CX_SRCS-yes += encoder/vp9_segmentation.c VP9_CX_SRCS-yes += encoder/vp9_segmentation.h -- 2.7.4