summaryrefslogtreecommitdiff
path: root/vp9/encoder
diff options
context:
space:
mode:
Diffstat (limited to 'vp9/encoder')
-rw-r--r--vp9/encoder/vp9_encoder.h4
-rw-r--r--vp9/encoder/vp9_firstpass.c26
-rw-r--r--vp9/encoder/vp9_pickmode.c63
-rw-r--r--vp9/encoder/vp9_ratectrl.c40
-rw-r--r--vp9/encoder/vp9_ratectrl.h2
-rw-r--r--vp9/encoder/vp9_speed_features.c4
6 files changed, 110 insertions, 29 deletions
diff --git a/vp9/encoder/vp9_encoder.h b/vp9/encoder/vp9_encoder.h
index f448f961c..ddba3275e 100644
--- a/vp9/encoder/vp9_encoder.h
+++ b/vp9/encoder/vp9_encoder.h
@@ -119,8 +119,8 @@ typedef enum {
COMPLEXITY_AQ = 2,
CYCLIC_REFRESH_AQ = 3,
EQUATOR360_AQ = 4,
- PSNR_AQ = 5,
- PERCEPTUAL_AQ = 6,
+ PERCEPTUAL_AQ = 5,
+ PSNR_AQ = 6,
// AQ based on lookahead temporal
// variance (only valid for altref frames)
LOOKAHEAD_AQ = 7,
diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c
index 665b4c36e..392d1088e 100644
--- a/vp9/encoder/vp9_firstpass.c
+++ b/vp9/encoder/vp9_firstpass.c
@@ -2642,6 +2642,17 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
rc->source_alt_ref_pending = 0;
}
+#define LAST_ALR_ACTIVE_BEST_QUALITY_ADJUSTMENT_FACTOR 0.2
+ rc->arf_active_best_quality_adjustment_factor = 1.0;
+ if (rc->source_alt_ref_pending && !is_lossless_requested(&cpi->oxcf) &&
+ rc->frames_to_key <= rc->arf_active_best_quality_adjustment_window) {
+ rc->arf_active_best_quality_adjustment_factor =
+ LAST_ALR_ACTIVE_BEST_QUALITY_ADJUSTMENT_FACTOR +
+ (1.0 - LAST_ALR_ACTIVE_BEST_QUALITY_ADJUSTMENT_FACTOR) *
+ (rc->frames_to_key - i) /
+ VPXMAX(1, (rc->arf_active_best_quality_adjustment_window - i));
+ }
+
#ifdef AGGRESSIVE_VBR
// Limit maximum boost based on interval length.
rc->gfu_boost = VPXMIN((int)rc->gfu_boost, i * 140);
@@ -3190,6 +3201,11 @@ static void find_next_key_frame(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
// Default to normal-sized frame on keyframes.
cpi->rc.next_frame_size_selector = UNSCALED;
}
+#define ARF_ACTIVE_BEST_QUALITY_ADJUSTMENT_WINDOW_SIZE 64
+ // TODO(ravi.chaudhary@ittiam.com): Experiment without the below min
+ // condition. This might be helpful for small key frame intervals.
+ rc->arf_active_best_quality_adjustment_window =
+ VPXMIN(ARF_ACTIVE_BEST_QUALITY_ADJUSTMENT_WINDOW_SIZE, rc->frames_to_key);
}
static int is_skippable_frame(const VP9_COMP *cpi) {
@@ -3225,6 +3241,11 @@ void vp9_rc_get_second_pass_params(VP9_COMP *cpi) {
if (gf_group->update_type[gf_group->index] == ARF_UPDATE) {
int target_rate;
+ vp9_zero(this_frame);
+ this_frame =
+ cpi->twopass.stats_in_start[cm->current_video_frame +
+ gf_group->arf_src_offset[gf_group->index]];
+
vp9_configure_buffer_updates(cpi, gf_group->index);
target_rate = gf_group->bit_allocation[gf_group->index];
@@ -3240,6 +3261,11 @@ void vp9_rc_get_second_pass_params(VP9_COMP *cpi) {
cpi->partition_search_skippable_frame = is_skippable_frame(cpi);
}
+ // The multiplication by 256 reverses a scaling factor of (>> 8)
+ // applied when combining MB error values for the frame.
+ twopass->mb_av_energy = log((this_frame.intra_error * 256.0) + 1.0);
+ twopass->mb_smooth_pct = this_frame.intra_smooth_pct;
+
return;
}
diff --git a/vp9/encoder/vp9_pickmode.c b/vp9/encoder/vp9_pickmode.c
index a431e4ca6..d6052fade 100644
--- a/vp9/encoder/vp9_pickmode.c
+++ b/vp9/encoder/vp9_pickmode.c
@@ -376,10 +376,52 @@ static TX_SIZE calculate_tx_size(VP9_COMP *const cpi, BLOCK_SIZE bsize,
tx_size = VPXMIN(max_txsize_lookup[bsize],
tx_mode_to_biggest_tx_size[cpi->common.tx_mode]);
}
-
return tx_size;
}
+static void compute_intra_yprediction(PREDICTION_MODE mode, BLOCK_SIZE bsize,
+ MACROBLOCK *x, MACROBLOCKD *xd) {
+ struct macroblockd_plane *const pd = &xd->plane[0];
+ struct macroblock_plane *const p = &x->plane[0];
+ uint8_t *const src_buf_base = p->src.buf;
+ uint8_t *const dst_buf_base = pd->dst.buf;
+ const int src_stride = p->src.stride;
+ const int dst_stride = pd->dst.stride;
+ // block and transform sizes, in number of 4x4 blocks log 2 ("*_b")
+ // 4x4=0, 8x8=2, 16x16=4, 32x32=6, 64x64=8
+ const TX_SIZE tx_size = max_txsize_lookup[bsize];
+ const int num_4x4_w = num_4x4_blocks_wide_lookup[bsize];
+ const int num_4x4_h = num_4x4_blocks_high_lookup[bsize];
+ int row, col;
+ // If mb_to_right_edge is < 0 we are in a situation in which
+ // the current block size extends into the UMV and we won't
+ // visit the sub blocks that are wholly within the UMV.
+ const int max_blocks_wide =
+ num_4x4_w + (xd->mb_to_right_edge >= 0
+ ? 0
+ : xd->mb_to_right_edge >> (5 + pd->subsampling_x));
+ const int max_blocks_high =
+ num_4x4_h + (xd->mb_to_bottom_edge >= 0
+ ? 0
+ : xd->mb_to_bottom_edge >> (5 + pd->subsampling_y));
+
+ // Keep track of the row and column of the blocks we use so that we know
+ // if we are in the unrestricted motion border.
+ for (row = 0; row < max_blocks_high; row += (1 << tx_size)) {
+ // Skip visiting the sub blocks that are wholly within the UMV.
+ for (col = 0; col < max_blocks_wide; col += (1 << tx_size)) {
+ p->src.buf = &src_buf_base[4 * (row * (int64_t)src_stride + col)];
+ pd->dst.buf = &dst_buf_base[4 * (row * (int64_t)dst_stride + col)];
+ vp9_predict_intra_block(xd, b_width_log2_lookup[bsize], tx_size, mode,
+ x->skip_encode ? p->src.buf : pd->dst.buf,
+ x->skip_encode ? src_stride : dst_stride,
+ pd->dst.buf, dst_stride, col, row, 0);
+ }
+ }
+ p->src.buf = src_buf_base;
+ pd->dst.buf = dst_buf_base;
+}
+
static void model_rd_for_sb_y_large(VP9_COMP *cpi, BLOCK_SIZE bsize,
MACROBLOCK *x, MACROBLOCKD *xd,
int *out_rate_sum, int64_t *out_dist_sum,
@@ -1013,8 +1055,8 @@ static void estimate_block_intra(int plane, int block, int row, int col,
(void)block;
- p->src.buf = &src_buf_base[4 * (row * src_stride + col)];
- pd->dst.buf = &dst_buf_base[4 * (row * dst_stride + col)];
+ p->src.buf = &src_buf_base[4 * (row * (int64_t)src_stride + col)];
+ pd->dst.buf = &dst_buf_base[4 * (row * (int64_t)dst_stride + col)];
// Use source buffer as an approximation for the fully reconstructed buffer.
vp9_predict_intra_block(xd, b_width_log2_lookup[plane_bsize], tx_size,
args->mode, x->skip_encode ? p->src.buf : pd->dst.buf,
@@ -1023,13 +1065,12 @@ static void estimate_block_intra(int plane, int block, int row, int col,
if (plane == 0) {
int64_t this_sse = INT64_MAX;
- // TODO(jingning): This needs further refactoring.
block_yrd(cpi, x, &this_rdc, &args->skippable, &this_sse, bsize_tx,
VPXMIN(tx_size, TX_16X16), 0, 1);
} else {
unsigned int var = 0;
unsigned int sse = 0;
- model_rd_for_sb_uv(cpi, plane_bsize, x, xd, &this_rdc, &var, &sse, plane,
+ model_rd_for_sb_uv(cpi, bsize_tx, x, xd, &this_rdc, &var, &sse, plane,
plane);
}
@@ -2472,13 +2513,12 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, TileDataEnc *tile_data,
bsize <= cpi->sf.max_intra_bsize && !x->skip_low_source_sad &&
!x->lowvar_highsumdiff)) {
struct estimate_block_intra_args args = { cpi, x, DC_PRED, 1, 0 };
+ int64_t this_sse = INT64_MAX;
int i;
PRED_BUFFER *const best_pred = best_pickmode.best_pred;
TX_SIZE intra_tx_size =
VPXMIN(max_txsize_lookup[bsize],
tx_mode_to_biggest_tx_size[cpi->common.tx_mode]);
- if (cpi->oxcf.content != VP9E_CONTENT_SCREEN && intra_tx_size > TX_16X16)
- intra_tx_size = TX_16X16;
if (reuse_inter_pred && best_pred != NULL) {
if (best_pred->data == orig_dst.buf) {
@@ -2539,8 +2579,13 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, TileDataEnc *tile_data,
args.skippable = 1;
args.rdc = &this_rdc;
mi->tx_size = intra_tx_size;
- vp9_foreach_transformed_block_in_plane(xd, bsize, 0, estimate_block_intra,
- &args);
+
+ compute_intra_yprediction(this_mode, bsize, x, xd);
+ model_rd_for_sb_y(cpi, bsize, x, xd, &this_rdc.rate, &this_rdc.dist,
+ &var_y, &sse_y, 1);
+ block_yrd(cpi, x, &this_rdc, &args.skippable, &this_sse, bsize,
+ VPXMIN(mi->tx_size, TX_16X16), 1, 1);
+
// Check skip cost here since skippable is not set for for uv, this
// mirrors the behavior used by inter
if (args.skippable) {
diff --git a/vp9/encoder/vp9_ratectrl.c b/vp9/encoder/vp9_ratectrl.c
index b51f6797b..e45030ab8 100644
--- a/vp9/encoder/vp9_ratectrl.c
+++ b/vp9/encoder/vp9_ratectrl.c
@@ -211,17 +211,15 @@ int vp9_rc_clamp_pframe_target_size(const VP9_COMP *const cpi, int target) {
const RATE_CONTROL *rc = &cpi->rc;
const VP9EncoderConfig *oxcf = &cpi->oxcf;
- if (cpi->oxcf.pass != 2) {
- const int min_frame_target =
- VPXMAX(rc->min_frame_bandwidth, rc->avg_frame_bandwidth >> 5);
- if (target < min_frame_target) target = min_frame_target;
- if (cpi->refresh_golden_frame && rc->is_src_frame_alt_ref) {
- // If there is an active ARF at this location use the minimum
- // bits on this frame even if it is a constructed arf.
- // The active maximum quantizer insures that an appropriate
- // number of bits will be spent if needed for constructed ARFs.
- target = min_frame_target;
- }
+ const int min_frame_target =
+ VPXMAX(rc->min_frame_bandwidth, rc->avg_frame_bandwidth >> 5);
+ if (target < min_frame_target) target = min_frame_target;
+ if (cpi->refresh_golden_frame && rc->is_src_frame_alt_ref) {
+ // If there is an active ARF at this location use the minimum
+ // bits on this frame even if it is a constructed arf.
+ // The active maximum quantizer insures that an appropriate
+ // number of bits will be spent if needed for constructed ARFs.
+ target = min_frame_target;
}
// Clip the frame target to the maximum allowed value.
@@ -437,6 +435,7 @@ void vp9_rc_init(const VP9EncoderConfig *oxcf, int pass, RATE_CONTROL *rc) {
rc->last_post_encode_dropped_scene_change = 0;
rc->use_post_encode_drop = 0;
rc->ext_use_post_encode_drop = 0;
+ rc->arf_active_best_quality_adjustment_factor = 1.0;
}
static int check_buffer_above_thresh(VP9_COMP *cpi, int drop_mark) {
@@ -1417,6 +1416,8 @@ static int rc_pick_q_and_bounds_two_pass(const VP9_COMP *cpi, int *bottom_index,
int active_worst_quality = cpi->twopass.active_worst_quality;
int q;
int *inter_minq;
+ int arf_active_best_quality_adjustment, arf_active_best_quality_max;
+ int *arfgf_high_motion_minq;
const int boost_frame =
!rc->is_src_frame_alt_ref &&
(cpi->refresh_golden_frame || cpi->refresh_alt_ref_frame);
@@ -1441,14 +1442,17 @@ static int rc_pick_q_and_bounds_two_pass(const VP9_COMP *cpi, int *bottom_index,
// For constrained quality dont allow Q less than the cq level
if (oxcf->rc_mode == VPX_CQ) {
if (q < cq_level) q = cq_level;
+ }
+ active_best_quality = get_gf_active_quality(cpi, q, cm->bit_depth);
- active_best_quality = get_gf_active_quality(cpi, q, cm->bit_depth);
+ ASSIGN_MINQ_TABLE(cm->bit_depth, arfgf_high_motion_minq);
+ arf_active_best_quality_max = arfgf_high_motion_minq[q];
+ arf_active_best_quality_adjustment =
+ arf_active_best_quality_max - active_best_quality;
+ active_best_quality = arf_active_best_quality_max -
+ (int)(arf_active_best_quality_adjustment *
+ rc->arf_active_best_quality_adjustment_factor);
- // Constrained quality use slightly lower active best.
- active_best_quality = active_best_quality * 15 / 16;
- } else {
- active_best_quality = get_gf_active_quality(cpi, q, cm->bit_depth);
- }
// Modify best quality for second level arfs. For mode VPX_Q this
// becomes the baseline frame q.
if (gf_group->rf_level[gf_group_index] == GF_ARF_LOW) {
@@ -3049,7 +3053,7 @@ int vp9_encodedframe_overshoot(VP9_COMP *cpi, int frame_size, int *q) {
// Lower thresh_qp for video (more overshoot at lower Q) to be
// more conservative for video.
if (cpi->oxcf.content != VP9E_CONTENT_SCREEN)
- thresh_qp = rc->worst_quality >> 1;
+ thresh_qp = 3 * (rc->worst_quality >> 2);
// If this decision is not based on an encoded frame size but just on
// scene/slide change detection (i.e., re_encode_overshoot_cbr_rt ==
// FAST_DETECTION_MAXQ), for now skip the (frame_size > thresh_rate)
diff --git a/vp9/encoder/vp9_ratectrl.h b/vp9/encoder/vp9_ratectrl.h
index a5c1f4cf0..2c2048edc 100644
--- a/vp9/encoder/vp9_ratectrl.h
+++ b/vp9/encoder/vp9_ratectrl.h
@@ -197,6 +197,8 @@ typedef struct {
int ext_use_post_encode_drop;
int damped_adjustment[RATE_FACTOR_LEVELS];
+ double arf_active_best_quality_adjustment_factor;
+ int arf_active_best_quality_adjustment_window;
} RATE_CONTROL;
struct VP9_COMP;
diff --git a/vp9/encoder/vp9_speed_features.c b/vp9/encoder/vp9_speed_features.c
index 18130dded..df2afceda 100644
--- a/vp9/encoder/vp9_speed_features.c
+++ b/vp9/encoder/vp9_speed_features.c
@@ -725,6 +725,10 @@ static void set_rt_speed_feature_framesize_independent(
if (!frame_is_intra_only(cm) && cm->width * cm->height <= 352 * 288) {
sf->nonrd_use_ml_partition = 1;
}
+#if CONFIG_VP9_HIGHBITDEPTH
+ if (cpi->Source->flags & YV12_FLAG_HIGHBITDEPTH)
+ sf->nonrd_use_ml_partition = 0;
+#endif
if (content == VP9E_CONTENT_SCREEN) sf->mv.subpel_force_stop = HALF_PEL;
// Only keep INTRA_DC mode for speed 8.
if (!is_keyframe) {