Commit 18b6e9a3 authored by Yaowu Xu's avatar Yaowu Xu

Merge branch 'masterbase' into nextgenv2

Conflicts:
	vp10/encoder/rdopt.c

Change-Id: If720e7f9810378d24bf9fd51a95fd29c3bc5d774
parents 13efa8a0 34d12d11
...@@ -94,13 +94,53 @@ unsigned int ScaleForFrameNumber(unsigned int frame, unsigned int val) { ...@@ -94,13 +94,53 @@ unsigned int ScaleForFrameNumber(unsigned int frame, unsigned int val) {
if (frame < 10) if (frame < 10)
return val; return val;
if (frame < 20) if (frame < 20)
return val / 2; return val * 3 / 4;
if (frame < 30) if (frame < 30)
return val * 2 / 3; return val / 2;
if (frame < 40) if (frame < 40)
return val / 4; return val;
if (frame < 50) if (frame < 50)
return val * 7 / 8; return val * 3 / 4;
if (frame < 60)
return val / 2;
if (frame < 70)
return val * 3 / 4;
if (frame < 80)
return val;
if (frame < 90)
return val * 3 / 4;
if (frame < 100)
return val / 2;
if (frame < 110)
return val * 3 / 4;
if (frame < 120)
return val;
if (frame < 130)
return val * 3 / 4;
if (frame < 140)
return val / 2;
if (frame < 150)
return val * 3 / 4;
if (frame < 160)
return val;
if (frame < 170)
return val / 2;
if (frame < 180)
return val * 3 / 4;
if (frame < 190)
return val;
if (frame < 200)
return val * 3 / 4;
if (frame < 210)
return val / 2;
if (frame < 220)
return val * 3 / 4;
if (frame < 230)
return val;
if (frame < 240)
return val / 2;
if (frame < 250)
return val * 3 / 4;
return val; return val;
} }
...@@ -108,7 +148,7 @@ class ResizingVideoSource : public ::libvpx_test::DummyVideoSource { ...@@ -108,7 +148,7 @@ class ResizingVideoSource : public ::libvpx_test::DummyVideoSource {
public: public:
ResizingVideoSource() { ResizingVideoSource() {
SetSize(kInitialWidth, kInitialHeight); SetSize(kInitialWidth, kInitialHeight);
limit_ = 60; limit_ = 300;
} }
virtual ~ResizingVideoSource() {} virtual ~ResizingVideoSource() {}
...@@ -347,6 +387,8 @@ class ResizeRealtimeTest : public ::libvpx_test::EncoderTest, ...@@ -347,6 +387,8 @@ class ResizeRealtimeTest : public ::libvpx_test::EncoderTest,
TEST_P(ResizeRealtimeTest, TestExternalResizeWorks) { TEST_P(ResizeRealtimeTest, TestExternalResizeWorks) {
ResizingVideoSource video; ResizingVideoSource video;
DefaultConfig(); DefaultConfig();
// Disable internal resize for this test.
cfg_.rc_resize_allowed = 0;
change_bitrate_ = false; change_bitrate_ = false;
ASSERT_NO_FATAL_FAILURE(RunLoop(&video)); ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#ifndef VP8_COMMON_THREADING_H_ #ifndef VP8_COMMON_THREADING_H_
#define VP8_COMMON_THREADING_H_ #define VP8_COMMON_THREADING_H_
#include "./vpx_config.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
...@@ -20,7 +21,7 @@ extern "C" { ...@@ -20,7 +21,7 @@ extern "C" {
#if CONFIG_OS_SUPPORT && CONFIG_MULTITHREAD #if CONFIG_OS_SUPPORT && CONFIG_MULTITHREAD
/* Thread management macros */ /* Thread management macros */
#ifdef _WIN32 #if defined(_WIN32) && !HAVE_PTHREAD_H
/* Win32 */ /* Win32 */
#include <process.h> #include <process.h>
#include <windows.h> #include <windows.h>
...@@ -77,8 +78,8 @@ extern "C" { ...@@ -77,8 +78,8 @@ extern "C" {
#define ts_key_create(ts_key, destructor) pthread_key_create (&(ts_key), destructor); #define ts_key_create(ts_key, destructor) pthread_key_create (&(ts_key), destructor);
#endif #endif
/* Syncrhronization macros: Win32 and Pthreads */ /* Synchronization macros: Win32 and Pthreads */
#ifdef _WIN32 #if defined(_WIN32) && !HAVE_PTHREAD_H
#define sem_t HANDLE #define sem_t HANDLE
#define pause(voidpara) __asm PAUSE #define pause(voidpara) __asm PAUSE
#define sem_init(sem, sem_attr1, sem_init_value) (int)((*sem = CreateSemaphore(NULL,0,32768,NULL))==NULL) #define sem_init(sem, sem_attr1, sem_init_value) (int)((*sem = CreateSemaphore(NULL,0,32768,NULL))==NULL)
......
...@@ -737,7 +737,8 @@ static void dec_build_inter_predictors_sb(VP9Decoder *const pbi, ...@@ -737,7 +737,8 @@ static void dec_build_inter_predictors_sb(VP9Decoder *const pbi,
"Reference frame has invalid dimensions"); "Reference frame has invalid dimensions");
is_scaled = vp9_is_scaled(sf); is_scaled = vp9_is_scaled(sf);
vp9_setup_pre_planes(xd, ref, ref_buf->buf, mi_row, mi_col, sf); vp9_setup_pre_planes(xd, ref, ref_buf->buf, mi_row, mi_col,
is_scaled ? sf : NULL);
xd->block_refs[ref] = ref_buf; xd->block_refs[ref] = ref_buf;
if (sb_type < BLOCK_8X8) { if (sb_type < BLOCK_8X8) {
......
...@@ -81,8 +81,8 @@ static TX_SIZE read_selected_tx_size(VP9_COMMON *cm, MACROBLOCKD *xd, ...@@ -81,8 +81,8 @@ static TX_SIZE read_selected_tx_size(VP9_COMMON *cm, MACROBLOCKD *xd,
return (TX_SIZE)tx_size; return (TX_SIZE)tx_size;
} }
static TX_SIZE read_tx_size(VP9_COMMON *cm, MACROBLOCKD *xd, static INLINE TX_SIZE read_tx_size(VP9_COMMON *cm, MACROBLOCKD *xd,
int allow_select, vpx_reader *r) { int allow_select, vpx_reader *r) {
TX_MODE tx_mode = cm->tx_mode; TX_MODE tx_mode = cm->tx_mode;
BLOCK_SIZE bsize = xd->mi[0]->sb_type; BLOCK_SIZE bsize = xd->mi[0]->sb_type;
const TX_SIZE max_tx_size = max_txsize_lookup[bsize]; const TX_SIZE max_tx_size = max_txsize_lookup[bsize];
...@@ -416,6 +416,14 @@ static INLINE int is_mv_valid(const MV *mv) { ...@@ -416,6 +416,14 @@ static INLINE int is_mv_valid(const MV *mv) {
mv->col > MV_LOW && mv->col < MV_UPP; mv->col > MV_LOW && mv->col < MV_UPP;
} }
static INLINE void copy_mv_pair(int_mv *dst, const int_mv *src) {
memcpy(dst, src, sizeof(*dst) * 2);
}
static INLINE void zero_mv_pair(int_mv *dst) {
memset(dst, 0, sizeof(*dst) * 2);
}
static INLINE int assign_mv(VP9_COMMON *cm, MACROBLOCKD *xd, static INLINE int assign_mv(VP9_COMMON *cm, MACROBLOCKD *xd,
PREDICTION_MODE mode, PREDICTION_MODE mode,
int_mv mv[2], int_mv ref_mv[2], int_mv mv[2], int_mv ref_mv[2],
...@@ -437,13 +445,11 @@ static INLINE int assign_mv(VP9_COMMON *cm, MACROBLOCKD *xd, ...@@ -437,13 +445,11 @@ static INLINE int assign_mv(VP9_COMMON *cm, MACROBLOCKD *xd,
} }
case NEARMV: case NEARMV:
case NEARESTMV: { case NEARESTMV: {
mv[0].as_int = near_nearest_mv[0].as_int; copy_mv_pair(mv, near_nearest_mv);
mv[1].as_int = near_nearest_mv[1].as_int;
break; break;
} }
case ZEROMV: { case ZEROMV: {
mv[0].as_int = 0; zero_mv_pair(mv);
mv[1].as_int = 0;
break; break;
} }
default: { default: {
...@@ -824,8 +830,7 @@ static void read_inter_block_mode_info(VP9Decoder *const pbi, ...@@ -824,8 +830,7 @@ static void read_inter_block_mode_info(VP9Decoder *const pbi,
mi->mode = b_mode; mi->mode = b_mode;
mi->mv[0].as_int = mi->bmi[3].as_mv[0].as_int; copy_mv_pair(mi->mv, mi->bmi[3].as_mv);
mi->mv[1].as_int = mi->bmi[3].as_mv[1].as_int;
} else { } else {
xd->corrupted |= !assign_mv(cm, xd, mi->mode, mi->mv, best_ref_mvs, xd->corrupted |= !assign_mv(cm, xd, mi->mode, mi->mv, best_ref_mvs,
best_ref_mvs, is_compound, allow_hp, r); best_ref_mvs, is_compound, allow_hp, r);
...@@ -839,8 +844,6 @@ static void read_inter_frame_mode_info(VP9Decoder *const pbi, ...@@ -839,8 +844,6 @@ static void read_inter_frame_mode_info(VP9Decoder *const pbi,
MODE_INFO *const mi = xd->mi[0]; MODE_INFO *const mi = xd->mi[0];
int inter_block; int inter_block;
mi->mv[0].as_int = 0;
mi->mv[1].as_int = 0;
mi->segment_id = read_inter_segment_id(cm, xd, mi_row, mi_col, r); mi->segment_id = read_inter_segment_id(cm, xd, mi_row, mi_col, r);
mi->skip = read_skip(cm, xd, mi->segment_id, r); mi->skip = read_skip(cm, xd, mi->segment_id, r);
inter_block = read_is_inter_block(cm, xd, mi->segment_id, r); inter_block = read_is_inter_block(cm, xd, mi->segment_id, r);
...@@ -852,6 +855,11 @@ static void read_inter_frame_mode_info(VP9Decoder *const pbi, ...@@ -852,6 +855,11 @@ static void read_inter_frame_mode_info(VP9Decoder *const pbi,
read_intra_block_mode_info(cm, xd, mi, r); read_intra_block_mode_info(cm, xd, mi, r);
} }
static INLINE void copy_ref_frame_pair(MV_REFERENCE_FRAME *dst,
const MV_REFERENCE_FRAME *src) {
memcpy(dst, src, sizeof(*dst) * 2);
}
void vpx_read_mode_info(VP9Decoder *const pbi, MACROBLOCKD *xd, void vpx_read_mode_info(VP9Decoder *const pbi, MACROBLOCKD *xd,
int mi_row, int mi_col, vpx_reader *r, int mi_row, int mi_col, vpx_reader *r,
int x_mis, int y_mis) { int x_mis, int y_mis) {
...@@ -866,14 +874,12 @@ void vpx_read_mode_info(VP9Decoder *const pbi, MACROBLOCKD *xd, ...@@ -866,14 +874,12 @@ void vpx_read_mode_info(VP9Decoder *const pbi, MACROBLOCKD *xd,
read_inter_frame_mode_info(pbi, xd, mi_row, mi_col, r); read_inter_frame_mode_info(pbi, xd, mi_row, mi_col, r);
for (h = 0; h < y_mis; ++h) { for (h = 0; h < y_mis; ++h) {
MV_REF *const frame_mv = frame_mvs + h * cm->mi_cols;
for (w = 0; w < x_mis; ++w) { for (w = 0; w < x_mis; ++w) {
MV_REF *const mv = frame_mv + w; MV_REF *const mv = frame_mvs + w;
mv->ref_frame[0] = mi->ref_frame[0]; copy_ref_frame_pair(mv->ref_frame, mi->ref_frame);
mv->ref_frame[1] = mi->ref_frame[1]; copy_mv_pair(mv->mv, mi->mv);
mv->mv[0].as_int = mi->mv[0].as_int;
mv->mv[1].as_int = mi->mv[1].as_int;
} }
frame_mvs += cm->mi_cols;
} }
} }
} }
...@@ -58,29 +58,6 @@ void vp9_cyclic_refresh_free(CYCLIC_REFRESH *cr) { ...@@ -58,29 +58,6 @@ void vp9_cyclic_refresh_free(CYCLIC_REFRESH *cr) {
vpx_free(cr); vpx_free(cr);
} }
// Check if we should turn off cyclic refresh based on bitrate condition.
// TODO(marpan): May be better in some cases to just reduce the amount/delta-qp
// instead of completely shutting off.
static int apply_cyclic_refresh_bitrate(const VP9_COMMON *cm,
const RATE_CONTROL *rc) {
// Turn off cyclic refresh if bits available per frame is not sufficiently
// larger than bit cost of segmentation. Segment map bit cost should scale
// with number of seg blocks, so compare available bits to number of blocks.
// Average bits available per frame = avg_frame_bandwidth
// Number of (8x8) blocks in frame = mi_rows * mi_cols;
const float factor = 0.15f;
const int number_blocks = cm->mi_rows * cm->mi_cols;
// The condition below corresponds to turning off at target bitrates:
// (at 30fps), ~8kbps for CIF, 20kbps for VGA, 60kps for HD/720p.
// Also turn off at very small frame sizes, to avoid too large fraction of
// superblocks to be refreshed per frame. Threshold below is less than QCIF.
if (rc->avg_frame_bandwidth < factor * number_blocks ||
number_blocks / 64 < 5)
return 0;
else
return 1;
}
// Check if this coding block, of size bsize, should be considered for refresh // Check if this coding block, of size bsize, should be considered for refresh
// (lower-qp coding). Decision can be based on various factors, such as // (lower-qp coding). Decision can be based on various factors, such as
// size of the coding block (i.e., below min_block size rejected), coding // size of the coding block (i.e., below min_block size rejected), coding
...@@ -534,7 +511,10 @@ void vp9_cyclic_refresh_setup(VP9_COMP *const cpi) { ...@@ -534,7 +511,10 @@ void vp9_cyclic_refresh_setup(VP9_COMP *const cpi) {
const RATE_CONTROL *const rc = &cpi->rc; const RATE_CONTROL *const rc = &cpi->rc;
CYCLIC_REFRESH *const cr = cpi->cyclic_refresh; CYCLIC_REFRESH *const cr = cpi->cyclic_refresh;
struct segmentation *const seg = &cm->seg; struct segmentation *const seg = &cm->seg;
const int apply_cyclic_refresh = apply_cyclic_refresh_bitrate(cm, rc); // TODO(marpan): Look into whether we should reduce the amount/delta-qp
// instead of completely shutting off at low bitrates. For now keep it on.
// const int apply_cyclic_refresh = apply_cyclic_refresh_bitrate(cm, rc);
const int apply_cyclic_refresh = 1;
if (cm->current_video_frame == 0) if (cm->current_video_frame == 0)
cr->low_content_avg = 0.0; cr->low_content_avg = 0.0;
// Don't apply refresh on key frame or temporal enhancement layer frames. // Don't apply refresh on key frame or temporal enhancement layer frames.
...@@ -627,4 +607,5 @@ void vp9_cyclic_refresh_reset_resize(VP9_COMP *const cpi) { ...@@ -627,4 +607,5 @@ void vp9_cyclic_refresh_reset_resize(VP9_COMP *const cpi) {
memset(cr->consec_zero_mv, 0, cm->mi_rows * cm->mi_cols); memset(cr->consec_zero_mv, 0, cm->mi_rows * cm->mi_cols);
cr->sb_index = 0; cr->sb_index = 0;
cpi->refresh_golden_frame = 1; cpi->refresh_golden_frame = 1;
cpi->refresh_alt_ref_frame = 1;
} }
...@@ -65,8 +65,14 @@ struct macroblock { ...@@ -65,8 +65,14 @@ struct macroblock {
int skip_optimize; int skip_optimize;
int q_index; int q_index;
// The equivalent error at the current rdmult of one whole bit (not one
// bitcost unit).
int errorperbit; int errorperbit;
// The equivalend SAD error of one (whole) bit at the current quantizer
// for large blocks.
int sadperbit16; int sadperbit16;
// The equivalend SAD error of one (whole) bit at the current quantizer
// for sub-8x8 blocks.
int sadperbit4; int sadperbit4;
int rddiv; int rddiv;
int rdmult; int rdmult;
......
...@@ -332,7 +332,7 @@ void vp9_denoiser_denoise(VP9_DENOISER *denoiser, MACROBLOCK *mb, ...@@ -332,7 +332,7 @@ void vp9_denoiser_denoise(VP9_DENOISER *denoiser, MACROBLOCK *mb,
struct buf_2d src = mb->plane[0].src; struct buf_2d src = mb->plane[0].src;
int is_skin = 0; int is_skin = 0;
if (bs <= BLOCK_16X16 && denoiser->denoising_level >= kDenLow) { if (bs <= BLOCK_32X32 && denoiser->denoising_level >= kDenLow) {
is_skin = vp9_compute_skin_block(mb->plane[0].src.buf, is_skin = vp9_compute_skin_block(mb->plane[0].src.buf,
mb->plane[1].src.buf, mb->plane[1].src.buf,
mb->plane[2].src.buf, mb->plane[2].src.buf,
......
...@@ -1525,6 +1525,7 @@ void vp9_change_config(struct VP9_COMP *cpi, const VP9EncoderConfig *oxcf) { ...@@ -1525,6 +1525,7 @@ void vp9_change_config(struct VP9_COMP *cpi, const VP9EncoderConfig *oxcf) {
if (last_w != cpi->oxcf.width || last_h != cpi->oxcf.height) { if (last_w != cpi->oxcf.width || last_h != cpi->oxcf.height) {
cm->width = cpi->oxcf.width; cm->width = cpi->oxcf.width;
cm->height = cpi->oxcf.height; cm->height = cpi->oxcf.height;
cpi->external_resize = 1;
} }
if (cpi->initial_width) { if (cpi->initial_width) {
...@@ -1536,10 +1537,15 @@ void vp9_change_config(struct VP9_COMP *cpi, const VP9EncoderConfig *oxcf) { ...@@ -1536,10 +1537,15 @@ void vp9_change_config(struct VP9_COMP *cpi, const VP9EncoderConfig *oxcf) {
alloc_compressor_data(cpi); alloc_compressor_data(cpi);
realloc_segmentation_maps(cpi); realloc_segmentation_maps(cpi);
cpi->initial_width = cpi->initial_height = 0; cpi->initial_width = cpi->initial_height = 0;
cpi->external_resize = 0;
} }
} }
update_frame_size(cpi); update_frame_size(cpi);
if ((last_w != cpi->oxcf.width || last_h != cpi->oxcf.height) &&
cpi->oxcf.aq_mode == CYCLIC_REFRESH_AQ)
vp9_cyclic_refresh_reset_resize(cpi);
if ((cpi->svc.number_temporal_layers > 1 && if ((cpi->svc.number_temporal_layers > 1 &&
cpi->oxcf.rc_mode == VPX_CBR) || cpi->oxcf.rc_mode == VPX_CBR) ||
((cpi->svc.number_temporal_layers > 1 || ((cpi->svc.number_temporal_layers > 1 ||
...@@ -1667,6 +1673,7 @@ VP9_COMP *vp9_create_compressor(VP9EncoderConfig *oxcf, ...@@ -1667,6 +1673,7 @@ VP9_COMP *vp9_create_compressor(VP9EncoderConfig *oxcf,
cpi->use_svc = 0; cpi->use_svc = 0;
cpi->resize_state = 0; cpi->resize_state = 0;
cpi->external_resize = 0;
cpi->resize_avg_qp = 0; cpi->resize_avg_qp = 0;
cpi->resize_buffer_underflow = 0; cpi->resize_buffer_underflow = 0;
cpi->use_skin_detection = 0; cpi->use_skin_detection = 0;
...@@ -2959,8 +2966,19 @@ void vp9_scale_references(VP9_COMP *cpi) { ...@@ -2959,8 +2966,19 @@ void vp9_scale_references(VP9_COMP *cpi) {
} }
#endif // CONFIG_VP9_HIGHBITDEPTH #endif // CONFIG_VP9_HIGHBITDEPTH
} else { } else {
const int buf_idx = get_ref_frame_buf_idx(cpi, ref_frame); int buf_idx;
RefCntBuffer *const buf = &pool->frame_bufs[buf_idx]; RefCntBuffer *buf = NULL;
if (cpi->oxcf.pass == 0 && !cpi->use_svc) {
// Check for release of scaled reference.
buf_idx = cpi->scaled_ref_idx[ref_frame - 1];
buf = (buf_idx != INVALID_IDX) ? &pool->frame_bufs[buf_idx] : NULL;
if (buf != NULL) {
--buf->ref_count;
cpi->scaled_ref_idx[ref_frame - 1] = INVALID_IDX;
}
}
buf_idx = get_ref_frame_buf_idx(cpi, ref_frame);
buf = &pool->frame_bufs[buf_idx];
buf->buf.y_crop_width = ref->y_crop_width; buf->buf.y_crop_width = ref->y_crop_width;
buf->buf.y_crop_height = ref->y_crop_height; buf->buf.y_crop_height = ref->y_crop_height;
cpi->scaled_ref_idx[ref_frame - 1] = buf_idx; cpi->scaled_ref_idx[ref_frame - 1] = buf_idx;
...@@ -4129,7 +4147,7 @@ int vp9_receive_raw_frame(VP9_COMP *cpi, unsigned int frame_flags, ...@@ -4129,7 +4147,7 @@ int vp9_receive_raw_frame(VP9_COMP *cpi, unsigned int frame_flags,
const int subsampling_x = sd->subsampling_x; const int subsampling_x = sd->subsampling_x;
const int subsampling_y = sd->subsampling_y; const int subsampling_y = sd->subsampling_y;
#if CONFIG_VP9_HIGHBITDEPTH #if CONFIG_VP9_HIGHBITDEPTH
const int use_highbitdepth = sd->flags & YV12_FLAG_HIGHBITDEPTH; const int use_highbitdepth = (sd->flags & YV12_FLAG_HIGHBITDEPTH) != 0;
check_initial_width(cpi, use_highbitdepth, subsampling_x, subsampling_y); check_initial_width(cpi, use_highbitdepth, subsampling_x, subsampling_y);
#else #else
check_initial_width(cpi, subsampling_x, subsampling_y); check_initial_width(cpi, subsampling_x, subsampling_y);
......
...@@ -485,6 +485,7 @@ typedef struct VP9_COMP { ...@@ -485,6 +485,7 @@ typedef struct VP9_COMP {
int resize_pending; int resize_pending;
int resize_state; int resize_state;
int external_resize;
int resize_scale_num; int resize_scale_num;
int resize_scale_den; int resize_scale_den;
int resize_avg_qp; int resize_avg_qp;
......
...@@ -80,27 +80,29 @@ int vp9_mv_bit_cost(const MV *mv, const MV *ref, ...@@ -80,27 +80,29 @@ int vp9_mv_bit_cost(const MV *mv, const MV *ref,
return ROUND_POWER_OF_TWO(mv_cost(&diff, mvjcost, mvcost) * weight, 7); return ROUND_POWER_OF_TWO(mv_cost(&diff, mvjcost, mvcost) * weight, 7);
} }
static int mv_err_cost(const MV *mv, const MV *ref, #define PIXEL_TRANSFORM_ERROR_SCALE 4
const int *mvjcost, int *mvcost[2], static int mv_err_cost(const MV *mv, const MV *ref, const int *mvjcost,
int error_per_bit) { int *mvcost[2], int error_per_bit) {
if (mvcost) { if (mvcost) {
const MV diff = { mv->row - ref->row, const MV diff = {mv->row - ref->row, mv->col - ref->col};
mv->col - ref->col }; // This product sits at a 32-bit ceiling right now and any additional
// TODO(aconverse): See if this shift needs to be tied to // accuracy in either bit cost or error cost will cause it to overflow.
// VP9_PROB_COST_SHIFT. return ROUND_POWER_OF_TWO(
return ROUND_POWER_OF_TWO((unsigned)mv_cost(&diff, mvjcost, mvcost) * (unsigned)mv_cost(&diff, mvjcost, mvcost) * error_per_bit,
error_per_bit, 13); RDDIV_BITS + VP9_PROB_COST_SHIFT - RD_EPB_SHIFT +
PIXEL_TRANSFORM_ERROR_SCALE);
} }
return 0; return 0;
} }
static int mvsad_err_cost(const MACROBLOCK *x, const MV *mv, const MV *ref, static int mvsad_err_cost(const MACROBLOCK *x, const MV *mv, const MV *ref,
int error_per_bit) { int sad_per_bit) {
const MV diff = { mv->row - ref->row, const MV diff = { mv->row - ref->row,
mv->col - ref->col }; mv->col - ref->col };
// TODO(aconverse): See if this shift needs to be tied to VP9_PROB_COST_SHIFT. return ROUND_POWER_OF_TWO(
return ROUND_POWER_OF_TWO((unsigned)mv_cost(&diff, x->nmvjointsadcost, (unsigned)mv_cost(&diff, x->nmvjointsadcost, x->nmvsadcost) *
x->nmvsadcost) * error_per_bit, 8); sad_per_bit,
VP9_PROB_COST_SHIFT);
} }
void vp9_init_dsmotion_compensation(search_site_config *cfg, int stride) { void vp9_init_dsmotion_compensation(search_site_config *cfg, int stride) {
...@@ -152,12 +154,13 @@ void vp9_init3smotion_compensation(search_site_config *cfg, int stride) { ...@@ -152,12 +154,13 @@ void vp9_init3smotion_compensation(search_site_config *cfg, int stride) {
* could reduce the area. * could reduce the area.
*/ */
/* estimated cost of a motion vector (r,c) */ /* Estimated (square) error cost of a motion vector (r,c). The 14 scale comes
* from the same math as in mv_err_cost(). */
#define MVC(r, c) \ #define MVC(r, c) \
(mvcost ? \ (mvcost ? \
((unsigned)(mvjcost[((r) != rr) * 2 + ((c) != rc)] + \ ((unsigned)(mvjcost[((r) != rr) * 2 + ((c) != rc)] + \
mvcost[0][((r) - rr)] + mvcost[1][((c) - rc)]) * \ mvcost[0][((r) - rr)] + mvcost[1][((c) - rc)]) * \
error_per_bit + 4096) >> 13 : 0) error_per_bit + 8192) >> 14 : 0)
// convert motion vector component to offset for sv[a]f calc // convert motion vector component to offset for sv[a]f calc
......
...@@ -949,7 +949,8 @@ static void estimate_block_intra(int plane, int block, BLOCK_SIZE plane_bsize, ...@@ -949,7 +949,8 @@ static void estimate_block_intra(int plane, int block, BLOCK_SIZE plane_bsize,
// TODO(jingning): Skip is signalled per prediciton block not per tx block. // TODO(jingning): Skip is signalled per prediciton block not per tx block.
rate += vp9_cost_bit(vp9_get_skip_prob(&cpi->common, xd), is_skippable); rate += vp9_cost_bit(vp9_get_skip_prob(&cpi->common, xd), is_skippable);
} else { } else {
unsigned int var, sse; unsigned int var = 0;
unsigned int sse = 0;
model_rd_for_sb_uv(cpi, plane_bsize, x, xd, &rate, &dist, &var, &sse, model_rd_for_sb_uv(cpi, plane_bsize, x, xd, &rate, &dist, &var, &sse,
plane, plane); plane, plane);
} }
......
...@@ -342,8 +342,7 @@ void vp9_init_plane_quantizers(VP9_COMP *cpi, MACROBLOCK *x) { ...@@ -342,8 +342,7 @@ void vp9_init_plane_quantizers(VP9_COMP *cpi, MACROBLOCK *x) {
x->skip_block = segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP); x->skip_block = segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP);
x->q_index = qindex; x->q_index = qindex;
x->errorperbit = rdmult >> 6; set_error_per_bit(x, rdmult);
x->errorperbit += (x->errorperbit == 0);
vp9_initialize_me_consts(cpi, x, x->q_index); vp9_initialize_me_consts(cpi, x, x->q_index);
} }
......
...@@ -41,7 +41,6 @@ ...@@ -41,7 +41,6 @@
#include "vp9/encoder/vp9_tokenize.h" #include "vp9/encoder/vp9_tokenize.h"
#define RD_THRESH_POW 1.25 #define RD_THRESH_POW 1.25
#define RD_MULT_EPB_RATIO 64
// Factor to weigh the rate for switchable interp filters. // Factor to weigh the rate for switchable interp filters.
#define SWITCHABLE_INTERP_RATE_FACTOR 1 #define SWITCHABLE_INTERP_RATE_FACTOR 1
...@@ -279,8 +278,7 @@ void vp9_initialize_rd_consts(VP9_COMP *cpi) { ...@@ -279,8 +278,7 @@ void vp9_initialize_rd_consts(VP9_COMP *cpi) {
rd->RDDIV = RDDIV_BITS; // In bits (to multiply D by 128). rd->RDDIV = RDDIV_BITS; // In bits (to multiply D by 128).
rd->RDMULT = vp9_compute_rd_mult(cpi, cm->base_qindex + cm->y_dc_delta_q); rd->RDMULT = vp9_compute_rd_mult(cpi, cm->base_qindex + cm->y_dc_delta_q);
x->errorperbit = rd->RDMULT / RD_MULT_EPB_RATIO; set_error_per_bit(x, rd->RDMULT);
x->errorperbit += (x->errorperbit == 0);
x->select_tx_size = (cpi->sf.tx_size_search_method == USE_LARGESTALL && x->select_tx_size = (cpi->sf.tx_size_search_method == USE_LARGESTALL &&
cm->frame_type != KEY_FRAME) ? 0 : 1; cm->frame_type != KEY_FRAME) ? 0 : 1;
......
...@@ -24,6 +24,7 @@ extern "C" { ...@@ -24,6 +24,7 @@ extern "C" {
#endif #endif
#define RDDIV_BITS 7 #define RDDIV_BITS 7
#define RD_EPB_SHIFT 6
#define RDCOST(RM, DM, R, D) \ #define RDCOST(RM, DM, R, D) \
(ROUND_POWER_OF_TWO(((int64_t)R) * (RM), VP9_PROB_COST_SHIFT) + (D << DM)) (ROUND_POWER_OF_TWO(((int64_t)R) * (RM), VP9_PROB_COST_SHIFT) + (D << DM))
...@@ -168,6 +169,11 @@ static INLINE int rd_less_than_thresh(int64_t best_rd, int thresh, ...@@ -168,6 +169,11 @@ static INLINE int rd_less_than_thresh(int64_t best_rd, int thresh,
return best_rd < ((int64_t)thresh * thresh_fact >> 5) || thresh == INT_MAX;