decode_perf_test.cc 8.69 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
/*
 *  Copyright (c) 2013 The WebM project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

11
#include <string>
12
13
#include "test/codec_factory.h"
#include "test/decode_test_driver.h"
14
15
#include "test/encode_test_driver.h"
#include "test/i420_video_source.h"
16
17
18
19
20
#include "test/ivf_video_source.h"
#include "test/md5_helper.h"
#include "test/util.h"
#include "test/webm_video_source.h"
#include "vpx_ports/vpx_timer.h"
21
#include "./ivfenc.h"
22
23
24
25
26
27
28
29
30
#include "./vpx_version.h"

using std::tr1::make_tuple;

namespace {

#define VIDEO_NAME 0
#define THREADS 1

31
const int kMaxPsnr = 100;
32
const double kUsecsInSec = 1000000.0;
33
const char kNewEncodeOutputFile[] = "new_encode.ivf";
34
35
36
37

/*
 DecodePerfTest takes a tuple of filename + number of threads to decode with
 */
38
typedef std::tr1::tuple<const char *, unsigned> DecodePerfParam;
39

40
const DecodePerfParam kVP9DecodePerfVectors[] = {
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
  make_tuple("vp90-2-bbb_426x240_tile_1x1_180kbps.webm", 1),
  make_tuple("vp90-2-bbb_640x360_tile_1x2_337kbps.webm", 2),
  make_tuple("vp90-2-bbb_854x480_tile_1x2_651kbps.webm", 2),
  make_tuple("vp90-2-bbb_1280x720_tile_1x4_1310kbps.webm", 4),
  make_tuple("vp90-2-bbb_1920x1080_tile_1x1_2581kbps.webm", 1),
  make_tuple("vp90-2-bbb_1920x1080_tile_1x4_2586kbps.webm", 4),
  make_tuple("vp90-2-bbb_1920x1080_tile_1x4_fpm_2304kbps.webm", 4),
  make_tuple("vp90-2-sintel_426x182_tile_1x1_171kbps.webm", 1),
  make_tuple("vp90-2-sintel_640x272_tile_1x2_318kbps.webm", 2),
  make_tuple("vp90-2-sintel_854x364_tile_1x2_621kbps.webm", 2),
  make_tuple("vp90-2-sintel_1280x546_tile_1x4_1257kbps.webm", 4),
  make_tuple("vp90-2-sintel_1920x818_tile_1x4_fpm_2279kbps.webm", 4),
  make_tuple("vp90-2-tos_426x178_tile_1x1_181kbps.webm", 1),
  make_tuple("vp90-2-tos_640x266_tile_1x2_336kbps.webm", 2),
  make_tuple("vp90-2-tos_854x356_tile_1x2_656kbps.webm", 2),
Joshua Litt's avatar
Joshua Litt committed
56
  make_tuple("vp90-2-tos_854x356_tile_1x2_fpm_546kbps.webm", 2),
57
  make_tuple("vp90-2-tos_1280x534_tile_1x4_1306kbps.webm", 4),
Joshua Litt's avatar
Joshua Litt committed
58
  make_tuple("vp90-2-tos_1280x534_tile_1x4_fpm_952kbps.webm", 4),
59
60
61
62
63
64
65
66
67
68
69
70
71
72
  make_tuple("vp90-2-tos_1920x800_tile_1x4_fpm_2335kbps.webm", 4),
};

/*
 In order to reflect real world performance as much as possible, Perf tests
 *DO NOT* do any correctness checks. Please run them alongside correctness
 tests to ensure proper codec integrity. Furthermore, in this test we
 deliberately limit the amount of system calls we make to avoid OS
 preemption.

 TODO(joshualitt) create a more detailed perf measurement test to collect
   power/temp/min max frame decode times/etc
 */

clang-format's avatar
clang-format committed
73
class DecodePerfTest : public ::testing::TestWithParam<DecodePerfParam> {};
74
75
76
77
78
79
80
81

