summaryrefslogtreecommitdiff
path: root/vp9
diff options
context:
space:
mode:
Diffstat (limited to 'vp9')
-rw-r--r--vp9/decoder/vp9_decoder.c8
-rw-r--r--vp9/encoder/vp9_bitstream.c9
-rw-r--r--vp9/encoder/vp9_encodeframe.c129
-rw-r--r--vp9/encoder/vp9_encoder.c497
-rw-r--r--vp9/encoder/vp9_encoder.h2
-rw-r--r--vp9/encoder/vp9_firstpass.c58
-rw-r--r--vp9/encoder/vp9_pickmode.c6
-rw-r--r--vp9/encoder/vp9_ratectrl.c4
-rw-r--r--vp9/encoder/vp9_rd.c12
-rw-r--r--vp9/encoder/vp9_rd.h5
-rw-r--r--vp9/encoder/vp9_rdopt.c9
-rw-r--r--vp9/encoder/vp9_svc_layercontext.c63
-rw-r--r--vp9/encoder/vp9_svc_layercontext.h10
-rw-r--r--vp9/encoder/vp9_temporal_filter.c3
-rw-r--r--vp9/encoder/x86/vp9_denoiser_sse2.c56
-rw-r--r--vp9/vp9_cx_iface.c6
16 files changed, 472 insertions, 405 deletions
diff --git a/vp9/decoder/vp9_decoder.c b/vp9/decoder/vp9_decoder.c
index 3c9469c4c..baf6ab7ef 100644
--- a/vp9/decoder/vp9_decoder.c
+++ b/vp9/decoder/vp9_decoder.c
@@ -232,6 +232,8 @@ int vp9_receive_compressed_data(VP9Decoder *pbi,
cm->frame_refs[0].buf->corrupted = 1;
}
+ pbi->ready_for_new_data = 0;
+
// Check if the previous frame was a frame without any references to it.
if (cm->new_fb_idx >= 0 && cm->frame_bufs[cm->new_fb_idx].ref_count == 0)
cm->release_fb_cb(cm->cb_priv,
@@ -279,8 +281,6 @@ int vp9_receive_compressed_data(VP9Decoder *pbi,
cm->current_video_frame++;
}
- pbi->ready_for_new_data = 0;
-
cm->error.setjmp = 0;
return retcode;
}
@@ -296,12 +296,12 @@ int vp9_get_raw_frame(VP9Decoder *pbi, YV12_BUFFER_CONFIG *sd,
if (pbi->ready_for_new_data == 1)
return ret;
+ pbi->ready_for_new_data = 1;
+
/* no raw frame to show!!! */
if (!cm->show_frame)
return ret;
- pbi->ready_for_new_data = 1;
-
#if CONFIG_VP9_POSTPROC
if (!cm->show_existing_frame) {
ret = vp9_post_proc_frame(cm, sd, flags);
diff --git a/vp9/encoder/vp9_bitstream.c b/vp9/encoder/vp9_bitstream.c
index 694cac76f..3954fe6a7 100644
--- a/vp9/encoder/vp9_bitstream.c
+++ b/vp9/encoder/vp9_bitstream.c
@@ -1013,7 +1013,11 @@ static void write_frame_size_with_refs(VP9_COMP *cpi,
((cpi->svc.number_temporal_layers > 1 &&
cpi->oxcf.rc_mode == VPX_CBR) ||
(cpi->svc.number_spatial_layers > 1 &&
- cpi->svc.layer_context[cpi->svc.spatial_layer_id].is_key_frame))) {
+ cpi->svc.layer_context[cpi->svc.spatial_layer_id].is_key_frame) ||
+ (is_two_pass_svc(cpi) &&
+ cpi->svc.encode_empty_frame_state == ENCODING &&
+ cpi->svc.layer_context[0].frames_from_key_frame <
+ cpi->svc.number_temporal_layers + 1))) {
found = 0;
}
vp9_wb_write_bit(wb, found);
@@ -1105,8 +1109,7 @@ static void write_uncompressed_header(VP9_COMP *cpi,
// will change to show_frame flag to 0, then add an one byte frame with
// show_existing_frame flag which tells the decoder which frame we want to
// show.
- if (!cm->show_frame ||
- (is_two_pass_svc(cpi) && cm->error_resilient_mode == 0))
+ if (!cm->show_frame)
vp9_wb_write_bit(wb, cm->intra_only);
if (!cm->error_resilient_mode)
diff --git a/vp9/encoder/vp9_encodeframe.c b/vp9/encoder/vp9_encodeframe.c
index a4e4fa325..87114f1bd 100644
--- a/vp9/encoder/vp9_encodeframe.c
+++ b/vp9/encoder/vp9_encodeframe.c
@@ -412,29 +412,47 @@ static int set_vt_partitioning(VP9_COMP *cpi,
return 1;
}
- // Vertical split is available on all but the bottom border.
- if (mi_row + block_height / 2 < cm->mi_rows &&
- vt.part_variances->vert[0].variance < threshold &&
- vt.part_variances->vert[1].variance < threshold) {
- BLOCK_SIZE subsize = get_subsize(bsize, PARTITION_VERT);
- set_block_size(cpi, mi_row, mi_col, subsize);
- set_block_size(cpi, mi_row, mi_col + block_width / 2, subsize);
- return 1;
- }
-
- // Horizontal split is available on all but the right border.
- if (mi_col + block_width / 2 < cm->mi_cols &&
- vt.part_variances->horz[0].variance < threshold &&
- vt.part_variances->horz[1].variance < threshold) {
- BLOCK_SIZE subsize = get_subsize(bsize, PARTITION_HORZ);
- set_block_size(cpi, mi_row, mi_col, subsize);
- set_block_size(cpi, mi_row + block_height / 2, mi_col, subsize);
- return 1;
+ // Only allow split for blocks above 16x16.
+ if (bsize > BLOCK_16X16) {
+ // Vertical split is available on all but the bottom border.
+ if (mi_row + block_height / 2 < cm->mi_rows &&
+ vt.part_variances->vert[0].variance < threshold &&
+ vt.part_variances->vert[1].variance < threshold) {
+ BLOCK_SIZE subsize = get_subsize(bsize, PARTITION_VERT);
+ set_block_size(cpi, mi_row, mi_col, subsize);
+ set_block_size(cpi, mi_row, mi_col + block_width / 2, subsize);
+ return 1;
+ }
+
+ // Horizontal split is available on all but the right border.
+ if (mi_col + block_width / 2 < cm->mi_cols &&
+ vt.part_variances->horz[0].variance < threshold &&
+ vt.part_variances->horz[1].variance < threshold) {
+ BLOCK_SIZE subsize = get_subsize(bsize, PARTITION_HORZ);
+ set_block_size(cpi, mi_row, mi_col, subsize);
+ set_block_size(cpi, mi_row + block_height / 2, mi_col, subsize);
+ return 1;
+ }
+ }
+
+ // This will only allow 8x8 if the 16x16 variance is very large.
+ if (bsize == BLOCK_16X16) {
+ if (mi_col + block_width / 2 < cm->mi_cols &&
+ mi_row + block_height / 2 < cm->mi_rows &&
+ vt.part_variances->none.variance < (threshold << 6)) {
+ set_block_size(cpi, mi_row, mi_col, bsize);
+ return 1;
+ }
}
return 0;
}
-// TODO(debargha): Fix this function and make it work as expected.
+// This function chooses partitioning based on the variance
+// between source and reconstructed last, where variance is
+// computed for 8x8 downsampled inputs. Some things to check:
+// using the last source rather than reconstructed last, and
+// allowing for small downsampling (4x4 or 2x2) for selection
+// of smaller block sizes (i.e., < 16x16).
static void choose_partitioning(VP9_COMP *cpi,
const TileInfo *const tile,
int mi_row, int mi_col) {
@@ -549,27 +567,11 @@ static void choose_partitioning(VP9_COMP *cpi,
for (j = 0; j < 4; ++j) {
const int x16_idx = ((j & 1) << 1);
const int y16_idx = ((j >> 1) << 1);
- // NOTE: This is a temporary hack to disable 8x8 partitions,
- // since it works really bad - possibly due to a bug
-#define DISABLE_8X8_VAR_BASED_PARTITION
-#ifdef DISABLE_8X8_VAR_BASED_PARTITION
- if (mi_row + y32_idx + y16_idx + 1 < cm->mi_rows &&
- mi_row + x32_idx + x16_idx + 1 < cm->mi_cols) {
- set_block_size(cpi,
- (mi_row + y32_idx + y16_idx),
- (mi_col + x32_idx + x16_idx),
- BLOCK_16X16);
- } else {
- for (k = 0; k < 4; ++k) {
- const int x8_idx = (k & 1);
- const int y8_idx = (k >> 1);
- set_block_size(cpi,
- (mi_row + y32_idx + y16_idx + y8_idx),
- (mi_col + x32_idx + x16_idx + x8_idx),
- BLOCK_8X8);
- }
- }
-#else
+ // NOTE: Since this uses 8x8 downsampling for variance calculation
+ // we cannot really select block size 8x8 (or even 8x16/16x8),
+ // since we do not sufficient samples for variance.
+ // For now, 8x8 partition is only set if the variance of the 16x16
+ // block is very high. This is controlled in set_vt_partitioning.
if (!set_vt_partitioning(cpi, &vt.split[i].split[j],
BLOCK_16X16,
mi_row + y32_idx + y16_idx,
@@ -583,7 +585,6 @@ static void choose_partitioning(VP9_COMP *cpi,
BLOCK_8X8);
}
}
-#endif
}
}
}
@@ -1521,9 +1522,7 @@ static void rd_use_partition(VP9_COMP *cpi, const TileInfo *const tile,
BLOCK_SIZE subsize;
ENTROPY_CONTEXT l[16 * MAX_MB_PLANE], a[16 * MAX_MB_PLANE];
PARTITION_CONTEXT sl[8], sa[8];
- RD_COST last_part_rdc = {INT_MAX, INT64_MAX, INT64_MAX};
- RD_COST none_rdc = {INT_MAX, INT64_MAX, INT64_MAX};
- RD_COST chosen_rdc = {INT_MAX, INT64_MAX, INT64_MAX};
+ RD_COST last_part_rdc, none_rdc, chosen_rdc;
BLOCK_SIZE sub_subsize = BLOCK_4X4;
int splits_below = 0;
BLOCK_SIZE bs_type = mi_8x8[0].src_mi->mbmi.sb_type;
@@ -1536,6 +1535,10 @@ static void rd_use_partition(VP9_COMP *cpi, const TileInfo *const tile,
assert(num_4x4_blocks_wide_lookup[bsize] ==
num_4x4_blocks_high_lookup[bsize]);
+ vp9_rd_cost_reset(&last_part_rdc);
+ vp9_rd_cost_reset(&none_rdc);
+ vp9_rd_cost_reset(&chosen_rdc);
+
partition = partition_lookup[bsl][bs_type];
subsize = get_subsize(bsize, partition);
@@ -1597,16 +1600,15 @@ static void rd_use_partition(VP9_COMP *cpi, const TileInfo *const tile,
INT64_MAX);
if (last_part_rdc.rate != INT_MAX &&
bsize >= BLOCK_8X8 && mi_row + (mi_step >> 1) < cm->mi_rows) {
- RD_COST tmp_rdc = {0, 0, 0};
+ RD_COST tmp_rdc;
PICK_MODE_CONTEXT *ctx = &pc_tree->horizontal[0];
+ vp9_rd_cost_init(&tmp_rdc);
update_state(cpi, ctx, mi_row, mi_col, subsize, 0);
encode_superblock(cpi, tp, 0, mi_row, mi_col, subsize, ctx);
rd_pick_sb_modes(cpi, tile, mi_row + (mi_step >> 1), mi_col, &tmp_rdc,
subsize, &pc_tree->horizontal[1], INT64_MAX);
if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) {
- last_part_rdc.rate = INT_MAX;
- last_part_rdc.dist = INT64_MAX;
- last_part_rdc.rdcost = INT64_MAX;
+ vp9_rd_cost_reset(&last_part_rdc);
break;
}
last_part_rdc.rate += tmp_rdc.rate;
@@ -1619,17 +1621,16 @@ static void rd_use_partition(VP9_COMP *cpi, const TileInfo *const tile,
subsize, &pc_tree->vertical[0], INT64_MAX);
if (last_part_rdc.rate != INT_MAX &&
bsize >= BLOCK_8X8 && mi_col + (mi_step >> 1) < cm->mi_cols) {
- RD_COST tmp_rdc = {0, 0, 0};
+ RD_COST tmp_rdc;
PICK_MODE_CONTEXT *ctx = &pc_tree->vertical[0];
+ vp9_rd_cost_init(&tmp_rdc);
update_state(cpi, ctx, mi_row, mi_col, subsize, 0);
encode_superblock(cpi, tp, 0, mi_row, mi_col, subsize, ctx);
rd_pick_sb_modes(cpi, tile, mi_row, mi_col + (mi_step >> 1), &tmp_rdc,
subsize, &pc_tree->vertical[bsize > BLOCK_8X8],
INT64_MAX);
if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) {
- last_part_rdc.rate = INT_MAX;
- last_part_rdc.dist = INT64_MAX;
- last_part_rdc.rdcost = INT64_MAX;
+ vp9_rd_cost_reset(&last_part_rdc);
break;
}
last_part_rdc.rate += tmp_rdc.rate;
@@ -1650,19 +1651,17 @@ static void rd_use_partition(VP9_COMP *cpi, const TileInfo *const tile,
int x_idx = (i & 1) * (mi_step >> 1);
int y_idx = (i >> 1) * (mi_step >> 1);
int jj = i >> 1, ii = i & 0x01;
- RD_COST tmp_rdc = {0, 0, 0};
-
+ RD_COST tmp_rdc;
if ((mi_row + y_idx >= cm->mi_rows) || (mi_col + x_idx >= cm->mi_cols))
continue;
+ vp9_rd_cost_init(&tmp_rdc);
rd_use_partition(cpi, tile, mi_8x8 + jj * bss * mis + ii * bss, tp,
mi_row + y_idx, mi_col + x_idx, subsize,
&tmp_rdc.rate, &tmp_rdc.dist,
i != 3, pc_tree->split[i]);
if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) {
- last_part_rdc.rate = INT_MAX;
- last_part_rdc.dist = INT64_MAX;
- last_part_rdc.rdcost = INT64_MAX;
+ vp9_rd_cost_reset(&last_part_rdc);
break;
}
last_part_rdc.rate += tmp_rdc.rate;
@@ -1709,15 +1708,12 @@ static void rd_use_partition(VP9_COMP *cpi, const TileInfo *const tile,
save_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
pc_tree->split[i]->partitioning = PARTITION_NONE;
rd_pick_sb_modes(cpi, tile, mi_row + y_idx, mi_col + x_idx, &tmp_rdc,
- split_subsize, &pc_tree->split[i]->none,
- INT64_MAX);
+ split_subsize, &pc_tree->split[i]->none, INT64_MAX);
restore_context(cpi, mi_row, mi_col, a, l, sa, sl, bsize);
if (tmp_rdc.rate == INT_MAX || tmp_rdc.dist == INT64_MAX) {
- chosen_rdc.rate = INT_MAX;
- chosen_rdc.dist = INT64_MAX;
- chosen_rdc.rdcost = INT64_MAX;
+ vp9_rd_cost_reset(&chosen_rdc);
break;
}
@@ -2122,9 +2118,7 @@ static void rd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
PICK_MODE_CONTEXT *ctx = &pc_tree->none;
int i, pl;
BLOCK_SIZE subsize;
- RD_COST this_rdc = {0, 0, 0};
- RD_COST sum_rdc = {0, 0, 0};
- RD_COST best_rdc = {INT_MAX, INT64_MAX, best_rd};
+ RD_COST this_rdc, sum_rdc, best_rdc;
int do_split = bsize >= BLOCK_8X8;
int do_rect = 1;
@@ -2152,6 +2146,11 @@ static void rd_pick_partition(VP9_COMP *cpi, const TileInfo *const tile,
assert(num_8x8_blocks_wide_lookup[bsize] ==
num_8x8_blocks_high_lookup[bsize]);
+ vp9_rd_cost_init(&this_rdc);
+ vp9_rd_cost_init(&sum_rdc);
+ vp9_rd_cost_reset(&best_rdc);
+ best_rdc.rdcost = best_rd;
+
set_offsets(cpi, tile, mi_row, mi_col, bsize);
if (bsize == BLOCK_16X16 && cpi->oxcf.aq_mode)
diff --git a/vp9/encoder/vp9_encoder.c b/vp9/encoder/vp9_encoder.c
index dea93062b..1758e3fdb 100644
--- a/vp9/encoder/vp9_encoder.c
+++ b/vp9/encoder/vp9_encoder.c
@@ -160,7 +160,7 @@ static void dealloc_compressor_data(VP9_COMP *cpi) {
VP9_COMMON *const cm = &cpi->common;
int i;
- // Delete segmentation map.
+ // Delete sementation map
vpx_free(cpi->segmentation_map);
cpi->segmentation_map = NULL;
vpx_free(cm->last_frame_seg_map);
@@ -225,6 +225,9 @@ static void dealloc_compressor_data(VP9_COMP *cpi) {
}
vpx_memset(&cpi->svc.scaled_frames[0], 0,
MAX_LAG_BUFFERS * sizeof(cpi->svc.scaled_frames[0]));
+
+ vp9_free_frame_buffer(&cpi->svc.empty_frame.img);
+ vpx_memset(&cpi->svc.empty_frame, 0, sizeof(cpi->svc.empty_frame));
}
static void save_coding_context(VP9_COMP *cpi) {
@@ -2413,33 +2416,30 @@ void vp9_scale_references(VP9_COMP *cpi) {
const VP9_REFFRAME ref_mask[3] = {VP9_LAST_FLAG, VP9_GOLD_FLAG, VP9_ALT_FLAG};
for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
- // Need to convert from VP9_REFFRAME to index into ref_mask (subtract 1).
- if (cpi->ref_frame_flags & ref_mask[ref_frame - 1]) {
- const int idx = cm->ref_frame_map[get_ref_frame_idx(cpi, ref_frame)];
- const YV12_BUFFER_CONFIG *const ref = &cm->frame_bufs[idx].buf;
+ const int idx = cm->ref_frame_map[get_ref_frame_idx(cpi, ref_frame)];
+ const YV12_BUFFER_CONFIG *const ref = &cm->frame_bufs[idx].buf;
- if (ref->y_crop_width != cm->width || ref->y_crop_height != cm->height) {
- const int new_fb = get_free_fb(cm);
- vp9_realloc_frame_buffer(&cm->frame_bufs[new_fb].buf,
- cm->width, cm->height,
- cm->subsampling_x, cm->subsampling_y,
+ // Need to convert from VP9_REFFRAME to index into ref_mask (subtract 1).
+ if ((cpi->ref_frame_flags & ref_mask[ref_frame - 1]) &&
+ (ref->y_crop_width != cm->width || ref->y_crop_height != cm->height)) {
+ const int new_fb = get_free_fb(cm);
+ vp9_realloc_frame_buffer(&cm->frame_bufs[new_fb].buf,
+ cm->width, cm->height,
+ cm->subsampling_x, cm->subsampling_y,
#if CONFIG_VP9_HIGHBITDEPTH
- cm->use_highbitdepth,
+ cm->use_highbitdepth,
#endif // CONFIG_VP9_HIGHBITDEPTH
- VP9_ENC_BORDER_IN_PIXELS, NULL, NULL, NULL);
+ VP9_ENC_BORDER_IN_PIXELS, NULL, NULL, NULL);
#if CONFIG_VP9_HIGHBITDEPTH
- scale_and_extend_frame(ref, &cm->frame_bufs[new_fb].buf,
- (int)cm->bit_depth);
+ scale_and_extend_frame(ref, &cm->frame_bufs[new_fb].buf,
+ (int)cm->bit_depth);
#else
- scale_and_extend_frame(ref, &cm->frame_bufs[new_fb].buf);
+ scale_and_extend_frame(ref, &cm->frame_bufs[new_fb].buf);
#endif // CONFIG_VP9_HIGHBITDEPTH
- cpi->scaled_ref_idx[ref_frame - 1] = new_fb;
- } else {
- cpi->scaled_ref_idx[ref_frame - 1] = idx;
- ++cm->frame_bufs[idx].ref_count;
- }
+ cpi->scaled_ref_idx[ref_frame - 1] = new_fb;
} else {
- cpi->scaled_ref_idx[ref_frame - 1] = INVALID_REF_BUFFER_IDX;
+ cpi->scaled_ref_idx[ref_frame - 1] = idx;
+ cm->frame_bufs[idx].ref_count++;
}
}
}
@@ -2447,13 +2447,9 @@ void vp9_scale_references(VP9_COMP *cpi) {
static void release_scaled_references(VP9_COMP *cpi) {
VP9_COMMON *cm = &cpi->common;
int i;
- for (i = 0; i < 3; ++i) {
- const int idx = cpi->scaled_ref_idx[i];
- RefCntBuffer *const buf =
- idx != INVALID_REF_BUFFER_IDX ? &cm->frame_bufs[idx] : NULL;
- if (buf != NULL)
- --buf->ref_count;
- }
+
+ for (i = 0; i < 3; i++)
+ cm->frame_bufs[cpi->scaled_ref_idx[i]].ref_count--;
}
static void full_to_model_count(unsigned int *model_count,
@@ -2538,181 +2534,10 @@ static void output_frame_level_debug_stats(VP9_COMP *cpi) {
}
#endif
-static void set_mv_search_params(VP9_COMP *cpi) {
- const VP9_COMMON *const cm = &cpi->common;
- const unsigned int max_mv_def = MIN(cm->width, cm->height);
-
- // Default based on max resolution.
- cpi->mv_step_param = vp9_init_search_range(max_mv_def);
-
- if (cpi->sf.mv.auto_mv_step_size) {
- if (frame_is_intra_only(cm)) {
- // Initialize max_mv_magnitude for use in the first INTER frame
- // after a key/intra-only frame.
- cpi->max_mv_magnitude = max_mv_def;
- } else {
- if (cm->show_frame)
- // Allow mv_steps to correspond to twice the max mv magnitude found
- // in the previous frame, capped by the default max_mv_magnitude based
- // on resolution.
- cpi->mv_step_param =
- vp9_init_search_range(MIN(max_mv_def, 2 * cpi->max_mv_magnitude));
- cpi->max_mv_magnitude = 0;
- }
- }
-}
-
-static void set_size_dependent_vars(VP9_COMP *cpi, int *q,
- int *bottom_index, int *top_index) {
+static void encode_without_recode_loop(VP9_COMP *cpi,
+ int q) {
VP9_COMMON *const cm = &cpi->common;
- const VP9EncoderConfig *const oxcf = &cpi->oxcf;
-
- // Setup variables that depend on the dimensions of the frame.
- set_mv_search_params(cpi);
-
- // Configure experimental use of segmentation for enhanced coding of
- // static regions if indicated.
- // Only allowed in the second pass of a two pass encode, as it requires
- // lagged coding, and if the relevant speed feature flag is set.
- if (oxcf->pass == 2 && cpi->sf.static_segmentation)
- configure_static_seg_features(cpi);
-
-#if CONFIG_VP9_POSTPROC
- if (oxcf->noise_sensitivity > 0) {
- int l = 0;
- switch (oxcf->noise_sensitivity) {
- case 1:
- l = 20;
- break;
- case 2:
- l = 40;
- break;
- case 3:
- l = 60;
- break;
- case 4:
- case 5:
- l = 100;
- break;
- case 6:
- l = 150;
- break;
- }
- vp9_denoise(cpi->Source, cpi->Source, l);
- }
-#endif // CONFIG_VP9_POSTPROC
-
- vp9_set_speed_features(cpi);
-
- vp9_set_rd_speed_thresholds(cpi);
- vp9_set_rd_speed_thresholds_sub8x8(cpi);
-
- // Decide q and q bounds.
- *q = vp9_rc_pick_q_and_bounds(cpi, bottom_index, top_index);
-
- if (!frame_is_intra_only(cm)) {
- cm->interp_filter = cpi->sf.default_interp_filter;
- // TODO: Decide this more intelligently.
- vp9_set_high_precision_mv(cpi, (*q) < HIGH_PRECISION_MV_QTHRESH);
- }
-}
-
-static void init_motion_estimation(VP9_COMP *cpi) {
- int y_stride = cpi->scaled_source.y_stride;
-
- if (cpi->sf.mv.search_method == NSTEP) {
- vp9_init3smotion_compensation(&cpi->ss_cfg, y_stride);
- } else if (cpi->sf.mv.search_method == DIAMOND) {
- vp9_init_dsmotion_compensation(&cpi->ss_cfg, y_stride);
- }
-}
-
-void set_frame_size(VP9_COMP *cpi) {
- int ref_frame;
- VP9_COMMON *const cm = &cpi->common;
- const VP9EncoderConfig *const oxcf = &cpi->oxcf;
- MACROBLOCKD *const xd = &cpi->mb.e_mbd;
-
- // For two pass encodes analyse the first pass stats and determine
- // the bit allocation and other parameters for this frame / group of frames.
- if ((oxcf->pass == 2) && (!cpi->use_svc || is_two_pass_svc(cpi))) {
- vp9_rc_get_second_pass_params(cpi);
- }
-
- if (!cpi->use_svc && cpi->multi_arf_allowed) {
- if (cm->frame_type == KEY_FRAME) {
- init_buffer_indices(cpi);
- } else if (oxcf->pass == 2) {
- const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
- cpi->alt_fb_idx = gf_group->arf_ref_idx[gf_group->index];
- }
- }
-
- if (oxcf->pass == 2 &&
- cm->current_video_frame == 0 &&
- oxcf->allow_spatial_resampling &&
- oxcf->rc_mode == VPX_VBR) {
- // Internal scaling is triggered on the first frame.
- vp9_set_size_literal(cpi, oxcf->scaled_frame_width,
- oxcf->scaled_frame_height);
- }
-
- // Reset the frame pointers to the current frame size.
- vp9_realloc_frame_buffer(get_frame_new_buffer(cm),
- cm->width, cm->height,
- cm->subsampling_x, cm->subsampling_y,
-#if CONFIG_VP9_HIGHBITDEPTH
- cm->use_highbitdepth,
-#endif
- VP9_ENC_BORDER_IN_PIXELS, NULL, NULL, NULL);
-
- alloc_util_frame_buffers(cpi);
- init_motion_estimation(cpi);
-
- for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
- const int idx = cm->ref_frame_map[get_ref_frame_idx(cpi, ref_frame)];
- YV12_BUFFER_CONFIG *const buf = &cm->frame_bufs[idx].buf;
- RefBuffer *const ref_buf = &cm->frame_refs[ref_frame - 1];
- ref_buf->buf = buf;
- ref_buf->idx = idx;
-#if CONFIG_VP9_HIGHBITDEPTH
- vp9_setup_scale_factors_for_frame(&ref_buf->sf,
- buf->y_crop_width, buf->y_crop_height,
- cm->width, cm->height,
- (buf->flags & YV12_FLAG_HIGHBITDEPTH) ?
- 1 : 0);
-#else
- vp9_setup_scale_factors_for_frame(&ref_buf->sf,
- buf->y_crop_width, buf->y_crop_height,
- cm->width, cm->height);
-#endif // CONFIG_VP9_HIGHBITDEPTH
- if (vp9_is_scaled(&ref_buf->sf))
- vp9_extend_frame_borders(buf);
- }
-
- set_ref_ptrs(cm, xd, LAST_FRAME, LAST_FRAME);
-}
-
-static void encode_without_recode_loop(VP9_COMP *cpi) {
- int q;
- int bottom_index, top_index; // Dummy.
- VP9_COMMON *const cm = &cpi->common;
-
vp9_clear_system_state();
-
- set_frame_size(cpi);
-
- cpi->Source = vp9_scale_if_required(cm, cpi->un_scaled_source,
- &cpi->scaled_source);
-
- if (cpi->unscaled_last_source != NULL)
- cpi->Last_Source = vp9_scale_if_required(cm, cpi->unscaled_last_source,
- &cpi->scaled_last_source);
-
- vp9_scale_references(cpi);
-
- set_size_dependent_vars(cpi, &q, &bottom_index, &top_index);
-
vp9_set_quantizer(cm, q);
setup_frame(cpi);
// Variance adaptive and in frame q adjustment experiments are mutually
@@ -2735,45 +2560,28 @@ static void encode_without_recode_loop(VP9_COMP *cpi) {
static void encode_with_recode_loop(VP9_COMP *cpi,
size_t *size,
- uint8_t *dest) {
+ uint8_t *dest,
+ int q,
+ int bottom_index,
+ int top_index) {
VP9_COMMON *const cm = &cpi->common;
RATE_CONTROL *const rc = &cpi->rc;
- int q;
- int q_low, q_high;
- int bottom_index, top_index;
int loop_count = 0;
int loop = 0;
int overshoot_seen = 0;
int undershoot_seen = 0;
+ int q_low = bottom_index, q_high = top_index;
int frame_over_shoot_limit;
int frame_under_shoot_limit;
+ // Decide frame size bounds
+ vp9_rc_compute_frame_size_bounds(cpi, rc->this_frame_target,
+ &frame_under_shoot_limit,
+ &frame_over_shoot_limit);
+
do {
vp9_clear_system_state();
- if (loop_count == 0) {
- set_frame_size(cpi);
-
- // Decide frame size bounds
- vp9_rc_compute_frame_size_bounds(cpi, rc->this_frame_target,
- &frame_under_shoot_limit,
- &frame_over_shoot_limit);
-
- cpi->Source = vp9_scale_if_required(cm, cpi->un_scaled_source,
- &cpi->scaled_source);
-
- if (cpi->unscaled_last_source != NULL)
- cpi->Last_Source = vp9_scale_if_required(cm, cpi->unscaled_last_source,
- &cpi->scaled_last_source);
-
- vp9_scale_references(cpi);
-
- set_size_dependent_vars(cpi, &q, &bottom_index, &top_index);
-
- q_low = bottom_index;
- q_high = top_index;
- }
-
vp9_set_quantizer(cm, q);
if (loop_count == 0)
@@ -3050,6 +2858,31 @@ static void set_arf_sign_bias(VP9_COMP *cpi) {
cm->ref_frame_sign_bias[ALTREF_FRAME] = arf_sign_bias;
}
+static void set_mv_search_params(VP9_COMP *cpi) {
+ const VP9_COMMON *const cm = &cpi->common;
+ const unsigned int max_mv_def = MIN(cm->width, cm->height);
+
+ // Default based on max resolution.
+ cpi->mv_step_param = vp9_init_search_range(max_mv_def);
+
+ if (cpi->sf.mv.auto_mv_step_size) {
+ if (frame_is_intra_only(cm)) {
+ // Initialize max_mv_magnitude for use in the first INTER frame
+ // after a key/intra-only frame.
+ cpi->max_mv_magnitude = max_mv_def;
+ } else {
+ if (cm->show_frame)
+ // Allow mv_steps to correspond to twice the max mv magnitude found
+ // in the previous frame, capped by the default max_mv_magnitude based
+ // on resolution.
+ cpi->mv_step_param =
+ vp9_init_search_range(MIN(max_mv_def, 2 * cpi->max_mv_magnitude));
+ cpi->max_mv_magnitude = 0;
+ }
+ }
+}
+
+
int setup_interp_filter_search_mask(VP9_COMP *cpi) {
INTERP_FILTER ifilter;
int ref_total[MAX_REF_FRAMES] = {0};
@@ -3084,9 +2917,21 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
const VP9EncoderConfig *const oxcf = &cpi->oxcf;
struct segmentation *const seg = &cm->seg;
TX_SIZE t;
+ int q;
+ int top_index;
+ int bottom_index;
set_ext_overrides(cpi);
+ cpi->Source = vp9_scale_if_required(cm, cpi->un_scaled_source,
+ &cpi->scaled_source);
+
+ if (cpi->unscaled_last_source != NULL)
+ cpi->Last_Source = vp9_scale_if_required(cm, cpi->unscaled_last_source,
+ &cpi->scaled_last_source);
+
+ vp9_scale_references(cpi);
+
vp9_clear_system_state();
// Enable or disable mode based tweaking of the zbin.
@@ -3101,11 +2946,14 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
// Set default state for segment based loop filter update flags.
cm->lf.mode_ref_delta_update = 0;
+ set_mv_search_params(cpi);
+
if (cpi->oxcf.pass == 2 &&
cpi->sf.adaptive_interp_filter_search)
cpi->sf.interp_filter_search_mask =
setup_interp_filter_search_mask(cpi);
+
// Set various flags etc to special state if it is a key frame.
if (frame_is_intra_only(cm)) {
// Reset the loop filter deltas and segmentation map.
@@ -3134,7 +2982,9 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
}
}
if (is_two_pass_svc(cpi) && cm->error_resilient_mode == 0) {
+ // Use the last frame context for the empty frame.
cm->frame_context_idx =
+ (cpi->svc.encode_empty_frame_state == ENCODING) ? FRAME_CONTEXTS - 1 :
cpi->svc.spatial_layer_id * cpi->svc.number_temporal_layers +
cpi->svc.temporal_layer_id;
@@ -3163,6 +3013,13 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
}
}
+ // Configure experimental use of segmentation for enhanced coding of
+ // static regions if indicated.
+ // Only allowed in second pass of two pass (as requires lagged coding)
+ // and if the relevant speed feature flag is set.
+ if (oxcf->pass == 2 && cpi->sf.static_segmentation)
+ configure_static_seg_features(cpi);
+
// Check if the current frame is skippable for the partition search in the
// second pass according to the first pass stats
if (cpi->sf.allow_partition_search_skip && oxcf->pass == 2 &&
@@ -3184,6 +3041,31 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
vp9_clear_system_state();
+#if CONFIG_VP9_POSTPROC
+ if (oxcf->noise_sensitivity > 0) {
+ int l = 0;
+ switch (oxcf->noise_sensitivity) {
+ case 1:
+ l = 20;
+ break;
+ case 2:
+ l = 40;
+ break;
+ case 3:
+ l = 60;
+ break;
+ case 4:
+ case 5:
+ l = 100;
+ break;
+ case 6:
+ l = 150;
+ break;
+ }
+ vp9_denoise(cpi->Source, cpi->Source, l);
+ }
+#endif
+
#if CONFIG_INTERNAL_STATS
{
int i;
@@ -3192,10 +3074,24 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
}
#endif
+ vp9_set_speed_features(cpi);
+
+ vp9_set_rd_speed_thresholds(cpi);
+ vp9_set_rd_speed_thresholds_sub8x8(cpi);
+
+ // Decide q and q bounds.
+ q = vp9_rc_pick_q_and_bounds(cpi, &bottom_index, &top_index);
+
+ if (!frame_is_intra_only(cm)) {
+ cm->interp_filter = cpi->sf.default_interp_filter;
+ /* TODO: Decide this more intelligently */
+ vp9_set_high_precision_mv(cpi, q < HIGH_PRECISION_MV_QTHRESH);
+ }
+
if (cpi->sf.recode_loop == DISALLOW_RECODE) {
- encode_without_recode_loop(cpi);
+ encode_without_recode_loop(cpi, q);
} else {
- encode_with_recode_loop(cpi, size, dest);
+ encode_with_recode_loop(cpi, size, dest, q, bottom_index, top_index);
}
#if CONFIG_VP9_TEMPORAL_DENOISING
@@ -3269,7 +3165,9 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
cpi->ref_frame_flags = get_ref_frame_flags(cpi);
cm->last_frame_type = cm->frame_type;
- vp9_rc_postencode_update(cpi, *size);
+
+ if (!(is_two_pass_svc(cpi) && cpi->svc.encode_empty_frame_state == ENCODING))
+ vp9_rc_postencode_update(cpi, *size);
#if 0
output_frame_level_debug_stats(cpi);
@@ -3293,12 +3191,8 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
cm->last_height = cm->height;
// reset to normal state now that we are done.
- if (!cm->show_existing_frame) {
- if (is_two_pass_svc(cpi) && cm->error_resilient_mode == 0)
- cm->last_show_frame = 0;
- else
- cm->last_show_frame = cm->show_frame;
- }
+ if (!cm->show_existing_frame)
+ cm->last_show_frame = cm->show_frame;
if (cm->show_frame) {
vp9_swap_mi_and_prev_mi(cm);
@@ -3335,7 +3229,19 @@ static void Pass2Encode(VP9_COMP *cpi, size_t *size,
uint8_t *dest, unsigned int *frame_flags) {
cpi->allow_encode_breakout = ENCODE_BREAKOUT_ENABLED;
encode_frame_to_data_rate(cpi, size, dest, frame_flags);
- vp9_twopass_postencode_update(cpi);
+
+ if (!(is_two_pass_svc(cpi) && cpi->svc.encode_empty_frame_state == ENCODING))
+ vp9_twopass_postencode_update(cpi);
+}
+
+static void init_motion_estimation(VP9_COMP *cpi) {
+ int y_stride = cpi->scaled_source.y_stride;
+
+ if (cpi->sf.mv.search_method == NSTEP) {
+ vp9_init3smotion_compensation(&cpi->ss_cfg, y_stride);
+ } else if (cpi->sf.mv.search_method == DIAMOND) {
+ vp9_init_dsmotion_compensation(&cpi->ss_cfg, y_stride);
+ }
}
static void check_initial_width(VP9_COMP *cpi,
@@ -3356,11 +3262,10 @@ static void check_initial_width(VP9_COMP *cpi,
alloc_ref_frame_buffers(cpi);
alloc_util_frame_buffers(cpi);
- init_motion_estimation(cpi); // TODO(agrange) This can be removed.
+ init_motion_estimation(cpi);
cpi->initial_width = cm->width;
cpi->initial_height = cm->height;
- cpi->initial_mbs = cm->MBs;
}
}
@@ -3502,17 +3407,21 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
int64_t *time_stamp, int64_t *time_end, int flush) {
const VP9EncoderConfig *const oxcf = &cpi->oxcf;
VP9_COMMON *const cm = &cpi->common;
+ MACROBLOCKD *const xd = &cpi->mb.e_mbd;
RATE_CONTROL *const rc = &cpi->rc;
struct vpx_usec_timer cmptimer;
YV12_BUFFER_CONFIG *force_src_buffer = NULL;
struct lookahead_entry *last_source = NULL;
struct lookahead_entry *source = NULL;
+ MV_REFERENCE_FRAME ref_frame;
int arf_src_index;
- int i;
if (is_two_pass_svc(cpi)) {
#if CONFIG_SPATIAL_SVC
vp9_svc_start_frame(cpi);
+ // Use a small empty frame instead of a real frame
+ if (cpi->svc.encode_empty_frame_state == ENCODING)
+ source = &cpi->svc.empty_frame;
#endif
if (oxcf->pass == 2)
vp9_restore_layer_context(cpi);
@@ -3531,6 +3440,11 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
// Should we encode an arf frame.
arf_src_index = get_arf_src_index(cpi);
+
+ // Skip alt frame if we encode the empty frame
+ if (is_two_pass_svc(cpi) && source != NULL)
+ arf_src_index = 0;
+
if (arf_src_index) {
assert(arf_src_index <= rc->frames_to_key);
@@ -3630,28 +3544,83 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
vp9_restore_layer_context(cpi);
}
- // Find a free buffer for the new frame, releasing the reference previously
- // held.
+ // start with a 0 size frame
+ *size = 0;
+
+ /* find a free buffer for the new frame, releasing the reference previously
+ * held.
+ */
cm->frame_bufs[cm->new_fb_idx].ref_count--;
cm->new_fb_idx = get_free_fb(cm);
- // Start with a 0 size frame.
- *size = 0;
+ // For two pass encodes analyse the first pass stats and determine
+ // the bit allocation and other parameters for this frame / group of frames.
+ if ((oxcf->pass == 2) &&
+ (!cpi->use_svc ||
+ (is_two_pass_svc(cpi) &&
+ cpi->svc.encode_empty_frame_state != ENCODING))) {
+ vp9_rc_get_second_pass_params(cpi);
+ }
+
+ if (!cpi->use_svc && cpi->multi_arf_allowed) {
+ if (cm->frame_type == KEY_FRAME) {
+ init_buffer_indices(cpi);
+ } else if (oxcf->pass == 2) {
+ const GF_GROUP *const gf_group = &cpi->twopass.gf_group;
+ cpi->alt_fb_idx = gf_group->arf_ref_idx[gf_group->index];
+ }
+ }
cpi->frame_flags = *frame_flags;
- // Delay setting frame-size until the encode loop for 2-pass non-SVC.
- if (!(oxcf->pass == 2 && (!cpi->use_svc || is_two_pass_svc(cpi)))) {
- set_frame_size(cpi);
+ if (oxcf->pass == 2 &&
+ cm->current_video_frame == 0 &&
+ oxcf->allow_spatial_resampling &&
+ oxcf->rc_mode == VPX_VBR) {
+ // Internal scaling is triggered on the first frame.
+ vp9_set_size_literal(cpi, oxcf->scaled_frame_width,
+ oxcf->scaled_frame_height);
+ }
+
+ // Reset the frame pointers to the current frame size
+ vp9_realloc_frame_buffer(get_frame_new_buffer(cm),
+ cm->width, cm->height,
+ cm->subsampling_x, cm->subsampling_y,
+#if CONFIG_VP9_HIGHBITDEPTH
+ cm->use_highbitdepth,
+#endif
+ VP9_ENC_BORDER_IN_PIXELS, NULL, NULL, NULL);
+
+ alloc_util_frame_buffers(cpi);
+ init_motion_estimation(cpi);
+
+ for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
+ const int idx = cm->ref_frame_map[get_ref_frame_idx(cpi, ref_frame)];
+ YV12_BUFFER_CONFIG *const buf = &cm->frame_bufs[idx].buf;
+ RefBuffer *const ref_buf = &cm->frame_refs[ref_frame - 1];
+ ref_buf->buf = buf;
+ ref_buf->idx = idx;
+#if CONFIG_VP9_HIGHBITDEPTH
+ vp9_setup_scale_factors_for_frame(&ref_buf->sf,
+ buf->y_crop_width, buf->y_crop_height,
+ cm->width, cm->height,
+ (buf->flags & YV12_FLAG_HIGHBITDEPTH) ?
+ 1 : 0);
+#else
+ vp9_setup_scale_factors_for_frame(&ref_buf->sf,
+ buf->y_crop_width, buf->y_crop_height,
+ cm->width, cm->height);
+#endif // CONFIG_VP9_HIGHBITDEPTH
+ if (vp9_is_scaled(&ref_buf->sf))
+ vp9_extend_frame_borders(buf);
}
+ set_ref_ptrs(cm, xd, LAST_FRAME, LAST_FRAME);
+
if (oxcf->aq_mode == VARIANCE_AQ) {
vp9_vaq_init();
}
- for (i = 0; i < 3; ++i)
- cpi->scaled_ref_idx[i] = INVALID_REF_BUFFER_IDX;
-
if (oxcf->pass == 1 &&
(!cpi->use_svc || is_two_pass_svc(cpi))) {
const int lossless = is_lossless_requested(oxcf);
@@ -3680,7 +3649,7 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
if (cm->refresh_frame_context)
cm->frame_contexts[cm->frame_context_idx] = cm->fc;
- // No frame encoded, or frame was dropped, release scaled references.
+ // Frame was dropped, release scaled references.
if (*size == 0) {
release_scaled_references(cpi);
}
@@ -3818,10 +3787,18 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
#endif
- if (is_two_pass_svc(cpi) && cm->show_frame) {
- ++cpi->svc.spatial_layer_to_encode;
- if (cpi->svc.spatial_layer_to_encode >= cpi->svc.number_spatial_layers)
- cpi->svc.spatial_layer_to_encode = 0;
+ if (is_two_pass_svc(cpi)) {
+ if (cpi->svc.encode_empty_frame_state == ENCODING)
+ cpi->svc.encode_empty_frame_state = ENCODED;
+
+ if (cm->show_frame) {
+ ++cpi->svc.spatial_layer_to_encode;
+ if (cpi->svc.spatial_layer_to_encode >= cpi->svc.number_spatial_layers)
+ cpi->svc.spatial_layer_to_encode = 0;
+
+ // May need the empty frame after an visible frame.
+ cpi->svc.encode_empty_frame_state = NEED_TO_ENCODE;
+ }
}
return 0;
}
@@ -3912,10 +3889,6 @@ int vp9_set_size_literal(VP9_COMP *cpi, unsigned int width,
if (width) {
cm->width = width;
- if (cm->width * 5 < cpi->initial_width) {
- cm->width = cpi->initial_width / 5 + 1;
- printf("Warning: Desired width too small, changed to %d\n", cm->width);
- }
if (cm->width > cpi->initial_width) {
cm->width = cpi->initial_width;
printf("Warning: Desired width too large, changed to %d\n", cm->width);
@@ -3924,10 +3897,6 @@ int vp9_set_size_literal(VP9_COMP *cpi, unsigned int width,
if (height) {
cm->height = height;
- if (cm->height * 5 < cpi->initial_height) {
- cm->height = cpi->initial_height / 5 + 1;
- printf("Warning: Desired height too small, changed to %d\n", cm->height);
- }
if (cm->height > cpi->initial_height) {
cm->height = cpi->initial_height;
printf("Warning: Desired height too large, changed to %d\n", cm->height);
diff --git a/vp9/encoder/vp9_encoder.h b/vp9/encoder/vp9_encoder.h
index 1eb2629e1..6091ae290 100644
--- a/vp9/encoder/vp9_encoder.h
+++ b/vp9/encoder/vp9_encoder.h
@@ -44,7 +44,6 @@ extern "C" {
#endif
#define DEFAULT_GF_INTERVAL 10
-#define INVALID_REF_BUFFER_IDX -1
typedef struct {
int nmvjointcost[MV_JOINTS];
@@ -376,7 +375,6 @@ typedef struct VP9_COMP {
int initial_width;
int initial_height;
- int initial_mbs;
int use_svc;
diff --git a/vp9/encoder/vp9_firstpass.c b/vp9/encoder/vp9_firstpass.c
index 9e204d7e9..96c3e0aa4 100644
--- a/vp9/encoder/vp9_firstpass.c
+++ b/vp9/encoder/vp9_firstpass.c
@@ -145,7 +145,7 @@ static void output_fpmb_stats(uint8_t *this_frame_mb_stats, VP9_COMMON *cm,
struct vpx_codec_cx_pkt pkt;
pkt.kind = VPX_CODEC_FPMB_STATS_PKT;
pkt.data.firstpass_mb_stats.buf = this_frame_mb_stats;
- pkt.data.firstpass_mb_stats.sz = cpi->initial_mbs * sizeof(uint8_t);
+ pkt.data.firstpass_mb_stats.sz = cm->MBs * sizeof(uint8_t);
vpx_codec_pkt_list_add(pktlist, &pkt);
}
#endif
@@ -339,9 +339,9 @@ static unsigned int highbd_get_prediction_error(BLOCK_SIZE bsize,
// Refine the motion search range according to the frame dimension
// for first pass test.
-static int get_search_range(const VP9_COMP *cpi) {
+static int get_search_range(const VP9_COMMON *cm) {
int sr = 0;
- const int dim = MIN(cpi->initial_width, cpi->initial_height);
+ const int dim = MIN(cm->width, cm->height);
while ((dim << sr) < MAX_FULL_PEL_VAL)
++sr;
@@ -361,7 +361,7 @@ static void first_pass_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
int step_param = 3;
int further_steps = (MAX_MVSEARCH_STEPS - 1) - step_param;
- const int sr = get_search_range(cpi);
+ const int sr = get_search_range(&cpi->common);
step_param += sr;
further_steps -= sr;
@@ -490,7 +490,7 @@ void vp9_first_pass(VP9_COMP *cpi, const struct lookahead_entry *source) {
#if CONFIG_FP_MB_STATS
if (cpi->use_fp_mb_stats) {
- vp9_zero_array(cpi->twopass.frame_mb_stats_buf, cpi->initial_mbs);
+ vp9_zero_array(cpi->twopass.frame_mb_stats_buf, cm->MBs);
}
#endif
@@ -946,7 +946,7 @@ void vp9_first_pass(VP9_COMP *cpi, const struct lookahead_entry *source) {
// where the typical "real" energy per MB also falls.
// Initial estimate here uses sqrt(mbs) to define the min_err, where the
// number of mbs is propotional to image area.
- const double min_err = 200 * sqrt(cpi->initial_mbs);
+ const double min_err = 200 * sqrt(cm->MBs);
fps.frame = cm->current_video_frame;
fps.spatial_layer_id = cpi->svc.spatial_layer_id;
@@ -954,9 +954,9 @@ void vp9_first_pass(VP9_COMP *cpi, const struct lookahead_entry *source) {
fps.sr_coded_error = (double)(sr_coded_error >> 8) + min_err;
fps.intra_error = (double)(intra_error >> 8) + min_err;
fps.count = 1.0;
- fps.pcnt_inter = (double)intercount / cpi->initial_mbs;
- fps.pcnt_second_ref = (double)second_ref_count / cpi->initial_mbs;
- fps.pcnt_neutral = (double)neutral_count / cpi->initial_mbs;
+ fps.pcnt_inter = (double)intercount / cm->MBs;
+ fps.pcnt_second_ref = (double)second_ref_count / cm->MBs;
+ fps.pcnt_neutral = (double)neutral_count / cm->MBs;
if (mvcount > 0) {
fps.MVr = (double)sum_mvr / mvcount;
@@ -967,7 +967,7 @@ void vp9_first_pass(VP9_COMP *cpi, const struct lookahead_entry *source) {
fps.MVcv = ((double)sum_mvcs - (fps.MVc * fps.MVc / mvcount)) / mvcount;
fps.mv_in_out_count = (double)sum_in_vectors / (mvcount * 2);
fps.new_mv_count = new_mv_count;
- fps.pcnt_motion = (double)mvcount / cpi->initial_mbs;
+ fps.pcnt_motion = (double)mvcount / cm->MBs;
} else {
fps.MVr = 0.0;
fps.mvr_abs = 0.0;
@@ -1081,7 +1081,7 @@ static int get_twopass_worst_quality(const VP9_COMP *cpi,
if (section_target_bandwidth <= 0) {
return rc->worst_quality; // Highest value allowed
} else {
- const int num_mbs = cpi->initial_mbs;
+ const int num_mbs = cpi->common.MBs;
const double section_err = stats->coded_error / stats->count;
const double err_per_mb = section_err / num_mbs;
const double speed_term = 1.0 + 0.04 * oxcf->speed;
@@ -1195,10 +1195,9 @@ void vp9_init_second_pass(VP9_COMP *cpi) {
#define LOW_SR_DIFF_TRHESH 0.1
#define SR_DIFF_MAX 128.0
-static double get_sr_decay_rate(const VP9_COMP *cpi,
+static double get_sr_decay_rate(const VP9_COMMON *cm,
const FIRSTPASS_STATS *frame) {
- double sr_diff =
- (frame->sr_coded_error - frame->coded_error) / cpi->initial_mbs;
+ double sr_diff = (frame->sr_coded_error - frame->coded_error) / cm->MBs;
double sr_decay = 1.0;
const double motion_amplitude_factor =
frame->pcnt_motion * ((frame->mvc_abs + frame->mvr_abs) / 2);
@@ -1215,19 +1214,19 @@ static double get_sr_decay_rate(const VP9_COMP *cpi,
// This function gives an estimate of how badly we believe the prediction
// quality is decaying from frame to frame.
-static double get_zero_motion_factor(const VP9_COMP *cpi,
+static double get_zero_motion_factor(const VP9_COMMON *cm,
const FIRSTPASS_STATS *frame) {
const double zero_motion_pct = frame->pcnt_inter -
frame->pcnt_motion;
- double sr_decay = get_sr_decay_rate(cpi, frame);
+ double sr_decay = get_sr_decay_rate(cm, frame);
return MIN(sr_decay, zero_motion_pct);
}
#define ZM_POWER_FACTOR 0.75
-static double get_prediction_decay_rate(const VP9_COMP *cpi,
+static double get_prediction_decay_rate(const VP9_COMMON *cm,
const FIRSTPASS_STATS *next_frame) {
- const double sr_decay_rate = get_sr_decay_rate(cpi, next_frame);
+ const double sr_decay_rate = get_sr_decay_rate(cm, next_frame);
const double zero_motion_factor =
(0.95 * pow((next_frame->pcnt_inter - next_frame->pcnt_motion),
ZM_POWER_FACTOR));
@@ -1323,7 +1322,7 @@ static double calc_frame_boost(VP9_COMP *cpi,
const double q_correction = MIN((0.8 + (lq * 0.001)), 1.0);
// Underlying boost factor is based on inter error ratio.
- frame_boost = (BASELINE_ERR_PER_MB * cpi->initial_mbs) /
+ frame_boost = (BASELINE_ERR_PER_MB * cpi->common.MBs) /
DOUBLE_DIVIDE_CHECK(this_frame->coded_error);
frame_boost = frame_boost * BOOST_FACTOR * q_correction;
@@ -1372,7 +1371,7 @@ static int calc_arf_boost(VP9_COMP *cpi, int offset,
// Accumulate the effect of prediction quality decay.
if (!flash_detected) {
- decay_accumulator *= get_prediction_decay_rate(cpi, this_frame);
+ decay_accumulator *= get_prediction_decay_rate(&cpi->common, this_frame);
decay_accumulator = decay_accumulator < MIN_DECAY_FACTOR
? MIN_DECAY_FACTOR : decay_accumulator;
}
@@ -1411,7 +1410,7 @@ static int calc_arf_boost(VP9_COMP *cpi, int offset,
// Cumulative effect of prediction quality decay.
if (!flash_detected) {
- decay_accumulator *= get_prediction_decay_rate(cpi, this_frame);
+ decay_accumulator *= get_prediction_decay_rate(&cpi->common, this_frame);
decay_accumulator = decay_accumulator < MIN_DECAY_FACTOR
? MIN_DECAY_FACTOR : decay_accumulator;
}
@@ -1730,8 +1729,7 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
gf_group_err -= gf_first_frame_err;
// Motion breakout threshold for loop below depends on image size.
- mv_ratio_accumulator_thresh =
- (cpi->initial_height + cpi->initial_width) / 4.0;
+ mv_ratio_accumulator_thresh = (cpi->common.width + cpi->common.height) / 4.0;
// Set a maximum and minimum interval for the GF group.
// If the image appears almost completely static we can extend beyond this.
@@ -1783,14 +1781,14 @@ static void define_gf_group(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
// Accumulate the effect of prediction quality decay.
if (!flash_detected) {
last_loop_decay_rate = loop_decay_rate;
- loop_decay_rate = get_prediction_decay_rate(cpi, &next_frame);
+ loop_decay_rate = get_prediction_decay_rate(&cpi->common, &next_frame);
decay_accumulator = decay_accumulator * loop_decay_rate;
// Monitor for static sections.
zero_motion_accumulator =
MIN(zero_motion_accumulator,
- get_zero_motion_factor(cpi, &next_frame));
+ get_zero_motion_factor(&cpi->common, &next_frame));
// Break clause to detect very still sections after motion. For example,
// a static image after a fade or other transition.
@@ -2067,7 +2065,8 @@ static void find_next_key_frame(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
break;
// How fast is the prediction quality decaying?
- loop_decay_rate = get_prediction_decay_rate(cpi, twopass->stats_in);
+ loop_decay_rate = get_prediction_decay_rate(&cpi->common,
+ twopass->stats_in);
// We want to know something about the recent past... rather than
// as used elsewhere where we are concerned with decay in prediction
@@ -2178,7 +2177,7 @@ static void find_next_key_frame(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
// Monitor for static sections.
zero_motion_accumulator =
MIN(zero_motion_accumulator,
- get_zero_motion_factor(cpi, &next_frame));
+ get_zero_motion_factor(&cpi->common, &next_frame));
// Not all frames in the group are necessarily used in calculating boost.
if ((i <= rc->max_gf_interval) ||
@@ -2189,7 +2188,7 @@ static void find_next_key_frame(VP9_COMP *cpi, FIRSTPASS_STATS *this_frame) {
// How fast is prediction quality decaying.
if (!detect_flash(twopass, 0)) {
const double loop_decay_rate =
- get_prediction_decay_rate(cpi, &next_frame);
+ get_prediction_decay_rate(&cpi->common, &next_frame);
decay_accumulator *= loop_decay_rate;
decay_accumulator = MAX(decay_accumulator, MIN_DECAY_FACTOR);
av_decay_accumulator += decay_accumulator;
@@ -2406,6 +2405,9 @@ void vp9_rc_get_second_pass_params(VP9_COMP *cpi) {
cpi->ref_frame_flags &=
(~VP9_LAST_FLAG & ~VP9_GOLD_FLAG & ~VP9_ALT_FLAG);
lc->frames_from_key_frame = 0;
+ // Reset the empty frame resolution since we have a key frame.
+ cpi->svc.empty_frame_width = cm->width;
+ cpi->svc.empty_frame_height = cm->height;
}
} else {
cm->frame_type = INTER_FRAME;
diff --git a/vp9/encoder/vp9_pickmode.c b/vp9/encoder/vp9_pickmode.c
index 42f46917c..b74b2dd56 100644
--- a/vp9/encoder/vp9_pickmode.c
+++ b/vp9/encoder/vp9_pickmode.c
@@ -486,8 +486,12 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
// var_y and sse_y are saved to be used in skipping checking
unsigned int var_y = UINT_MAX;
unsigned int sse_y = UINT_MAX;
+ // Reduce the intra cost penalty for small blocks (<=16x16).
+ const int reduction_fac =
+ (cpi->sf.partition_search_type == VAR_BASED_PARTITION &&
+ bsize <= BLOCK_16X16) ? 4 : 1;
const int intra_cost_penalty = vp9_get_intra_cost_penalty(
- cm->base_qindex, cm->y_dc_delta_q, cm->bit_depth);
+ cm->base_qindex, cm->y_dc_delta_q, cm->bit_depth) / reduction_fac;
const int64_t inter_mode_thresh = RDCOST(x->rdmult, x->rddiv,
intra_cost_penalty, 0);
const int intra_mode_cost = 50;
diff --git a/vp9/encoder/vp9_ratectrl.c b/vp9/encoder/vp9_ratectrl.c
index ef32fe179..65bca669a 100644
--- a/vp9/encoder/vp9_ratectrl.c
+++ b/vp9/encoder/vp9_ratectrl.c
@@ -1500,9 +1500,7 @@ void vp9_rc_set_gf_max_interval(const VP9_COMP *const cpi,
rc->max_gf_interval = 16;
// Extended interval for genuinely static scenes
- rc->static_scene_max_gf_interval = oxcf->key_freq >> 1;
- if (rc->static_scene_max_gf_interval > (MAX_LAG_BUFFERS * 2))
- rc->static_scene_max_gf_interval = MAX_LAG_BUFFERS * 2;
+ rc->static_scene_max_gf_interval = MAX_LAG_BUFFERS * 2;
if (is_altref_enabled(cpi)) {
if (rc->static_scene_max_gf_interval > oxcf->lag_in_frames - 1)
diff --git a/vp9/encoder/vp9_rd.c b/vp9/encoder/vp9_rd.c
index 75c396433..7f526fc42 100644
--- a/vp9/encoder/vp9_rd.c
+++ b/vp9/encoder/vp9_rd.c
@@ -44,6 +44,18 @@
// Factor to weigh the rate for switchable interp filters.
#define SWITCHABLE_INTERP_RATE_FACTOR 1
+void vp9_rd_cost_reset(RD_COST *rd_cost) {
+ rd_cost->rate = INT_MAX;
+ rd_cost->dist = INT64_MAX;
+ rd_cost->rdcost = INT64_MAX;
+}
+
+void vp9_rd_cost_init(RD_COST *rd_cost) {
+ rd_cost->rate = 0;
+ rd_cost->dist = 0;
+ rd_cost->rdcost = 0;
+}
+
// The baseline rd thresholds for breaking out of the rd loop for
// certain modes are assumed to be based on 8x8 blocks.
// This table is used to correct for block size.
diff --git a/vp9/encoder/vp9_rd.h b/vp9/encoder/vp9_rd.h
index 33fb4ac94..1aa52663a 100644
--- a/vp9/encoder/vp9_rd.h
+++ b/vp9/encoder/vp9_rd.h
@@ -123,6 +123,11 @@ typedef struct RD_COST {
int64_t rdcost;
} RD_COST;
+// Reset the rate distortion cost values to maximum (invalid) value.
+void vp9_rd_cost_reset(RD_COST *rd_cost);
+// Initialize the rate distortion cost values to zero.
+void vp9_rd_cost_init(RD_COST *rd_cost);
+
struct TileInfo;
struct VP9_COMP;
struct macroblock;
diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c
index 7565cc5c9..eca8e5880 100644
--- a/vp9/encoder/vp9_rdopt.c
+++ b/vp9/encoder/vp9_rdopt.c
@@ -1140,12 +1140,14 @@ static int super_block_uvrd(const VP9_COMP *cpi, MACROBLOCK *x,
*sse = 0;
*skippable = 1;
- for (plane = 1; plane < MAX_MB_PLANE && is_cost_valid; ++plane) {
+ for (plane = 1; plane < MAX_MB_PLANE; ++plane) {
txfm_rd_in_plane(x, &pnrate, &pndist, &pnskip, &pnsse,
ref_best_rd, plane, bsize, uv_tx_size,
cpi->sf.use_fast_coef_costing);
- if (pnrate == INT_MAX)
+ if (pnrate == INT_MAX) {
is_cost_valid = 0;
+ break;
+ }
*rate += pnrate;
*distortion += pndist;
*sse += pnsse;
@@ -3392,6 +3394,7 @@ void vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
}
if (best_mode_index < 0 || best_rd >= best_rd_so_far) {
+ rd_cost->rate = INT_MAX;
rd_cost->rdcost = INT64_MAX;
return;
}
@@ -3562,6 +3565,7 @@ void vp9_rd_pick_inter_mode_sb_seg_skip(VP9_COMP *cpi, MACROBLOCK *x,
rd_cost->rdcost = this_rd;
if (this_rd >= best_rd_so_far) {
+ rd_cost->rate = INT_MAX;
rd_cost->rdcost = INT64_MAX;
return;
}
@@ -4113,6 +4117,7 @@ void vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi, MACROBLOCK *x,
}
if (best_rd >= best_rd_so_far) {
+ rd_cost->rate = INT_MAX;
rd_cost->rdcost = INT64_MAX;
return;
}
diff --git a/vp9/encoder/vp9_svc_layercontext.c b/vp9/encoder/vp9_svc_layercontext.c
index eed681c96..1573557d4 100644
--- a/vp9/encoder/vp9_svc_layercontext.c
+++ b/vp9/encoder/vp9_svc_layercontext.c
@@ -14,6 +14,8 @@
#include "vp9/encoder/vp9_svc_layercontext.h"
#include "vp9/encoder/vp9_extend.h"
+#define SMALL_FRAME_FB_IDX 7
+
void vp9_init_layer_context(VP9_COMP *const cpi) {
SVC *const svc = &cpi->svc;
const VP9EncoderConfig *const oxcf = &cpi->oxcf;
@@ -28,6 +30,25 @@ void vp9_init_layer_context(VP9_COMP *const cpi) {
layer_end = svc->number_temporal_layers;
} else {
layer_end = svc->number_spatial_layers;
+
+ if (cpi->oxcf.error_resilient_mode == 0 && cpi->oxcf.pass == 2) {
+ if (vp9_realloc_frame_buffer(&cpi->svc.empty_frame.img,
+ cpi->common.width, cpi->common.height,
+ cpi->common.subsampling_x,
+ cpi->common.subsampling_y,
+#if CONFIG_VP9_HIGHBITDEPTH
+ cpi->common.use_highbitdepth,
+#endif
+ VP9_ENC_BORDER_IN_PIXELS, NULL, NULL, NULL))
+ vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR,
+ "Failed to allocate empty frame for multiple frame "
+ "contexts");
+
+ vpx_memset(cpi->svc.empty_frame.img.buffer_alloc, 0x80,
+ cpi->svc.empty_frame.img.buffer_alloc_sz);
+ cpi->svc.empty_frame_width = cpi->common.width;
+ cpi->svc.empty_frame_height = cpi->common.height;
+ }
}
for (layer = 0; layer < layer_end; ++layer) {
@@ -310,6 +331,47 @@ int vp9_svc_start_frame(VP9_COMP *const cpi) {
get_layer_resolution(cpi->oxcf.width, cpi->oxcf.height,
lc->scaling_factor_num, lc->scaling_factor_den,
&width, &height);
+
+ // Workaround for multiple frame contexts. In some frames we can't use prev_mi
+ // since its previous frame could be changed during decoding time. The idea is
+ // we put a empty invisible frame in front of them, then we will not use
+ // prev_mi when encoding these frames.
+ if (cpi->oxcf.error_resilient_mode == 0 && cpi->oxcf.pass == 2 &&
+ cpi->svc.encode_empty_frame_state == NEED_TO_ENCODE) {
+ if ((cpi->svc.number_temporal_layers > 1 &&
+ cpi->svc.temporal_layer_id < cpi->svc.number_temporal_layers - 1) ||
+ (cpi->svc.number_spatial_layers > 1 &&
+ cpi->svc.spatial_layer_id == 0)) {
+ struct lookahead_entry *buf = vp9_lookahead_peek(cpi->lookahead, 0);
+
+ if (buf != NULL) {
+ cpi->svc.empty_frame.ts_start = buf->ts_start;
+ cpi->svc.empty_frame.ts_end = buf->ts_end;
+ cpi->svc.encode_empty_frame_state = ENCODING;
+ cpi->common.show_frame = 0;
+ cpi->ref_frame_flags = 0;
+ cpi->common.frame_type = INTER_FRAME;
+ cpi->lst_fb_idx =
+ cpi->gld_fb_idx = cpi->alt_fb_idx = SMALL_FRAME_FB_IDX;
+
+ // Gradually make the empty frame smaller to save bits. Make it half of
+ // its previous size because of the scaling factor restriction.
+ cpi->svc.empty_frame_width >>= 1;
+ cpi->svc.empty_frame_width = (cpi->svc.empty_frame_width + 1) & ~1;
+ if (cpi->svc.empty_frame_width < 16)
+ cpi->svc.empty_frame_width = 16;
+
+ cpi->svc.empty_frame_height >>= 1;
+ cpi->svc.empty_frame_height = (cpi->svc.empty_frame_height + 1) & ~1;
+ if (cpi->svc.empty_frame_height < 16)
+ cpi->svc.empty_frame_height = 16;
+
+ width = cpi->svc.empty_frame_width;
+ height = cpi->svc.empty_frame_height;
+ }
+ }
+ }
+
if (vp9_set_size_literal(cpi, width, height) != 0)
return VPX_CODEC_INVALID_PARAM;
@@ -317,7 +379,6 @@ int vp9_svc_start_frame(VP9_COMP *const cpi) {
cpi->oxcf.best_allowed_q = vp9_quantizer_to_qindex(lc->min_q);
vp9_change_config(cpi, &cpi->oxcf);
-
vp9_set_high_precision_mv(cpi, 1);
cpi->alt_ref_source = get_layer_context(cpi)->alt_ref_source;
diff --git a/vp9/encoder/vp9_svc_layercontext.h b/vp9/encoder/vp9_svc_layercontext.h
index 47a5456b6..e9645ce9f 100644
--- a/vp9/encoder/vp9_svc_layercontext.h
+++ b/vp9/encoder/vp9_svc_layercontext.h
@@ -50,6 +50,16 @@ typedef struct {
int spatial_layer_to_encode;
+ // Workaround for multiple frame contexts
+ enum {
+ ENCODED = 0,
+ ENCODING,
+ NEED_TO_ENCODE
+ }encode_empty_frame_state;
+ struct lookahead_entry empty_frame;
+ int empty_frame_width;
+ int empty_frame_height;
+
// Store scaled source frames to be used for temporal filter to generate
// a alt ref frame.
YV12_BUFFER_CONFIG scaled_frames[MAX_LAG_BUFFERS];
diff --git a/vp9/encoder/vp9_temporal_filter.c b/vp9/encoder/vp9_temporal_filter.c
index 9ae81e761..5599227ce 100644
--- a/vp9/encoder/vp9_temporal_filter.c
+++ b/vp9/encoder/vp9_temporal_filter.c
@@ -719,6 +719,9 @@ void vp9_temporal_filter(VP9_COMP *cpi, int distance) {
++frame_used;
}
}
+ cm->mi = cm->mip + cm->mi_stride + 1;
+ cpi->mb.e_mbd.mi = cm->mi;
+ cpi->mb.e_mbd.mi[0].src_mi = &cpi->mb.e_mbd.mi[0];
} else {
// ARF is produced at the native frame size and resized when coded.
#if CONFIG_VP9_HIGHBITDEPTH
diff --git a/vp9/encoder/x86/vp9_denoiser_sse2.c b/vp9/encoder/x86/vp9_denoiser_sse2.c
index bf400d38b..bf5fa889f 100644
--- a/vp9/encoder/x86/vp9_denoiser_sse2.c
+++ b/vp9/encoder/x86/vp9_denoiser_sse2.c
@@ -41,40 +41,40 @@ static INLINE int sum_diff_16x1(__m128i acc_diff) {
static INLINE __m128i vp9_denoiser_16x1_sse2(const uint8_t *sig,
const uint8_t *mc_running_avg_y,
uint8_t *running_avg_y,
- const __m128i k_0,
- const __m128i k_4,
- const __m128i k_8,
- const __m128i k_16,
- const __m128i l3,
- const __m128i l32,
- const __m128i l21,
+ const __m128i *k_0,
+ const __m128i *k_4,
+ const __m128i *k_8,
+ const __m128i *k_16,
+ const __m128i *l3,
+ const __m128i *l32,
+ const __m128i *l21,
__m128i acc_diff) {
// Calculate differences
- const __m128i v_sig = _mm_loadu_si128((__m128i *)(&sig[0]));
+ const __m128i v_sig = _mm_loadu_si128((const __m128i *)(&sig[0]));
const __m128i v_mc_running_avg_y = _mm_loadu_si128(
- (__m128i *)(&mc_running_avg_y[0]));
+ (const __m128i *)(&mc_running_avg_y[0]));
__m128i v_running_avg_y;
const __m128i pdiff = _mm_subs_epu8(v_mc_running_avg_y, v_sig);
const __m128i ndiff = _mm_subs_epu8(v_sig, v_mc_running_avg_y);
// Obtain the sign. FF if diff is negative.
- const __m128i diff_sign = _mm_cmpeq_epi8(pdiff, k_0);
+ const __m128i diff_sign = _mm_cmpeq_epi8(pdiff, *k_0);
// Clamp absolute difference to 16 to be used to get mask. Doing this
// allows us to use _mm_cmpgt_epi8, which operates on signed byte.
const __m128i clamped_absdiff = _mm_min_epu8(
- _mm_or_si128(pdiff, ndiff), k_16);
+ _mm_or_si128(pdiff, ndiff), *k_16);
// Get masks for l2 l1 and l0 adjustments.
- const __m128i mask2 = _mm_cmpgt_epi8(k_16, clamped_absdiff);
- const __m128i mask1 = _mm_cmpgt_epi8(k_8, clamped_absdiff);
- const __m128i mask0 = _mm_cmpgt_epi8(k_4, clamped_absdiff);
+ const __m128i mask2 = _mm_cmpgt_epi8(*k_16, clamped_absdiff);
+ const __m128i mask1 = _mm_cmpgt_epi8(*k_8, clamped_absdiff);
+ const __m128i mask0 = _mm_cmpgt_epi8(*k_4, clamped_absdiff);
// Get adjustments for l2, l1, and l0.
- __m128i adj2 = _mm_and_si128(mask2, l32);
- const __m128i adj1 = _mm_and_si128(mask1, l21);
+ __m128i adj2 = _mm_and_si128(mask2, *l32);
+ const __m128i adj1 = _mm_and_si128(mask1, *l21);
const __m128i adj0 = _mm_and_si128(mask0, clamped_absdiff);
__m128i adj, padj, nadj;
// Combine the adjustments and get absolute adjustments.
adj2 = _mm_add_epi8(adj2, adj1);
- adj = _mm_sub_epi8(l3, adj2);
+ adj = _mm_sub_epi8(*l3, adj2);
adj = _mm_andnot_si128(mask0, adj);
adj = _mm_or_si128(adj, adj0);
@@ -103,9 +103,9 @@ static INLINE __m128i vp9_denoiser_adj_16x1_sse2(const uint8_t *sig,
__m128i acc_diff) {
__m128i v_running_avg_y = _mm_loadu_si128((__m128i *)(&running_avg_y[0]));
// Calculate differences.
- const __m128i v_sig = _mm_loadu_si128((__m128i *)(&sig[0]));
+ const __m128i v_sig = _mm_loadu_si128((const __m128i *)(&sig[0]));
const __m128i v_mc_running_avg_y =
- _mm_loadu_si128((__m128i *)(&mc_running_avg_y[0]));
+ _mm_loadu_si128((const __m128i *)(&mc_running_avg_y[0]));
const __m128i pdiff = _mm_subs_epu8(v_mc_running_avg_y, v_sig);
const __m128i ndiff = _mm_subs_epu8(v_sig, v_mc_running_avg_y);
// Obtain the sign. FF if diff is negative.
@@ -178,8 +178,8 @@ static int vp9_denoiser_4xM_sse2(const uint8_t *sig, int sig_stride,
acc_diff = vp9_denoiser_16x1_sse2(sig_buffer[r],
mc_running_buffer[r],
running_buffer[r],
- k_0, k_4, k_8, k_16,
- l3, l32, l21, acc_diff);
+ &k_0, &k_4, &k_8, &k_16,
+ &l3, &l32, &l21, acc_diff);
vpx_memcpy(running_avg_y, running_buffer[r], 4);
vpx_memcpy(running_avg_y + avg_y_stride, running_buffer[r] + 4, 4);
vpx_memcpy(running_avg_y + avg_y_stride * 2,
@@ -279,8 +279,8 @@ static int vp9_denoiser_8xM_sse2(const uint8_t *sig, int sig_stride,
acc_diff = vp9_denoiser_16x1_sse2(sig_buffer[r],
mc_running_buffer[r],
running_buffer[r],
- k_0, k_4, k_8, k_16,
- l3, l32, l21, acc_diff);
+ &k_0, &k_4, &k_8, &k_16,
+ &l3, &l32, &l21, acc_diff);
vpx_memcpy(running_avg_y, running_buffer[r], 8);
vpx_memcpy(running_avg_y + avg_y_stride, running_buffer[r] + 8, 8);
// Update pointers for next iteration.
@@ -357,9 +357,9 @@ static int vp9_denoiser_64_32_16xM_sse2(const uint8_t *sig, int sig_stride,
const __m128i l21 = _mm_set1_epi8(1);
int sum_diff = 0;
- for (int i = 0; i < 4; i++) {
- for (int j = 0; j < 4; j++) {
- acc_diff[i][j] = _mm_setzero_si128();
+ for (c = 0; c < 4; ++c) {
+ for (r = 0; r < 4; ++r) {
+ acc_diff[c][r] = _mm_setzero_si128();
}
}
@@ -368,8 +368,8 @@ static int vp9_denoiser_64_32_16xM_sse2(const uint8_t *sig, int sig_stride,
acc_diff[c>>4][r>>4] = vp9_denoiser_16x1_sse2(
sig, mc_running_avg_y,
running_avg_y,
- k_0, k_4, k_8, k_16,
- l3, l32, l21, acc_diff[c>>4][r>>4]);
+ &k_0, &k_4, &k_8, &k_16,
+ &l3, &l32, &l21, acc_diff[c>>4][r>>4]);
// Update pointers for next iteration.
sig += 16;
mc_running_avg_y += 16;
diff --git a/vp9/vp9_cx_iface.c b/vp9/vp9_cx_iface.c
index 041ba27da..d0ca5242c 100644
--- a/vp9/vp9_cx_iface.c
+++ b/vp9/vp9_cx_iface.c
@@ -188,11 +188,9 @@ static vpx_codec_err_t validate_config(vpx_codec_alg_priv_t *ctx,
}
if (alt_ref_sum > REF_FRAMES - cfg->ss_number_layers)
ERROR("Not enough ref buffers for svc alt ref frames");
- if ((cfg->ss_number_layers > 3 ||
- cfg->ss_number_layers * cfg->ts_number_layers > 4) &&
+ if (cfg->ss_number_layers * cfg->ts_number_layers > 3 &&
cfg->g_error_resilient == 0)
- ERROR("Multiple frame context are not supported for more than 3 spatial "
- "layers or more than 4 spatial x temporal layers");
+ ERROR("Multiple frame context are not supported for more than 3 layers");
}
#endif