1/* 2 * Copyright (c) 2014 The WebM project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11#include "third_party/googletest/src/include/gtest/gtest.h" 12 13#include "test/codec_factory.h" 14#include "test/encode_test_driver.h" 15#include "test/util.h" 16#include "test/y4m_video_source.h" 17#include "test/yuv_video_source.h" 18 19namespace { 20 21const unsigned int kWidth = 160; 22const unsigned int kHeight = 90; 23const unsigned int kFramerate = 50; 24const unsigned int kFrames = 10; 25const int kBitrate = 500; 26// List of psnr thresholds for speed settings 0-7 and 5 encoding modes 27const double kPsnrThreshold[][5] = { 28 { 36.0, 37.0, 37.0, 37.0, 37.0 }, { 35.0, 36.0, 36.0, 36.0, 36.0 }, 29 { 34.0, 35.0, 35.0, 35.0, 35.0 }, { 33.0, 34.0, 34.0, 34.0, 34.0 }, 30 { 32.0, 33.0, 33.0, 33.0, 33.0 }, { 31.0, 32.0, 32.0, 32.0, 32.0 }, 31 { 30.0, 31.0, 31.0, 31.0, 31.0 }, { 29.0, 30.0, 30.0, 30.0, 30.0 }, 32}; 33 34typedef struct { 35 const char *filename; 36 unsigned int input_bit_depth; 37 vpx_img_fmt fmt; 38 vpx_bit_depth_t bit_depth; 39 unsigned int profile; 40} TestVideoParam; 41 42const TestVideoParam kTestVectors[] = { 43 { "park_joy_90p_8_420.y4m", 8, VPX_IMG_FMT_I420, VPX_BITS_8, 0 }, 44 { "park_joy_90p_8_422.y4m", 8, VPX_IMG_FMT_I422, VPX_BITS_8, 1 }, 45 { "park_joy_90p_8_444.y4m", 8, VPX_IMG_FMT_I444, VPX_BITS_8, 1 }, 46 { "park_joy_90p_8_440.yuv", 8, VPX_IMG_FMT_I440, VPX_BITS_8, 1 }, 47#if CONFIG_VP9_HIGHBITDEPTH 48 { "park_joy_90p_10_420.y4m", 10, VPX_IMG_FMT_I42016, VPX_BITS_10, 2 }, 49 { "park_joy_90p_10_422.y4m", 10, VPX_IMG_FMT_I42216, VPX_BITS_10, 3 }, 50 { "park_joy_90p_10_444.y4m", 10, VPX_IMG_FMT_I44416, VPX_BITS_10, 3 }, 51 { "park_joy_90p_10_440.yuv", 10, VPX_IMG_FMT_I44016, VPX_BITS_10, 3 }, 52 { "park_joy_90p_12_420.y4m", 12, VPX_IMG_FMT_I42016, VPX_BITS_12, 2 }, 53 { "park_joy_90p_12_422.y4m", 12, VPX_IMG_FMT_I42216, VPX_BITS_12, 3 }, 54 { "park_joy_90p_12_444.y4m", 12, VPX_IMG_FMT_I44416, VPX_BITS_12, 3 }, 55 { "park_joy_90p_12_440.yuv", 12, VPX_IMG_FMT_I44016, VPX_BITS_12, 3 }, 56#endif // CONFIG_VP9_HIGHBITDEPTH 57}; 58 59// Encoding modes tested 60const libvpx_test::TestMode kEncodingModeVectors[] = { 61 ::libvpx_test::kTwoPassGood, ::libvpx_test::kOnePassGood, 62 ::libvpx_test::kRealTime, 63}; 64 65// Speed settings tested 66const int kCpuUsedVectors[] = { 1, 2, 3, 5, 6 }; 67 68int is_extension_y4m(const char *filename) { 69 const char *dot = strrchr(filename, '.'); 70 if (!dot || dot == filename) { 71 return 0; 72 } else { 73 return !strcmp(dot, ".y4m"); 74 } 75} 76 77class EndToEndTestLarge 78 : public ::libvpx_test::EncoderTest, 79 public ::libvpx_test::CodecTestWith3Params<libvpx_test::TestMode, 80 TestVideoParam, int> { 81 protected: 82 EndToEndTestLarge() 83 : EncoderTest(GET_PARAM(0)), test_video_param_(GET_PARAM(2)), 84 cpu_used_(GET_PARAM(3)), psnr_(0.0), nframes_(0), 85 encoding_mode_(GET_PARAM(1)) {} 86 87 virtual ~EndToEndTestLarge() {} 88 89 virtual void SetUp() { 90 InitializeConfig(); 91 SetMode(encoding_mode_); 92 if (encoding_mode_ != ::libvpx_test::kRealTime) { 93 cfg_.g_lag_in_frames = 5; 94 cfg_.rc_end_usage = VPX_VBR; 95 } else { 96 cfg_.g_lag_in_frames = 0; 97 cfg_.rc_end_usage = VPX_CBR; 98 cfg_.rc_buf_sz = 1000; 99 cfg_.rc_buf_initial_sz = 500; 100 cfg_.rc_buf_optimal_sz = 600; 101 } 102 dec_cfg_.threads = 4; 103 } 104 105 virtual void BeginPassHook(unsigned int) { 106 psnr_ = 0.0; 107 nframes_ = 0; 108 } 109 110 virtual void PSNRPktHook(const vpx_codec_cx_pkt_t *pkt) { 111 psnr_ += pkt->data.psnr.psnr[0]; 112 nframes_++; 113 } 114 115 virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video, 116 ::libvpx_test::Encoder *encoder) { 117 if (video->frame() == 1) { 118 encoder->Control(VP9E_SET_FRAME_PARALLEL_DECODING, 1); 119 encoder->Control(VP9E_SET_TILE_COLUMNS, 4); 120 encoder->Control(VP8E_SET_CPUUSED, cpu_used_); 121 if (encoding_mode_ != ::libvpx_test::kRealTime) { 122 encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 1); 123 encoder->Control(VP8E_SET_ARNR_MAXFRAMES, 7); 124 encoder->Control(VP8E_SET_ARNR_STRENGTH, 5); 125 encoder->Control(VP8E_SET_ARNR_TYPE, 3); 126 } 127 } 128 } 129 130 double GetAveragePsnr() const { 131 if (nframes_) return psnr_ / nframes_; 132 return 0.0; 133 } 134 135 double GetPsnrThreshold() { 136 return kPsnrThreshold[cpu_used_][encoding_mode_]; 137 } 138 139 TestVideoParam test_video_param_; 140 int cpu_used_; 141 142 private: 143 double psnr_; 144 unsigned int nframes_; 145 libvpx_test::TestMode encoding_mode_; 146}; 147 148TEST_P(EndToEndTestLarge, EndtoEndPSNRTest) { 149 cfg_.rc_target_bitrate = kBitrate; 150 cfg_.g_error_resilient = 0; 151 cfg_.g_profile = test_video_param_.profile; 152 cfg_.g_input_bit_depth = test_video_param_.input_bit_depth; 153 cfg_.g_bit_depth = test_video_param_.bit_depth; 154 init_flags_ = VPX_CODEC_USE_PSNR; 155 if (cfg_.g_bit_depth > 8) init_flags_ |= VPX_CODEC_USE_HIGHBITDEPTH; 156 157 testing::internal::scoped_ptr<libvpx_test::VideoSource> video; 158 if (is_extension_y4m(test_video_param_.filename)) { 159 video.reset(new libvpx_test::Y4mVideoSource(test_video_param_.filename, 0, 160 kFrames)); 161 } else { 162 video.reset(new libvpx_test::YUVVideoSource( 163 test_video_param_.filename, test_video_param_.fmt, kWidth, kHeight, 164 kFramerate, 1, 0, kFrames)); 165 } 166 ASSERT_TRUE(video.get() != NULL); 167 168 ASSERT_NO_FATAL_FAILURE(RunLoop(video.get())); 169 const double psnr = GetAveragePsnr(); 170 EXPECT_GT(psnr, GetPsnrThreshold()); 171} 172 173VP9_INSTANTIATE_TEST_CASE(EndToEndTestLarge, 174 ::testing::ValuesIn(kEncodingModeVectors), 175 ::testing::ValuesIn(kTestVectors), 176 ::testing::ValuesIn(kCpuUsedVectors)); 177} // namespace 178