end_to_end_psnr_test.cc (9944B)
1 /* 2 * Copyright (c) 2016, Alliance for Open Media. All rights reserved. 3 * 4 * This source code is subject to the terms of the BSD 2 Clause License and 5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License 6 * was not distributed with this source code in the LICENSE file, you can 7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open 8 * Media Patent License 1.0 was not distributed with this source code in the 9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent. 10 */ 11 12 #include <memory> 13 #include <ostream> 14 #include <unordered_map> 15 16 #include "gtest/gtest.h" 17 18 #include "test/codec_factory.h" 19 #include "test/encode_test_driver.h" 20 #include "test/util.h" 21 #include "test/y4m_video_source.h" 22 #include "test/yuv_video_source.h" 23 24 namespace { 25 26 const unsigned int kWidth = 160; 27 const unsigned int kHeight = 90; 28 const unsigned int kFramerate = 50; 29 const unsigned int kFrames = 10; 30 const int kBitrate = 500; 31 const unsigned int kCqLevel = 18; 32 // List of psnr thresholds for speed settings 0-8 and 4 encoding modes 33 const double kPsnrThreshold[][4] = { 34 { 34.9, 44.4, 39.5, 41.9 }, { 34.9, 44.4, 39.5, 41.9 }, 35 { 34.9, 44.4, 39.4, 41.9 }, { 34.9, 44.4, 39.1, 41.8 }, 36 { 34.9, 44.4, 39.1, 41.8 }, { 34.9, 44.29, 38.5, 41.8 }, 37 { 34.9, 44.3, 38.5, 41.3 }, { 34.9, 44.3, 38.5, 40.8 }, 38 { 34.9, 44.3, 38.5, 40.8 } 39 }; 40 41 struct TestVideoParam { 42 const char *filename; 43 unsigned int input_bit_depth; 44 aom_img_fmt fmt; 45 aom_bit_depth_t bit_depth; 46 unsigned int profile; 47 }; 48 49 std::ostream &operator<<(std::ostream &os, const TestVideoParam &test_arg) { 50 return os << "TestVideoParam { filename:" << test_arg.filename 51 << " input_bit_depth:" << test_arg.input_bit_depth 52 << " fmt:" << test_arg.fmt << " bit_depth:" << test_arg.bit_depth 53 << " profile:" << test_arg.profile << " }"; 54 } 55 56 const TestVideoParam kTestVectors[] = { 57 { "park_joy_90p_8_420.y4m", 8, AOM_IMG_FMT_I420, AOM_BITS_8, 0 }, 58 { "park_joy_90p_8_422.y4m", 8, AOM_IMG_FMT_I422, AOM_BITS_8, 2 }, 59 { "park_joy_90p_8_444.y4m", 8, AOM_IMG_FMT_I444, AOM_BITS_8, 1 }, 60 #if CONFIG_AV1_HIGHBITDEPTH 61 { "park_joy_90p_10_420.y4m", 10, AOM_IMG_FMT_I42016, AOM_BITS_10, 0 }, 62 { "park_joy_90p_10_422.y4m", 10, AOM_IMG_FMT_I42216, AOM_BITS_10, 2 }, 63 { "park_joy_90p_10_444.y4m", 10, AOM_IMG_FMT_I44416, AOM_BITS_10, 1 }, 64 { "park_joy_90p_12_420.y4m", 12, AOM_IMG_FMT_I42016, AOM_BITS_12, 2 }, 65 { "park_joy_90p_12_422.y4m", 12, AOM_IMG_FMT_I42216, AOM_BITS_12, 2 }, 66 { "park_joy_90p_12_444.y4m", 12, AOM_IMG_FMT_I44416, AOM_BITS_12, 2 }, 67 #endif 68 }; 69 70 // List of psnr thresholds for speed settings 1-3 and low complexity decode mode 71 // keys: content -> speed -> PSNR threshold 72 std::unordered_map<std::string, std::unordered_map<int, double>> 73 kPsnrThresholdLcMode = { { "SDR_Animal_oqo7.y4m", 74 { 75 { 1, 27.9 }, 76 { 2, 27.8 }, 77 { 3, 27.3 }, 78 } }, 79 { "SDR_Health_rtd0_720p.y4m", 80 { 81 { 1, 41.8 }, 82 { 2, 41.4 }, 83 { 3, 41.1 }, 84 } } }; 85 86 // Encoding modes tested 87 const libaom_test::TestMode kEncodingModeVectors[] = { 88 ::libaom_test::kTwoPassGood, 89 ::libaom_test::kOnePassGood, 90 ::libaom_test::kRealTime, 91 }; 92 93 const TestVideoParam kTestVectorsLcMode[] = { 94 { "SDR_Animal_oqo7.y4m", 8, AOM_IMG_FMT_I420, AOM_BITS_8, 0 }, 95 { "SDR_Health_rtd0_720p.y4m", 8, AOM_IMG_FMT_I420, AOM_BITS_8, 0 }, 96 }; 97 98 // Speed settings tested 99 const int kCpuUsedVectors[] = { 1, 2, 3, 5, 6 }; 100 101 class EndToEndTest 102 : public ::libaom_test::CodecTestWith3Params<libaom_test::TestMode, 103 TestVideoParam, int>, 104 public ::libaom_test::EncoderTest { 105 protected: 106 EndToEndTest() 107 : EncoderTest(GET_PARAM(0)), test_video_param_(GET_PARAM(2)), 108 cpu_used_(GET_PARAM(3)), psnr_(0.0), nframes_(0), 109 encoding_mode_(GET_PARAM(1)) {} 110 111 ~EndToEndTest() override = default; 112 113 void SetUp() override { 114 InitializeConfig(encoding_mode_); 115 if (encoding_mode_ == ::libaom_test::kOnePassGood || 116 encoding_mode_ == ::libaom_test::kTwoPassGood || 117 encoding_mode_ == ::libaom_test::kLowComplexityDecode) { 118 cfg_.g_lag_in_frames = 5; 119 } else if (encoding_mode_ == ::libaom_test::kRealTime) { 120 cfg_.rc_buf_sz = 1000; 121 cfg_.rc_buf_initial_sz = 500; 122 cfg_.rc_buf_optimal_sz = 600; 123 } 124 } 125 126 void BeginPassHook(unsigned int) override { 127 psnr_ = 0.0; 128 nframes_ = 0; 129 } 130 131 void PSNRPktHook(const aom_codec_cx_pkt_t *pkt) override { 132 psnr_ += pkt->data.psnr.psnr[0]; 133 nframes_++; 134 } 135 136 void PreEncodeFrameHook(::libaom_test::VideoSource *video, 137 ::libaom_test::Encoder *encoder) override { 138 if (video->frame() == 0) { 139 if (encoding_mode_ == ::libaom_test::kLowComplexityDecode) { 140 ASSERT_LE(cpu_used_, 3); 141 encoder->Control(AV1E_SET_TILE_COLUMNS, 1); 142 encoder->Control(AV1E_SET_TILE_ROWS, 1); 143 encoder->Control(AV1E_SET_ENABLE_CDEF, 0); 144 encoder->Control(AV1E_SET_ENABLE_LOW_COMPLEXITY_DECODE, 1); 145 } else { 146 encoder->Control(AV1E_SET_FRAME_PARALLEL_DECODING, 1); 147 encoder->Control(AV1E_SET_TILE_COLUMNS, 4); 148 } 149 encoder->Control(AOME_SET_CPUUSED, cpu_used_); 150 // Test screen coding tools at cpu_used = 1 && encoding mode is two-pass. 151 if (cpu_used_ == 1 && encoding_mode_ == ::libaom_test::kTwoPassGood) 152 encoder->Control(AV1E_SET_TUNE_CONTENT, AOM_CONTENT_SCREEN); 153 else 154 encoder->Control(AV1E_SET_TUNE_CONTENT, AOM_CONTENT_DEFAULT); 155 if (encoding_mode_ == ::libaom_test::kOnePassGood || 156 encoding_mode_ == ::libaom_test::kTwoPassGood || 157 encoding_mode_ == ::libaom_test::kLowComplexityDecode) { 158 encoder->Control(AOME_SET_ENABLEAUTOALTREF, 1); 159 encoder->Control(AOME_SET_ARNR_MAXFRAMES, 7); 160 encoder->Control(AOME_SET_ARNR_STRENGTH, 5); 161 } else if (encoding_mode_ == ::libaom_test::kAllIntra) { 162 encoder->Control(AOME_SET_CQ_LEVEL, kCqLevel); 163 } 164 } 165 } 166 167 double GetAveragePsnr() const { 168 if (nframes_) return psnr_ / nframes_; 169 return 0.0; 170 } 171 172 double GetPsnrThreshold() { 173 if (encoding_mode_ == ::libaom_test::kLowComplexityDecode) 174 return kPsnrThresholdLcMode[test_video_param_.filename][cpu_used_]; 175 else 176 return kPsnrThreshold[cpu_used_][encoding_mode_]; 177 } 178 179 void DoTest() { 180 cfg_.rc_target_bitrate = kBitrate; 181 cfg_.g_error_resilient = 0; 182 cfg_.g_profile = test_video_param_.profile; 183 cfg_.g_input_bit_depth = test_video_param_.input_bit_depth; 184 cfg_.g_bit_depth = test_video_param_.bit_depth; 185 init_flags_ = AOM_CODEC_USE_PSNR; 186 if (cfg_.g_bit_depth > 8) init_flags_ |= AOM_CODEC_USE_HIGHBITDEPTH; 187 188 std::unique_ptr<libaom_test::VideoSource> video; 189 if (is_extension_y4m(test_video_param_.filename)) { 190 video.reset(new libaom_test::Y4mVideoSource(test_video_param_.filename, 0, 191 kFrames)); 192 } else { 193 video.reset(new libaom_test::YUVVideoSource( 194 test_video_param_.filename, test_video_param_.fmt, kWidth, kHeight, 195 kFramerate, 1, 0, kFrames)); 196 } 197 ASSERT_NE(video, nullptr); 198 199 ASSERT_NO_FATAL_FAILURE(RunLoop(video.get())); 200 const double psnr = GetAveragePsnr(); 201 EXPECT_GT(psnr, GetPsnrThreshold() * 0.98) 202 << "cpu used = " << cpu_used_ << ", encoding mode = " << encoding_mode_; 203 } 204 205 TestVideoParam test_video_param_; 206 int cpu_used_; 207 208 private: 209 double psnr_; 210 unsigned int nframes_; 211 libaom_test::TestMode encoding_mode_; 212 }; 213 214 class EndToEndTestLarge : public EndToEndTest {}; 215 216 class EndToEndAllIntraTestLarge : public EndToEndTest {}; 217 218 class EndToEndAllIntraTest : public EndToEndTest {}; 219 220 class EndToEndLcModeTestLarge : public EndToEndTest {}; 221 222 class EndToEndLcModeTest : public EndToEndTest {}; 223 224 TEST_P(EndToEndTestLarge, EndtoEndPSNRTest) { DoTest(); } 225 226 TEST_P(EndToEndTest, EndtoEndPSNRTest) { DoTest(); } 227 228 TEST_P(EndToEndAllIntraTestLarge, EndtoEndPSNRTest) { DoTest(); } 229 230 TEST_P(EndToEndAllIntraTest, EndtoEndPSNRTest) { DoTest(); } 231 232 TEST_P(EndToEndLcModeTestLarge, EndtoEndPSNRTest) { DoTest(); } 233 234 TEST_P(EndToEndLcModeTest, EndtoEndPSNRTest) { DoTest(); } 235 236 AV1_INSTANTIATE_TEST_SUITE(EndToEndTestLarge, 237 ::testing::ValuesIn(kEncodingModeVectors), 238 ::testing::ValuesIn(kTestVectors), 239 ::testing::ValuesIn(kCpuUsedVectors)); 240 241 AV1_INSTANTIATE_TEST_SUITE(EndToEndTest, 242 ::testing::Values(::libaom_test::kTwoPassGood), 243 ::testing::Values(kTestVectors[2]), // 444 244 ::testing::Values(3)); // cpu_used 245 246 AV1_INSTANTIATE_TEST_SUITE(EndToEndAllIntraTestLarge, 247 ::testing::Values(::libaom_test::kAllIntra), 248 ::testing::ValuesIn(kTestVectors), 249 ::testing::Values(2, 4, 6, 8)); // cpu_used 250 251 AV1_INSTANTIATE_TEST_SUITE(EndToEndAllIntraTest, 252 ::testing::Values(::libaom_test::kAllIntra), 253 ::testing::Values(kTestVectors[0]), // 420 254 ::testing::Values(6)); // cpu_used 255 256 AV1_INSTANTIATE_TEST_SUITE( 257 EndToEndLcModeTestLarge, 258 ::testing::Values(::libaom_test::kLowComplexityDecode), 259 ::testing::ValuesIn(kTestVectorsLcMode), 260 ::testing::Values(1, 3)); // cpu_used 261 262 AV1_INSTANTIATE_TEST_SUITE( 263 EndToEndLcModeTest, ::testing::Values(::libaom_test::kLowComplexityDecode), 264 ::testing::ValuesIn(kTestVectorsLcMode), 265 ::testing::Values(2)); // cpu_used 266 } // namespace