tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

decode_perf_test.cc (8031B)


      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 <string>
     13 #include <tuple>
     14 
     15 #include "aom/aom_codec.h"
     16 #include "aom_ports/aom_timer.h"
     17 #include "common/ivfenc.h"
     18 #include "test/codec_factory.h"
     19 #include "test/decode_test_driver.h"
     20 #include "test/encode_test_driver.h"
     21 #include "test/i420_video_source.h"
     22 #include "test/ivf_video_source.h"
     23 #include "test/md5_helper.h"
     24 #include "test/util.h"
     25 #include "test/webm_video_source.h"
     26 
     27 using std::make_tuple;
     28 
     29 namespace {
     30 
     31 #define VIDEO_NAME 0
     32 #define THREADS 1
     33 
     34 const double kUsecsInSec = 1000000.0;
     35 const char kNewEncodeOutputFile[] = "new_encode.ivf";
     36 
     37 /*
     38 DecodePerfTest takes a tuple of filename + number of threads to decode with
     39 */
     40 using DecodePerfParam = std::tuple<const char *, unsigned int>;
     41 
     42 // TODO(jimbankoski): Add actual test vectors here when available.
     43 // const DecodePerfParam kAV1DecodePerfVectors[] = {};
     44 
     45 /*
     46 In order to reflect real world performance as much as possible, Perf tests
     47 *DO NOT* do any correctness checks. Please run them alongside correctness
     48 tests to ensure proper codec integrity. Furthermore, in this test we
     49 deliberately limit the amount of system calls we make to avoid OS
     50 preemption.
     51 
     52 TODO(joshualitt) create a more detailed perf measurement test to collect
     53   power/temp/min max frame decode times/etc
     54 */
     55 
     56 class DecodePerfTest : public ::testing::TestWithParam<DecodePerfParam> {};
     57 
     58 TEST_P(DecodePerfTest, PerfTest) {
     59  const char *const video_name = GET_PARAM(VIDEO_NAME);
     60  const unsigned threads = GET_PARAM(THREADS);
     61 
     62  libaom_test::WebMVideoSource video(video_name);
     63  video.Init();
     64 
     65  aom_codec_dec_cfg_t cfg = aom_codec_dec_cfg_t();
     66  cfg.threads = threads;
     67  cfg.allow_lowbitdepth = 1;
     68  libaom_test::AV1Decoder decoder(cfg, 0);
     69 
     70  aom_usec_timer t;
     71  aom_usec_timer_start(&t);
     72 
     73  for (video.Begin(); video.cxdata() != nullptr; video.Next()) {
     74    decoder.DecodeFrame(video.cxdata(), video.frame_size());
     75  }
     76 
     77  aom_usec_timer_mark(&t);
     78  const double elapsed_secs = double(aom_usec_timer_elapsed(&t)) / kUsecsInSec;
     79  const unsigned frames = video.frame_number();
     80  const double fps = double(frames) / elapsed_secs;
     81 
     82  printf("{\n");
     83  printf("\t\"type\" : \"decode_perf_test\",\n");
     84  printf("\t\"version\" : \"%s\",\n", aom_codec_version_str());
     85  printf("\t\"videoName\" : \"%s\",\n", video_name);
     86  printf("\t\"threadCount\" : %u,\n", threads);
     87  printf("\t\"decodeTimeSecs\" : %f,\n", elapsed_secs);
     88  printf("\t\"totalFrames\" : %u,\n", frames);
     89  printf("\t\"framesPerSecond\" : %f\n", fps);
     90  printf("}\n");
     91 }
     92 
     93 // TODO(jimbankoski): Enabled when we have actual AV1 Decode vectors.
     94 // INSTANTIATE_TEST_SUITE_P(AV1, DecodePerfTest,
     95 //                        ::testing::ValuesIn(kAV1DecodePerfVectors));
     96 
     97 class AV1NewEncodeDecodePerfTest
     98    : public ::libaom_test::CodecTestWithParam<libaom_test::TestMode>,
     99      public ::libaom_test::EncoderTest {
    100 protected:
    101  AV1NewEncodeDecodePerfTest()
    102      : EncoderTest(GET_PARAM(0)), encoding_mode_(GET_PARAM(1)), speed_(0),
    103        outfile_(nullptr), out_frames_(0) {}
    104 
    105  ~AV1NewEncodeDecodePerfTest() override = default;
    106 
    107  void SetUp() override {
    108    InitializeConfig(encoding_mode_);
    109 
    110    cfg_.g_lag_in_frames = 25;
    111    cfg_.rc_min_quantizer = 2;
    112    cfg_.rc_max_quantizer = 56;
    113    cfg_.rc_dropframe_thresh = 0;
    114    cfg_.rc_undershoot_pct = 50;
    115    cfg_.rc_overshoot_pct = 50;
    116    cfg_.rc_buf_sz = 1000;
    117    cfg_.rc_buf_initial_sz = 500;
    118    cfg_.rc_buf_optimal_sz = 600;
    119    cfg_.rc_end_usage = AOM_VBR;
    120  }
    121 
    122  void PreEncodeFrameHook(::libaom_test::VideoSource *video,
    123                          ::libaom_test::Encoder *encoder) override {
    124    if (video->frame() == 0) {
    125      encoder->Control(AOME_SET_CPUUSED, speed_);
    126      encoder->Control(AV1E_SET_FRAME_PARALLEL_DECODING, 1);
    127      encoder->Control(AV1E_SET_TILE_COLUMNS, 2);
    128    }
    129  }
    130 
    131  void BeginPassHook(unsigned int /*pass*/) override {
    132    const char *const env = getenv("LIBAOM_TEST_DATA_PATH");
    133    const std::string data_path(env ? env : ".");
    134    const std::string path_to_source = data_path + "/" + kNewEncodeOutputFile;
    135    outfile_ = fopen(path_to_source.c_str(), "wb");
    136    ASSERT_NE(outfile_, nullptr);
    137  }
    138 
    139  void EndPassHook() override {
    140    if (outfile_ != nullptr) {
    141      if (!fseek(outfile_, 0, SEEK_SET))
    142        ivf_write_file_header(outfile_, &cfg_, AV1_FOURCC, out_frames_);
    143      fclose(outfile_);
    144      outfile_ = nullptr;
    145    }
    146  }
    147 
    148  void FramePktHook(const aom_codec_cx_pkt_t *pkt) override {
    149    ++out_frames_;
    150 
    151    // Write initial file header if first frame.
    152    if (pkt->data.frame.pts == 0)
    153      ivf_write_file_header(outfile_, &cfg_, AV1_FOURCC, out_frames_);
    154 
    155    // Write frame header and data.
    156    ivf_write_frame_header(outfile_, out_frames_, pkt->data.frame.sz);
    157    ASSERT_EQ(fwrite(pkt->data.frame.buf, 1, pkt->data.frame.sz, outfile_),
    158              pkt->data.frame.sz);
    159  }
    160 
    161  bool DoDecode() const override { return false; }
    162 
    163  void set_speed(unsigned int speed) { speed_ = speed; }
    164 
    165 private:
    166  libaom_test::TestMode encoding_mode_;
    167  uint32_t speed_;
    168  FILE *outfile_;
    169  uint32_t out_frames_;
    170 };
    171 
    172 struct EncodePerfTestVideo {
    173  EncodePerfTestVideo(const char *name_, uint32_t width_, uint32_t height_,
    174                      uint32_t bitrate_, int frames_)
    175      : name(name_), width(width_), height(height_), bitrate(bitrate_),
    176        frames(frames_) {}
    177  const char *name;
    178  uint32_t width;
    179  uint32_t height;
    180  uint32_t bitrate;
    181  int frames;
    182 };
    183 
    184 const EncodePerfTestVideo kAV1EncodePerfTestVectors[] = {
    185  EncodePerfTestVideo("niklas_1280_720_30.yuv", 1280, 720, 600, 470),
    186 };
    187 
    188 TEST_P(AV1NewEncodeDecodePerfTest, PerfTest) {
    189  SetUp();
    190 
    191  // TODO(JBB): Make this work by going through the set of given files.
    192  const int i = 0;
    193  const aom_rational timebase = { 33333333, 1000000000 };
    194  cfg_.g_timebase = timebase;
    195  cfg_.rc_target_bitrate = kAV1EncodePerfTestVectors[i].bitrate;
    196 
    197  init_flags_ = AOM_CODEC_USE_PSNR;
    198 
    199  const char *video_name = kAV1EncodePerfTestVectors[i].name;
    200  libaom_test::I420VideoSource video(
    201      video_name, kAV1EncodePerfTestVectors[i].width,
    202      kAV1EncodePerfTestVectors[i].height, timebase.den, timebase.num, 0,
    203      kAV1EncodePerfTestVectors[i].frames);
    204  set_speed(2);
    205 
    206  ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
    207 
    208  const uint32_t threads = 4;
    209 
    210  libaom_test::IVFVideoSource decode_video(kNewEncodeOutputFile);
    211  decode_video.Init();
    212 
    213  aom_codec_dec_cfg_t cfg = aom_codec_dec_cfg_t();
    214  cfg.threads = threads;
    215  cfg.allow_lowbitdepth = 1;
    216  libaom_test::AV1Decoder decoder(cfg, 0);
    217 
    218  aom_usec_timer t;
    219  aom_usec_timer_start(&t);
    220 
    221  for (decode_video.Begin(); decode_video.cxdata() != nullptr;
    222       decode_video.Next()) {
    223    decoder.DecodeFrame(decode_video.cxdata(), decode_video.frame_size());
    224  }
    225 
    226  aom_usec_timer_mark(&t);
    227  const double elapsed_secs =
    228      static_cast<double>(aom_usec_timer_elapsed(&t)) / kUsecsInSec;
    229  const unsigned decode_frames = decode_video.frame_number();
    230  const double fps = static_cast<double>(decode_frames) / elapsed_secs;
    231 
    232  printf("{\n");
    233  printf("\t\"type\" : \"decode_perf_test\",\n");
    234  printf("\t\"version\" : \"%s\",\n", aom_codec_version_str());
    235  printf("\t\"videoName\" : \"%s\",\n", kNewEncodeOutputFile);
    236  printf("\t\"threadCount\" : %u,\n", threads);
    237  printf("\t\"decodeTimeSecs\" : %f,\n", elapsed_secs);
    238  printf("\t\"totalFrames\" : %u,\n", decode_frames);
    239  printf("\t\"framesPerSecond\" : %f\n", fps);
    240  printf("}\n");
    241 }
    242 
    243 AV1_INSTANTIATE_TEST_SUITE(AV1NewEncodeDecodePerfTest,
    244                           ::testing::Values(::libaom_test::kTwoPassGood));
    245 }  // namespace