Commit cb85ba6aed for aom
commit cb85ba6aed15ff0430defecd52a1338815426e8f
Author: Cheng Chen <chengchen@google.com>
Date: Wed Apr 15 16:04:48 2026 -0700
Add a condition when we do not read frame header obu
When ext_tile_debug = 1, camera_frame_header_ready is never set to 1.
If there are multiple OBUs, the first OBU will read frame header,
allocate buffer. When the second OBU comes, the frame header is read
again, leading to assertion failure.
Add a contition to avoid the second OBU triggering frame header reading.
BUG=aomedia:502030569
Change-Id: Ifd013840318c14f85c9adf1860be71a465c35b1d
diff --git a/av1/decoder/obu.c b/av1/decoder/obu.c
index 9df0e88255..ff1aca0bda 100644
--- a/av1/decoder/obu.c
+++ b/av1/decoder/obu.c
@@ -988,7 +988,8 @@ int aom_decode_frame_from_obus(struct AV1Decoder *pbi, const uint8_t *data,
}
// Only decode first frame header received
if (!pbi->seen_frame_header ||
- (cm->tiles.large_scale && !pbi->camera_frame_header_ready)) {
+ (cm->tiles.large_scale && !pbi->camera_frame_header_ready &&
+ obu_header.type != OBU_REDUNDANT_FRAME_HEADER)) {
frame_header_size = read_frame_header_obu(
pbi, &rb, data, p_data_end, obu_header.type != OBU_FRAME);
frame_header = data;
diff --git a/test/invalid_file_test.cc b/test/invalid_file_test.cc
index b344e3c08e..f6e180599a 100644
--- a/test/invalid_file_test.cc
+++ b/test/invalid_file_test.cc
@@ -9,10 +9,12 @@
* PATENTS file, you can obtain it at www.aomedia.org/license/patent.
*/
+#include <array>
#include <cstdio>
#include <ostream>
#include <string>
+#include "aom/aomdx.h"
#include "config/aom_config.h"
#include "gtest/gtest.h"
#include "test/codec_factory.h"
@@ -167,4 +169,120 @@ const DecodeParam kAV1InvalidFileTests[] = {
AV1_INSTANTIATE_TEST_SUITE(InvalidFileTest,
::testing::ValuesIn(kAV1InvalidFileTests));
+class InvalidFilePoCTest : public ::testing::Test,
+ public ::libaom_test::DecoderTest {
+ protected:
+ InvalidFilePoCTest() : DecoderTest(&libaom_test::kAV1) {}
+
+ void PreDecodeFrameHook(const libaom_test::CompressedVideoSource & /*video*/,
+ libaom_test::Decoder *decoder) override {
+ decoder->Control(AV1D_EXT_TILE_DEBUG, 1);
+ decoder->Control(AV1_SET_TILE_MODE, 1);
+ }
+
+ bool HandleDecodeResult(const aom_codec_err_t res_dec,
+ const libaom_test::CompressedVideoSource & /*video*/,
+ libaom_test::Decoder *decoder) override {
+ (void)res_dec;
+ (void)decoder;
+ return true;
+ }
+
+ void HandlePeekResult(libaom_test::Decoder *const /*decoder*/,
+ libaom_test::CompressedVideoSource * /*video*/,
+ const aom_codec_err_t /*res_peek*/) override {}
+};
+
+TEST_F(InvalidFilePoCTest, CrashTest) {
+ aom_codec_dec_cfg_t cfg = { 1, 0, 0, 0 }; // 1 thread
+
+ static const unsigned int kPoCDataLen = 642;
+ static constexpr std::array<unsigned char, kPoCDataLen> kPoCData = {
+ 0x00, 0x00, 0xe7, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x47, 0x63, 0x67, 0xef,
+ 0xf1, 0xbd, 0x00, 0x00, 0x00, 0x00, 0x04, 0x36, 0x00, 0x4b, 0x49, 0x41,
+ 0x56, 0x30, 0x31, 0x00, 0x00, 0x00, 0x12, 0xf6, 0x0a, 0x0b, 0x00, 0x00,
+ 0x80, 0x40, 0x00, 0x4b, 0x49, 0x46, 0x00, 0x30, 0x4b, 0x32, 0x41, 0x09,
+ 0x30, 0x44, 0x44, 0x3d, 0x44, 0x1c, 0x02, 0x6b, 0xc9, 0x9a, 0x29, 0xcc,
+ 0x15, 0x4a, 0x9e, 0x25, 0xc8, 0x0d, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x6b, 0xc9,
+ 0x9a, 0x29, 0xc8, 0x15, 0x4a, 0x9e, 0x25, 0xc8, 0x0d, 0x02, 0x02, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
+ 0x1a, 0x1a, 0x1a, 0x1a, 0x1a, 0x44, 0x4b, 0x49, 0x46, 0x00, 0x00, 0x20,
+ 0x00, 0x41, 0x56, 0x30, 0x31, 0x00, 0x04, 0xd0, 0x02, 0x1e, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x3b, 0x6f, 0xec, 0xcb, 0xd9, 0x8d, 0x21, 0x8b,
+ 0x04, 0x4f, 0x92, 0xb5, 0x11, 0x42, 0x87, 0x0c, 0xf1, 0xf8, 0x85, 0xde,
+ 0x62, 0x16, 0x4f, 0xac, 0xb4, 0xdb, 0xc4, 0x4d, 0xab, 0x09, 0x25, 0x29,
+ 0xc4, 0xb1, 0x75, 0x0c, 0x47, 0x01, 0x2a, 0x6a, 0x90, 0x2b, 0xf0, 0xad,
+ 0x9b, 0xd7, 0x9f, 0x26, 0x45, 0xf3, 0xd8, 0x5b, 0xba, 0x49, 0x19, 0x0d,
+ 0xd1, 0x55, 0x82, 0x0b, 0x3b, 0xbb, 0x51, 0x5c, 0x30, 0x9f, 0xf3, 0x94,
+ 0xb0, 0xd6, 0x40, 0x07, 0xe5, 0x98, 0x4d, 0x24, 0x49, 0x02, 0xd9, 0xee,
+ 0x56, 0x6b, 0x85, 0x44, 0x3a, 0xa0, 0xc7, 0xc7, 0x6e, 0x46, 0x9b, 0x27,
+ 0x7f, 0x66, 0x34, 0x87, 0x8f, 0x24, 0xb0, 0xe7, 0x74, 0x62, 0x3e, 0x4e,
+ 0x0c, 0xa4, 0x01, 0x21, 0x0c, 0x6c, 0xc2, 0x58, 0x7a, 0x8d, 0xdc, 0xf9,
+ 0x73, 0x62, 0x33, 0xf3, 0x47, 0xe9, 0xe4, 0x12, 0xc5, 0x64, 0xde, 0x08,
+ 0x56, 0x06, 0x60, 0x7d, 0xe9, 0xfd, 0x4d, 0xf0, 0x4f, 0xa0, 0xa3, 0x9d,
+ 0x94, 0x16, 0x52, 0x83, 0xaa, 0xa6, 0x77, 0x51, 0xb1, 0xbd, 0x76, 0xcc,
+ 0x53, 0xb1, 0xb8, 0x21, 0x5e, 0x08, 0x6a, 0x74, 0x95, 0x4d, 0x70, 0xc5,
+ 0xfc, 0xe3, 0x21, 0x6d, 0x8a, 0xd5, 0xb7, 0xef, 0xf5, 0xd1, 0xb3, 0x15,
+ 0x66, 0xd5, 0xe4, 0xaf, 0x44, 0x4b, 0x49, 0x46, 0x00, 0x00, 0xf3, 0xac,
+ 0xdc, 0x84, 0x3a, 0x2b, 0x86, 0xd5, 0x0d, 0x4f, 0x41, 0x57, 0x18, 0x5c,
+ 0x75, 0xf0, 0xa7, 0xcf, 0xdf, 0x8b, 0x2f, 0x7e, 0x38, 0xea, 0x04, 0x30,
+ 0xd2, 0x2d, 0xd4, 0x63, 0xc2, 0x2c, 0x49, 0x20, 0xaf, 0x6b, 0x97, 0xde,
+ 0x87, 0x9d, 0x9f, 0x17, 0x0f, 0x8f, 0x8a, 0x55, 0x73, 0x5d, 0x90, 0x46,
+ 0xf6, 0xb2, 0xa4, 0xce, 0xc5, 0x68, 0x77, 0x19, 0x12, 0x45, 0x54, 0x0e,
+ 0xdb, 0x05, 0x24, 0x25, 0xe4, 0x84, 0x30, 0x70, 0xe9, 0xeb, 0x9a, 0x7b,
+ 0x53, 0xf5, 0x87, 0xf8, 0x01, 0x6c, 0x6a, 0xe5, 0x8d, 0x1f, 0x0c, 0x60,
+ 0xcc, 0xa9, 0x74, 0x1c, 0xc3, 0x2d, 0x1d, 0x1a, 0xd4, 0x2b, 0xa4, 0x1c,
+ 0xea, 0xfc, 0x18, 0x21, 0xdc, 0xac, 0x43, 0xb3, 0xb9, 0x79, 0x16, 0xae,
+ 0xbb, 0x75, 0xb2, 0xda, 0xbd, 0x71, 0x37, 0xdb, 0x97, 0xa7, 0xbe, 0xfe,
+ 0xce, 0x1e, 0x1f, 0xb4, 0x2b, 0x6d, 0x05, 0x27, 0xcd, 0x9c, 0x65, 0x0e,
+ 0x33, 0x08, 0x11, 0xc6, 0x7a, 0x16, 0x13, 0xe6, 0xbf, 0xdd, 0xce, 0xf3,
+ 0x07, 0x72, 0x14, 0x51, 0x8a, 0x6d, 0x83, 0xec, 0x67, 0xfb, 0xf1, 0xdb,
+ 0xa2, 0x58, 0x61, 0x1b, 0xe9, 0xe9, 0xa1, 0x47, 0x3b, 0xa0, 0xf8, 0x42,
+ 0x49, 0xd8, 0x49, 0x30, 0x98, 0x2b, 0x9e, 0x8f, 0xe6, 0x70, 0x40, 0xbb,
+ 0x02, 0x93, 0x68, 0x77, 0x0c, 0xf7, 0xb3, 0xf7, 0xf9, 0xc7, 0xad, 0xab,
+ 0xda, 0x61, 0xd7, 0x33, 0xad, 0x17, 0xdd, 0x90, 0xeb, 0x04, 0x52, 0x2b,
+ 0x12, 0x37, 0xa2, 0xf6, 0x22, 0xcc, 0x6a, 0x1d, 0x3e, 0xe4, 0xe9, 0xc9,
+ 0xb4, 0x04, 0x40, 0xe3, 0x91, 0x26, 0x75, 0xc5, 0x3a, 0x0b, 0x2e, 0x6d,
+ 0x64, 0x7f, 0x29, 0x39, 0xfc, 0x35, 0x6d, 0xa1, 0x33, 0x15, 0x41, 0xf4,
+ 0x51, 0x8b, 0xbd, 0x2e, 0x76, 0xe7, 0xb9, 0x92, 0x01, 0xdb, 0x80, 0x82,
+ 0x05, 0xa5, 0xe9, 0xb1, 0x8f, 0x29, 0x3c, 0xd7, 0xb9, 0xcb, 0xe8, 0x3c,
+ 0xfa, 0xa1, 0x57, 0xe5, 0x05, 0xc3, 0xaa, 0x35, 0x89, 0xbe, 0x15, 0x6d,
+ 0x88, 0x58, 0x03, 0x70, 0xcf, 0xfd, 0xf2, 0xb6, 0x68, 0x13, 0xb3, 0x01,
+ 0x4f, 0xbe, 0xb7, 0x12, 0xfb, 0x92
+ };
+
+ class InMemoryVideoSource : public ::libaom_test::CompressedVideoSource {
+ public:
+ InMemoryVideoSource(const std::array<unsigned char, kPoCDataLen> data)
+ : data_(data), frame_number_(0) {}
+
+ ~InMemoryVideoSource() override = default;
+
+ void Init() override {}
+ void Begin() override { frame_number_ = 0; }
+ void Next() override { frame_number_++; }
+
+ const uint8_t *cxdata() const override {
+ return frame_number_ == 0 ? data_.data() : nullptr;
+ }
+
+ size_t frame_size() const override {
+ return frame_number_ == 0 ? data_.size() : 0;
+ }
+
+ unsigned int frame_number() const override { return frame_number_; }
+
+ private:
+ const std::array<unsigned char, kPoCDataLen> data_;
+ unsigned int frame_number_;
+ };
+
+ InMemoryVideoSource decode_video(kPoCData);
+ decode_video.Init();
+ ASSERT_NO_FATAL_FAILURE(RunLoop(&decode_video, cfg));
+}
+
} // namespace