Debargha Mukherjee | 9852643 | 2015-04-01 16:39:06 -0700 | [diff] [blame] | 1 | /* |
Yaowu Xu | 9c01aa1 | 2016-09-01 14:32:49 -0700 | [diff] [blame] | 2 | * Copyright (c) 2016, Alliance for Open Media. All rights reserved |
Debargha Mukherjee | 9852643 | 2015-04-01 16:39:06 -0700 | [diff] [blame] | 3 | * |
Yaowu Xu | 9c01aa1 | 2016-09-01 14:32:49 -0700 | [diff] [blame] | 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 | */ |
Debargha Mukherjee | 9852643 | 2015-04-01 16:39:06 -0700 | [diff] [blame] | 11 | |
Jingning Han | 097d59c | 2015-07-29 14:51:36 -0700 | [diff] [blame] | 12 | #include "third_party/googletest/src/include/gtest/gtest.h" |
| 13 | |
Debargha Mukherjee | 9852643 | 2015-04-01 16:39:06 -0700 | [diff] [blame] | 14 | #include "test/codec_factory.h" |
| 15 | #include "test/encode_test_driver.h" |
Jingning Han | 097d59c | 2015-07-29 14:51:36 -0700 | [diff] [blame] | 16 | #include "test/util.h" |
Debargha Mukherjee | 9852643 | 2015-04-01 16:39:06 -0700 | [diff] [blame] | 17 | #include "test/y4m_video_source.h" |
| 18 | #include "test/yuv_video_source.h" |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 19 | #include "av1/encoder/ratectrl.h" |
Debargha Mukherjee | 9852643 | 2015-04-01 16:39:06 -0700 | [diff] [blame] | 20 | |
| 21 | namespace { |
| 22 | |
| 23 | const unsigned int kFrames = 100; |
| 24 | const int kBitrate = 500; |
| 25 | |
clang-format | 3a826f1 | 2016-08-11 17:46:05 -0700 | [diff] [blame] | 26 | #define ARF_NOT_SEEN 1000001 |
| 27 | #define ARF_SEEN_ONCE 1000000 |
Debargha Mukherjee | 9852643 | 2015-04-01 16:39:06 -0700 | [diff] [blame] | 28 | |
| 29 | typedef struct { |
| 30 | const char *filename; |
| 31 | unsigned int width; |
| 32 | unsigned int height; |
| 33 | unsigned int framerate_num; |
| 34 | unsigned int framerate_den; |
| 35 | unsigned int input_bit_depth; |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 36 | aom_img_fmt fmt; |
| 37 | aom_bit_depth_t bit_depth; |
Debargha Mukherjee | 9852643 | 2015-04-01 16:39:06 -0700 | [diff] [blame] | 38 | unsigned int profile; |
| 39 | } TestVideoParam; |
| 40 | |
| 41 | typedef struct { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 42 | libaom_test::TestMode mode; |
Debargha Mukherjee | 9852643 | 2015-04-01 16:39:06 -0700 | [diff] [blame] | 43 | int cpu_used; |
| 44 | } TestEncodeParam; |
| 45 | |
| 46 | const TestVideoParam kTestVectors[] = { |
| 47 | // artificially increase framerate to trigger default check |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 48 | { "hantro_collage_w352h288.yuv", 352, 288, 5000, 1, 8, AOM_IMG_FMT_I420, |
| 49 | AOM_BITS_8, 0 }, |
| 50 | { "hantro_collage_w352h288.yuv", 352, 288, 30, 1, 8, AOM_IMG_FMT_I420, |
| 51 | AOM_BITS_8, 0 }, |
| 52 | { "rush_hour_444.y4m", 352, 288, 30, 1, 8, AOM_IMG_FMT_I444, AOM_BITS_8, 1 }, |
| 53 | #if CONFIG_AOM_HIGHBITDEPTH |
clang-format | 3a826f1 | 2016-08-11 17:46:05 -0700 | [diff] [blame] | 54 | // Add list of profile 2/3 test videos here ... |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 55 | #endif // CONFIG_AOM_HIGHBITDEPTH |
Debargha Mukherjee | 9852643 | 2015-04-01 16:39:06 -0700 | [diff] [blame] | 56 | }; |
| 57 | |
| 58 | const TestEncodeParam kEncodeVectors[] = { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 59 | { ::libaom_test::kOnePassGood, 2 }, { ::libaom_test::kOnePassGood, 5 }, |
| 60 | { ::libaom_test::kTwoPassGood, 1 }, { ::libaom_test::kTwoPassGood, 2 }, |
| 61 | { ::libaom_test::kTwoPassGood, 5 }, { ::libaom_test::kRealTime, 5 }, |
Debargha Mukherjee | 9852643 | 2015-04-01 16:39:06 -0700 | [diff] [blame] | 62 | }; |
| 63 | |
| 64 | const int kMinArfVectors[] = { |
| 65 | // NOTE: 0 refers to the default built-in logic in: |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 66 | // av1_rc_get_default_min_gf_interval(...) |
Debargha Mukherjee | 9852643 | 2015-04-01 16:39:06 -0700 | [diff] [blame] | 67 | 0, 4, 8, 12, 15 |
| 68 | }; |
| 69 | |
| 70 | int is_extension_y4m(const char *filename) { |
| 71 | const char *dot = strrchr(filename, '.'); |
| 72 | if (!dot || dot == filename) |
| 73 | return 0; |
| 74 | else |
| 75 | return !strcmp(dot, ".y4m"); |
| 76 | } |
| 77 | |
hui su | a3a1b2d | 2015-11-02 15:47:55 -0800 | [diff] [blame] | 78 | class ArfFreqTestLarge |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 79 | : public ::libaom_test::EncoderTest, |
| 80 | public ::libaom_test::CodecTestWith3Params<TestVideoParam, |
Debargha Mukherjee | 9852643 | 2015-04-01 16:39:06 -0700 | [diff] [blame] | 81 | TestEncodeParam, int> { |
| 82 | protected: |
hui su | a3a1b2d | 2015-11-02 15:47:55 -0800 | [diff] [blame] | 83 | ArfFreqTestLarge() |
clang-format | 3a826f1 | 2016-08-11 17:46:05 -0700 | [diff] [blame] | 84 | : EncoderTest(GET_PARAM(0)), test_video_param_(GET_PARAM(1)), |
| 85 | test_encode_param_(GET_PARAM(2)), min_arf_requested_(GET_PARAM(3)) {} |
Debargha Mukherjee | 9852643 | 2015-04-01 16:39:06 -0700 | [diff] [blame] | 86 | |
hui su | a3a1b2d | 2015-11-02 15:47:55 -0800 | [diff] [blame] | 87 | virtual ~ArfFreqTestLarge() {} |
Debargha Mukherjee | 9852643 | 2015-04-01 16:39:06 -0700 | [diff] [blame] | 88 | |
| 89 | virtual void SetUp() { |
| 90 | InitializeConfig(); |
| 91 | SetMode(test_encode_param_.mode); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 92 | if (test_encode_param_.mode != ::libaom_test::kRealTime) { |
Debargha Mukherjee | 9852643 | 2015-04-01 16:39:06 -0700 | [diff] [blame] | 93 | cfg_.g_lag_in_frames = 25; |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 94 | cfg_.rc_end_usage = AOM_VBR; |
Debargha Mukherjee | 9852643 | 2015-04-01 16:39:06 -0700 | [diff] [blame] | 95 | } else { |
| 96 | cfg_.g_lag_in_frames = 0; |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 97 | cfg_.rc_end_usage = AOM_CBR; |
Debargha Mukherjee | 9852643 | 2015-04-01 16:39:06 -0700 | [diff] [blame] | 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) { |
Debargha Mukherjee | 3c52448 | 2015-07-10 09:49:17 -0700 | [diff] [blame] | 106 | min_run_ = ARF_NOT_SEEN; |
Debargha Mukherjee | 9852643 | 2015-04-01 16:39:06 -0700 | [diff] [blame] | 107 | run_of_visible_frames_ = 0; |
| 108 | } |
| 109 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 110 | int GetNumFramesInPkt(const aom_codec_cx_pkt_t *pkt) { |
clang-format | 3a826f1 | 2016-08-11 17:46:05 -0700 | [diff] [blame] | 111 | const uint8_t *buffer = reinterpret_cast<uint8_t *>(pkt->data.frame.buf); |
Debargha Mukherjee | 9852643 | 2015-04-01 16:39:06 -0700 | [diff] [blame] | 112 | const uint8_t marker = buffer[pkt->data.frame.sz - 1]; |
| 113 | const int mag = ((marker >> 3) & 3) + 1; |
| 114 | int frames = (marker & 0x7) + 1; |
clang-format | 3a826f1 | 2016-08-11 17:46:05 -0700 | [diff] [blame] | 115 | const unsigned int index_sz = 2 + mag * frames; |
Debargha Mukherjee | 9852643 | 2015-04-01 16:39:06 -0700 | [diff] [blame] | 116 | // Check for superframe or not. |
| 117 | // Assume superframe has only one visible frame, the rest being |
| 118 | // invisible. If superframe index is not found, then there is only |
| 119 | // one frame. |
clang-format | 3a826f1 | 2016-08-11 17:46:05 -0700 | [diff] [blame] | 120 | if (!((marker & 0xe0) == 0xc0 && pkt->data.frame.sz >= index_sz && |
Debargha Mukherjee | 9852643 | 2015-04-01 16:39:06 -0700 | [diff] [blame] | 121 | buffer[pkt->data.frame.sz - index_sz] == marker)) { |
| 122 | frames = 1; |
| 123 | } |
| 124 | return frames; |
| 125 | } |
| 126 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 127 | virtual void FramePktHook(const aom_codec_cx_pkt_t *pkt) { |
| 128 | if (pkt->kind != AOM_CODEC_CX_FRAME_PKT) return; |
Debargha Mukherjee | 9852643 | 2015-04-01 16:39:06 -0700 | [diff] [blame] | 129 | const int frames = GetNumFramesInPkt(pkt); |
| 130 | if (frames == 1) { |
| 131 | run_of_visible_frames_++; |
| 132 | } else if (frames == 2) { |
Debargha Mukherjee | 3c52448 | 2015-07-10 09:49:17 -0700 | [diff] [blame] | 133 | if (min_run_ == ARF_NOT_SEEN) { |
| 134 | min_run_ = ARF_SEEN_ONCE; |
| 135 | } else if (min_run_ == ARF_SEEN_ONCE || |
| 136 | run_of_visible_frames_ < min_run_) { |
| 137 | min_run_ = run_of_visible_frames_; |
Debargha Mukherjee | 9852643 | 2015-04-01 16:39:06 -0700 | [diff] [blame] | 138 | } |
| 139 | run_of_visible_frames_ = 1; |
| 140 | } else { |
Debargha Mukherjee | 3c52448 | 2015-07-10 09:49:17 -0700 | [diff] [blame] | 141 | min_run_ = 0; |
Debargha Mukherjee | 9852643 | 2015-04-01 16:39:06 -0700 | [diff] [blame] | 142 | run_of_visible_frames_ = 1; |
| 143 | } |
| 144 | } |
| 145 | |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 146 | virtual void PreEncodeFrameHook(::libaom_test::VideoSource *video, |
| 147 | ::libaom_test::Encoder *encoder) { |
Debargha Mukherjee | 9852643 | 2015-04-01 16:39:06 -0700 | [diff] [blame] | 148 | if (video->frame() == 0) { |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 149 | encoder->Control(AV1E_SET_FRAME_PARALLEL_DECODING, 1); |
| 150 | encoder->Control(AV1E_SET_TILE_COLUMNS, 4); |
| 151 | encoder->Control(AOME_SET_CPUUSED, test_encode_param_.cpu_used); |
| 152 | encoder->Control(AV1E_SET_MIN_GF_INTERVAL, min_arf_requested_); |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 153 | if (test_encode_param_.mode != ::libaom_test::kRealTime) { |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 154 | encoder->Control(AOME_SET_ENABLEAUTOALTREF, 1); |
| 155 | encoder->Control(AOME_SET_ARNR_MAXFRAMES, 7); |
| 156 | encoder->Control(AOME_SET_ARNR_STRENGTH, 5); |
Debargha Mukherjee | 9852643 | 2015-04-01 16:39:06 -0700 | [diff] [blame] | 157 | } |
| 158 | } |
| 159 | } |
| 160 | |
clang-format | 3a826f1 | 2016-08-11 17:46:05 -0700 | [diff] [blame] | 161 | int GetMinVisibleRun() const { return min_run_; } |
Debargha Mukherjee | 9852643 | 2015-04-01 16:39:06 -0700 | [diff] [blame] | 162 | |
| 163 | int GetMinArfDistanceRequested() const { |
| 164 | if (min_arf_requested_) |
| 165 | return min_arf_requested_; |
| 166 | else |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 167 | return av1_rc_get_default_min_gf_interval( |
Debargha Mukherjee | 9852643 | 2015-04-01 16:39:06 -0700 | [diff] [blame] | 168 | test_video_param_.width, test_video_param_.height, |
| 169 | (double)test_video_param_.framerate_num / |
clang-format | 3a826f1 | 2016-08-11 17:46:05 -0700 | [diff] [blame] | 170 | test_video_param_.framerate_den); |
Debargha Mukherjee | 9852643 | 2015-04-01 16:39:06 -0700 | [diff] [blame] | 171 | } |
| 172 | |
| 173 | TestVideoParam test_video_param_; |
| 174 | TestEncodeParam test_encode_param_; |
| 175 | |
| 176 | private: |
| 177 | int min_arf_requested_; |
Debargha Mukherjee | 3c52448 | 2015-07-10 09:49:17 -0700 | [diff] [blame] | 178 | int min_run_; |
Debargha Mukherjee | 9852643 | 2015-04-01 16:39:06 -0700 | [diff] [blame] | 179 | int run_of_visible_frames_; |
| 180 | }; |
| 181 | |
hui su | a3a1b2d | 2015-11-02 15:47:55 -0800 | [diff] [blame] | 182 | TEST_P(ArfFreqTestLarge, MinArfFreqTest) { |
Debargha Mukherjee | 9852643 | 2015-04-01 16:39:06 -0700 | [diff] [blame] | 183 | cfg_.rc_target_bitrate = kBitrate; |
| 184 | cfg_.g_error_resilient = 0; |
| 185 | cfg_.g_profile = test_video_param_.profile; |
| 186 | cfg_.g_input_bit_depth = test_video_param_.input_bit_depth; |
| 187 | cfg_.g_bit_depth = test_video_param_.bit_depth; |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 188 | init_flags_ = AOM_CODEC_USE_PSNR; |
| 189 | if (cfg_.g_bit_depth > 8) init_flags_ |= AOM_CODEC_USE_HIGHBITDEPTH; |
Debargha Mukherjee | 9852643 | 2015-04-01 16:39:06 -0700 | [diff] [blame] | 190 | |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 191 | testing::internal::scoped_ptr<libaom_test::VideoSource> video; |
Debargha Mukherjee | 9852643 | 2015-04-01 16:39:06 -0700 | [diff] [blame] | 192 | if (is_extension_y4m(test_video_param_.filename)) { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 193 | video.reset(new libaom_test::Y4mVideoSource(test_video_param_.filename, 0, |
clang-format | 3a826f1 | 2016-08-11 17:46:05 -0700 | [diff] [blame] | 194 | kFrames)); |
Debargha Mukherjee | 9852643 | 2015-04-01 16:39:06 -0700 | [diff] [blame] | 195 | } else { |
Yaowu Xu | c27fc14 | 2016-08-22 16:08:15 -0700 | [diff] [blame] | 196 | video.reset(new libaom_test::YUVVideoSource( |
clang-format | 3a826f1 | 2016-08-11 17:46:05 -0700 | [diff] [blame] | 197 | test_video_param_.filename, test_video_param_.fmt, |
| 198 | test_video_param_.width, test_video_param_.height, |
| 199 | test_video_param_.framerate_num, test_video_param_.framerate_den, 0, |
| 200 | kFrames)); |
Debargha Mukherjee | 9852643 | 2015-04-01 16:39:06 -0700 | [diff] [blame] | 201 | } |
| 202 | |
Alex Converse | 12ca90d | 2016-07-21 11:38:27 -0700 | [diff] [blame] | 203 | ASSERT_NO_FATAL_FAILURE(RunLoop(video.get())); |
Debargha Mukherjee | 3c52448 | 2015-07-10 09:49:17 -0700 | [diff] [blame] | 204 | const int min_run = GetMinVisibleRun(); |
Debargha Mukherjee | 9852643 | 2015-04-01 16:39:06 -0700 | [diff] [blame] | 205 | const int min_arf_dist_requested = GetMinArfDistanceRequested(); |
Debargha Mukherjee | 3c52448 | 2015-07-10 09:49:17 -0700 | [diff] [blame] | 206 | if (min_run != ARF_NOT_SEEN && min_run != ARF_SEEN_ONCE) { |
| 207 | const int min_arf_dist = min_run + 1; |
Debargha Mukherjee | 9852643 | 2015-04-01 16:39:06 -0700 | [diff] [blame] | 208 | EXPECT_GE(min_arf_dist, min_arf_dist_requested); |
| 209 | } |
Debargha Mukherjee | 9852643 | 2015-04-01 16:39:06 -0700 | [diff] [blame] | 210 | } |
| 211 | |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 212 | #if CONFIG_AOM_HIGHBITDEPTH || CONFIG_EXT_REFS |
| 213 | #if CONFIG_AV1_ENCODER |
Yaowu Xu | 7c514e2 | 2015-09-28 15:55:46 -0700 | [diff] [blame] | 214 | // TODO(angiebird): 25-29 fail in high bitdepth mode. |
Zoe Liu | 5201280 | 2016-06-16 09:41:30 -0700 | [diff] [blame] | 215 | // TODO(zoeliu): This ArfFreqTest does not work with BWDREF_FRAME, as |
| 216 | // BWDREF_FRAME is also a non-show frame, and the minimum run between two |
| 217 | // consecutive BWDREF_FRAME's may vary between 1 and any arbitrary positive |
| 218 | // number as long as it does not exceed the gf_group interval. |
Yaowu Xu | 7c514e2 | 2015-09-28 15:55:46 -0700 | [diff] [blame] | 219 | INSTANTIATE_TEST_CASE_P( |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 220 | DISABLED_AV1, ArfFreqTestLarge, |
Yaowu Xu | 7c514e2 | 2015-09-28 15:55:46 -0700 | [diff] [blame] | 221 | ::testing::Combine( |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 222 | ::testing::Values( |
| 223 | static_cast<const libaom_test::CodecFactory *>(&libaom_test::kAV1)), |
clang-format | 3a826f1 | 2016-08-11 17:46:05 -0700 | [diff] [blame] | 224 | ::testing::ValuesIn(kTestVectors), ::testing::ValuesIn(kEncodeVectors), |
Yaowu Xu | 7c514e2 | 2015-09-28 15:55:46 -0700 | [diff] [blame] | 225 | ::testing::ValuesIn(kMinArfVectors))); |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 226 | #endif // CONFIG_AV1_ENCODER |
Yaowu Xu | 7c514e2 | 2015-09-28 15:55:46 -0700 | [diff] [blame] | 227 | #else |
Yaowu Xu | f883b42 | 2016-08-30 14:01:10 -0700 | [diff] [blame] | 228 | AV1_INSTANTIATE_TEST_CASE(ArfFreqTestLarge, ::testing::ValuesIn(kTestVectors), |
| 229 | ::testing::ValuesIn(kEncodeVectors), |
| 230 | ::testing::ValuesIn(kMinArfVectors)); |
| 231 | #endif // CONFIG_AOM_HIGHBITDEPTH || CONFIG_EXT_REFS |
Debargha Mukherjee | 9852643 | 2015-04-01 16:39:06 -0700 | [diff] [blame] | 232 | } // namespace |