summaryrefslogtreecommitdiff
path: root/vp9
diff options
context:
space:
mode:
Diffstat (limited to 'vp9')
-rw-r--r--vp9/common/vp9_common.h8
-rw-r--r--vp9/encoder/mips/msa/vp9_fdct_msa.h8
-rw-r--r--vp9/encoder/vp9_encodeframe.c5
-rw-r--r--vp9/encoder/vp9_firstpass.c5
-rw-r--r--vp9/encoder/vp9_firstpass.h2
-rw-r--r--vp9/encoder/vp9_mcomp.c44
-rw-r--r--vp9/encoder/vp9_pickmode.c22
-rw-r--r--vp9/encoder/vp9_rdopt.c37
-rw-r--r--vp9/encoder/vp9_speed_features.c8
9 files changed, 78 insertions, 61 deletions
diff --git a/vp9/common/vp9_common.h b/vp9/common/vp9_common.h
index e3c5535dd..9048b515b 100644
--- a/vp9/common/vp9_common.h
+++ b/vp9/common/vp9_common.h
@@ -27,17 +27,17 @@ extern "C" {
// Only need this for fixed-size arrays, for structs just assign.
#define vp9_copy(dest, src) \
- { \
+ do { \
assert(sizeof(dest) == sizeof(src)); \
memcpy(dest, src, sizeof(src)); \
- }
+ } while (0)
// Use this for variably-sized arrays.
#define vp9_copy_array(dest, src, n) \
- { \
+ do { \
assert(sizeof(*(dest)) == sizeof(*(src))); \
memcpy(dest, src, (n) * sizeof(*(src))); \
- }
+ } while (0)
#define vp9_zero(dest) memset(&(dest), 0, sizeof(dest))
#define vp9_zero_array(dest, n) memset(dest, 0, (n) * sizeof(*(dest)))
diff --git a/vp9/encoder/mips/msa/vp9_fdct_msa.h b/vp9/encoder/mips/msa/vp9_fdct_msa.h
index fa1af2fc5..564c879fb 100644
--- a/vp9/encoder/mips/msa/vp9_fdct_msa.h
+++ b/vp9/encoder/mips/msa/vp9_fdct_msa.h
@@ -17,7 +17,7 @@
#define VP9_ADST8(in0, in1, in2, in3, in4, in5, in6, in7, out0, out1, out2, \
out3, out4, out5, out6, out7) \
- { \
+ do { \
v8i16 cnst0_m, cnst1_m, cnst2_m, cnst3_m, cnst4_m; \
v8i16 vec0_m, vec1_m, vec2_m, vec3_m, s0_m, s1_m; \
v8i16 coeff0_m = { cospi_2_64, cospi_6_64, cospi_10_64, cospi_14_64, \
@@ -77,10 +77,10 @@
out1 = -out1; \
out3 = -out3; \
out5 = -out5; \
- }
+ } while (0)
#define VP9_FADST4(in0, in1, in2, in3, out0, out1, out2, out3) \
- { \
+ do { \
v4i32 s0_m, s1_m, s2_m, s3_m, constant_m; \
v4i32 in0_r_m, in1_r_m, in2_r_m, in3_r_m; \
\
@@ -112,5 +112,5 @@
SRARI_W4_SW(in0_r_m, in1_r_m, s2_m, s3_m, DCT_CONST_BITS); \
PCKEV_H4_SH(in0_r_m, in0_r_m, in1_r_m, in1_r_m, s2_m, s2_m, s3_m, s3_m, \
out0, out1, out2, out3); \
- }
+ } while (0)
#endif // VPX_VP9_ENCODER_MIPS_MSA_VP9_FDCT_MSA_H_
diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c
index 4d39520dd..c2669b03f 100644
--- a/vp9/encoder/vp9_encodeframe.c
+++ b/vp9/encoder/vp9_encodeframe.c
@@ -1354,6 +1354,11 @@ static int choose_partitioning(VP9_COMP *cpi, const TileInfo *const tile,
} else {
set_vbp_thresholds(cpi, thresholds, cm->base_qindex, content_state);
}
+ // Decrease 32x32 split threshold for screen on base layer, for scene
+ // change/high motion frames.
+ if (cpi->oxcf.content == VP9E_CONTENT_SCREEN &&
+ cpi->svc.spatial_layer_id == 0 && force_64_split)
+ thresholds[1] = 3 * thresholds[1] >> 2;
// For non keyframes, disable 4x4 average for low resolution when speed = 8
threshold_4x4avg = (cpi->oxcf.speed < 8) ? thresholds[1] << 1 : INT64_MAX;
diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c
index 003e522b7..01cc55eb5 100644
--- a/vp9/encoder/vp9_firstpass.c
+++ b/vp9/encoder/vp9_firstpass.c
@@ -49,7 +49,6 @@
#define MIN_DECAY_FACTOR 0.01
#define NEW_MV_MODE_PENALTY 32
#define DARK_THRESH 64
-#define SECTION_NOISE_DEF 250.0
#define LOW_I_THRESH 24000
#define NCOUNT_INTRA_THRESH 8192
@@ -2659,6 +2658,10 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
// Calculate the bits to be allocated to the gf/arf group as a whole
gf_group_bits = calculate_total_gf_group_bits(cpi, gf_group_err);
+ // Store the average moise level measured for the group
+ twopass->gf_group.group_noise_energy =
+ (int)(gf_group_noise / rc->baseline_gf_interval);
+
// Calculate an estimate of the maxq needed for the group.
// We are more aggressive about correcting for sections
// where there could be significant overshoot than for easier
diff --git a/vp9/encoder/vp9_firstpass.h b/vp9/encoder/vp9_firstpass.h
index 5d9a7fd0d..d8a0a3b9b 100644
--- a/vp9/encoder/vp9_firstpass.h
+++ b/vp9/encoder/vp9_firstpass.h
@@ -44,6 +44,7 @@ typedef struct {
#define INVALID_ROW (-1)
#define MAX_ARF_LAYERS 6
+#define SECTION_NOISE_DEF 250.0
typedef struct {
double frame_mb_intra_factor;
@@ -142,6 +143,7 @@ typedef struct {
int gf_group_size;
int max_layer_depth;
int allowed_max_layer_depth;
+ int group_noise_energy;
} GF_GROUP;
typedef struct {
diff --git a/vp9/encoder/vp9_mcomp.c b/vp9/encoder/vp9_mcomp.c
index b82cbcdaa..09c5532b3 100644
--- a/vp9/encoder/vp9_mcomp.c
+++ b/vp9/encoder/vp9_mcomp.c
@@ -211,7 +211,7 @@ static INLINE const uint8_t *pre(const uint8_t *buf, int stride, int r, int c) {
#endif
#define FIRST_LEVEL_CHECKS \
- { \
+ do { \
unsigned int left, right, up, down, diag; \
CHECK_BETTER(left, tr, tc - hstep); \
CHECK_BETTER(right, tr, tc + hstep); \
@@ -224,10 +224,10 @@ static INLINE const uint8_t *pre(const uint8_t *buf, int stride, int r, int c) {
case 2: CHECK_BETTER(diag, tr + hstep, tc - hstep); break; \
case 3: CHECK_BETTER(diag, tr + hstep, tc + hstep); break; \
} \
- }
+ } while (0)
#define SECOND_LEVEL_CHECKS \
- { \
+ do { \
int kr, kc; \
unsigned int second; \
if (tr != br && tc != bc) { \
@@ -256,7 +256,7 @@ static INLINE const uint8_t *pre(const uint8_t *buf, int stride, int r, int c) {
case 3: CHECK_BETTER(second, tr + kr, tc - hstep); break; \
} \
} \
- }
+ } while (0)
#define SETUP_SUBPEL_SEARCH \
const uint8_t *const z = x->plane[0].src.buf; \
@@ -946,7 +946,7 @@ static INLINE int is_mv_in(const MvLimits *mv_limits, const MV *mv) {
}
#define CHECK_BETTER \
- { \
+ do { \
if (thissad < bestsad) { \
if (use_mvcost) \
thissad += mvsad_err_cost(x, &this_mv, &fcenter_mv, sad_per_bit); \
@@ -955,7 +955,7 @@ static INLINE int is_mv_in(const MvLimits *mv_limits, const MV *mv) {
best_site = i; \
} \
} \
- }
+ } while (0)
#define MAX_PATTERN_SCALES 11
#define MAX_PATTERN_CANDIDATES 8 // max number of canddiates per scale
@@ -1056,7 +1056,7 @@ static int vp9_pattern_search(
thissad =
vfp->sdf(what->buf, what->stride,
get_buf_from_mv(in_what, &this_mv), in_what->stride);
- CHECK_BETTER
+ CHECK_BETTER;
}
} else {
for (i = 0; i < num_candidates[t]; i++) {
@@ -1066,7 +1066,7 @@ static int vp9_pattern_search(
thissad =
vfp->sdf(what->buf, what->stride,
get_buf_from_mv(in_what, &this_mv), in_what->stride);
- CHECK_BETTER
+ CHECK_BETTER;
}
}
if (best_site == -1) {
@@ -1098,7 +1098,7 @@ static int vp9_pattern_search(
thissad =
vfp->sdf(what->buf, what->stride,
get_buf_from_mv(in_what, &this_mv), in_what->stride);
- CHECK_BETTER
+ CHECK_BETTER;
}
} else {
for (i = 0; i < num_candidates[s]; i++) {
@@ -1108,7 +1108,7 @@ static int vp9_pattern_search(
thissad =
vfp->sdf(what->buf, what->stride,
get_buf_from_mv(in_what, &this_mv), in_what->stride);
- CHECK_BETTER
+ CHECK_BETTER;
}
}
@@ -1137,7 +1137,7 @@ static int vp9_pattern_search(
thissad =
vfp->sdf(what->buf, what->stride,
get_buf_from_mv(in_what, &this_mv), in_what->stride);
- CHECK_BETTER
+ CHECK_BETTER;
}
} else {
for (i = 0; i < PATTERN_CANDIDATES_REF; i++) {
@@ -1149,7 +1149,7 @@ static int vp9_pattern_search(
thissad =
vfp->sdf(what->buf, what->stride,
get_buf_from_mv(in_what, &this_mv), in_what->stride);
- CHECK_BETTER
+ CHECK_BETTER;
}
}
@@ -1230,7 +1230,7 @@ static int vp9_pattern_search_sad(
thissad =
vfp->sdf(what->buf, what->stride,
get_buf_from_mv(in_what, &this_mv), in_what->stride);
- CHECK_BETTER
+ CHECK_BETTER;
}
} else {
for (i = 0; i < num_candidates[t]; i++) {
@@ -1240,7 +1240,7 @@ static int vp9_pattern_search_sad(
thissad =
vfp->sdf(what->buf, what->stride,
get_buf_from_mv(in_what, &this_mv), in_what->stride);
- CHECK_BETTER
+ CHECK_BETTER;
}
}
if (best_site == -1) {
@@ -1272,7 +1272,7 @@ static int vp9_pattern_search_sad(
thissad =
vfp->sdf(what->buf, what->stride,
get_buf_from_mv(in_what, &this_mv), in_what->stride);
- CHECK_BETTER
+ CHECK_BETTER;
}
} else {
for (i = 0; i < num_candidates[s]; i++) {
@@ -1282,7 +1282,7 @@ static int vp9_pattern_search_sad(
thissad =
vfp->sdf(what->buf, what->stride,
get_buf_from_mv(in_what, &this_mv), in_what->stride);
- CHECK_BETTER
+ CHECK_BETTER;
}
}
@@ -1311,7 +1311,7 @@ static int vp9_pattern_search_sad(
thissad =
vfp->sdf(what->buf, what->stride,
get_buf_from_mv(in_what, &this_mv), in_what->stride);
- CHECK_BETTER
+ CHECK_BETTER;
}
} else {
for (i = 0; i < PATTERN_CANDIDATES_REF; i++) {
@@ -1323,7 +1323,7 @@ static int vp9_pattern_search_sad(
thissad =
vfp->sdf(what->buf, what->stride,
get_buf_from_mv(in_what, &this_mv), in_what->stride);
- CHECK_BETTER
+ CHECK_BETTER;
}
}
@@ -1346,7 +1346,7 @@ static int vp9_pattern_search_sad(
cost_list[i + 1] = thissad =
vfp->sdf(what->buf, what->stride,
get_buf_from_mv(in_what, &this_mv), in_what->stride);
- CHECK_BETTER
+ CHECK_BETTER;
}
} else {
for (i = 0; i < num_candidates[s]; i++) {
@@ -1356,7 +1356,7 @@ static int vp9_pattern_search_sad(
cost_list[i + 1] = thissad =
vfp->sdf(what->buf, what->stride,
get_buf_from_mv(in_what, &this_mv), in_what->stride);
- CHECK_BETTER
+ CHECK_BETTER;
}
}
@@ -1385,7 +1385,7 @@ static int vp9_pattern_search_sad(
cost_list[next_chkpts_indices[i] + 1] = thissad =
vfp->sdf(what->buf, what->stride,
get_buf_from_mv(in_what, &this_mv), in_what->stride);
- CHECK_BETTER
+ CHECK_BETTER;
}
} else {
for (i = 0; i < PATTERN_CANDIDATES_REF; i++) {
@@ -1400,7 +1400,7 @@ static int vp9_pattern_search_sad(
cost_list[next_chkpts_indices[i] + 1] = thissad =
vfp->sdf(what->buf, what->stride,
get_buf_from_mv(in_what, &this_mv), in_what->stride);
- CHECK_BETTER
+ CHECK_BETTER;
}
}
diff --git a/vp9/encoder/vp9_pickmode.c b/vp9/encoder/vp9_pickmode.c
index b69b269fd..86831b972 100644
--- a/vp9/encoder/vp9_pickmode.c
+++ b/vp9/encoder/vp9_pickmode.c
@@ -2337,7 +2337,8 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, TileDataEnc *tile_data,
// Skipping checking: test to see if this block can be reconstructed by
// prediction only.
- if (cpi->allow_encode_breakout && !xd->lossless && !scene_change_detected) {
+ if (cpi->allow_encode_breakout && !xd->lossless && !scene_change_detected &&
+ !svc->high_num_blocks_with_motion) {
encode_breakout_test(cpi, x, bsize, mi_row, mi_col, ref_frame, this_mode,
var_y, sse_y, yv12_mb, &this_rdc.rate,
&this_rdc.dist, flag_preduv_computed);
@@ -2348,6 +2349,15 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, TileDataEnc *tile_data,
}
}
+ // On spatially flat blocks for screne content: bias against zero-last
+ // if the sse_y is non-zero. Only on scene change or high motion frames.
+ if (cpi->oxcf.content == VP9E_CONTENT_SCREEN &&
+ (scene_change_detected || svc->high_num_blocks_with_motion) &&
+ ref_frame == LAST_FRAME && frame_mv[this_mode][ref_frame].as_int == 0 &&
+ svc->spatial_layer_id == 0 && x->source_variance == 0 && sse_y > 0) {
+ this_rdc.rdcost = this_rdc.rdcost << 2;
+ }
+
#if CONFIG_VP9_TEMPORAL_DENOISING
if (cpi->oxcf.noise_sensitivity > 0 && denoise_svc_pickmode &&
cpi->denoiser.denoising_level > kDenLowLow) {
@@ -2489,8 +2499,14 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, TileDataEnc *tile_data,
&rd_thresh_freq_fact[mode_index])) ||
(!cpi->sf.adaptive_rd_thresh_row_mt &&
rd_less_than_thresh(best_rdc.rdcost, mode_rd_thresh,
- &rd_thresh_freq_fact[mode_index])))
- continue;
+ &rd_thresh_freq_fact[mode_index]))) {
+ // Avoid this early exit for screen on base layer, for scene
+ // changes or high motion frames.
+ if (cpi->oxcf.content != VP9E_CONTENT_SCREEN ||
+ svc->spatial_layer_id > 0 ||
+ (!scene_change_detected && !svc->high_num_blocks_with_motion))
+ continue;
+ }
mi->mode = this_mode;
mi->ref_frame[0] = INTRA_FRAME;
diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c
index 5fc3b7c05..2c54bf5d3 100644
--- a/vp9/encoder/vp9_rdopt.c
+++ b/vp9/encoder/vp9_rdopt.c
@@ -3013,42 +3013,31 @@ static void rd_variance_adjustment(VP9_COMP *cpi, MACROBLOCK *x,
unsigned int absvar_diff = 0;
unsigned int var_factor = 0;
unsigned int adj_max;
+ const int bw = num_8x8_blocks_wide_lookup[bsize];
+ const int bh = num_8x8_blocks_high_lookup[bsize];
vp9e_tune_content content_type = cpi->oxcf.content;
if (*this_rd == INT64_MAX) return;
#if CONFIG_VP9_HIGHBITDEPTH
if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
- if (source_variance > 100) {
- rec_variance = vp9_high_get_sby_perpixel_variance(cpi, &xd->plane[0].dst,
- bsize, xd->bd);
- src_variance = source_variance;
- } else {
- rec_variance =
- vp9_high_get_sby_variance(cpi, &xd->plane[0].dst, bsize, xd->bd);
- src_variance =
- vp9_high_get_sby_variance(cpi, &x->plane[0].src, bsize, xd->bd);
- }
- } else {
- if (source_variance > 100) {
- rec_variance =
- vp9_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
- src_variance = source_variance;
- } else {
- rec_variance = vp9_get_sby_variance(cpi, &xd->plane[0].dst, bsize);
- src_variance = vp9_get_sby_variance(cpi, &x->plane[0].src, bsize);
- }
- }
-#else
- if (source_variance > 100) {
- rec_variance = vp9_get_sby_perpixel_variance(cpi, &xd->plane[0].dst, bsize);
- src_variance = source_variance;
+ rec_variance =
+ vp9_high_get_sby_variance(cpi, &xd->plane[0].dst, bsize, xd->bd);
+ src_variance =
+ vp9_high_get_sby_variance(cpi, &x->plane[0].src, bsize, xd->bd);
} else {
rec_variance = vp9_get_sby_variance(cpi, &xd->plane[0].dst, bsize);
src_variance = vp9_get_sby_variance(cpi, &x->plane[0].src, bsize);
}
+#else
+ rec_variance = vp9_get_sby_variance(cpi, &xd->plane[0].dst, bsize);
+ src_variance = vp9_get_sby_variance(cpi, &x->plane[0].src, bsize);
#endif // CONFIG_VP9_HIGHBITDEPTH
+ // Scale based on area in 8x8 blocks
+ rec_variance /= (bw * bh);
+ src_variance /= (bw * bh);
+
// Lower of source (raw per pixel value) and recon variance. Note that
// if the source per pixel is 0 then the recon value here will not be per
// pixel (see above) so will likely be much larger.
diff --git a/vp9/encoder/vp9_speed_features.c b/vp9/encoder/vp9_speed_features.c
index 46bd196ed..92c115fd1 100644
--- a/vp9/encoder/vp9_speed_features.c
+++ b/vp9/encoder/vp9_speed_features.c
@@ -265,14 +265,16 @@ static void set_good_speed_feature_framesize_independent(VP9_COMP *cpi,
sf->mv.auto_mv_step_size = 1;
sf->adaptive_rd_thresh = 2;
sf->mv.subpel_search_level = 1;
- sf->mode_skip_start = 10;
+ if (cpi->oxcf.content != VP9E_CONTENT_FILM) sf->mode_skip_start = 10;
sf->adaptive_pred_interp_filter = 1;
sf->allow_acl = 0;
sf->intra_y_mode_mask[TX_32X32] = INTRA_DC_H_V;
sf->intra_uv_mode_mask[TX_32X32] = INTRA_DC_H_V;
- sf->intra_y_mode_mask[TX_16X16] = INTRA_DC_H_V;
- sf->intra_uv_mode_mask[TX_16X16] = INTRA_DC_H_V;
+ if (cpi->oxcf.content != VP9E_CONTENT_FILM) {
+ sf->intra_y_mode_mask[TX_16X16] = INTRA_DC_H_V;
+ sf->intra_uv_mode_mask[TX_16X16] = INTRA_DC_H_V;
+ }
sf->recode_tolerance_low = 15;
sf->recode_tolerance_high = 30;