ref: 2f52decd22ca02187ccc9f5d88bd4f5bc921b47d
parent: 94bb09cab8a31cb28c265d509b24353c01263c9f
author: Jingning Han <jingning@google.com>
date: Fri Jan 10 06:51:20 EST 2014
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
--- a/vp9/encoder/vp9_block.h
+++ b/vp9/encoder/vp9_block.h
@@ -116,6 +116,7 @@
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];
--- 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 @@
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 @@
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 @@
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));
--- /dev/null
+++ b/vp9/encoder/vp9_pickmode.c
@@ -1,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 <stdio.h>
+#include <math.h>
+#include <limits.h>
+#include <assert.h>
+
+#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;
+}
--- /dev/null
+++ b/vp9/encoder/vp9_pickmode.h
@@ -1,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);
--- 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 @@
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 @@
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 @@
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 @@
}
}
+ 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 @@
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 @@
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 @@
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) {
--- 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);
@@ -35,6 +45,8 @@
int_mv frame_nearest_mv[MAX_REF_FRAMES],
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,
--- a/vp9/vp9cx.mk
+++ b/vp9/vp9cx.mk
@@ -43,6 +43,7 @@
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_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
--
⑨