Low-delay config: No level 1 frames in last subgop
Specifically, use level 4 instead of 1 for frame 14 in last subgop, as
this frame will be used as reference for very few frames after it.
Also, change the ratecontrol code to support this case, where no frames
in a subgop are at level 1.
Note: This also fixes the qp allocation of the last frame, if it's the
only frame left in the last subgop. Earlier, this got same qp as level
1; now we assign qp based on the actual layer depth of this frame in the
subgop config.
BDRate (Ovr PSNR) Before vs After:
- CTC with --use-fixed-qp-offsets=1:
lowres2: -2.733
midres2: -2.740
objective-1-fast: -2.798
- CTC with --use-fixed-qp-offsets=0:
lowres2: -2.367
midres2: -2.523
objective-1-fast: -2.578
BUG=aomedia:2832
Change-Id: I42640af9a2ee7245798b9c84f70aff04e3f81bb4
diff --git a/av1/av1_cx_iface.c b/av1/av1_cx_iface.c
index bb8fb9a..c5873ab 100644
--- a/av1/av1_cx_iface.c
+++ b/av1/av1_cx_iface.c
@@ -254,7 +254,7 @@
"9V5/10V4/11V5/12V3/13V5/14V4/15V5/16V1,"
"16:1:1V5/2V4/3V5/4V3/5V5/6V4/7V5/8V2/"
- "9V5/10V4/11V5/12V3/13V5/14V1/15V5/16V5";
+ "9V5/10V4/11V5/12V3/13V5/14V4/15V5/16V5";
typedef struct {
const char *preset_tag;
diff --git a/av1/encoder/ratectrl.c b/av1/encoder/ratectrl.c
index 1656dfd..0f68743 100644
--- a/av1/encoder/ratectrl.c
+++ b/av1/encoder/ratectrl.c
@@ -1529,18 +1529,19 @@
const RATE_CONTROL *const rc = &cpi->rc;
const AV1EncoderConfig *const oxcf = &cpi->oxcf;
const RefreshFrameFlagsInfo *const refresh_frame_flags = &cpi->refresh_frame;
+ (void)refresh_frame_flags;
const GF_GROUP *gf_group = &cpi->gf_group;
const enum aom_rc_mode rc_mode = oxcf->rc_cfg.mode;
int *inter_minq;
ASSIGN_MINQ_TABLE(bit_depth, inter_minq);
int active_best_quality = 0;
- const int is_intrl_arf_boost =
- gf_group->update_type[gf_index] == INTNL_ARF_UPDATE;
- const int is_leaf_frame =
- !(refresh_frame_flags->golden_frame ||
- refresh_frame_flags->alt_ref_frame || is_intrl_arf_boost);
+ const int is_level1_frame = (gf_group->layer_depth[gf_index] <= 1);
+ assert(IMPLIES(
+ gf_group->layer_depth[gf_index] == 1,
+ refresh_frame_flags->golden_frame || refresh_frame_flags->alt_ref_frame));
const int is_bottom_leaf_frame =
- is_leaf_frame && (gf_group->layer_depth[gf_index] == MAX_ARF_LAYERS);
+ (gf_group->layer_depth[gf_index] == MAX_ARF_LAYERS);
+ assert(IMPLIES(is_bottom_leaf_frame, !is_level1_frame));
const int is_overlay_frame = rc->is_src_frame_alt_ref;
if (is_bottom_leaf_frame || is_overlay_frame) {
@@ -1573,7 +1574,7 @@
q, cpi->oxcf.gf_cfg.lag_in_frames == 0, bit_depth);
const int boost = min_boost - active_best_quality;
active_best_quality = min_boost - (int)(boost * rc->arf_boost_factor);
- if (!is_intrl_arf_boost && !is_leaf_frame) return active_best_quality;
+ if (is_level1_frame) return active_best_quality;
if (rc_mode == AOM_Q || rc_mode == AOM_CQ) {
if (rc->level1_qp == -1) { // Uninitialized
@@ -1581,7 +1582,7 @@
// 'pyramid' levels. In this case, there is no ARF_UPDATE frame, and
// rc->level1_qp may not be set yet. So, we set that now, to be used for
// the subsequent frames in this GF group.
- assert(is_leaf_frame && !is_bottom_leaf_frame);
+ assert(!is_level1_frame && !is_bottom_leaf_frame);
*level1_qp = active_best_quality;
} else {
// rc->level1_qp was set from: