rtc: Update conditions for selective cdf_update mode
This only affects cdf-update-mode = 2 (selective mode)
for real-time mode.
Move the logic for disable/enable to a separate function,
and account for some use cases (layers, resize, scene-change).
The update can have significant reduction in frame size
(~20% in some cases) on key frames or on scene changes,
so explicity add those conditions, along with resized frames.
Also keep update on for a few frames before the GF update,
as this can help with the quality of the GF reference.
To avoid bdrate loss, keep forcing udpate every ~10 frames for now.
For speed 10 on rtc set with cdf-update-mode=2:
bdrate loss ~0.8%. Small speedup observed on vga clip (as updates
are less than doing it every other frames) of ~2%.
Change-Id: I2286558d72d6bcacd80de47272b1892ae2a39256
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c
index 51feb0c..0221ca8 100644
--- a/av1/encoder/encoder.c
+++ b/av1/encoder/encoder.c
@@ -3148,6 +3148,33 @@
return err;
}
+// Conditions to disable cdf_update mode in selective mode for real-time.
+// Handle case for layers, scene change, and resizing.
+static int selective_disable_cdf_rtc(AV1_COMP *cpi) {
+ AV1_COMMON *const cm = &cpi->common;
+ RATE_CONTROL *const rc = &cpi->rc;
+ // For single layer.
+ if (cpi->svc.number_spatial_layers == 1 &&
+ cpi->svc.number_temporal_layers == 1) {
+ // Don't disable on intra_only, scene change (high_source_sad = 1),
+ // or resized frame. Don't disable for some consecutive frames after
+ // key, or for some consecutive frames before the golden_refresh
+ // (cpi->rc.frames_till_gf_update_due < 6).
+ // To avoid quality loss for now, force enable at every x frames.
+ if (frame_is_intra_only(cm) || is_frame_resize_pending(cpi) ||
+ rc->high_source_sad || rc->frames_since_key < 10 ||
+ rc->frames_till_gf_update_due < 5 ||
+ cm->current_frame.frame_number % 10 == 0)
+ return 0;
+ else
+ return 1;
+ } else if (cpi->svc.number_temporal_layers > 1) {
+ // Disable only on top temporal enhancement layer for now.
+ return cpi->svc.temporal_layer_id == cpi->svc.number_temporal_layers - 1;
+ }
+ return 1;
+}
+
#if !CONFIG_REALTIME_ONLY
static void subtract_stats(FIRSTPASS_STATS *section,
const FIRSTPASS_STATS *frame) {
@@ -3440,21 +3467,12 @@
case 2:
// Strategically determine at which frames to do CDF update.
// Currently only enable CDF update for all-intra and no-show frames(1.5%
- // compression loss).
- // TODO(huisu@google.com): design schemes for various trade-offs between
- // compression quality and decoding speed.
+ // compression loss) for good qualiy or allintra mode.
if (oxcf->mode == GOOD || oxcf->mode == ALLINTRA) {
features->disable_cdf_update =
(frame_is_intra_only(cm) || !cm->show_frame) ? 0 : 1;
} else {
- if (cpi->svc.number_spatial_layers == 1 &&
- cpi->svc.number_temporal_layers == 1)
- features->disable_cdf_update =
- !((cm->current_frame.frame_number % 2) == 0);
- else if (cpi->svc.number_temporal_layers > 1)
- // Disable only on top temporal enhancement layer for now.
- features->disable_cdf_update = (cpi->svc.temporal_layer_id ==
- cpi->svc.number_temporal_layers - 1);
+ features->disable_cdf_update = selective_disable_cdf_rtc(cpi);
}
break;
}