summaryrefslogtreecommitdiff
path: root/vp9
diff options
context:
space:
mode:
Diffstat (limited to 'vp9')
-rw-r--r--vp9/encoder/vp9_encoder.c13
-rw-r--r--vp9/encoder/vp9_pickmode.c6
-rw-r--r--vp9/encoder/vp9_ratectrl.c30
-rw-r--r--vp9/encoder/vp9_speed_features.c5
-rw-r--r--vp9/encoder/vp9_speed_features.h4
-rw-r--r--vp9/encoder/vp9_svc_layercontext.c2
-rw-r--r--vp9/encoder/vp9_svc_layercontext.h5
7 files changed, 51 insertions, 14 deletions
diff --git a/vp9/encoder/vp9_encoder.c b/vp9/encoder/vp9_encoder.c
index 31b6214ae..9ec539733 100644
--- a/vp9/encoder/vp9_encoder.c
+++ b/vp9/encoder/vp9_encoder.c
@@ -3683,12 +3683,15 @@ static void encode_without_recode_loop(VP9_COMP *cpi, size_t *size,
// For other cases (e.g., CBR mode) use it for 5 <= speed < 8 for now
// (need to check encoding time cost for doing this for speed 8).
cpi->rc.high_source_sad = 0;
- if (cpi->compute_source_sad_onepass && cm->show_frame &&
+ if (cm->show_frame &&
(cpi->oxcf.rc_mode == VPX_VBR ||
cpi->oxcf.content == VP9E_CONTENT_SCREEN ||
(cpi->oxcf.speed >= 5 && cpi->oxcf.speed < 8 && !cpi->use_svc)))
vp9_scene_detection_onepass(cpi);
+ if (cpi->svc.spatial_layer_id == 0)
+ cpi->svc.high_source_sad_superframe = cpi->rc.high_source_sad;
+
// For 1 pass CBR SVC, only ZEROMV is allowed for spatial reference frame
// when svc->force_zero_mode_spatial_ref = 1. Under those conditions we can
// avoid this frame-level upsampling (for non intra_only frames).
@@ -3774,10 +3777,10 @@ static void encode_without_recode_loop(VP9_COMP *cpi, size_t *size,
// Check if we should drop this frame because of high overshoot.
// Only for frames where high temporal-source SAD is detected.
- if (cpi->oxcf.pass == 0 && cpi->oxcf.rc_mode == VPX_CBR &&
- cpi->resize_state == ORIG && cm->frame_type != KEY_FRAME &&
- cpi->oxcf.content == VP9E_CONTENT_SCREEN &&
- cpi->rc.high_source_sad == 1) {
+ // For SVC: all spatial layers are checked for re-encoding.
+ if (cpi->sf.re_encode_overshoot_rt &&
+ (cpi->rc.high_source_sad ||
+ (cpi->use_svc && cpi->svc.high_source_sad_superframe))) {
int frame_size = 0;
// Get an estimate of the encoded frame size.
save_coding_context(cpi);
diff --git a/vp9/encoder/vp9_pickmode.c b/vp9/encoder/vp9_pickmode.c
index a9c7c7d3d..3aee46636 100644
--- a/vp9/encoder/vp9_pickmode.c
+++ b/vp9/encoder/vp9_pickmode.c
@@ -1503,10 +1503,12 @@ void vp9_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x, TileDataEnc *tile_data,
int svc_mv_col = 0;
int svc_mv_row = 0;
unsigned int thresh_svc_skip_golden = 500;
+ if (cpi->svc.spatial_layer_id > 0 && cpi->svc.high_source_sad_superframe)
+ thresh_svc_skip_golden = 0;
// Lower the skip threshold if lower spatial layer is better quality relative
// to current layer.
- if (cpi->svc.spatial_layer_id > 0 && cm->base_qindex > 150 &&
- cm->base_qindex > cpi->svc.lower_layer_qindex + 15)
+ else if (cpi->svc.spatial_layer_id > 0 && cm->base_qindex > 150 &&
+ cm->base_qindex > cpi->svc.lower_layer_qindex + 15)
thresh_svc_skip_golden = 100;
// Increase skip threshold if lower spatial layer is lower quality relative
// to current layer.
diff --git a/vp9/encoder/vp9_ratectrl.c b/vp9/encoder/vp9_ratectrl.c
index c9632e904..748a0ddd8 100644
--- a/vp9/encoder/vp9_ratectrl.c
+++ b/vp9/encoder/vp9_ratectrl.c
@@ -2284,18 +2284,34 @@ static void adjust_gf_boost_lag_one_pass_vbr(VP9_COMP *cpi,
void vp9_scene_detection_onepass(VP9_COMP *cpi) {
VP9_COMMON *const cm = &cpi->common;
RATE_CONTROL *const rc = &cpi->rc;
+ YV12_BUFFER_CONFIG const *unscaled_src = cpi->un_scaled_source;
+ YV12_BUFFER_CONFIG const *unscaled_last_src = cpi->unscaled_last_source;
+ uint8_t *src_y;
+ int src_ystride;
+ int src_width;
+ int src_height;
+ uint8_t *last_src_y;
+ int last_src_ystride;
+ int last_src_width;
+ int last_src_height;
+ if (cpi->un_scaled_source == NULL || cpi->unscaled_last_source == NULL ||
+ (cpi->use_svc && cpi->svc.current_superframe == 0))
+ return;
+ src_y = unscaled_src->y_buffer;
+ src_ystride = unscaled_src->y_stride;
+ src_width = unscaled_src->y_width;
+ src_height = unscaled_src->y_height;
+ last_src_y = unscaled_last_src->y_buffer;
+ last_src_ystride = unscaled_last_src->y_stride;
+ last_src_width = unscaled_last_src->y_width;
+ last_src_height = unscaled_last_src->y_height;
#if CONFIG_VP9_HIGHBITDEPTH
if (cm->use_highbitdepth) return;
#endif
rc->high_source_sad = 0;
- if (cpi->Last_Source != NULL &&
- cpi->Last_Source->y_width == cpi->Source->y_width &&
- cpi->Last_Source->y_height == cpi->Source->y_height) {
+ if (cpi->svc.spatial_layer_id == 0 && src_width == last_src_width &&
+ src_height == last_src_height) {
YV12_BUFFER_CONFIG *frames[MAX_LAG_BUFFERS] = { NULL };
- uint8_t *src_y = cpi->Source->y_buffer;
- int src_ystride = cpi->Source->y_stride;
- uint8_t *last_src_y = cpi->Last_Source->y_buffer;
- int last_src_ystride = cpi->Last_Source->y_stride;
int start_frame = 0;
int frames_to_buffer = 1;
int frame = 0;
diff --git a/vp9/encoder/vp9_speed_features.c b/vp9/encoder/vp9_speed_features.c
index b44f88098..c0f985cbd 100644
--- a/vp9/encoder/vp9_speed_features.c
+++ b/vp9/encoder/vp9_speed_features.c
@@ -374,6 +374,7 @@ static void set_rt_speed_feature_framesize_independent(
sf->use_compound_nonrd_pickmode = 0;
sf->nonrd_keyframe = 0;
sf->svc_use_lowres_part = 0;
+ sf->re_encode_overshoot_rt = 0;
if (speed >= 1) {
sf->allow_txfm_domain_distortion = 1;
@@ -534,6 +535,10 @@ static void set_rt_speed_feature_framesize_independent(
// Keep nonrd_keyframe = 1 for non-base spatial layers to prevent
// increase in encoding time.
if (cpi->use_svc && cpi->svc.spatial_layer_id > 0) sf->nonrd_keyframe = 1;
+ if (cpi->oxcf.pass == 0 && cpi->oxcf.rc_mode == VPX_CBR &&
+ cm->frame_type != KEY_FRAME && cpi->resize_state == ORIG &&
+ cpi->oxcf.content == VP9E_CONTENT_SCREEN)
+ sf->re_encode_overshoot_rt = 1;
}
if (speed >= 6) {
diff --git a/vp9/encoder/vp9_speed_features.h b/vp9/encoder/vp9_speed_features.h
index 50d52bc23..15e8dacbd 100644
--- a/vp9/encoder/vp9_speed_features.h
+++ b/vp9/encoder/vp9_speed_features.h
@@ -508,6 +508,10 @@ typedef struct SPEED_FEATURES {
// For SVC: enables use of partition from lower spatial resolution.
int svc_use_lowres_part;
+
+ // Enable re-encoding on scene change with potential high overshoot,
+ // for real-time encoding flow.
+ int re_encode_overshoot_rt;
} SPEED_FEATURES;
struct VP9_COMP;
diff --git a/vp9/encoder/vp9_svc_layercontext.c b/vp9/encoder/vp9_svc_layercontext.c
index 88b8daf4c..42a197769 100644
--- a/vp9/encoder/vp9_svc_layercontext.c
+++ b/vp9/encoder/vp9_svc_layercontext.c
@@ -712,6 +712,8 @@ int vp9_one_pass_cbr_svc_start_layer(VP9_COMP *const cpi) {
cpi->svc.non_reference_frame = 1;
}
+ if (cpi->svc.spatial_layer_id == 0) cpi->svc.high_source_sad_superframe = 0;
+
if (vp9_set_size_literal(cpi, width, height) != 0)
return VPX_CODEC_INVALID_PARAM;
diff --git a/vp9/encoder/vp9_svc_layercontext.h b/vp9/encoder/vp9_svc_layercontext.h
index a7fa26924..022fd00f7 100644
--- a/vp9/encoder/vp9_svc_layercontext.h
+++ b/vp9/encoder/vp9_svc_layercontext.h
@@ -118,6 +118,11 @@ typedef struct SVC {
SVC_LAYER_DROP_MODE framedrop_mode;
INTER_LAYER_PRED disable_inter_layer_pred;
+
+ // Flag to indicate scene change at current superframe, scene detection is
+ // currently checked for each superframe prior to encoding, on the full
+ // resolution source.
+ int high_source_sad_superframe;
} SVC;
struct VP9_COMP;