horz_superres_test.cc (14013B)
1 /* 2 * Copyright (c) 2018, 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 <tuple> 15 16 #include "gtest/gtest.h" 17 18 #include "av1/encoder/encoder.h" 19 20 #include "test/codec_factory.h" 21 #include "test/encode_test_driver.h" 22 #include "test/util.h" 23 #include "test/y4m_video_source.h" 24 #include "test/yuv_video_source.h" 25 26 namespace { 27 28 using std::make_tuple; 29 using std::tuple; 30 31 /* TESTING PARAMETERS */ 32 33 const int kBitrate = 40; 34 35 struct TestVideoParam { 36 const char *filename; 37 aom_img_fmt fmt; 38 aom_bit_depth_t bit_depth; 39 unsigned int profile; 40 unsigned int limit; 41 unsigned int screen_content; 42 double psnr_threshold; // used by modes other than AOM_SUPERRES_AUTO 43 double psnr_threshold2; // used by AOM_SUPERRES_AUTO 44 }; 45 46 std::ostream &operator<<(std::ostream &os, const TestVideoParam &test_arg) { 47 return os << "TestVideoParam { filename:" << test_arg.filename 48 << " fmt:" << test_arg.fmt << " bit_depth:" << test_arg.bit_depth 49 << " profile:" << test_arg.profile << " limit:" << test_arg.limit 50 << " screen_content:" << test_arg.screen_content 51 << " psnr_threshold:" << test_arg.psnr_threshold << " }"; 52 } 53 54 const TestVideoParam kTestVideoVectors[] = { 55 { "park_joy_90p_8_420.y4m", AOM_IMG_FMT_I420, AOM_BITS_8, 0, 5, 0, 25.3, 56 44.7 }, 57 #if CONFIG_AV1_HIGHBITDEPTH 58 { "park_joy_90p_10_444.y4m", AOM_IMG_FMT_I44416, AOM_BITS_10, 1, 5, 0, 27.0, 59 46.8 }, 60 #endif 61 { "screendata.y4m", AOM_IMG_FMT_I420, AOM_BITS_8, 0, 4, 1, 23.0, 52.5 }, 62 // Image coding (single frame). 63 { "niklas_1280_720_30.y4m", AOM_IMG_FMT_I420, AOM_BITS_8, 0, 1, 0, 32.0, 64 49.0 }, 65 }; 66 67 // Modes with extra params have their own tests. 68 const aom_superres_mode kSuperresModesWithoutParams[] = { AOM_SUPERRES_RANDOM, 69 AOM_SUPERRES_AUTO }; 70 71 // Superres denominators and superres kf denominators to be tested 72 using SuperresDenominatorPair = tuple<int, int>; 73 const SuperresDenominatorPair kSuperresDenominators[] = { 74 make_tuple(16, 9), make_tuple(13, 11), make_tuple(9, 9), 75 make_tuple(13, 13), make_tuple(11, 16), make_tuple(8, 16), 76 make_tuple(16, 8), make_tuple(8, 8), make_tuple(9, 14), 77 }; 78 79 // Superres q thresholds and superres kf q thresholds to be tested 80 using SuperresQThresholdPair = tuple<int, int>; 81 const SuperresQThresholdPair kSuperresQThresholds[] = { 82 make_tuple(63, 63), make_tuple(63, 41), make_tuple(17, 63), 83 make_tuple(41, 11), make_tuple(1, 37), make_tuple(11, 11), 84 make_tuple(1, 1), make_tuple(17, 29), make_tuple(29, 11), 85 }; 86 87 /* END (TESTING PARAMETERS) */ 88 89 // Test parameter list: 90 // <[needed for EncoderTest], test_video_param_, superres_mode_> 91 using HorzSuperresTestParam = 92 tuple<const libaom_test::CodecFactory *, TestVideoParam, aom_superres_mode>; 93 94 class HorzSuperresEndToEndTest 95 : public ::testing::TestWithParam<HorzSuperresTestParam>, 96 public ::libaom_test::EncoderTest { 97 protected: 98 HorzSuperresEndToEndTest() 99 : EncoderTest(GET_PARAM(0)), test_video_param_(GET_PARAM(1)), 100 superres_mode_(GET_PARAM(2)), psnr_(0.0), frame_count_(0) {} 101 102 ~HorzSuperresEndToEndTest() override = default; 103 104 void SetUp() override { 105 InitializeConfig(::libaom_test::kTwoPassGood); 106 cfg_.g_lag_in_frames = 5; 107 cfg_.rc_end_usage = AOM_Q; 108 cfg_.rc_target_bitrate = kBitrate; 109 cfg_.g_error_resilient = 0; 110 cfg_.g_profile = test_video_param_.profile; 111 cfg_.g_input_bit_depth = (unsigned int)test_video_param_.bit_depth; 112 cfg_.g_bit_depth = test_video_param_.bit_depth; 113 init_flags_ = AOM_CODEC_USE_PSNR; 114 if (cfg_.g_bit_depth > 8) init_flags_ |= AOM_CODEC_USE_HIGHBITDEPTH; 115 116 // Set superres parameters 117 cfg_.rc_superres_mode = superres_mode_; 118 } 119 120 void BeginPassHook(unsigned int) override { 121 psnr_ = 0.0; 122 frame_count_ = 0; 123 } 124 125 void PSNRPktHook(const aom_codec_cx_pkt_t *pkt) override { 126 psnr_ += pkt->data.psnr.psnr[0]; 127 frame_count_++; 128 } 129 130 void PreEncodeFrameHook(::libaom_test::VideoSource *video, 131 ::libaom_test::Encoder *encoder) override { 132 if (video->frame() == 0) { 133 encoder->Control(AV1E_SET_FRAME_PARALLEL_DECODING, 1); 134 encoder->Control(AV1E_SET_TILE_COLUMNS, 4); 135 136 // Set cpu-used = 8 for speed 137 encoder->Control(AOME_SET_CPUUSED, 8); 138 139 // Test screen coding tools 140 if (test_video_param_.screen_content) 141 encoder->Control(AV1E_SET_TUNE_CONTENT, AOM_CONTENT_SCREEN); 142 else 143 encoder->Control(AV1E_SET_TUNE_CONTENT, AOM_CONTENT_DEFAULT); 144 145 encoder->Control(AOME_SET_ENABLEAUTOALTREF, 1); 146 encoder->Control(AOME_SET_ARNR_MAXFRAMES, 7); 147 encoder->Control(AOME_SET_ARNR_STRENGTH, 5); 148 } 149 } 150 151 double GetAveragePsnr() const { 152 if (frame_count_) return psnr_ / frame_count_; 153 return 0.0; 154 } 155 156 void DoTest() { 157 std::unique_ptr<libaom_test::VideoSource> video; 158 video.reset(new libaom_test::Y4mVideoSource(test_video_param_.filename, 0, 159 test_video_param_.limit)); 160 ASSERT_NE(video, nullptr); 161 162 ASSERT_NO_FATAL_FAILURE(RunLoop(video.get())); 163 const double psnr_thresh = (superres_mode_ == AOM_SUPERRES_AUTO) 164 ? test_video_param_.psnr_threshold2 165 : test_video_param_.psnr_threshold; 166 const double psnr = GetAveragePsnr(); 167 EXPECT_GT(psnr, psnr_thresh); 168 169 EXPECT_EQ(test_video_param_.limit, frame_count_); 170 } 171 172 TestVideoParam test_video_param_; 173 aom_superres_mode superres_mode_; 174 175 private: 176 double psnr_; 177 unsigned int frame_count_; 178 }; 179 180 TEST_P(HorzSuperresEndToEndTest, HorzSuperresEndToEndPSNRTest) { DoTest(); } 181 182 AV1_INSTANTIATE_TEST_SUITE(HorzSuperresEndToEndTest, 183 ::testing::ValuesIn(kTestVideoVectors), 184 ::testing::ValuesIn(kSuperresModesWithoutParams)); 185 186 // Test parameter list: 187 // <[needed for EncoderTest], test_video_param_, tuple(superres_denom_, 188 // superres_kf_denom_)> 189 using HorzSuperresFixedTestParam = 190 tuple<const libaom_test::CodecFactory *, TestVideoParam, 191 SuperresDenominatorPair>; 192 193 class HorzSuperresFixedEndToEndTest 194 : public ::testing::TestWithParam<HorzSuperresFixedTestParam>, 195 public ::libaom_test::EncoderTest { 196 protected: 197 HorzSuperresFixedEndToEndTest() 198 : EncoderTest(GET_PARAM(0)), test_video_param_(GET_PARAM(1)), 199 superres_mode_(AOM_SUPERRES_FIXED), psnr_(0.0), frame_count_(0) { 200 SuperresDenominatorPair denoms = GET_PARAM(2); 201 superres_denom_ = std::get<0>(denoms); 202 superres_kf_denom_ = std::get<1>(denoms); 203 } 204 205 ~HorzSuperresFixedEndToEndTest() override = default; 206 207 void SetUp() override { 208 InitializeConfig(::libaom_test::kTwoPassGood); 209 cfg_.g_lag_in_frames = 5; 210 cfg_.rc_end_usage = AOM_VBR; 211 cfg_.rc_target_bitrate = kBitrate; 212 cfg_.g_error_resilient = 0; 213 cfg_.g_profile = test_video_param_.profile; 214 cfg_.g_input_bit_depth = (unsigned int)test_video_param_.bit_depth; 215 cfg_.g_bit_depth = test_video_param_.bit_depth; 216 init_flags_ = AOM_CODEC_USE_PSNR; 217 if (cfg_.g_bit_depth > 8) init_flags_ |= AOM_CODEC_USE_HIGHBITDEPTH; 218 219 // Set superres parameters 220 cfg_.rc_superres_mode = superres_mode_; 221 cfg_.rc_superres_denominator = superres_denom_; 222 cfg_.rc_superres_kf_denominator = superres_kf_denom_; 223 } 224 225 void BeginPassHook(unsigned int) override { 226 psnr_ = 0.0; 227 frame_count_ = 0; 228 } 229 230 void PSNRPktHook(const aom_codec_cx_pkt_t *pkt) override { 231 psnr_ += pkt->data.psnr.psnr[0]; 232 frame_count_++; 233 } 234 235 void PreEncodeFrameHook(::libaom_test::VideoSource *video, 236 ::libaom_test::Encoder *encoder) override { 237 if (video->frame() == 0) { 238 encoder->Control(AV1E_SET_FRAME_PARALLEL_DECODING, 1); 239 encoder->Control(AV1E_SET_TILE_COLUMNS, 4); 240 241 // Set cpu-used = 8 for speed 242 encoder->Control(AOME_SET_CPUUSED, 8); 243 244 // Test screen coding tools 245 if (test_video_param_.screen_content) 246 encoder->Control(AV1E_SET_TUNE_CONTENT, AOM_CONTENT_SCREEN); 247 else 248 encoder->Control(AV1E_SET_TUNE_CONTENT, AOM_CONTENT_DEFAULT); 249 250 encoder->Control(AOME_SET_ENABLEAUTOALTREF, 1); 251 encoder->Control(AOME_SET_ARNR_MAXFRAMES, 7); 252 encoder->Control(AOME_SET_ARNR_STRENGTH, 5); 253 } 254 } 255 256 double GetAveragePsnr() const { 257 if (frame_count_) return psnr_ / frame_count_; 258 return 0.0; 259 } 260 261 void DoTest() { 262 std::unique_ptr<libaom_test::VideoSource> video; 263 video.reset(new libaom_test::Y4mVideoSource(test_video_param_.filename, 0, 264 test_video_param_.limit)); 265 ASSERT_NE(video, nullptr); 266 267 ASSERT_NO_FATAL_FAILURE(RunLoop(video.get())); 268 const double psnr = GetAveragePsnr(); 269 EXPECT_GT(psnr, test_video_param_.psnr_threshold) 270 << "superres_mode_ = " << superres_mode_ 271 << ", superres_denom_ = " << superres_denom_ 272 << ", superres_kf_denom_ = " << superres_kf_denom_; 273 274 EXPECT_EQ(test_video_param_.limit, frame_count_) 275 << "superres_mode_ = " << superres_mode_ 276 << ", superres_denom_ = " << superres_denom_ 277 << ", superres_kf_denom_ = " << superres_kf_denom_; 278 } 279 280 TestVideoParam test_video_param_; 281 aom_superres_mode superres_mode_; 282 int superres_denom_; 283 int superres_kf_denom_; 284 285 private: 286 double psnr_; 287 unsigned int frame_count_; 288 }; 289 290 TEST_P(HorzSuperresFixedEndToEndTest, HorzSuperresFixedTestParam) { DoTest(); } 291 292 AV1_INSTANTIATE_TEST_SUITE(HorzSuperresFixedEndToEndTest, 293 ::testing::ValuesIn(kTestVideoVectors), 294 ::testing::ValuesIn(kSuperresDenominators)); 295 296 // Test parameter list: 297 // <[needed for EncoderTest], test_video_param_, 298 // tuple(superres_qthresh_,superres_kf_qthresh_)> 299 using HorzSuperresQThreshTestParam = 300 tuple<const libaom_test::CodecFactory *, TestVideoParam, 301 SuperresQThresholdPair>; 302 303 class HorzSuperresQThreshEndToEndTest 304 : public ::testing::TestWithParam<HorzSuperresQThreshTestParam>, 305 public ::libaom_test::EncoderTest { 306 protected: 307 HorzSuperresQThreshEndToEndTest() 308 : EncoderTest(GET_PARAM(0)), test_video_param_(GET_PARAM(1)), 309 superres_mode_(AOM_SUPERRES_QTHRESH), psnr_(0.0), frame_count_(0) { 310 SuperresQThresholdPair qthresholds = GET_PARAM(2); 311 superres_qthresh_ = std::get<0>(qthresholds); 312 superres_kf_qthresh_ = std::get<1>(qthresholds); 313 } 314 315 ~HorzSuperresQThreshEndToEndTest() override = default; 316 317 void SetUp() override { 318 InitializeConfig(::libaom_test::kTwoPassGood); 319 cfg_.g_lag_in_frames = 5; 320 cfg_.rc_end_usage = AOM_VBR; 321 cfg_.rc_target_bitrate = kBitrate; 322 cfg_.g_error_resilient = 0; 323 cfg_.g_profile = test_video_param_.profile; 324 cfg_.g_input_bit_depth = (unsigned int)test_video_param_.bit_depth; 325 cfg_.g_bit_depth = test_video_param_.bit_depth; 326 init_flags_ = AOM_CODEC_USE_PSNR; 327 if (cfg_.g_bit_depth > 8) init_flags_ |= AOM_CODEC_USE_HIGHBITDEPTH; 328 329 // Set superres parameters 330 cfg_.rc_superres_mode = superres_mode_; 331 cfg_.rc_superres_qthresh = superres_qthresh_; 332 cfg_.rc_superres_kf_qthresh = superres_kf_qthresh_; 333 } 334 335 void BeginPassHook(unsigned int) override { 336 psnr_ = 0.0; 337 frame_count_ = 0; 338 } 339 340 void PSNRPktHook(const aom_codec_cx_pkt_t *pkt) override { 341 psnr_ += pkt->data.psnr.psnr[0]; 342 frame_count_++; 343 } 344 345 void PreEncodeFrameHook(::libaom_test::VideoSource *video, 346 ::libaom_test::Encoder *encoder) override { 347 if (video->frame() == 0) { 348 encoder->Control(AV1E_SET_FRAME_PARALLEL_DECODING, 1); 349 encoder->Control(AV1E_SET_TILE_COLUMNS, 0); 350 351 // Set cpu-used = 8 for speed 352 encoder->Control(AOME_SET_CPUUSED, 8); 353 354 // Test screen coding tools 355 if (test_video_param_.screen_content) 356 encoder->Control(AV1E_SET_TUNE_CONTENT, AOM_CONTENT_SCREEN); 357 else 358 encoder->Control(AV1E_SET_TUNE_CONTENT, AOM_CONTENT_DEFAULT); 359 360 encoder->Control(AOME_SET_ENABLEAUTOALTREF, 1); 361 encoder->Control(AOME_SET_ARNR_MAXFRAMES, 7); 362 encoder->Control(AOME_SET_ARNR_STRENGTH, 5); 363 } 364 } 365 366 double GetAveragePsnr() const { 367 if (frame_count_) return psnr_ / frame_count_; 368 return 0.0; 369 } 370 371 void DoTest() { 372 std::unique_ptr<libaom_test::VideoSource> video; 373 video.reset(new libaom_test::Y4mVideoSource(test_video_param_.filename, 0, 374 test_video_param_.limit)); 375 ASSERT_NE(video, nullptr); 376 377 ASSERT_NO_FATAL_FAILURE(RunLoop(video.get())); 378 const double psnr = GetAveragePsnr(); 379 EXPECT_GT(psnr, test_video_param_.psnr_threshold) 380 << "superres_mode_ = " << superres_mode_ 381 << ", superres_qthresh_ = " << superres_qthresh_ 382 << ", superres_kf_qthresh_ = " << superres_kf_qthresh_; 383 384 EXPECT_EQ(test_video_param_.limit, frame_count_) 385 << "superres_mode_ = " << superres_mode_ 386 << ", superres_qthresh_ = " << superres_qthresh_ 387 << ", superres_kf_qthresh_ = " << superres_kf_qthresh_; 388 } 389 390 TestVideoParam test_video_param_; 391 aom_superres_mode superres_mode_; 392 int superres_qthresh_; 393 int superres_kf_qthresh_; 394 395 private: 396 double psnr_; 397 unsigned int frame_count_; 398 }; 399 400 TEST_P(HorzSuperresQThreshEndToEndTest, HorzSuperresQThreshEndToEndPSNRTest) { 401 DoTest(); 402 } 403 404 AV1_INSTANTIATE_TEST_SUITE(HorzSuperresQThreshEndToEndTest, 405 ::testing::ValuesIn(kTestVideoVectors), 406 ::testing::ValuesIn(kSuperresQThresholds)); 407 408 } // namespace