blob: 7e9f0d6c440f1d76ce1566e9708c7f04d1183fe7 [file] [log] [blame]
Joshua Litt83b843f2014-07-21 10:57:16 -07001/*
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 */
Frank Galligand80d9442014-12-19 11:21:52 -080010#include <string>
Joshua Litt83b843f2014-07-21 10:57:16 -070011#include "third_party/googletest/src/include/gtest/gtest.h"
12#include "./vpx_config.h"
13#include "./vpx_version.h"
14#include "test/codec_factory.h"
15#include "test/encode_test_driver.h"
16#include "test/i420_video_source.h"
17#include "test/util.h"
18#include "test/y4m_video_source.h"
19#include "vpx_ports/vpx_timer.h"
20
21namespace {
22
23const int kMaxPsnr = 100;
24const double kUsecsInSec = 1000000.0;
25
26struct EncodePerfTestVideo {
27 EncodePerfTestVideo(const char *name_, uint32_t width_, uint32_t height_,
28 uint32_t bitrate_, int frames_)
29 : name(name_),
30 width(width_),
31 height(height_),
32 bitrate(bitrate_),
33 frames(frames_) {}
34 const char *name;
35 uint32_t width;
36 uint32_t height;
37 uint32_t bitrate;
38 int frames;
39};
40
41const EncodePerfTestVideo kVP9EncodePerfTestVectors[] = {
42 EncodePerfTestVideo("desktop_640_360_30.yuv", 640, 360, 200, 2484),
43 EncodePerfTestVideo("kirland_640_480_30.yuv", 640, 480, 200, 300),
44 EncodePerfTestVideo("macmarcomoving_640_480_30.yuv", 640, 480, 200, 987),
45 EncodePerfTestVideo("macmarcostationary_640_480_30.yuv", 640, 480, 200, 718),
46 EncodePerfTestVideo("niklas_640_480_30.yuv", 640, 480, 200, 471),
47 EncodePerfTestVideo("tacomanarrows_640_480_30.yuv", 640, 480, 200, 300),
48 EncodePerfTestVideo("tacomasmallcameramovement_640_480_30.yuv",
49 640, 480, 200, 300),
50 EncodePerfTestVideo("thaloundeskmtg_640_480_30.yuv", 640, 480, 200, 300),
51 EncodePerfTestVideo("niklas_1280_720_30.yuv", 1280, 720, 600, 470),
52};
53
Frank Galligan0f3d3882014-12-18 15:19:21 -080054const int kEncodePerfTestSpeeds[] = { 5, 6, 7, 8 };
Frank Galligand80d9442014-12-19 11:21:52 -080055const int kEncodePerfTestThreads[] = { 1, 2, 4 };
Joshua Litt83b843f2014-07-21 10:57:16 -070056
57#define NELEMENTS(x) (sizeof((x)) / sizeof((x)[0]))
58
59class VP9EncodePerfTest
60 : public ::libvpx_test::EncoderTest,
61 public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
62 protected:
63 VP9EncodePerfTest()
64 : EncoderTest(GET_PARAM(0)),
65 min_psnr_(kMaxPsnr),
66 nframes_(0),
67 encoding_mode_(GET_PARAM(1)),
Frank Galligand80d9442014-12-19 11:21:52 -080068 speed_(0),
69 threads_(1) {}
Joshua Litt83b843f2014-07-21 10:57:16 -070070
71 virtual ~VP9EncodePerfTest() {}
72
73 virtual void SetUp() {
74 InitializeConfig();
75 SetMode(encoding_mode_);
76
77 cfg_.g_lag_in_frames = 0;
78 cfg_.rc_min_quantizer = 2;
79 cfg_.rc_max_quantizer = 56;
80 cfg_.rc_dropframe_thresh = 0;
81 cfg_.rc_undershoot_pct = 50;
82 cfg_.rc_overshoot_pct = 50;
83 cfg_.rc_buf_sz = 1000;
84 cfg_.rc_buf_initial_sz = 500;
85 cfg_.rc_buf_optimal_sz = 600;
86 cfg_.rc_resize_allowed = 0;
87 cfg_.rc_end_usage = VPX_CBR;
Frank Galligand80d9442014-12-19 11:21:52 -080088 cfg_.g_error_resilient = 1;
89 cfg_.g_threads = threads_;
Joshua Litt83b843f2014-07-21 10:57:16 -070090 }
91
92 virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
93 ::libvpx_test::Encoder *encoder) {
Frank Galligand80d9442014-12-19 11:21:52 -080094 if (video->frame() == 0) {
95 const int log2_tile_columns = 3;
Joshua Litt83b843f2014-07-21 10:57:16 -070096 encoder->Control(VP8E_SET_CPUUSED, speed_);
Frank Galligand80d9442014-12-19 11:21:52 -080097 encoder->Control(VP9E_SET_TILE_COLUMNS, log2_tile_columns);
98 encoder->Control(VP9E_SET_FRAME_PARALLEL_DECODING, 1);
99 encoder->Control(VP8E_SET_ENABLEAUTOALTREF, 0);
Joshua Litt83b843f2014-07-21 10:57:16 -0700100 }
101 }
102
103 virtual void BeginPassHook(unsigned int /*pass*/) {
104 min_psnr_ = kMaxPsnr;
105 nframes_ = 0;
106 }
107
108 virtual void PSNRPktHook(const vpx_codec_cx_pkt_t *pkt) {
109 if (pkt->data.psnr.psnr[0] < min_psnr_) {
110 min_psnr_= pkt->data.psnr.psnr[0];
111 }
112 }
113
114 // for performance reasons don't decode
115 virtual bool DoDecode() { return 0; }
116
117 double min_psnr() const {
118 return min_psnr_;
119 }
120
121 void set_speed(unsigned int speed) {
122 speed_ = speed;
123 }
124
Frank Galligand80d9442014-12-19 11:21:52 -0800125 void set_threads(unsigned int threads) {
126 threads_ = threads;
127 }
128
Joshua Litt83b843f2014-07-21 10:57:16 -0700129 private:
130 double min_psnr_;
131 unsigned int nframes_;
132 libvpx_test::TestMode encoding_mode_;
133 unsigned speed_;
Frank Galligand80d9442014-12-19 11:21:52 -0800134 unsigned int threads_;
Joshua Litt83b843f2014-07-21 10:57:16 -0700135};
136
137TEST_P(VP9EncodePerfTest, PerfTest) {
138 for (size_t i = 0; i < NELEMENTS(kVP9EncodePerfTestVectors); ++i) {
139 for (size_t j = 0; j < NELEMENTS(kEncodePerfTestSpeeds); ++j) {
Frank Galligand80d9442014-12-19 11:21:52 -0800140 for (size_t k = 0; k < NELEMENTS(kEncodePerfTestThreads); ++k) {
141 if (kVP9EncodePerfTestVectors[i].width < 512 &&
142 kEncodePerfTestThreads[k] > 1)
143 continue;
144 else if (kVP9EncodePerfTestVectors[i].width < 1024 &&
145 kEncodePerfTestThreads[k] > 2)
146 continue;
Joshua Litt83b843f2014-07-21 10:57:16 -0700147
Frank Galligand80d9442014-12-19 11:21:52 -0800148 set_threads(kEncodePerfTestThreads[k]);
149 SetUp();
Joshua Litt83b843f2014-07-21 10:57:16 -0700150
Frank Galligand80d9442014-12-19 11:21:52 -0800151 const vpx_rational timebase = { 33333333, 1000000000 };
152 cfg_.g_timebase = timebase;
153 cfg_.rc_target_bitrate = kVP9EncodePerfTestVectors[i].bitrate;
Joshua Litt83b843f2014-07-21 10:57:16 -0700154
Frank Galligand80d9442014-12-19 11:21:52 -0800155 init_flags_ = VPX_CODEC_USE_PSNR;
Joshua Litt83b843f2014-07-21 10:57:16 -0700156
Frank Galligand80d9442014-12-19 11:21:52 -0800157 const unsigned frames = kVP9EncodePerfTestVectors[i].frames;
158 const char *video_name = kVP9EncodePerfTestVectors[i].name;
159 libvpx_test::I420VideoSource video(
160 video_name,
161 kVP9EncodePerfTestVectors[i].width,
162 kVP9EncodePerfTestVectors[i].height,
163 timebase.den, timebase.num, 0,
164 kVP9EncodePerfTestVectors[i].frames);
165 set_speed(kEncodePerfTestSpeeds[j]);
Joshua Litt83b843f2014-07-21 10:57:16 -0700166
Frank Galligand80d9442014-12-19 11:21:52 -0800167 vpx_usec_timer t;
168 vpx_usec_timer_start(&t);
Joshua Litt83b843f2014-07-21 10:57:16 -0700169
Frank Galligand80d9442014-12-19 11:21:52 -0800170 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
Joshua Litt83b843f2014-07-21 10:57:16 -0700171
Frank Galligand80d9442014-12-19 11:21:52 -0800172 vpx_usec_timer_mark(&t);
173 const double elapsed_secs = vpx_usec_timer_elapsed(&t) / kUsecsInSec;
174 const double fps = frames / elapsed_secs;
175 const double minimum_psnr = min_psnr();
176 std::string display_name(video_name);
177 if (kEncodePerfTestThreads[k] > 1) {
178 char thread_count[32];
179 snprintf(thread_count, sizeof(thread_count), "_t-%d",
180 kEncodePerfTestThreads[k]);
181 display_name += thread_count;
182 }
183
184 printf("{\n");
185 printf("\t\"type\" : \"encode_perf_test\",\n");
186 printf("\t\"version\" : \"%s\",\n", VERSION_STRING_NOSP);
187 printf("\t\"videoName\" : \"%s\",\n", display_name.c_str());
188 printf("\t\"encodeTimeSecs\" : %f,\n", elapsed_secs);
189 printf("\t\"totalFrames\" : %u,\n", frames);
190 printf("\t\"framesPerSecond\" : %f,\n", fps);
191 printf("\t\"minPsnr\" : %f,\n", minimum_psnr);
Frank Galligan238c4fa2015-01-06 11:06:33 -0800192 printf("\t\"speed\" : %d,\n", kEncodePerfTestSpeeds[j]);
Frank Galligand80d9442014-12-19 11:21:52 -0800193 printf("\t\"threads\" : %d\n", kEncodePerfTestThreads[k]);
194 printf("}\n");
195 }
Joshua Litt83b843f2014-07-21 10:57:16 -0700196 }
197 }
198}
199
200VP9_INSTANTIATE_TEST_CASE(
201 VP9EncodePerfTest, ::testing::Values(::libvpx_test::kRealTime));
202} // namespace