Commit 930599bcbe for aom
commit 930599bcbe1f2205ac69d4d94594eb679029110c
Author: Marco Paniconi <marpan@google.com>
Date: Wed Nov 11 19:17:45 2026 +0000
rtc: Fix data race for cdef_strength in encode_nonrd_sb
In nonrd mode, mi_grid_base is not cleared between frames, and
partitioning only updates mi_grid_base at the top-left of each in-bounds
partition block. After reconfiguring to a smaller frame size,
encode_nonrd_sb() could dereference stale mi_grid_base pointers for
64x64 sub-blocks of a 128x128 superblock that now point to mi_alloc
entries owned by other superblock rows.
Check that each 64x64 sub-block is within the frame bounds and
initialize cdef_strength directly in mi_alloc.
Bug: 584727137
Change-Id: I935494533a1065793da2b1eab97ee4bb560f2225
diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c
index 8b0a1addec..96a3cc57fa 100644
--- a/av1/encoder/encodeframe.c
+++ b/av1/encoder/encodeframe.c
@@ -653,10 +653,14 @@ static inline void encode_nonrd_sb(AV1_COMP *cpi, ThreadData *td,
// If 128x128 block is used, we need to set the flag for all 4 64x64 sub
// "blocks".
for (int r = 0; r < block64_in_sb; ++r) {
+ const int mi_row_sub = mi_row + r * MI_SIZE_64X64;
+ if (mi_row_sub >= cm->mi_params.mi_rows) continue;
for (int c = 0; c < block64_in_sb; ++c) {
- const int idx_in_sb =
- r * MI_SIZE_64X64 * cm->mi_params.mi_stride + c * MI_SIZE_64X64;
- if (mi[idx_in_sb]) mi[idx_in_sb]->cdef_strength = 1;
+ const int mi_col_sub = mi_col + c * MI_SIZE_64X64;
+ if (mi_col_sub >= cm->mi_params.mi_cols) continue;
+ const int alloc_mi_idx =
+ get_alloc_mi_idx(&cm->mi_params, mi_row_sub, mi_col_sub);
+ cm->mi_params.mi_alloc[alloc_mi_idx].cdef_strength = 1;
}
}
}
diff --git a/test/encode_api_test.cc b/test/encode_api_test.cc
index 83c493333e..ce57f87122 100644
--- a/test/encode_api_test.cc
+++ b/test/encode_api_test.cc
@@ -1520,6 +1520,19 @@ TEST(EncodeAPI, Buganizer487259772RowMT) {
ReproBuganizer487259772(/*row_mt=*/true);
}
+// Reproduces b/584727137: data race in encode_nonrd_sb() when initializing
+// cdef_strength for 128x128 superblocks after reconfiguring to a smaller
+// frame size with multi-threading.
+TEST(EncodeAPI, Buganizer584727137) {
+ AV1Encoder encoder(11);
+ encoder.Configure(10, 721, 877, AOM_VBR, AOM_USAGE_REALTIME);
+ encoder.Encode(true);
+ encoder.Configure(6, 721, 603, AOM_CBR, AOM_USAGE_REALTIME);
+ encoder.Encode(false);
+ encoder.Configure(8, 436, 687, AOM_VBR, AOM_USAGE_REALTIME);
+ encoder.Encode(false);
+}
+
class EncodeAPIParameterized
: public testing::TestWithParam<std::tuple<
/*usage=*/unsigned int, /*speed=*/int, /*aq_mode=*/unsigned int>> {};