encode_api_test: add test coverage for issue 487259772 This covers a fix made in c2daa0f13c Use enc_row_mt->allocated_tile_cols/rows correctly that involved resolution / tile configurations related to row-mt. In some situations this would cause the tile data size to fall out of sync with the `row_mt_sync` allocation causing a memset on a NULL value. Note there is still an additional crash with row-mt disabled. A test is added, but disabled in this commit. Bug: 487259772 Change-Id: I58cf96e729a64c3cf1ca0e93d77fb636cbc271a9 (cherry picked from commit 2468231c631b71a34900ab388049311ae7e82219)
diff --git a/test/encode_api_test.cc b/test/encode_api_test.cc index d43b9e6..bccbf30 100644 --- a/test/encode_api_test.cc +++ b/test/encode_api_test.cc
@@ -11,6 +11,7 @@ #include <cassert> #include <climits> +#include <cmath> #include <cstdint> #include <cstdlib> #include <cstring> @@ -489,6 +490,8 @@ aom_rc_mode end_usage, unsigned int usage); void Encode(bool key_frame); + aom_codec_ctx_t *GetCodecCtx() { return &enc_; } + private: // Flushes the encoder. Should be called after all the Encode() calls. void Flush(); @@ -527,6 +530,32 @@ cfg_.rc_max_quantizer = 58; ASSERT_EQ(aom_codec_enc_init(&enc_, iface, &cfg_, 0), AOM_CODEC_OK); ASSERT_EQ(aom_codec_control(&enc_, AOME_SET_CPUUSED, speed_), AOM_CODEC_OK); + + const int log2_threads = + (cfg_.g_threads == 0) ? 0 : static_cast<int>(std::log2(cfg_.g_threads)); + int tile_columns_log2 = 0; + int tile_rows_log2 = 0; + switch (log2_threads) { + case 4: + tile_columns_log2 = 2; + tile_rows_log2 = 2; + break; + case 3: + tile_columns_log2 = 2; + tile_rows_log2 = 1; + break; + case 2: + tile_columns_log2 = 1; + tile_rows_log2 = 1; + break; + default: tile_columns_log2 = log2_threads; + } + ASSERT_EQ( + aom_codec_control(&enc_, AV1E_SET_TILE_COLUMNS, tile_columns_log2), + AOM_CODEC_OK); + ASSERT_EQ(aom_codec_control(&enc_, AV1E_SET_TILE_ROWS, tile_rows_log2), + AOM_CODEC_OK); + initialized_ = true; return; } @@ -976,6 +1005,60 @@ ASSERT_EQ(aom_codec_destroy(&enc), AOM_CODEC_OK); } +void ReproBuganizer487259772(const bool row_mt, int initial_threads = 2) { + AV1Encoder encoder(7); + + encoder.Configure(initial_threads, 800, 600, AOM_VBR, AOM_USAGE_REALTIME); + // This is not exposed by the WebCodecs interface. It's set to 1 in Chrome's + // implementation. + ASSERT_EQ(aom_codec_control(encoder.GetCodecCtx(), AV1E_SET_ROW_MT, row_mt), + AOM_CODEC_OK); + encoder.Encode(false); + encoder.Encode(false); + encoder.Encode(false); + + encoder.Configure(1, 352, 288, AOM_VBR, AOM_USAGE_REALTIME); + encoder.Encode(false); + encoder.Encode(false); + encoder.Encode(false); + encoder.Encode(false); + + encoder.Configure(1, 48, 480, AOM_VBR, AOM_USAGE_REALTIME); + encoder.Encode(false); + encoder.Encode(true); + encoder.Encode(false); + + encoder.Configure(1, 8, 8, AOM_VBR, AOM_USAGE_REALTIME); + encoder.Encode(false); + encoder.Encode(false); + + encoder.Configure(1, 24, 24, AOM_VBR, AOM_USAGE_REALTIME); + encoder.Encode(false); + encoder.Encode(false); + + encoder.Configure(1, 97, 53, AOM_VBR, AOM_USAGE_REALTIME); + encoder.Encode(false); + encoder.Encode(false); + + encoder.Configure(1, 32, 320, AOM_VBR, AOM_USAGE_REALTIME); + encoder.Encode(false); + encoder.Encode(false); +} + +TEST(EncodeAPI, Buganizer487259772NoThreads) { + ReproBuganizer487259772(/*row_mt=*/false, /*initial_threads=*/1); +} + +// TODO: bug 487259772 - Enable this test after assertion/crash (NULL mbmi) in +// av1_loopfilter is fixed. +TEST(EncodeAPI, DISABLED_Buganizer487259772NoRowMT) { + ReproBuganizer487259772(/*row_mt=*/false); +} + +TEST(EncodeAPI, Buganizer487259772RowMT) { + ReproBuganizer487259772(/*row_mt=*/true); +} + class EncodeAPIParameterized : public testing::TestWithParam<std::tuple< /*usage=*/unsigned int, /*speed=*/int, /*aq_mode=*/unsigned int>> {};