summaryrefslogtreecommitdiff
path: root/vp9/encoder/vp9_encoder.c
diff options
context:
space:
mode:
Diffstat (limited to 'vp9/encoder/vp9_encoder.c')
-rw-r--r--vp9/encoder/vp9_encoder.c97
1 files changed, 58 insertions, 39 deletions
diff --git a/vp9/encoder/vp9_encoder.c b/vp9/encoder/vp9_encoder.c
index 9f12d664c..8464882ea 100644
--- a/vp9/encoder/vp9_encoder.c
+++ b/vp9/encoder/vp9_encoder.c
@@ -2106,6 +2106,7 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
uint8_t *dest,
unsigned int *frame_flags) {
VP9_COMMON *const cm = &cpi->common;
+ const VP9EncoderConfig *const oxcf = &cpi->oxcf;
struct segmentation *const seg = &cm->seg;
TX_SIZE t;
int q;
@@ -2159,9 +2160,7 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
// The alternate reference frame cannot be active for a key frame.
cpi->rc.source_alt_ref_active = 0;
- cm->error_resilient_mode = (cpi->oxcf.error_resilient_mode != 0);
- cm->frame_parallel_decoding_mode =
- (cpi->oxcf.frame_parallel_decoding_mode != 0);
+ cm->error_resilient_mode = oxcf->error_resilient_mode;
// By default, encoder assumes decoder can use prev_mi.
if (cm->error_resilient_mode) {
@@ -2169,29 +2168,43 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
cm->reset_frame_context = 0;
cm->refresh_frame_context = 0;
} else if (cm->intra_only) {
+ cm->frame_parallel_decoding_mode = oxcf->frame_parallel_decoding_mode;
// Only reset the current context.
cm->reset_frame_context = 2;
}
}
+ if (is_spatial_svc(cpi) && cm->error_resilient_mode == 0) {
+ cm->frame_context_idx = cpi->svc.spatial_layer_id;
+
+ // The probs will be updated based on the frame type of its previous
+ // frame if frame_parallel_decoding_mode is 0. The type may vary for
+ // the frame after a key frame in base layer since we may drop enhancement
+ // layers. So set frame_parallel_decoding_mode to 1 in this case.
+ if (cpi->svc.spatial_layer_id == 0 &&
+ cpi->svc.layer_context[0].last_frame_type == KEY_FRAME)
+ cm->frame_parallel_decoding_mode = 1;
+ else
+ cm->frame_parallel_decoding_mode = 0;
+ }
// 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 (cpi->oxcf.pass == 2 && cpi->sf.static_segmentation)
+ 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->oxcf.pass == 2 &&
+ if (oxcf->pass == 2 &&
(!cpi->use_svc || is_spatial_svc(cpi))) {
configure_skippable_frame(cpi);
}
// For 1 pass CBR, check if we are dropping this frame.
// Never drop on key frame.
- if (cpi->oxcf.pass == 0 &&
- cpi->oxcf.rc_mode == VPX_CBR &&
+ if (oxcf->pass == 0 &&
+ oxcf->rc_mode == VPX_CBR &&
cm->frame_type != KEY_FRAME) {
if (vp9_rc_drop_frame(cpi)) {
vp9_rc_postencode_update_drop_frame(cpi);
@@ -2203,9 +2216,9 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
vp9_clear_system_state();
#if CONFIG_VP9_POSTPROC
- if (cpi->oxcf.noise_sensitivity > 0) {
+ if (oxcf->noise_sensitivity > 0) {
int l = 0;
- switch (cpi->oxcf.noise_sensitivity) {
+ switch (oxcf->noise_sensitivity) {
case 1:
l = 20;
break;
@@ -2246,7 +2259,7 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
#if CONFIG_VP9_TEMPORAL_DENOISING
#ifdef OUTPUT_YUV_DENOISED
- if (cpi->oxcf.noise_sensitivity > 0) {
+ if (oxcf->noise_sensitivity > 0) {
vp9_write_yuv_frame_420(&cpi->denoiser.running_avg_y[INTRA_FRAME],
yuv_denoised_file);
}
@@ -2348,8 +2361,12 @@ 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)
- cm->last_show_frame = cm->show_frame;
+ if (!cm->show_existing_frame) {
+ if (is_spatial_svc(cpi) && cm->error_resilient_mode == 0)
+ cm->last_show_frame = 0;
+ else
+ cm->last_show_frame = cm->show_frame;
+ }
if (cm->show_frame) {
vp9_swap_mi_and_prev_mi(cm);
@@ -2360,6 +2377,10 @@ static void encode_frame_to_data_rate(VP9_COMP *cpi,
if (cpi->use_svc)
vp9_inc_frame_in_layer(&cpi->svc);
}
+
+ if (is_spatial_svc(cpi))
+ cpi->svc.layer_context[cpi->svc.spatial_layer_id].last_frame_type =
+ cm->frame_type;
}
static void SvcEncode(VP9_COMP *cpi, size_t *size, uint8_t *dest,
@@ -2474,8 +2495,8 @@ static int frame_is_reference(const VP9_COMP *cpi) {
cm->seg.update_data;
}
-void adjust_frame_rate(VP9_COMP *cpi) {
- const struct lookahead_entry *const source = cpi->source;
+void adjust_frame_rate(VP9_COMP *cpi,
+ const struct lookahead_entry *source) {
int64_t this_duration;
int step = 0;
@@ -2531,7 +2552,8 @@ static int get_arf_src_index(VP9_COMP *cpi) {
return arf_src_index;
}
-static void check_src_altref(VP9_COMP *cpi) {
+static void check_src_altref(VP9_COMP *cpi,
+ const struct lookahead_entry *source) {
RATE_CONTROL *const rc = &cpi->rc;
if (cpi->oxcf.pass == 2) {
@@ -2540,7 +2562,7 @@ static void check_src_altref(VP9_COMP *cpi) {
(gf_group->update_type[gf_group->index] == OVERLAY_UPDATE);
} else {
rc->is_src_frame_alt_ref = cpi->alt_ref_source &&
- (cpi->source == cpi->alt_ref_source);
+ (source == cpi->alt_ref_source);
}
if (rc->is_src_frame_alt_ref) {
@@ -2563,6 +2585,7 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
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;
@@ -2575,8 +2598,6 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
vpx_usec_timer_start(&cmptimer);
- cpi->source = NULL;
-
vp9_set_high_precision_mv(cpi, ALTREF_HIGH_PRECISION_MV);
// Normal defaults
@@ -2593,13 +2614,12 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
#if CONFIG_SPATIAL_SVC
if (is_spatial_svc(cpi))
- cpi->source = vp9_svc_lookahead_peek(cpi, cpi->lookahead,
- arf_src_index, 0);
+ source = vp9_svc_lookahead_peek(cpi, cpi->lookahead, arf_src_index, 0);
else
#endif
- cpi->source = vp9_lookahead_peek(cpi->lookahead, arf_src_index);
- if (cpi->source != NULL) {
- cpi->alt_ref_source = cpi->source;
+ source = vp9_lookahead_peek(cpi->lookahead, arf_src_index);
+ if (source != NULL) {
+ cpi->alt_ref_source = source;
#if CONFIG_SPATIAL_SVC
if (is_spatial_svc(cpi) && cpi->svc.spatial_layer_id > 0) {
@@ -2633,7 +2653,7 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
}
}
- if (!cpi->source) {
+ if (!source) {
// Get last frame source.
if (cm->current_video_frame > 0) {
#if CONFIG_SPATIAL_SVC
@@ -2649,29 +2669,28 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
// Read in the source frame.
#if CONFIG_SPATIAL_SVC
if (is_spatial_svc(cpi))
- cpi->source = vp9_svc_lookahead_pop(cpi, cpi->lookahead, flush);
+ source = vp9_svc_lookahead_pop(cpi, cpi->lookahead, flush);
else
#endif
- cpi->source = vp9_lookahead_pop(cpi->lookahead, flush);
- if (cpi->source != NULL) {
+ source = vp9_lookahead_pop(cpi->lookahead, flush);
+ if (source != NULL) {
cm->show_frame = 1;
cm->intra_only = 0;
// Check to see if the frame should be encoded as an arf overlay.
- check_src_altref(cpi);
+ check_src_altref(cpi, source);
}
}
- if (cpi->source) {
+ if (source) {
cpi->un_scaled_source = cpi->Source = force_src_buffer ? force_src_buffer
- : &cpi->source->img;
+ : &source->img;
cpi->unscaled_last_source = last_source != NULL ? &last_source->img : NULL;
- *time_stamp = cpi->source->ts_start;
- *time_end = cpi->source->ts_end;
- *frame_flags =
- (cpi->source->flags & VPX_EFLAG_FORCE_KF) ? FRAMEFLAGS_KEY : 0;
+ *time_stamp = source->ts_start;
+ *time_end = source->ts_end;
+ *frame_flags = (source->flags & VPX_EFLAG_FORCE_KF) ? FRAMEFLAGS_KEY : 0;
} else {
*size = 0;
@@ -2682,9 +2701,9 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
return -1;
}
- if (cpi->source->ts_start < cpi->first_time_stamp_ever) {
- cpi->first_time_stamp_ever = cpi->source->ts_start;
- cpi->last_end_time_stamp_seen = cpi->source->ts_start;
+ if (source->ts_start < cpi->first_time_stamp_ever) {
+ cpi->first_time_stamp_ever = source->ts_start;
+ cpi->last_end_time_stamp_seen = source->ts_start;
}
// Clear down mmx registers
@@ -2692,7 +2711,7 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
// adjust frame rates based on timestamps given
if (cm->show_frame) {
- adjust_frame_rate(cpi);
+ adjust_frame_rate(cpi, source);
}
if (cpi->svc.number_temporal_layers > 1 &&
@@ -2764,7 +2783,7 @@ int vp9_get_compressed_data(VP9_COMP *cpi, unsigned int *frame_flags,
const int lossless = is_lossless_requested(oxcf);
cpi->mb.fwd_txm4x4 = lossless ? vp9_fwht4x4 : vp9_fdct4x4;
cpi->mb.itxm_add = lossless ? vp9_iwht4x4_add : vp9_idct4x4_add;
- vp9_first_pass(cpi);
+ vp9_first_pass(cpi, source);
} else if (oxcf->pass == 2 &&
(!cpi->use_svc || is_spatial_svc(cpi))) {
Pass2Encode(cpi, size, dest, frame_flags);