summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarco Paniconi <marpan@google.com>2018-12-03 10:49:41 -0800
committerMarco Paniconi <marpan@google.com>2018-12-03 12:49:29 -0800
commitb2f37bac65457d327002130a58d98ae2d2dcab7f (patch)
treee92ee4e67aa3cbd9be9781af9ff2a6746191b291
parent5fbc7a286b4d72883392fdbb10ec52bace662f66 (diff)
downloadlibvpx-b2f37bac65457d327002130a58d98ae2d2dcab7f.tar
libvpx-b2f37bac65457d327002130a58d98ae2d2dcab7f.tar.gz
libvpx-b2f37bac65457d327002130a58d98ae2d2dcab7f.tar.bz2
libvpx-b2f37bac65457d327002130a58d98ae2d2dcab7f.zip
vp9: Overshoot detection for skipped base layer.
If scene/slide change is detected on current superframe and max-q set because of high overshoot: then if the lower/base spatial layer are skipped on the current superframe, max-q is forced on the next encoded base/lower spatial layers. Change-Id: Id61efda86ee545395012e19476d19845e3932678
-rw-r--r--vp9/encoder/vp9_encoder.c7
-rw-r--r--vp9/encoder/vp9_ratectrl.c32
2 files changed, 23 insertions, 16 deletions
diff --git a/vp9/encoder/vp9_encoder.c b/vp9/encoder/vp9_encoder.c
index 04d25247d..353857b8a 100644
--- a/vp9/encoder/vp9_encoder.c
+++ b/vp9/encoder/vp9_encoder.c
@@ -3832,9 +3832,10 @@ static int encode_without_recode_loop(VP9_COMP *cpi, size_t *size,
if (svc->spatial_layer_id == svc->first_spatial_layer_to_encode) {
svc->high_source_sad_superframe = cpi->rc.high_source_sad;
// On scene change reset temporal layer pattern to TL0.
- // TODO(marpan/jianj): Fix this to handle case where base
- // spatial layers are skipped, in which case we should insert
- // and reset to spatial layer 0 on scene change.
+ // Note that if the base/lower spatial layers are skipped: instead of
+ // inserting base layer here, we force max-q for the next superframe
+ // with lower spatial layers: this is done in vp9_encodedframe_overshoot()
+ // when max-q is decided for the current layer.
if (svc->high_source_sad_superframe && svc->temporal_layer_id > 0) {
// rc->high_source_sad will get reset so copy it to restore it.
int tmp_high_source_sad = cpi->rc.high_source_sad;
diff --git a/vp9/encoder/vp9_ratectrl.c b/vp9/encoder/vp9_ratectrl.c
index 396ba0269..4c0bf378f 100644
--- a/vp9/encoder/vp9_ratectrl.c
+++ b/vp9/encoder/vp9_ratectrl.c
@@ -3081,21 +3081,27 @@ int vp9_encodedframe_overshoot(VP9_COMP *cpi, int frame_size, int *q) {
cpi->rc.rate_correction_factors[INTER_NORMAL] = rate_correction_factor;
}
// For temporal layers, reset the rate control parametes across all
- // temporal layers.
+ // temporal layers. If the first_spatial_layer_to_encode > 0, then this
+ // superframe has skipped lower base layers. So in this case we should also
+ // reset and force max-q for spatial layers < first_spatial_layer_to_encode.
if (cpi->use_svc) {
- int i = 0;
+ int tl = 0;
+ int sl = 0;
SVC *svc = &cpi->svc;
- for (i = 0; i < svc->number_temporal_layers; ++i) {
- const int layer = LAYER_IDS_TO_IDX(svc->spatial_layer_id, i,
- svc->number_temporal_layers);
- LAYER_CONTEXT *lc = &svc->layer_context[layer];
- RATE_CONTROL *lrc = &lc->rc;
- lrc->avg_frame_qindex[INTER_FRAME] = *q;
- lrc->buffer_level = lrc->optimal_buffer_level;
- lrc->bits_off_target = lrc->optimal_buffer_level;
- lrc->rc_1_frame = 0;
- lrc->rc_2_frame = 0;
- lrc->rate_correction_factors[INTER_NORMAL] = rate_correction_factor;
+ for (sl = 0; sl < svc->first_spatial_layer_to_encode; ++sl) {
+ for (tl = 0; tl < svc->number_temporal_layers; ++tl) {
+ const int layer =
+ LAYER_IDS_TO_IDX(sl, tl, svc->number_temporal_layers);
+ LAYER_CONTEXT *lc = &svc->layer_context[layer];
+ RATE_CONTROL *lrc = &lc->rc;
+ lrc->avg_frame_qindex[INTER_FRAME] = *q;
+ lrc->buffer_level = lrc->optimal_buffer_level;
+ lrc->bits_off_target = lrc->optimal_buffer_level;
+ lrc->rc_1_frame = 0;
+ lrc->rc_2_frame = 0;
+ lrc->rate_correction_factors[INTER_NORMAL] = rate_correction_factor;
+ lrc->force_max_q = 1;
+ }
}
}
return 1;