Commit 8260aa6000 for aom
commit 8260aa6000f6fba5feca7261b77be90525358310
Author: Marco Paniconi <marpan@google.com>
Date: Thu May 28 21:42:07 2026 +0000
rtc: Unittest for flat source chessboard artifact issue
Bug: 382465458
Change-Id: Ia4f4b8ec882aa7d32a97eb10ac642ce2f2fdf54d
diff --git a/test/svc_datarate_test.cc b/test/svc_datarate_test.cc
index 2f68ba7a21..15852e461c 100644
--- a/test/svc_datarate_test.cc
+++ b/test/svc_datarate_test.cc
@@ -112,6 +112,40 @@ class ResizingVideoSource : public ::libaom_test::DummyVideoSource {
int top_height_;
};
+class GrayscaleFlatVideoSource : public ::libaom_test::DummyVideoSource {
+ public:
+ GrayscaleFlatVideoSource() {
+ SetSize(1280, 720);
+ SetImageFormat(AOM_IMG_FMT_I420);
+ limit_ = 1;
+ }
+
+ ~GrayscaleFlatVideoSource() override = default;
+
+ void SetValue(uint8_t val) { val_ = val; }
+
+ protected:
+ void FillFrame() override {
+ if (img_) {
+ const unsigned int y_stride = img_->stride[0];
+ const unsigned int y_height = img_->h;
+ for (unsigned int r = 0; r < y_height; ++r) {
+ memset(img_->planes[0] + r * y_stride, val_, img_->d_w);
+ }
+ const unsigned int uv_stride = img_->stride[1];
+ const unsigned int uv_height = (img_->h + 1) >> 1;
+ const unsigned int uv_width = (img_->d_w + 1) >> 1;
+ for (unsigned int r = 0; r < uv_height; ++r) {
+ memset(img_->planes[1] + r * uv_stride, 128, uv_width);
+ memset(img_->planes[2] + r * uv_stride, 128, uv_width);
+ }
+ }
+ }
+
+ private:
+ uint8_t val_ = 0;
+};
+
class DatarateTestSVC
: public ::libaom_test::CodecTestWith4Params<libaom_test::TestMode, int,
unsigned int, int>,
@@ -199,6 +233,10 @@ class DatarateTestSVC
aom_codec_pts_t pts) override {
frame_info_list_.push_back(FrameInfo(pts, img.d_w, img.d_h));
++decoded_nframes_;
+
+ if (check_reconstruction_) {
+ CheckReconstruction(img);
+ }
}
std::vector<FrameInfo> frame_info_list_;
@@ -207,6 +245,7 @@ class DatarateTestSVC
void ResetModel() override {
DatarateTest::ResetModel();
+ abort_ = false;
layer_frame_cnt_ = 0;
superframe_cnt_ = 0;
number_temporal_layers_ = 1;
@@ -248,6 +287,9 @@ class DatarateTestSVC
dynamic_tl_ = false;
dynamic_scale_factors_ = false;
disable_last_ref_ = false;
+ check_reconstruction_ = false;
+ expected_val_ = 0;
+ max_allowed_error_ = 0;
}
void PreEncodeFrameHook(::libaom_test::VideoSource *video,
@@ -2404,6 +2446,39 @@ class DatarateTestSVC
bool dynamic_tl_;
bool dynamic_scale_factors_;
bool disable_last_ref_;
+
+ void CheckReconstruction(const aom_image_t &img) {
+ const unsigned int w = img.d_w;
+ const unsigned int h = img.d_h;
+ const unsigned int stride = img.stride[0];
+ const uint8_t *y_plane = img.planes[0];
+ const unsigned int border = 256;
+ const unsigned int sb_size = 128;
+ const int bl = 16;
+ const uint8_t base_val =
+ y_plane[(border + sb_size / 2) * stride + (border + sb_size / 2)];
+
+ const int diff =
+ abs(static_cast<int>(base_val) - static_cast<int>(expected_val_));
+ EXPECT_LE(diff, max_allowed_error_);
+
+ for (unsigned int r = border; r < h - border; r += bl) {
+ for (unsigned int c = border; c < w - border; c += bl) {
+ if (y_plane[r * stride + c] != base_val) {
+ EXPECT_EQ(y_plane[r * stride + c], base_val)
+ << "Chessboard pattern detected at (" << r << ", " << c << ") "
+ << "value " << (int)y_plane[r * stride + c] << " vs base "
+ << (int)base_val;
+ abort_ = true;
+ return;
+ }
+ }
+ }
+ }
+
+ bool check_reconstruction_;
+ uint8_t expected_val_;
+ int max_allowed_error_;
};
// Check basic rate targeting for CBR, for 3 temporal layers, 1 spatial.
@@ -2773,6 +2848,37 @@ TEST_P(DatarateTestSVC, BasicRateTargetingSVC1TL3SLIssue433046392) {
BasicRateTargetingSVC1TL3SLIssue433046392();
}
+TEST_P(DatarateTestSVC, ReconstructionGrayScaleInput) {
+ if (set_cpu_used_ != 9 || aq_mode_ != 0 || GET_PARAM(4) != 0) return;
+
+ SetUpCbr();
+
+ for (int qp = 48; qp <= 63; ++qp) {
+ for (int x = 0; x <= 255; x += 10) {
+ ResetModel();
+
+ expected_val_ = static_cast<uint8_t>(x);
+ max_allowed_error_ = (qp > 60) ? 3 : (qp > 50) ? 1 : 0;
+ check_reconstruction_ = true;
+ screen_mode_ = true;
+
+ GrayscaleFlatVideoSource video;
+ video.SetValue(expected_val_);
+
+ cfg_.g_w = 1280;
+ cfg_.g_h = 720;
+ cfg_.g_profile = 0;
+ cfg_.g_lag_in_frames = 0;
+ cfg_.rc_end_usage = AOM_CBR;
+ cfg_.rc_min_quantizer = qp;
+ cfg_.rc_max_quantizer = qp;
+
+ SetTargetBitratesFor1SL1TL();
+ ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
+ }
+ }
+}
+
TEST(SvcParams, BitrateOverflow) {
uint8_t buf[6] = { 0 };
aom_image_t img;