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 2f68ba7..15852e4 100644 --- a/test/svc_datarate_test.cc +++ b/test/svc_datarate_test.cc
@@ -112,6 +112,40 @@ 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 @@ 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 @@ void ResetModel() override { DatarateTest::ResetModel(); + abort_ = false; layer_frame_cnt_ = 0; superframe_cnt_ = 0; number_temporal_layers_ = 1; @@ -248,6 +287,9 @@ 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 @@ 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 @@ 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;