Commit 935aaa9b71 for aom
commit 935aaa9b71eec2a06193174b80ae402ef886d98e
Author: Lin Zheng <linzhen@google.com>
Date: Sat Mar 14 16:28:22 2026 +0000
Fix data race issue in FrameParallelThreadEncodeTest
A data race issue was detected when cpi->ppi->p_rc.rtc_mode was
initialized in speed_feature.c. This commit removes rtc_mode from p_rc
structure, and passes a local parameter into the function during use.
Bug: 491358676
Change-Id: I0325d3ecd10bd4f026c4d79bf32cf79c8d54a100
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c
index 93d276f3d8..6182f1d781 100644
--- a/av1/encoder/encoder.c
+++ b/av1/encoder/encoder.c
@@ -1537,7 +1537,6 @@ AV1_COMP *av1_create_compressor(AV1_PRIMARY *ppi, const AV1EncoderConfig *oxcf,
cm->current_frame_id = -1;
cpi->tile_data = NULL;
cpi->last_show_frame_buf = NULL;
- cpi->ppi->p_rc.rtc_mode = (cpi->oxcf.mode == REALTIME);
realloc_segmentation_maps(cpi);
cpi->refresh_frame.alt_ref_frame = false;
diff --git a/av1/encoder/pass2_strategy.c b/av1/encoder/pass2_strategy.c
index 93ca3e435d..ae0b28b4b4 100644
--- a/av1/encoder/pass2_strategy.c
+++ b/av1/encoder/pass2_strategy.c
@@ -604,7 +604,7 @@ static double calc_frame_boost(const PRIMARY_RATE_CONTROL *p_rc,
// (zoom in). The range for this_frame_mv_in_out is -1.0 to +1.0.
if (this_frame_mv_in_out > 0.0) {
frame_boost += frame_boost * (this_frame_mv_in_out * 2.0);
- if (!p_rc->accumulate_stats_stage && !p_rc->rtc_mode)
+ if (!p_rc->accumulate_stats_stage)
max_boost += max_boost * (this_frame_mv_in_out * 2.0);
}
// In the extreme case the boost is halved.
@@ -2460,9 +2460,10 @@ static void set_gop_bits_boost(AV1_COMP *cpi, int i, int is_intra_only,
p_rc->gfu_boost_average = gfu_boost_sum / gfu_count;
}
cpi->twopass_frame = stats_in_backup;
- p_rc->accumulate_stats_stage = false;
}
+ p_rc->accumulate_stats_stage = (cpi->oxcf.mode == REALTIME);
+
int ext_len = i - is_intra_only;
if (use_alt_ref) {
const int forward_frames = (rc->frames_to_key - i >= ext_len)
diff --git a/av1/encoder/ratectrl.c b/av1/encoder/ratectrl.c
index c22cfdfc92..491e7a5222 100644
--- a/av1/encoder/ratectrl.c
+++ b/av1/encoder/ratectrl.c
@@ -1170,16 +1170,15 @@ static int get_active_quality(int q, int gfu_boost, int low, int high,
static int gfboost_thresh[3] = { 4000, 4000, 3000 };
static int get_kf_active_quality(const PRIMARY_RATE_CONTROL *const p_rc, int q,
- aom_bit_depth_t bit_depth, const int res_idx) {
+ aom_bit_depth_t bit_depth, const int res_idx,
+ const bool rtc_mode) {
int *kf_low_motion_minq;
int *kf_high_motion_minq;
- ASSIGN_MINQ_TABLE_2(bit_depth, kf_low_motion_minq, res_idx > 1,
- p_rc->rtc_mode);
- ASSIGN_MINQ_TABLE_2(bit_depth, kf_high_motion_minq, res_idx > 1,
- p_rc->rtc_mode);
+ ASSIGN_MINQ_TABLE_2(bit_depth, kf_low_motion_minq, res_idx > 1, rtc_mode);
+ ASSIGN_MINQ_TABLE_2(bit_depth, kf_high_motion_minq, res_idx > 1, rtc_mode);
- int kf_low_local = p_rc->rtc_mode ? kf_low_rtc : kf_low;
- int kf_high_local = p_rc->rtc_mode ? kf_high_rtc : kf_high;
+ int kf_low_local = rtc_mode ? kf_low_rtc : kf_low;
+ int kf_high_local = rtc_mode ? kf_high_rtc : kf_high;
return get_active_quality(q, p_rc->kf_boost, kf_low_local, kf_high_local,
kf_low_motion_minq, kf_high_motion_minq);
@@ -1187,16 +1186,14 @@ static int get_kf_active_quality(const PRIMARY_RATE_CONTROL *const p_rc, int q,
static int get_gf_active_quality_no_rc(const PRIMARY_RATE_CONTROL *const p_rc,
int q, aom_bit_depth_t bit_depth,
- const int res_idx) {
+ const int res_idx, const bool rtc_mode) {
int *arfgf_low_motion_minq;
int *arfgf_high_motion_minq;
- ASSIGN_MINQ_TABLE_2(bit_depth, arfgf_low_motion_minq, res_idx > 1,
- p_rc->rtc_mode);
- ASSIGN_MINQ_TABLE_2(bit_depth, arfgf_high_motion_minq, res_idx > 1,
- p_rc->rtc_mode);
+ ASSIGN_MINQ_TABLE_2(bit_depth, arfgf_low_motion_minq, res_idx > 1, rtc_mode);
+ ASSIGN_MINQ_TABLE_2(bit_depth, arfgf_high_motion_minq, res_idx > 1, rtc_mode);
int gf_low_local, gf_high_local;
- if (p_rc->rtc_mode == false) {
+ if (!rtc_mode) {
gf_low_local = (p_rc->gfu_boost_average < gfboost_thresh[res_idx])
? gf_low_1
: gf_low_2;
@@ -1213,12 +1210,13 @@ static int get_gf_active_quality_no_rc(const PRIMARY_RATE_CONTROL *const p_rc,
}
static int get_gf_active_quality(const PRIMARY_RATE_CONTROL *const p_rc, int q,
- aom_bit_depth_t bit_depth, const int res_idx) {
- return get_gf_active_quality_no_rc(p_rc, q, bit_depth, res_idx);
+ aom_bit_depth_t bit_depth, const int res_idx,
+ const bool rtc_mode) {
+ return get_gf_active_quality_no_rc(p_rc, q, bit_depth, res_idx, rtc_mode);
}
static int get_gf_high_motion_quality(int q, aom_bit_depth_t bit_depth,
- const int res_idx, bool rtc_mode) {
+ const int res_idx, const bool rtc_mode) {
int *arfgf_high_motion_minq;
ASSIGN_MINQ_TABLE_2(bit_depth, arfgf_high_motion_minq, res_idx > 1, rtc_mode);
return arfgf_high_motion_minq[q];
@@ -1384,6 +1382,7 @@ static int calc_active_best_quality_no_stats_cbr(const AV1_COMP *cpi,
const int is_480p_or_larger = AOMMIN(cm->width, cm->height) >= 480;
// res_idx is 0 for res < 480p, 1 for 480p, 2 for 608p+
const int res_idx = is_480p_or_larger + is_608p_or_larger;
+ const bool rtc_mode = (cpi->oxcf.mode == REALTIME);
if (frame_is_intra_only(cm)) {
// Handle the special case for key frames forced when we have reached
@@ -1399,8 +1398,9 @@ static int calc_active_best_quality_no_stats_cbr(const AV1_COMP *cpi,
// not first frame of one pass and kf_boost is set
double q_adj_factor = 1.0;
double q_val;
- active_best_quality = get_kf_active_quality(
- p_rc, p_rc->avg_frame_qindex[KEY_FRAME], bit_depth, res_idx);
+ active_best_quality =
+ get_kf_active_quality(p_rc, p_rc->avg_frame_qindex[KEY_FRAME],
+ bit_depth, res_idx, rtc_mode);
// Allow somewhat lower kf minq with small image formats.
if ((width * height) <= (352 * 288)) {
q_adj_factor -= 0.25;
@@ -1422,7 +1422,8 @@ static int calc_active_best_quality_no_stats_cbr(const AV1_COMP *cpi,
p_rc->avg_frame_qindex[INTER_FRAME] < active_worst_quality) {
q = p_rc->avg_frame_qindex[INTER_FRAME];
}
- active_best_quality = get_gf_active_quality(p_rc, q, bit_depth, res_idx);
+ active_best_quality =
+ get_gf_active_quality(p_rc, q, bit_depth, res_idx, rtc_mode);
} else {
// Use the lower of active_worst_quality and recent/average Q.
FRAME_TYPE frame_type =
@@ -1598,6 +1599,7 @@ static int rc_pick_q_and_bounds_no_stats(const AV1_COMP *cpi, int width,
const int is_480p_or_larger = AOMMIN(cm->width, cm->height) >= 480;
// res_idx is 0 for res < 480p, 1 for 480p, 2 for 608p+
const int res_idx = is_480p_or_larger + is_608p_or_larger;
+ const bool rtc_mode = (cpi->oxcf.mode == REALTIME);
assert(has_no_stats_stage(cpi));
assert(rc_mode == AOM_VBR ||
@@ -1613,7 +1615,7 @@ static int rc_pick_q_and_bounds_no_stats(const AV1_COMP *cpi, int width,
int active_worst_quality = calc_active_worst_quality_no_stats_vbr(cpi);
int q;
int *inter_minq;
- ASSIGN_MINQ_TABLE_2(bit_depth, inter_minq, res_idx > 1, p_rc->rtc_mode);
+ ASSIGN_MINQ_TABLE_2(bit_depth, inter_minq, res_idx > 1, rtc_mode);
if (frame_is_intra_only(cm)) {
if (rc_mode == AOM_Q) {
@@ -1639,8 +1641,9 @@ static int rc_pick_q_and_bounds_no_stats(const AV1_COMP *cpi, int width,
} else { // not first frame of one pass and kf_boost is set
double q_adj_factor = 1.0;
- active_best_quality = get_kf_active_quality(
- p_rc, p_rc->avg_frame_qindex[KEY_FRAME], bit_depth, res_idx);
+ active_best_quality =
+ get_kf_active_quality(p_rc, p_rc->avg_frame_qindex[KEY_FRAME],
+ bit_depth, res_idx, rtc_mode);
// Allow somewhat lower kf minq with small image formats.
if ((width * height) <= (352 * 288)) {
@@ -1667,7 +1670,8 @@ static int rc_pick_q_and_bounds_no_stats(const AV1_COMP *cpi, int width,
// For constrained quality don't allow Q less than the cq level
if (rc_mode == AOM_CQ) {
if (q < cq_level) q = cq_level;
- active_best_quality = get_gf_active_quality(p_rc, q, bit_depth, res_idx);
+ active_best_quality =
+ get_gf_active_quality(p_rc, q, bit_depth, res_idx, rtc_mode);
// Constrained quality use slightly lower active best.
active_best_quality = active_best_quality * 15 / 16;
} else if (rc_mode == AOM_Q) {
@@ -1679,7 +1683,8 @@ static int rc_pick_q_and_bounds_no_stats(const AV1_COMP *cpi, int width,
: av1_compute_qdelta(rc, q_val, q_val * 0.50, bit_depth);
active_best_quality = AOMMAX(qindex + delta_qindex, rc->best_quality);
} else {
- active_best_quality = get_gf_active_quality(p_rc, q, bit_depth, res_idx);
+ active_best_quality =
+ get_gf_active_quality(p_rc, q, bit_depth, res_idx, rtc_mode);
}
} else {
if (rc_mode == AOM_Q) {
@@ -1821,6 +1826,7 @@ static void get_intra_q_and_bounds(const AV1_COMP *cpi, int width, int height,
const int is_480p_or_larger = AOMMIN(cm->width, cm->height) >= 480;
// res_idx is 0 for res < 480p, 1 for 480p, 2 for 608p+
const int res_idx = is_480p_or_larger + is_608p_or_larger;
+ const bool rtc_mode = (cpi->oxcf.mode == REALTIME);
if (rc->frames_to_key <= 1 && oxcf->rc_cfg.mode == AOM_Q) {
// If the next frame is also a key frame or the current frame is the
@@ -1867,8 +1873,8 @@ static void get_intra_q_and_bounds(const AV1_COMP *cpi, int width, int height,
double q_val;
// Baseline value derived from active_worst_quality and kf boost.
- active_best_quality =
- get_kf_active_quality(p_rc, active_worst_quality, bit_depth, res_idx);
+ active_best_quality = get_kf_active_quality(p_rc, active_worst_quality,
+ bit_depth, res_idx, rtc_mode);
if (cpi->is_screen_content_type) {
active_best_quality /= 2;
}
@@ -2068,9 +2074,10 @@ static int get_active_best_quality(const AV1_COMP *const cpi,
const int is_480p_or_larger = AOMMIN(cm->width, cm->height) >= 480;
// res_idx is 0 for res < 480p, 1 for 480p, 2 for 608p+
const int res_idx = is_480p_or_larger + is_608p_or_larger;
+ const bool rtc_mode = (cpi->oxcf.mode == REALTIME);
int *inter_minq;
- ASSIGN_MINQ_TABLE_2(bit_depth, inter_minq, res_idx > 1, p_rc->rtc_mode);
+ ASSIGN_MINQ_TABLE_2(bit_depth, inter_minq, res_idx > 1, rtc_mode);
// TODO(jingning): Consider to rework this hack that covers issues incurred
// in lightfield setting.
@@ -2103,11 +2110,12 @@ static int get_active_best_quality(const AV1_COMP *const cpi,
q = p_rc->avg_frame_qindex[INTER_FRAME];
}
if (rc_mode == AOM_CQ && q < cq_level) q = cq_level;
- active_best_quality = get_gf_active_quality(p_rc, q, bit_depth, res_idx);
+ active_best_quality =
+ get_gf_active_quality(p_rc, q, bit_depth, res_idx, rtc_mode);
// Constrained quality use slightly lower active best.
if (rc_mode == AOM_CQ) active_best_quality = active_best_quality * 15 / 16;
const int min_boost =
- get_gf_high_motion_quality(q, bit_depth, res_idx, p_rc->rtc_mode);
+ get_gf_high_motion_quality(q, bit_depth, res_idx, rtc_mode);
const int boost = min_boost - active_best_quality;
active_best_quality = min_boost - (int)(boost * p_rc->arf_boost_factor);
if (!is_intrl_arf_boost) return active_best_quality;
diff --git a/av1/encoder/ratectrl.h b/av1/encoder/ratectrl.h
index a854304331..e83b7c0e18 100644
--- a/av1/encoder/ratectrl.h
+++ b/av1/encoder/ratectrl.h
@@ -338,11 +338,6 @@ typedef struct {
*/
bool accumulate_stats_stage;
- /*!
- * Indicate if it is realtime mode or not
- */
- bool rtc_mode;
-
/*!
* Stores the determined gf group lengths for a set of gf groups
*/
diff --git a/av1/encoder/speed_features.c b/av1/encoder/speed_features.c
index 97edb28df6..9537f0a2f8 100644
--- a/av1/encoder/speed_features.c
+++ b/av1/encoder/speed_features.c
@@ -2636,8 +2636,6 @@ void av1_set_speed_features_framesize_independent(AV1_COMP *cpi, int speed) {
init_lpf_sf(&sf->lpf_sf);
init_rt_sf(&sf->rt_sf);
- cpi->ppi->p_rc.rtc_mode = (cpi->oxcf.mode == REALTIME);
-
switch (oxcf->mode) {
case GOOD:
set_good_speed_features_framesize_independent(cpi, sf, speed);