tor-browser

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

arf_freq_test.cc (7462B)


      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 <memory>
     13 
     14 #include "gtest/gtest.h"
     15 
     16 #include "test/codec_factory.h"
     17 #include "test/encode_test_driver.h"
     18 #include "test/util.h"
     19 #include "test/y4m_video_source.h"
     20 #include "test/yuv_video_source.h"
     21 #include "av1/encoder/ratectrl.h"
     22 
     23 namespace {
     24 
     25 const unsigned int kFrames = 100;
     26 const int kBitrate = 500;
     27 
     28 #define ARF_NOT_SEEN 1000001
     29 #define ARF_SEEN_ONCE 1000000
     30 
     31 struct TestVideoParam {
     32  const char *filename;
     33  unsigned int width;
     34  unsigned int height;
     35  unsigned int framerate_num;
     36  unsigned int framerate_den;
     37  unsigned int input_bit_depth;
     38  aom_img_fmt fmt;
     39  aom_bit_depth_t bit_depth;
     40  unsigned int profile;
     41 };
     42 
     43 struct TestEncodeParam {
     44  libaom_test::TestMode mode;
     45  int cpu_used;
     46 };
     47 
     48 const TestVideoParam kTestVectors[] = {
     49  // artificially increase framerate to trigger default check
     50  { "hantro_collage_w352h288.yuv", 352, 288, 5000, 1, 8, AOM_IMG_FMT_I420,
     51    AOM_BITS_8, 0 },
     52  { "hantro_collage_w352h288.yuv", 352, 288, 30, 1, 8, AOM_IMG_FMT_I420,
     53    AOM_BITS_8, 0 },
     54  { "rush_hour_444.y4m", 352, 288, 30, 1, 8, AOM_IMG_FMT_I444, AOM_BITS_8, 1 },
     55  // Add list of profile 2/3 test videos here ...
     56 };
     57 
     58 const TestEncodeParam kEncodeVectors[] = {
     59 #if CONFIG_REALTIME_ONLY
     60  { ::libaom_test::kRealTime, 5 },
     61 #else
     62  { ::libaom_test::kRealTime, 5 },    { ::libaom_test::kOnePassGood, 2 },
     63  { ::libaom_test::kOnePassGood, 5 }, { ::libaom_test::kTwoPassGood, 1 },
     64  { ::libaom_test::kTwoPassGood, 2 }, { ::libaom_test::kTwoPassGood, 5 },
     65 #endif
     66 };
     67 
     68 const int kMinArfVectors[] = {
     69  // NOTE: 0 refers to the default built-in logic in:
     70  //       av1_rc_get_default_min_gf_interval(...)
     71  0, 4, 8, 12, 15
     72 };
     73 
     74 class ArfFreqTestLarge
     75    : public ::libaom_test::CodecTestWith3Params<TestVideoParam,
     76                                                 TestEncodeParam, int>,
     77      public ::libaom_test::EncoderTest {
     78 protected:
     79  ArfFreqTestLarge()
     80      : EncoderTest(GET_PARAM(0)), test_video_param_(GET_PARAM(1)),
     81        test_encode_param_(GET_PARAM(2)), min_arf_requested_(GET_PARAM(3)) {}
     82 
     83  ~ArfFreqTestLarge() override = default;
     84 
     85  void SetUp() override {
     86    InitializeConfig(test_encode_param_.mode);
     87    if (test_encode_param_.mode != ::libaom_test::kRealTime) {
     88      cfg_.g_lag_in_frames = 25;
     89    } else {
     90      cfg_.rc_buf_sz = 1000;
     91      cfg_.rc_buf_initial_sz = 500;
     92      cfg_.rc_buf_optimal_sz = 600;
     93    }
     94  }
     95 
     96  void BeginPassHook(unsigned int) override {
     97    min_run_ = ARF_NOT_SEEN;
     98    run_of_visible_frames_ = 0;
     99  }
    100 
    101  int GetNumFramesInPkt(const aom_codec_cx_pkt_t *pkt) {
    102    const uint8_t *buffer = reinterpret_cast<uint8_t *>(pkt->data.frame.buf);
    103    const uint8_t marker = buffer[pkt->data.frame.sz - 1];
    104    const int mag = ((marker >> 3) & 3) + 1;
    105    int frames = (marker & 0x7) + 1;
    106    const unsigned int index_sz = 2 + mag * frames;
    107    // Check for superframe or not.
    108    // Assume superframe has only one visible frame, the rest being
    109    // invisible. If superframe index is not found, then there is only
    110    // one frame.
    111    if (!((marker & 0xe0) == 0xc0 && pkt->data.frame.sz >= index_sz &&
    112          buffer[pkt->data.frame.sz - index_sz] == marker)) {
    113      frames = 1;
    114    }
    115    return frames;
    116  }
    117 
    118  void FramePktHook(const aom_codec_cx_pkt_t *pkt) override {
    119    if (pkt->kind != AOM_CODEC_CX_FRAME_PKT) return;
    120    const int frames = GetNumFramesInPkt(pkt);
    121    if (frames == 1) {
    122      run_of_visible_frames_++;
    123    } else if (frames == 2) {
    124      if (min_run_ == ARF_NOT_SEEN) {
    125        min_run_ = ARF_SEEN_ONCE;
    126      } else if (min_run_ == ARF_SEEN_ONCE ||
    127                 run_of_visible_frames_ < min_run_) {
    128        min_run_ = run_of_visible_frames_;
    129      }
    130      run_of_visible_frames_ = 1;
    131    } else {
    132      min_run_ = 0;
    133      run_of_visible_frames_ = 1;
    134    }
    135  }
    136 
    137  void PreEncodeFrameHook(::libaom_test::VideoSource *video,
    138                          ::libaom_test::Encoder *encoder) override {
    139    if (video->frame() == 0) {
    140      encoder->Control(AV1E_SET_FRAME_PARALLEL_DECODING, 1);
    141      encoder->Control(AV1E_SET_TILE_COLUMNS, 4);
    142      encoder->Control(AOME_SET_CPUUSED, test_encode_param_.cpu_used);
    143      encoder->Control(AV1E_SET_MIN_GF_INTERVAL, min_arf_requested_);
    144      if (test_encode_param_.mode != ::libaom_test::kRealTime) {
    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 
    152  int GetMinVisibleRun() const { return min_run_; }
    153 
    154  int GetMinArfDistanceRequested() const {
    155    if (min_arf_requested_)
    156      return min_arf_requested_;
    157    else
    158      return av1_rc_get_default_min_gf_interval(
    159          test_video_param_.width, test_video_param_.height,
    160          (double)test_video_param_.framerate_num /
    161              test_video_param_.framerate_den);
    162  }
    163 
    164  TestVideoParam test_video_param_;
    165  TestEncodeParam test_encode_param_;
    166 
    167 private:
    168  int min_arf_requested_;
    169  int min_run_;
    170  int run_of_visible_frames_;
    171 };
    172 
    173 TEST_P(ArfFreqTestLarge, MinArfFreqTest) {
    174  cfg_.rc_target_bitrate = kBitrate;
    175  cfg_.g_error_resilient = 0;
    176  cfg_.g_profile = test_video_param_.profile;
    177  cfg_.g_input_bit_depth = test_video_param_.input_bit_depth;
    178  cfg_.g_bit_depth = test_video_param_.bit_depth;
    179  init_flags_ = AOM_CODEC_USE_PSNR;
    180  if (cfg_.g_bit_depth > 8) init_flags_ |= AOM_CODEC_USE_HIGHBITDEPTH;
    181 
    182  std::unique_ptr<libaom_test::VideoSource> video;
    183  if (is_extension_y4m(test_video_param_.filename)) {
    184    video.reset(new libaom_test::Y4mVideoSource(test_video_param_.filename, 0,
    185                                                kFrames));
    186  } else {
    187    video.reset(new libaom_test::YUVVideoSource(
    188        test_video_param_.filename, test_video_param_.fmt,
    189        test_video_param_.width, test_video_param_.height,
    190        test_video_param_.framerate_num, test_video_param_.framerate_den, 0,
    191        kFrames));
    192  }
    193  ASSERT_NE(video, nullptr);
    194 
    195  ASSERT_NO_FATAL_FAILURE(RunLoop(video.get()));
    196  const int min_run = GetMinVisibleRun();
    197  const int min_arf_dist_requested = GetMinArfDistanceRequested();
    198  if (min_run != ARF_NOT_SEEN && min_run != ARF_SEEN_ONCE) {
    199    const int min_arf_dist = min_run + 1;
    200    EXPECT_GE(min_arf_dist, min_arf_dist_requested);
    201  }
    202 }
    203 
    204 #if CONFIG_AV1_ENCODER
    205 // TODO(angiebird): 25-29 fail in high bitdepth mode.
    206 // TODO(zoeliu): This ArfFreqTest does not work with BWDREF_FRAME, as
    207 // BWDREF_FRAME is also a non-show frame, and the minimum run between two
    208 // consecutive BWDREF_FRAME's may vary between 1 and any arbitrary positive
    209 // number as long as it does not exceed the gf_group interval.
    210 INSTANTIATE_TEST_SUITE_P(
    211    DISABLED_AV1, ArfFreqTestLarge,
    212    ::testing::Combine(
    213        ::testing::Values(
    214            static_cast<const libaom_test::CodecFactory *>(&libaom_test::kAV1)),
    215        ::testing::ValuesIn(kTestVectors), ::testing::ValuesIn(kEncodeVectors),
    216        ::testing::ValuesIn(kMinArfVectors)));
    217 #endif  // CONFIG_AV1_ENCODER
    218 }  // namespace