blob: 0f664407feb1d191b88f585643be56628b8fab4d [file] [log] [blame]
Jim Bankoski533470c2012-10-29 19:54:06 -07001/*
Yaowu Xu2ab7ff02016-09-02 12:04:54 -07002 * Copyright (c) 2016, Alliance for Open Media. All rights reserved
Jim Bankoski533470c2012-10-29 19:54:06 -07003 *
Yaowu Xu2ab7ff02016-09-02 12:04:54 -07004 * 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
Yaowu Xuf883b422016-08-30 14:01:10 -070012#include "./aom_config.h"
John Koleszar706cafe2013-01-18 11:51:12 -080013#include "third_party/googletest/src/include/gtest/gtest.h"
14#include "test/codec_factory.h"
Jim Bankoski533470c2012-10-29 19:54:06 -070015#include "test/encode_test_driver.h"
16#include "test/i420_video_source.h"
John Koleszar706cafe2013-01-18 11:51:12 -080017#include "test/util.h"
Alex Conversef5949fa2014-01-17 13:52:23 -080018#include "test/y4m_video_source.h"
Yaowu Xuf883b422016-08-30 14:01:10 -070019#include "aom/aom_codec.h"
John Koleszar706cafe2013-01-18 11:51:12 -080020
Jim Bankoski533470c2012-10-29 19:54:06 -070021namespace {
22
clang-format3a826f12016-08-11 17:46:05 -070023class DatarateTestLarge
Yaowu Xuc27fc142016-08-22 16:08:15 -070024 : public ::libaom_test::EncoderTest,
25 public ::libaom_test::CodecTestWith2Params<libaom_test::TestMode, int> {
John Koleszar706cafe2013-01-18 11:51:12 -080026 public:
Jim Bankoski6505b072014-03-12 17:20:16 -070027 DatarateTestLarge() : EncoderTest(GET_PARAM(0)) {}
28
James Zerncc73e1f2016-08-08 15:09:30 -070029 protected:
Jim Bankoski6505b072014-03-12 17:20:16 -070030 virtual ~DatarateTestLarge() {}
John Koleszar706cafe2013-01-18 11:51:12 -080031
Marco Paniconib26ce8b2013-10-22 11:30:06 -070032 virtual void SetUp() {
33 InitializeConfig();
34 SetMode(GET_PARAM(1));
35 set_cpu_used_ = GET_PARAM(2);
36 ResetModel();
37 }
38
39 virtual void ResetModel() {
40 last_pts_ = 0;
Marco Paniconi1b8b8b02013-12-17 15:45:30 -080041 bits_in_buffer_model_ = cfg_.rc_target_bitrate * cfg_.rc_buf_initial_sz;
Marco Paniconib26ce8b2013-10-22 11:30:06 -070042 frame_number_ = 0;
Marco Paniconi640885d2014-02-11 08:48:34 -080043 tot_frame_number_ = 0;
Marco Paniconi1b8b8b02013-12-17 15:45:30 -080044 first_drop_ = 0;
45 num_drops_ = 0;
JackyChena86e6e82014-09-17 13:54:48 -070046 // Denoiser is off by default.
47 denoiser_on_ = 0;
James Zerncc73e1f2016-08-08 15:09:30 -070048 bits_total_ = 0;
JackyChene82a3b22015-01-07 16:34:25 -080049 denoiser_offon_test_ = 0;
50 denoiser_offon_period_ = -1;
Marco Paniconi4864ab22014-02-06 09:23:17 -080051 }
52
Yaowu Xuc27fc142016-08-22 16:08:15 -070053 virtual void PreEncodeFrameHook(::libaom_test::VideoSource *video,
54 ::libaom_test::Encoder *encoder) {
Yaowu Xuf883b422016-08-30 14:01:10 -070055 if (video->frame() == 0) encoder->Control(AOME_SET_CPUUSED, set_cpu_used_);
Jingning Han5b860e12015-01-06 10:04:56 -080056
JackyChene82a3b22015-01-07 16:34:25 -080057 if (denoiser_offon_test_) {
58 ASSERT_GT(denoiser_offon_period_, 0)
59 << "denoiser_offon_period_ is not positive.";
60 if ((video->frame() + 1) % denoiser_offon_period_ == 0) {
61 // Flip denoiser_on_ periodically
62 denoiser_on_ ^= 1;
63 }
64 }
65
Yaowu Xuf883b422016-08-30 14:01:10 -070066 encoder->Control(AV1E_SET_NOISE_SENSITIVITY, denoiser_on_);
Jingning Han5b860e12015-01-06 10:04:56 -080067
Yaowu Xuf883b422016-08-30 14:01:10 -070068 const aom_rational_t tb = video->timebase();
Marco Paniconie078c3d2013-10-02 17:13:59 -070069 timebase_ = static_cast<double>(tb.num) / tb.den;
70 duration_ = 0;
71 }
72
Yaowu Xuf883b422016-08-30 14:01:10 -070073 virtual void FramePktHook(const aom_codec_cx_pkt_t *pkt) {
Marco Paniconi1b8b8b02013-12-17 15:45:30 -080074 // Time since last timestamp = duration.
Yaowu Xuf883b422016-08-30 14:01:10 -070075 aom_codec_pts_t duration = pkt->data.frame.pts - last_pts_;
Marco Paniconi1b8b8b02013-12-17 15:45:30 -080076
Marco Paniconi640885d2014-02-11 08:48:34 -080077 if (duration > 1) {
78 // If first drop not set and we have a drop set it to this time.
clang-format3a826f12016-08-11 17:46:05 -070079 if (!first_drop_) first_drop_ = last_pts_ + 1;
Marco Paniconi640885d2014-02-11 08:48:34 -080080 // Update the number of frame drops.
81 num_drops_ += static_cast<int>(duration - 1);
82 // Update counter for total number of frames (#frames input to encoder).
83 // Needed for setting the proper layer_id below.
84 tot_frame_number_ += static_cast<int>(duration - 1);
85 }
86
Marco Paniconi1b8b8b02013-12-17 15:45:30 -080087 // Add to the buffer the bits we'd expect from a constant bitrate server.
James Zerncac85f82013-12-18 16:58:43 -080088 bits_in_buffer_model_ += static_cast<int64_t>(
89 duration * timebase_ * cfg_.rc_target_bitrate * 1000);
Marco Paniconi1b8b8b02013-12-17 15:45:30 -080090
91 // Buffer should not go negative.
92 ASSERT_GE(bits_in_buffer_model_, 0) << "Buffer Underrun at frame "
clang-format3a826f12016-08-11 17:46:05 -070093 << pkt->data.frame.pts;
Marco Paniconi1b8b8b02013-12-17 15:45:30 -080094
James Zerncac85f82013-12-18 16:58:43 -080095 const size_t frame_size_in_bits = pkt->data.frame.sz * 8;
Marco Paniconi4864ab22014-02-06 09:23:17 -080096
James Zerncc73e1f2016-08-08 15:09:30 -070097 // Update the total encoded bits.
98 bits_total_ += frame_size_in_bits;
Marco Paniconi1b8b8b02013-12-17 15:45:30 -080099
Marco Paniconie078c3d2013-10-02 17:13:59 -0700100 // Update the most recent pts.
101 last_pts_ = pkt->data.frame.pts;
102 ++frame_number_;
Marco Paniconi640885d2014-02-11 08:48:34 -0800103 ++tot_frame_number_;
Marco Paniconie078c3d2013-10-02 17:13:59 -0700104 }
105
106 virtual void EndPassHook(void) {
James Zerncc73e1f2016-08-08 15:09:30 -0700107 duration_ = (last_pts_ + 1) * timebase_;
108 // Effective file datarate:
109 effective_datarate_ = (bits_total_ / 1000.0) / duration_;
Marco Paniconie078c3d2013-10-02 17:13:59 -0700110 }
Marco Paniconib26ce8b2013-10-22 11:30:06 -0700111
Yaowu Xuf883b422016-08-30 14:01:10 -0700112 aom_codec_pts_t last_pts_;
Marco Paniconib26ce8b2013-10-22 11:30:06 -0700113 double timebase_;
Marco Paniconi640885d2014-02-11 08:48:34 -0800114 int frame_number_; // Counter for number of non-dropped/encoded frames.
115 int tot_frame_number_; // Counter for total number of input frames.
James Zerncc73e1f2016-08-08 15:09:30 -0700116 int64_t bits_total_;
Marco Paniconib26ce8b2013-10-22 11:30:06 -0700117 double duration_;
James Zerncc73e1f2016-08-08 15:09:30 -0700118 double effective_datarate_;
Marco Paniconib26ce8b2013-10-22 11:30:06 -0700119 int set_cpu_used_;
James Zerncac85f82013-12-18 16:58:43 -0800120 int64_t bits_in_buffer_model_;
Yaowu Xuf883b422016-08-30 14:01:10 -0700121 aom_codec_pts_t first_drop_;
Marco Paniconi1b8b8b02013-12-17 15:45:30 -0800122 int num_drops_;
JackyChena86e6e82014-09-17 13:54:48 -0700123 int denoiser_on_;
JackyChene82a3b22015-01-07 16:34:25 -0800124 int denoiser_offon_test_;
125 int denoiser_offon_period_;
Marco Paniconie078c3d2013-10-02 17:13:59 -0700126};
127
Marco75d55172016-05-25 14:19:01 -0700128// Check basic rate targeting for VBR mode.
James Zerncc73e1f2016-08-08 15:09:30 -0700129TEST_P(DatarateTestLarge, BasicRateTargetingVBR) {
Marco75d55172016-05-25 14:19:01 -0700130 cfg_.rc_min_quantizer = 0;
131 cfg_.rc_max_quantizer = 63;
132 cfg_.g_error_resilient = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -0700133 cfg_.rc_end_usage = AOM_VBR;
Marco75d55172016-05-25 14:19:01 -0700134 cfg_.g_lag_in_frames = 0;
135
Yaowu Xuc27fc142016-08-22 16:08:15 -0700136 ::libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
Marco75d55172016-05-25 14:19:01 -0700137 30, 1, 0, 300);
138 for (int i = 400; i <= 800; i += 400) {
139 cfg_.rc_target_bitrate = i;
140 ResetModel();
141 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
James Zerncc73e1f2016-08-08 15:09:30 -0700142 ASSERT_GE(effective_datarate_, cfg_.rc_target_bitrate * 0.75)
Marco75d55172016-05-25 14:19:01 -0700143 << " The datarate for the file is lower than target by too much!";
James Zerncc73e1f2016-08-08 15:09:30 -0700144 ASSERT_LE(effective_datarate_, cfg_.rc_target_bitrate * 1.25)
Marco75d55172016-05-25 14:19:01 -0700145 << " The datarate for the file is greater than target by too much!";
146 }
147}
148
149// Check basic rate targeting for CBR,
James Zerncc73e1f2016-08-08 15:09:30 -0700150TEST_P(DatarateTestLarge, BasicRateTargeting) {
Marco Paniconi1b8b8b02013-12-17 15:45:30 -0800151 cfg_.rc_buf_initial_sz = 500;
152 cfg_.rc_buf_optimal_sz = 500;
153 cfg_.rc_buf_sz = 1000;
154 cfg_.rc_dropframe_thresh = 1;
Marco Paniconie078c3d2013-10-02 17:13:59 -0700155 cfg_.rc_min_quantizer = 0;
156 cfg_.rc_max_quantizer = 63;
Yaowu Xuf883b422016-08-30 14:01:10 -0700157 cfg_.rc_end_usage = AOM_CBR;
Marco Paniconi4864ab22014-02-06 09:23:17 -0800158 cfg_.g_lag_in_frames = 0;
Marco Paniconie078c3d2013-10-02 17:13:59 -0700159
Yaowu Xuc27fc142016-08-22 16:08:15 -0700160 ::libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
Marco Paniconie078c3d2013-10-02 17:13:59 -0700161 30, 1, 0, 140);
Marco Paniconib26ce8b2013-10-22 11:30:06 -0700162 for (int i = 150; i < 800; i += 200) {
Marco Paniconie078c3d2013-10-02 17:13:59 -0700163 cfg_.rc_target_bitrate = i;
164 ResetModel();
165 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
James Zerncc73e1f2016-08-08 15:09:30 -0700166 ASSERT_GE(effective_datarate_, cfg_.rc_target_bitrate * 0.85)
Marco Paniconi4864ab22014-02-06 09:23:17 -0800167 << " The datarate for the file is lower than target by too much!";
James Zerncc73e1f2016-08-08 15:09:30 -0700168 ASSERT_LE(effective_datarate_, cfg_.rc_target_bitrate * 1.15)
Marco Paniconi4864ab22014-02-06 09:23:17 -0800169 << " The datarate for the file is greater than target by too much!";
Marco Paniconie078c3d2013-10-02 17:13:59 -0700170 }
171}
172
Marco75d55172016-05-25 14:19:01 -0700173// Check basic rate targeting for CBR.
James Zerncc73e1f2016-08-08 15:09:30 -0700174TEST_P(DatarateTestLarge, BasicRateTargeting444) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700175 ::libaom_test::Y4mVideoSource video("rush_hour_444.y4m", 0, 140);
Alex Conversef5949fa2014-01-17 13:52:23 -0800176
177 cfg_.g_profile = 1;
178 cfg_.g_timebase = video.timebase();
179
180 cfg_.rc_buf_initial_sz = 500;
181 cfg_.rc_buf_optimal_sz = 500;
182 cfg_.rc_buf_sz = 1000;
183 cfg_.rc_dropframe_thresh = 1;
184 cfg_.rc_min_quantizer = 0;
185 cfg_.rc_max_quantizer = 63;
Yaowu Xuf883b422016-08-30 14:01:10 -0700186 cfg_.rc_end_usage = AOM_CBR;
Alex Conversef5949fa2014-01-17 13:52:23 -0800187
188 for (int i = 250; i < 900; i += 200) {
189 cfg_.rc_target_bitrate = i;
190 ResetModel();
191 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
192 ASSERT_GE(static_cast<double>(cfg_.rc_target_bitrate),
James Zerncc73e1f2016-08-08 15:09:30 -0700193 effective_datarate_ * 0.85)
Alex Conversef5949fa2014-01-17 13:52:23 -0800194 << " The datarate for the file exceeds the target by too much!";
195 ASSERT_LE(static_cast<double>(cfg_.rc_target_bitrate),
James Zerncc73e1f2016-08-08 15:09:30 -0700196 effective_datarate_ * 1.15)
Alex Conversef5949fa2014-01-17 13:52:23 -0800197 << " The datarate for the file missed the target!"
clang-format3a826f12016-08-11 17:46:05 -0700198 << cfg_.rc_target_bitrate << " " << effective_datarate_;
Alex Conversef5949fa2014-01-17 13:52:23 -0800199 }
200}
Alex Conversef5949fa2014-01-17 13:52:23 -0800201
Marco Paniconi1b8b8b02013-12-17 15:45:30 -0800202// Check that (1) the first dropped frame gets earlier and earlier
203// as the drop frame threshold is increased, and (2) that the total number of
204// frame drops does not decrease as we increase frame drop threshold.
205// Use a lower qp-max to force some frame drops.
James Zerncc73e1f2016-08-08 15:09:30 -0700206TEST_P(DatarateTestLarge, ChangingDropFrameThresh) {
Marco Paniconi1b8b8b02013-12-17 15:45:30 -0800207 cfg_.rc_buf_initial_sz = 500;
208 cfg_.rc_buf_optimal_sz = 500;
209 cfg_.rc_buf_sz = 1000;
210 cfg_.rc_undershoot_pct = 20;
211 cfg_.rc_undershoot_pct = 20;
212 cfg_.rc_dropframe_thresh = 10;
213 cfg_.rc_min_quantizer = 0;
214 cfg_.rc_max_quantizer = 50;
Yaowu Xuf883b422016-08-30 14:01:10 -0700215 cfg_.rc_end_usage = AOM_CBR;
Marco Paniconi1b8b8b02013-12-17 15:45:30 -0800216 cfg_.rc_target_bitrate = 200;
Marco Paniconi4864ab22014-02-06 09:23:17 -0800217 cfg_.g_lag_in_frames = 0;
James Zern4b00f0e2016-02-26 15:14:46 -0800218 // TODO(marpan): Investigate datarate target failures with a smaller keyframe
219 // interval (128).
220 cfg_.kf_max_dist = 9999;
Marco Paniconi1b8b8b02013-12-17 15:45:30 -0800221
Yaowu Xuc27fc142016-08-22 16:08:15 -0700222 ::libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
Marco Paniconi1b8b8b02013-12-17 15:45:30 -0800223 30, 1, 0, 140);
224
225 const int kDropFrameThreshTestStep = 30;
Yaowu Xuf883b422016-08-30 14:01:10 -0700226 aom_codec_pts_t last_drop = 140;
Marco Paniconi1b8b8b02013-12-17 15:45:30 -0800227 int last_num_drops = 0;
228 for (int i = 10; i < 100; i += kDropFrameThreshTestStep) {
229 cfg_.rc_dropframe_thresh = i;
230 ResetModel();
231 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
James Zerncc73e1f2016-08-08 15:09:30 -0700232 ASSERT_GE(effective_datarate_, cfg_.rc_target_bitrate * 0.85)
Marco Paniconi4864ab22014-02-06 09:23:17 -0800233 << " The datarate for the file is lower than target by too much!";
James Zerncc73e1f2016-08-08 15:09:30 -0700234 ASSERT_LE(effective_datarate_, cfg_.rc_target_bitrate * 1.15)
Marco Paniconi4864ab22014-02-06 09:23:17 -0800235 << " The datarate for the file is greater than target by too much!";
Marco Paniconi1b8b8b02013-12-17 15:45:30 -0800236 ASSERT_LE(first_drop_, last_drop)
237 << " The first dropped frame for drop_thresh " << i
238 << " > first dropped frame for drop_thresh "
239 << i - kDropFrameThreshTestStep;
Marcocb7b2a42015-11-03 08:15:04 -0800240 ASSERT_GE(num_drops_, last_num_drops * 0.85)
Marco Paniconi1b8b8b02013-12-17 15:45:30 -0800241 << " The number of dropped frames for drop_thresh " << i
242 << " < number of dropped frames for drop_thresh "
243 << i - kDropFrameThreshTestStep;
244 last_drop = first_drop_;
245 last_num_drops = num_drops_;
246 }
247}
248
Yaowu Xuf883b422016-08-30 14:01:10 -0700249AV1_INSTANTIATE_TEST_CASE(DatarateTestLarge,
250 ::testing::Values(::libaom_test::kOnePassGood,
251 ::libaom_test::kRealTime),
252 ::testing::Range(2, 9));
Jim Bankoski533470c2012-10-29 19:54:06 -0700253} // namespace