TEST_P(DecodePerfTest, PerfTest) {
  const char *const video_name = GET_PARAM(VIDEO_NAME);
  const unsigned threads = GET_PARAM(THREADS);

  libvpx_test::WebMVideoSource video(video_name);
  video.Init();

82
  vpx_codec_dec_cfg_t cfg = vpx_codec_dec_cfg_t();
83
84
85
86
87
88
89
90
91
92
93
  cfg.threads = threads;
  libvpx_test::VP9Decoder decoder(cfg, 0);

  vpx_usec_timer t;
  vpx_usec_timer_start(&t);

  for (video.Begin(); video.cxdata() != NULL; video.Next()) {
    decoder.DecodeFrame(video.cxdata(), video.frame_size());
  }

  vpx_usec_timer_mark(&t);
clang-format's avatar
clang-format committed
94
  const double elapsed_secs = double(vpx_usec_timer_elapsed(&t)) / kUsecsInSec;
95
96
97
98
  const unsigned frames = video.frame_number();
  const double fps = double(frames) / elapsed_secs;

  printf("{\n");
Joshua Litt's avatar
Joshua Litt committed
99
  printf("\t\"type\" : \"decode_perf_test\",\n");
100
101
102
103
104
105
106
107
108
109
110
111
  printf("\t\"version\" : \"%s\",\n", VERSION_STRING_NOSP);
  printf("\t\"videoName\" : \"%s\",\n", video_name);
  printf("\t\"threadCount\" : %u,\n", threads);
  printf("\t\"decodeTimeSecs\" : %f,\n", elapsed_secs);
  printf("\t\"totalFrames\" : %u,\n", frames);
  printf("\t\"framesPerSecond\" : %f\n", fps);
  printf("}\n");
}

INSTANTIATE_TEST_CASE_P(VP9, DecodePerfTest,
                        ::testing::ValuesIn(kVP9DecodePerfVectors));

clang-format's avatar
clang-format committed
112
113
114
class VP9NewEncodeDecodePerfTest
    : public ::libvpx_test::EncoderTest,
      public ::libvpx_test::CodecTestWithParam<libvpx_test::TestMode> {
115
116
 protected:
  VP9NewEncodeDecodePerfTest()
clang-format's avatar
clang-format committed
117
118
      : EncoderTest(GET_PARAM(0)), encoding_mode_(GET_PARAM(1)), speed_(0),
        outfile_(0), out_frames_(0) {}
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148

  virtual ~VP9NewEncodeDecodePerfTest() {}

  virtual void SetUp() {
    InitializeConfig();
    SetMode(encoding_mode_);

    cfg_.g_lag_in_frames = 25;
    cfg_.rc_min_quantizer = 2;
    cfg_.rc_max_quantizer = 56;
    cfg_.rc_dropframe_thresh = 0;
    cfg_.rc_undershoot_pct = 50;
    cfg_.rc_overshoot_pct = 50;
    cfg_.rc_buf_sz = 1000;
    cfg_.rc_buf_initial_sz = 500;
    cfg_.rc_buf_optimal_sz = 600;
    cfg_.rc_resize_allowed = 0;
    cfg_.rc_end_usage = VPX_VBR;
  }

  virtual void PreEncodeFrameHook(::libvpx_test::VideoSource *video,
                                  ::libvpx_test::Encoder *encoder) {
    if (video->frame() == 1) {
      encoder->Control(VP8E_SET_CPUUSED, speed_);
      encoder->Control(VP9E_SET_FRAME_PARALLEL_DECODING, 1);
      encoder->Control(VP9E_SET_TILE_COLUMNS, 2);
    }
  }

  virtual void BeginPassHook(unsigned int /*pass*/) {
Adrian Grange's avatar
Adrian Grange committed
149
    const std::string data_path = getenv("LIBAOM_TEST_DATA_PATH");
150
151
    const std::string path_to_source = data_path + "/" + kNewEncodeOutputFile;
    outfile_ = fopen(path_to_source.c_str(), "wb");
152
    ASSERT_TRUE(outfile_ != NULL);
153
154
155
  }

  virtual void EndPassHook() {
156
    if (outfile_ != NULL) {
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
      if (!fseek(outfile_, 0, SEEK_SET))
        ivf_write_file_header(outfile_, &cfg_, VP9_FOURCC, out_frames_);
      fclose(outfile_);
      outfile_ = NULL;
    }
  }

  virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
    ++out_frames_;

    // Write initial file header if first frame.
    if (pkt->data.frame.pts == 0)
      ivf_write_file_header(outfile_, &cfg_, VP9_FOURCC, out_frames_);

    // Write frame header and data.
    ivf_write_frame_header(outfile_, out_frames_, pkt->data.frame.sz);
173
174
    ASSERT_EQ(fwrite(pkt->data.frame.buf, 1, pkt->data.frame.sz, outfile_),
              pkt->data.frame.sz);
175
176
  }

