Add frame_refs_short_signaling support for rtc
This commit is to enable frame_refs_short_signaling feature for rtc low
resolution (resolution < 360p) and high speed (speed >= 9) case. In this
case, we only use LAST and GOLD ref frames, so we could
potentially save some header bits for parsing unused ref frame index,
which is frame_refs_short_signaling will do.
Note that "--enable-order-hint" is disabled in default rtc configutaions,
but enabling frame_refs_short_signaling requires "--enable-order-hint"
to be turned on. The Borg resutls below are comparing "origin/main +
--enable-order-hint=0 " vs. "this commit + --enable-order-hint=1". The
bdrate gain shows that enabling frame_refs_short_signaling not only
compensated the overhead by enabling order hint, but also provided some
extra gain.
Test set: rtc_derf
speed avg_psnr/ovr_psnr/ssim encoding_speedup
9 -0.209/-0.204/-0.233 +0.042
10 -0.024/-0.034/0.017 +0.005
Change-Id: I51c5bc7095f7f3fda135176b3e934d8a876fc9c5
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c
index a7d3254..0b74f2f 100644
--- a/av1/encoder/bitstream.c
+++ b/av1/encoder/bitstream.c
@@ -2764,7 +2764,31 @@
}
}
-static int check_frame_refs_short_signaling(AV1_COMMON *const cm) {
+static int check_frame_refs_short_signaling(AV1_COMMON *const cm,
+ int enable_ref_short_signaling) {
+ // In rtc case when res < 360p and speed >= 9, we turn on
+ // frame_refs_short_signaling if it won't break the decoder.
+ if (enable_ref_short_signaling) {
+ const int gld_map_idx = get_ref_frame_map_idx(cm, GOLDEN_FRAME);
+ const int base =
+ 1 << (cm->seq_params->order_hint_info.order_hint_bits_minus_1 + 1);
+
+ const int order_hint_group_cur =
+ cm->current_frame.display_order_hint / base;
+ const int order_hint_group_gld =
+ cm->ref_frame_map[gld_map_idx]->display_order_hint / base;
+ const int relative_dist = cm->current_frame.order_hint -
+ cm->ref_frame_map[gld_map_idx]->order_hint;
+
+ // If current frame and GOLDEN frame are in the same order_hint group, and
+ // they are not far apart (i.e., > 64 frames), then return 1.
+ if (order_hint_group_cur == order_hint_group_gld && relative_dist >= 0 &&
+ relative_dist <= 64) {
+ return 1;
+ }
+ return 0;
+ }
+
// Check whether all references are distinct frames.
const RefCntBuffer *seen_bufs[FRAME_BUFFERS] = { NULL };
int num_refs = 0;
@@ -2842,7 +2866,13 @@
CurrentFrame *const current_frame = &cm->current_frame;
FeatureFlags *const features = &cm->features;
- current_frame->frame_refs_short_signaling = 0;
+ if (!cpi->sf.rt_sf.enable_ref_short_signaling ||
+ !seq_params->order_hint_info.enable_order_hint ||
+ seq_params->order_hint_info.enable_ref_frame_mvs) {
+ current_frame->frame_refs_short_signaling = 0;
+ } else {
+ current_frame->frame_refs_short_signaling = 1;
+ }
if (seq_params->still_picture) {
assert(cm->show_existing_frame == 0);
@@ -3008,12 +3038,20 @@
#endif // FRAME_REFS_SHORT_SIGNALING
if (current_frame->frame_refs_short_signaling) {
- // NOTE(zoeliu@google.com):
- // An example solution for encoder-side implementation on frame refs
- // short signaling, which is only turned on when the encoder side
- // decision on ref frames is identical to that at the decoder side.
+ // In rtc case when cpi->sf.rt_sf.enable_ref_short_signaling is 1, we
+ // turn on frame_refs_short_signaling when the current frame
+ // and golden frame are in the same order_hint group,
+ // and their relative distance is <= 64 (in order to be decodable).
+
+ // For other cases, an example solution for encoder-side
+ // implementation on frame_refs_short_signaling is also provided in
+ // this function, where frame_refs_short_signaling is only turned on
+ // when the encoder side decision on ref frames is identical to that
+ // at the decoder side.
+
current_frame->frame_refs_short_signaling =
- check_frame_refs_short_signaling(cm);
+ check_frame_refs_short_signaling(
+ cm, cpi->sf.rt_sf.enable_ref_short_signaling);
}
if (seq_params->order_hint_info.enable_order_hint)
diff --git a/av1/encoder/speed_features.c b/av1/encoder/speed_features.c
index 998785f..601895e 100644
--- a/av1/encoder/speed_features.c
+++ b/av1/encoder/speed_features.c
@@ -1280,7 +1280,15 @@
sf->rt_sf.nonrd_agressive_skip = 1;
sf->rt_sf.skip_intra_pred = 1;
sf->rt_sf.use_rtc_tf = 2;
-
+ // Only turn on enable_ref_short_signaling for low resolution when only
+ // LAST and GOLDEN ref frames are used.
+ sf->rt_sf.enable_ref_short_signaling =
+ (sf->rt_sf.use_nonrd_altref_frame ||
+ (sf->rt_sf.use_comp_ref_nonrd &&
+ (sf->rt_sf.ref_frame_comp_nonrd[1] ||
+ sf->rt_sf.ref_frame_comp_nonrd[2])))
+ ? 0
+ : 1;
// TODO(kyslov) Re-enable when AV1 models are trained
#if 0
#if CONFIG_RT_ML_PARTITIONING
@@ -2075,6 +2083,7 @@
rt_sf->set_zeromv_skip_based_on_source_sad = 1;
rt_sf->use_adaptive_subpel_search = false;
rt_sf->screen_content_cdef_filter_qindex_thresh = 0;
+ rt_sf->enable_ref_short_signaling = 0;
}
// Populate appropriate sub-pel search method based on speed feature and user
diff --git a/av1/encoder/speed_features.h b/av1/encoder/speed_features.h
index 6af3afc..26735c49 100644
--- a/av1/encoder/speed_features.h
+++ b/av1/encoder/speed_features.h
@@ -1657,6 +1657,12 @@
// Downgrades the subpel search to av1_find_best_sub_pixel_tree_pruned_more
// when either the fullpel search performed well, or when zeromv has low sad.
bool use_adaptive_subpel_search;
+
+ // A flag used in RTC case to control frame_refs_short_signaling. Note that
+ // the final decision is made in check_frame_refs_short_signaling(). The flag
+ // can only be turned on when res < 360p and speed >= 9, in which case only
+ // LAST and GOLDEN ref frames are used now.
+ int enable_ref_short_signaling;
} REAL_TIME_SPEED_FEATURES;
/*!\endcond */