rtc: Skip loop filter on mostly inactive frames At speed 10 and up, screen content skips the loop filter when more than thresh_active_maps_skip_lf_cdef (90) percent of the blocks are inactive. The check sits in av1_cyclic_refresh_disable_lf_cdef(), and av1_pick_filter_level() only calls that with aq mode 3. With any other aq mode, an active map never gets the skip. Move the active map check into av1_pick_filter_level() so it applies to every aq mode. The cyclic refresh checks still need aq mode 3 and run in the same order, so aq mode 3 output does not change. Rename av1_cyclic_refresh_disable_lf_cdef() to av1_cyclic_refresh_disable_lf(), since it no longer has anything to do with CDEF. To see it, encode screen content at speed 11 with aq mode 0 and a map that marks over 90% of the blocks inactive. The loop filter now runs on none of those frames. Tested on two 2560x1440 screen recordings with an active map from frame diffs (speed 11, aq 0, q 8 to 13, VBR). 94% and 80% of the frames are over the threshold. With 4 threads the encoder uses 9.6 to 12.2% fewer cycles on the static recording and about 4% fewer on the other one, and the decoder 12 to 29% fewer. Size grows 0.2 to 1.0% on the static recording and stays the same on the other one. With a fixed 5% active map, the BD rate on the active area is +0.04% and +1.1%. Change-Id: I4f1455beaaba69518b8aa3dd611f4f2ffae6b75e
diff --git a/av1/encoder/aq_cyclicrefresh.c b/av1/encoder/aq_cyclicrefresh.c index d87ceae..b76fbf8 100644 --- a/av1/encoder/aq_cyclicrefresh.c +++ b/av1/encoder/aq_cyclicrefresh.c
@@ -679,13 +679,9 @@ return cr->rdmult; } -int av1_cyclic_refresh_disable_lf_cdef(AV1_COMP *const cpi) { +int av1_cyclic_refresh_disable_lf(AV1_COMP *const cpi) { CYCLIC_REFRESH *const cr = cpi->cyclic_refresh; const int qindex = cpi->common.quant_params.base_qindex; - if (cpi->active_map.enabled && - cpi->rc.percent_blocks_inactive > - cpi->sf.rt_sf.thresh_active_maps_skip_lf_cdef) - return 1; if (cpi->rc.frames_since_key > 30 && cr->percent_refresh > 0 && cr->counter_encode_maxq_scene_change > 300 / cr->percent_refresh && cpi->rc.frame_source_sad < 1000 &&
diff --git a/av1/encoder/aq_cyclicrefresh.h b/av1/encoder/aq_cyclicrefresh.h index 8fc6e15..7c71a69 100644 --- a/av1/encoder/aq_cyclicrefresh.h +++ b/av1/encoder/aq_cyclicrefresh.h
@@ -308,7 +308,7 @@ int av1_cyclic_refresh_get_rdmult(const CYCLIC_REFRESH *cr); -int av1_cyclic_refresh_disable_lf_cdef(struct AV1_COMP *const cpi); +int av1_cyclic_refresh_disable_lf(struct AV1_COMP *const cpi); static inline int cyclic_refresh_segment_id_boosted(int segment_id) { return segment_id == CR_SEGMENT_ID_BOOST1 ||
diff --git a/av1/encoder/picklpf.c b/av1/encoder/picklpf.c index 36ed5d6..cc11c14 100644 --- a/av1/encoder/picklpf.c +++ b/av1/encoder/picklpf.c
@@ -247,9 +247,15 @@ } if (cpi->oxcf.tune_cfg.content == AOM_CONTENT_SCREEN && - cpi->oxcf.q_cfg.aq_mode == CYCLIC_REFRESH_AQ && - cpi->sf.rt_sf.skip_lf_screen) - disable_filter_rt_screen = av1_cyclic_refresh_disable_lf_cdef(cpi); + cpi->sf.rt_sf.skip_lf_screen) { + // Skip the filter when most of the frame is inactive, for any aq mode. + if (cpi->active_map.enabled && + cpi->rc.percent_blocks_inactive > + cpi->sf.rt_sf.thresh_active_maps_skip_lf_cdef) + disable_filter_rt_screen = 1; + else if (cpi->oxcf.q_cfg.aq_mode == CYCLIC_REFRESH_AQ) + disable_filter_rt_screen = av1_cyclic_refresh_disable_lf(cpi); + } if (disable_filter_rt_screen || cpi->oxcf.algo_cfg.loopfilter_control == LOOPFILTER_NONE ||