177
  virtual bool DoDecode() { return false; }
178

clang-format's avatar
clang-format committed
179
  void set_speed(unsigned int speed) { speed_ = speed; }
180
181
182
183
184
185
186
187
188
189
190

 private:
  libvpx_test::TestMode encoding_mode_;
  uint32_t speed_;
  FILE *outfile_;
  uint32_t out_frames_;
};

struct EncodePerfTestVideo {
  EncodePerfTestVideo(const char *name_, uint32_t width_, uint32_t height_,
                      uint32_t bitrate_, int frames_)
clang-format's avatar
clang-format committed
191
      : name(name_), width(width_), height(height_), bitrate(bitrate_),
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
        frames(frames_) {}
  const char *name;
  uint32_t width;
  uint32_t height;
  uint32_t bitrate;
  int frames;
};

const EncodePerfTestVideo kVP9EncodePerfTestVectors[] = {
  EncodePerfTestVideo("niklas_1280_720_30.yuv", 1280, 720, 600, 470),
};

TEST_P(VP9NewEncodeDecodePerfTest, PerfTest) {
  SetUp();

  // TODO(JBB): Make this work by going through the set of given files.
  const int i = 0;
  const vpx_rational timebase = { 33333333, 1000000000 };
  cfg_.g_timebase = timebase;
  cfg_.rc_target_bitrate = kVP9EncodePerfTestVectors[i].bitrate;

  init_flags_ = VPX_CODEC_USE_PSNR;

  const char *video_name = kVP9EncodePerfTestVectors[i].name;
  libvpx_test::I420VideoSource video(
clang-format's avatar
clang-format committed
217
218
      video_name, kVP9EncodePerfTestVectors[i].width,
      kVP9EncodePerfTestVectors[i].height, timebase.den, timebase.num, 0,
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
      kVP9EncodePerfTestVectors[i].frames);
  set_speed(2);

  ASSERT_NO_FATAL_FAILURE(RunLoop(&video));

  const uint32_t threads = 4;

  libvpx_test::IVFVideoSource decode_video(kNewEncodeOutputFile);
  decode_video.Init();

  vpx_codec_dec_cfg_t cfg = vpx_codec_dec_cfg_t();
  cfg.threads = threads;
  libvpx_test::VP9Decoder decoder(cfg, 0);

  vpx_usec_timer t;
  vpx_usec_timer_start(&t);

  for (decode_video.Begin(); decode_video.cxdata() != NULL;
       decode_video.Next()) {
    decoder.DecodeFrame(decode_video.cxdata(), decode_video.frame_size());
  }

  vpx_usec_timer_mark(&t);
  const double elapsed_secs =
243
      static_cast<double>(vpx_usec_timer_elapsed(&t)) / kUsecsInSec;
244
  const unsigned decode_frames = decode_video.frame_number();
245
  const double fps = static_cast<double>(decode_frames) / elapsed_secs;
246
247
248
249
250
251
252
253
254
255
256
257

  printf("{\n");
  printf("\t\"type\" : \"decode_perf_test\",\n");
  printf("\t\"version\" : \"%s\",\n", VERSION_STRING_NOSP);
  printf("\t\"videoName\" : \"%s\",\n", kNewEncodeOutputFile);
  printf("\t\"threadCount\" : %u,\n", threads);
  printf("\t\"decodeTimeSecs\" : %f,\n", elapsed_secs);
  printf("\t\"totalFrames\" : %u,\n", decode_frames);
  printf("\t\"framesPerSecond\" : %f\n", fps);
  printf("}\n");
}

clang-format's avatar
clang-format committed
258
259
VP10_INSTANTIATE_TEST_CASE(VP9NewEncodeDecodePerfTest,
                           ::testing::Values(::libvpx_test::kTwoPassGood));
260
}  // namespace