Add flag to disable content based q adjustment
This flag is added for rate control library for av1, to disable content
dependency so the test can run the encoder without content related
adjustment to qp.
BD rate loss:
aq 0 aq 3
rtc 1% 2.2%
rtc_derf 1.7% 3.2%
Change-Id: I3c88f000b44e43ec537096232647776c44eda6e3
diff --git a/av1/encoder/aq_cyclicrefresh.c b/av1/encoder/aq_cyclicrefresh.c
index 5fb8943..479b23a 100644
--- a/av1/encoder/aq_cyclicrefresh.c
+++ b/av1/encoder/aq_cyclicrefresh.c
@@ -92,8 +92,14 @@
const int num4x4bl = mbs << 4;
// Weight for non-base segments: use actual number of blocks refreshed in
// previous/just encoded frame. Note number of blocks here is in 4x4 units.
- const double weight_segment1 = (double)cr->actual_num_seg1_blocks / num4x4bl;
- const double weight_segment2 = (double)cr->actual_num_seg2_blocks / num4x4bl;
+ double weight_segment1 = (double)cr->actual_num_seg1_blocks / num4x4bl;
+ double weight_segment2 = (double)cr->actual_num_seg2_blocks / num4x4bl;
+ if (cpi->rc.rtc_external_ratectrl) {
+ weight_segment1 = (double)(cr->percent_refresh * cm->mi_params.mi_rows *
+ cm->mi_params.mi_cols / 100) /
+ num4x4bl;
+ weight_segment2 = 0;
+ }
// Take segment weighted average for estimated bits.
const int estimated_bits =
(int)((1.0 - weight_segment1 - weight_segment2) *
@@ -124,6 +130,13 @@
cr->actual_num_seg2_blocks) >>
1) /
num4x4bl;
+ if (cpi->rc.rtc_external_ratectrl) {
+ weight_segment = (double)((cr->target_num_seg_blocks +
+ cr->percent_refresh * cm->mi_params.mi_rows *
+ cm->mi_params.mi_cols / 100) >>
+ 1) /
+ num4x4bl;
+ }
// Compute delta-q corresponding to qindex i.
int deltaq = compute_deltaq(cpi, i, cr->rate_ratio_qdelta);
// Take segment weighted average for bits per mb.
@@ -465,6 +478,12 @@
if (weight_segment_target < 7 * weight_segment / 8)
weight_segment = weight_segment_target;
cr->weight_segment = weight_segment;
+ if (rc->rtc_external_ratectrl) {
+ cr->actual_num_seg1_blocks = cr->percent_refresh * cm->mi_params.mi_rows *
+ cm->mi_params.mi_cols / 100;
+ cr->actual_num_seg2_blocks = 0;
+ cr->weight_segment = (double)(cr->actual_num_seg1_blocks) / num4x4bl;
+ }
}
// Setup cyclic background refresh: set delta q and segmentation map.
diff --git a/av1/encoder/encodeframe_utils.c b/av1/encoder/encodeframe_utils.c
index a86359f..c7fe3e6 100644
--- a/av1/encoder/encodeframe_utils.c
+++ b/av1/encoder/encodeframe_utils.c
@@ -260,7 +260,8 @@
}
// Else for cyclic refresh mode update the segment map, set the segment id
// and then update the quantizer.
- if (cpi->oxcf.q_cfg.aq_mode == CYCLIC_REFRESH_AQ) {
+ if (cpi->oxcf.q_cfg.aq_mode == CYCLIC_REFRESH_AQ &&
+ !cpi->rc.rtc_external_ratectrl) {
av1_cyclic_refresh_update_segment(cpi, x, mi_row, mi_col, bsize,
ctx->rd_stats.rate, ctx->rd_stats.dist,
txfm_info->skip_txfm, dry_run);
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c
index f7ef320..27f94be 100644
--- a/av1/encoder/encoder.c
+++ b/av1/encoder/encoder.c
@@ -2448,14 +2448,15 @@
av1_encode_frame(cpi);
// Update some stats from cyclic refresh.
- if (q_cfg->aq_mode == CYCLIC_REFRESH_AQ && !frame_is_intra_only(cm))
+ if (q_cfg->aq_mode == CYCLIC_REFRESH_AQ && !cpi->rc.rtc_external_ratectrl &&
+ !frame_is_intra_only(cm))
av1_cyclic_refresh_postencode(cpi);
// Adjust the refresh of the golden (longer-term) reference based on QP
// selected for this frame. This is for CBR with 1 layer/non-svc RTC mode.
if (!frame_is_intra_only(cm) && cpi->oxcf.rc_cfg.mode == AOM_CBR &&
cpi->oxcf.mode == REALTIME && svc->number_spatial_layers == 1 &&
- svc->number_temporal_layers == 1)
+ svc->number_temporal_layers == 1 && !cpi->rc.rtc_external_ratectrl)
av1_adjust_gf_refresh_qp_one_pass_rt(cpi);
#if CONFIG_COLLECT_COMPONENT_TIMING
diff --git a/av1/encoder/partition_search.c b/av1/encoder/partition_search.c
index 61aa878..5fce264 100644
--- a/av1/encoder/partition_search.c
+++ b/av1/encoder/partition_search.c
@@ -2089,7 +2089,7 @@
if (tile_data->allow_update_cdf) update_stats(&cpi->common, td);
}
if (cpi->oxcf.q_cfg.aq_mode == CYCLIC_REFRESH_AQ && mbmi->skip_txfm &&
- !cpi->cyclic_refresh->skip_over4x4)
+ !cpi->cyclic_refresh->skip_over4x4 && !cpi->rc.rtc_external_ratectrl)
av1_cyclic_reset_segment_skip(cpi, x, mi_row, mi_col, bsize);
// TODO(Ravi/Remya): Move this copy function to a better logical place
// This function will copy the best mode information from block
diff --git a/av1/encoder/ratectrl.c b/av1/encoder/ratectrl.c
index 312e438..6ac4f50 100644
--- a/av1/encoder/ratectrl.c
+++ b/av1/encoder/ratectrl.c
@@ -383,6 +383,7 @@
rc->resize_avg_qp = 0;
rc->resize_buffer_underflow = 0;
rc->resize_count = 0;
+ rc->rtc_external_ratectrl = 0;
#if CONFIG_FRAME_PARALLEL_ENCODE
rc->frame_level_fast_extra_bits = 0;
#endif
diff --git a/av1/encoder/ratectrl.h b/av1/encoder/ratectrl.h
index 3f822aa..7587075 100644
--- a/av1/encoder/ratectrl.h
+++ b/av1/encoder/ratectrl.h
@@ -227,6 +227,9 @@
int resize_avg_qp;
int resize_buffer_underflow;
int resize_count;
+
+ // Flag to disable content related qp adjustment.
+ int rtc_external_ratectrl;
#if CONFIG_FRAME_PARALLEL_ENCODE
int frame_level_fast_extra_bits;
double frame_level_rate_correction_factors[RATE_FACTOR_LEVELS];
diff --git a/av1/encoder/speed_features.c b/av1/encoder/speed_features.c
index 4b2ab6f..10be6d6 100644
--- a/av1/encoder/speed_features.c
+++ b/av1/encoder/speed_features.c
@@ -1408,6 +1408,7 @@
// TODO(any): This sf could be removed.
sf->rt_sf.short_circuit_low_temp_var = 1;
sf->rt_sf.check_scene_detection = 1;
+ if (cpi->rc.rtc_external_ratectrl) sf->rt_sf.check_scene_detection = 0;
if (cm->current_frame.frame_type != KEY_FRAME &&
cpi->oxcf.rc_cfg.mode == AOM_CBR)
sf->rt_sf.overshoot_detection_cbr = FAST_DETECTION_MAXQ;