Add PSNR comparison test for subgop configurations
This patch adds SubGopPSNRCheck unit test to compare the
psnr difference between subgop and no-subgop configuration.
BUG=aomedia:2888
Change-Id: Ide5b6c63871bf769399e70bb74a73be5b14b902c
diff --git a/test/subgop_test.cc b/test/subgop_test.cc
index c40e3c6..a16694d 100644
--- a/test/subgop_test.cc
+++ b/test/subgop_test.cc
@@ -435,4 +435,142 @@
// ::testing::Values(AOM_Q, AOM_VBR, AOM_CQ,
// AOM_CBR));
+typedef struct {
+ const char *subgop_str;
+ const char *input_file;
+ int frame_w;
+ int frame_h;
+ int cpu_used;
+} SubgopPsnrTestParams;
+
+static const SubgopPsnrTestParams SubGopPsnrTestVectors[] = {
+ { subgop_config_str_preset_map[DEFAULT].preset_tag,
+ "hantro_collage_w352h288.yuv", 352, 288, 3 },
+ { subgop_config_str_preset_map[DEFAULT].preset_tag, "desktop1.320_180.yuv",
+ 320, 180, 5 },
+
+ { subgop_config_str_preset_map[ENHANCE].preset_tag,
+ "hantro_collage_w352h288.yuv", 352, 288, 3 },
+ { subgop_config_str_preset_map[ENHANCE].preset_tag,
+ "pixel_capture_w320h240.yuv", 320, 240, 5 },
+ // TODO(any): Enable after fix
+ /* { subgop_config_str_preset_map[ENHANCE].preset_tag, "paris_352_288_30.y4m",
+ 352, 288, 3 },
+ { subgop_config_str_preset_map[ENHANCE].preset_tag, "screendata.y4m", 640,
+ 480, 5 },
+ { subgop_config_str_preset_map[ENHANCE].preset_tag, "paris_352_288_30.y4m",
+ 352, 288, 5 }, */
+
+ { subgop_config_str_preset_map[ASYMMETRIC].preset_tag,
+ "pixel_capture_w320h240.yuv", 320, 240, 5 },
+ // TODO(any): Enable after fix
+ /* { subgop_config_str_preset_map[ASYMMETRIC].preset_tag,
+ "desktop1.320_180.yuv", 320, 180, 3 }, */
+
+ { subgop_config_str_preset_map[TEMPORAL_SCALABLE].preset_tag,
+ "hantro_collage_w352h288.yuv", 352, 288, 5 },
+
+ // TODO(any) : Enable ld config
+ /* { subgop_config_str_preset_map[LOW_DELAY].preset_tag,
+ "paris_352_288_30.y4m", 352, 288, 5 },
+ { subgop_config_str_preset_map[LOW_DELAY].preset_tag,
+ "desktop1.320_180.yuv", 320, 180, 3 }, */
+};
+
+std::ostream &operator<<(std::ostream &os,
+ const SubgopPsnrTestParams &test_arg) {
+ return os << "SubgopPsnrTestParams { sub_gop_config:" << test_arg.subgop_str
+ << " source_file:" << test_arg.input_file
+ << " frame_width:" << test_arg.frame_w
+ << " frame_height:" << test_arg.frame_h
+ << " cpu_used:" << test_arg.cpu_used << " }";
+}
+
+class SubGopPSNRCheckTest
+ : public ::libaom_test::CodecTestWith2Params<SubgopPsnrTestParams,
+ aom_rc_mode>,
+ public ::libaom_test::EncoderTest {
+ protected:
+ SubGopPSNRCheckTest()
+ : EncoderTest(GET_PARAM(0)), test_params_(GET_PARAM(1)),
+ rc_end_usage_(GET_PARAM(2)) {
+ Reset();
+ }
+ virtual ~SubGopPSNRCheckTest() {}
+
+ void Reset() {
+ frame_num_ = 0;
+ total_psnr_ = 0.0;
+ enable_subgop_ = 0;
+ }
+
+ virtual void SetUp() {
+ InitializeConfig();
+ SetMode(::libaom_test::kOnePassGood);
+ cfg_.g_threads = 1;
+ cfg_.g_lag_in_frames = 35;
+ cfg_.rc_end_usage = rc_end_usage_;
+ init_flags_ = AOM_CODEC_USE_PSNR;
+ }
+
+ virtual void PSNRPktHook(const aom_codec_cx_pkt_t *pkt) {
+ // Accumulate total psnr
+ total_psnr_ += pkt->data.psnr.psnr[0];
+ frame_num_++;
+ }
+
+ double GetAveragePsnr() const {
+ if (frame_num_) return total_psnr_ / frame_num_;
+ return 0.0;
+ }
+
+ virtual void PreEncodeFrameHook(::libaom_test::VideoSource *video,
+ ::libaom_test::Encoder *encoder) {
+ if (video->frame() == 0) {
+ encoder->Control(AOME_SET_CPUUSED, test_params_.cpu_used);
+ if (enable_subgop_)
+ encoder->Control(AV1E_SET_SUBGOP_CONFIG_STR, test_params_.subgop_str);
+ }
+ }
+ unsigned int enable_subgop_;
+ SubgopPsnrTestParams test_params_;
+
+ private:
+ aom_rc_mode rc_end_usage_;
+ double total_psnr_;
+ unsigned int frame_num_;
+};
+
+TEST_P(SubGopPSNRCheckTest, SubGopPSNRCheck) {
+ std::unique_ptr<libaom_test::VideoSource> video;
+ const unsigned int kFrames = 100;
+ const double psnr_diff_thresh = 0.2;
+ if (is_extension_y4m(test_params_.input_file)) {
+ video.reset(
+ new libaom_test::Y4mVideoSource(test_params_.input_file, 0, kFrames));
+ } else {
+ video.reset(new libaom_test::YUVVideoSource(
+ test_params_.input_file, AOM_IMG_FMT_I420, test_params_.frame_w,
+ test_params_.frame_h, 30, 1, 0, kFrames));
+ }
+
+ // Encode with no sub-gop configuration
+ ASSERT_NO_FATAL_FAILURE(RunLoop(video.get()));
+ const double psnr_no_subgop_ = GetAveragePsnr();
+ Reset();
+
+ // Encode with default sub-gop configuration
+ enable_subgop_ = 1;
+ ASSERT_NO_FATAL_FAILURE(RunLoop(video.get()));
+ const double psnr_subgop_ = GetAveragePsnr();
+
+ const double psnr_diff = psnr_subgop_ - psnr_no_subgop_;
+ EXPECT_LE(abs(psnr_diff), psnr_diff_thresh);
+}
+
+// TODO(any) : Enable AOM_CBR after fix
+AV1_INSTANTIATE_TEST_SUITE(SubGopPSNRCheckTest,
+ ::testing::ValuesIn(SubGopPsnrTestVectors),
+ ::testing::Values(AOM_Q, AOM_VBR,
+ AOM_CQ /*, AOM_CBR*/));
} // namespace