blob: 1588d3cc1992445d547d987fd0957bbbe0737576 [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.
Johann123e8a62017-12-28 14:40:49 -080010 */
Yaowu Xu2ab7ff02016-09-02 12:04:54 -070011
Tom Finegan60e653d2018-05-22 11:34:58 -070012#include "config/aom_config.h"
13
Tom Finegan7a07ece2017-02-07 17:14:05 -080014#include "third_party/googletest/src/googletest/include/gtest/gtest.h"
John Koleszar706cafe2013-01-18 11:51:12 -080015#include "test/codec_factory.h"
Jim Bankoski533470c2012-10-29 19:54:06 -070016#include "test/encode_test_driver.h"
17#include "test/i420_video_source.h"
John Koleszar706cafe2013-01-18 11:51:12 -080018#include "test/util.h"
Alex Conversef5949fa2014-01-17 13:52:23 -080019#include "test/y4m_video_source.h"
Yaowu Xuf883b422016-08-30 14:01:10 -070020#include "aom/aom_codec.h"
John Koleszar706cafe2013-01-18 11:51:12 -080021
Jim Bankoski533470c2012-10-29 19:54:06 -070022namespace {
23
clang-format3a826f12016-08-11 17:46:05 -070024class DatarateTestLarge
Sebastien Alaiwan4322bc12017-06-05 10:18:28 +020025 : public ::libaom_test::CodecTestWith2Params<libaom_test::TestMode, int>,
26 public ::libaom_test::EncoderTest {
John Koleszar706cafe2013-01-18 11:51:12 -080027 public:
Jim Bankoski6505b072014-03-12 17:20:16 -070028 DatarateTestLarge() : EncoderTest(GET_PARAM(0)) {}
29
James Zerncc73e1f2016-08-08 15:09:30 -070030 protected:
Jim Bankoski6505b072014-03-12 17:20:16 -070031 virtual ~DatarateTestLarge() {}
John Koleszar706cafe2013-01-18 11:51:12 -080032
Marco Paniconib26ce8b2013-10-22 11:30:06 -070033 virtual void SetUp() {
34 InitializeConfig();
35 SetMode(GET_PARAM(1));
36 set_cpu_used_ = GET_PARAM(2);
37 ResetModel();
38 }
39
40 virtual void ResetModel() {
41 last_pts_ = 0;
Marco Paniconi1b8b8b02013-12-17 15:45:30 -080042 bits_in_buffer_model_ = cfg_.rc_target_bitrate * cfg_.rc_buf_initial_sz;
Marco Paniconib26ce8b2013-10-22 11:30:06 -070043 frame_number_ = 0;
Marco Paniconi640885d2014-02-11 08:48:34 -080044 tot_frame_number_ = 0;
Marco Paniconi1b8b8b02013-12-17 15:45:30 -080045 first_drop_ = 0;
46 num_drops_ = 0;
JackyChena86e6e82014-09-17 13:54:48 -070047 // Denoiser is off by default.
48 denoiser_on_ = 0;
James Zerncc73e1f2016-08-08 15:09:30 -070049 bits_total_ = 0;
JackyChene82a3b22015-01-07 16:34:25 -080050 denoiser_offon_test_ = 0;
51 denoiser_offon_period_ = -1;
Marco Paniconi4864ab22014-02-06 09:23:17 -080052 }
53
Yaowu Xuc27fc142016-08-22 16:08:15 -070054 virtual void PreEncodeFrameHook(::libaom_test::VideoSource *video,
55 ::libaom_test::Encoder *encoder) {
Yaowu Xuf883b422016-08-30 14:01:10 -070056 if (video->frame() == 0) encoder->Control(AOME_SET_CPUUSED, set_cpu_used_);
Jingning Han5b860e12015-01-06 10:04:56 -080057
JackyChene82a3b22015-01-07 16:34:25 -080058 if (denoiser_offon_test_) {
59 ASSERT_GT(denoiser_offon_period_, 0)
60 << "denoiser_offon_period_ is not positive.";
61 if ((video->frame() + 1) % denoiser_offon_period_ == 0) {
62 // Flip denoiser_on_ periodically
63 denoiser_on_ ^= 1;
64 }
65 }
66
Yaowu Xuf883b422016-08-30 14:01:10 -070067 encoder->Control(AV1E_SET_NOISE_SENSITIVITY, denoiser_on_);
Jingning Han5b860e12015-01-06 10:04:56 -080068
Yaowu Xuf883b422016-08-30 14:01:10 -070069 const aom_rational_t tb = video->timebase();
Marco Paniconie078c3d2013-10-02 17:13:59 -070070 timebase_ = static_cast<double>(tb.num) / tb.den;
71 duration_ = 0;
72 }
73
Yaowu Xuf883b422016-08-30 14:01:10 -070074 virtual void FramePktHook(const aom_codec_cx_pkt_t *pkt) {
Marco Paniconi1b8b8b02013-12-17 15:45:30 -080075 // Time since last timestamp = duration.
Yaowu Xuf883b422016-08-30 14:01:10 -070076 aom_codec_pts_t duration = pkt->data.frame.pts - last_pts_;
Marco Paniconi1b8b8b02013-12-17 15:45:30 -080077
Marco Paniconi640885d2014-02-11 08:48:34 -080078 if (duration > 1) {
79 // If first drop not set and we have a drop set it to this time.
clang-format3a826f12016-08-11 17:46:05 -070080 if (!first_drop_) first_drop_ = last_pts_ + 1;
Marco Paniconi640885d2014-02-11 08:48:34 -080081 // Update the number of frame drops.
82 num_drops_ += static_cast<int>(duration - 1);
83 // Update counter for total number of frames (#frames input to encoder).
84 // Needed for setting the proper layer_id below.
85 tot_frame_number_ += static_cast<int>(duration - 1);
86 }
87
Marco Paniconi1b8b8b02013-12-17 15:45:30 -080088 // Add to the buffer the bits we'd expect from a constant bitrate server.
James Zerncac85f82013-12-18 16:58:43 -080089 bits_in_buffer_model_ += static_cast<int64_t>(
90 duration * timebase_ * cfg_.rc_target_bitrate * 1000);
Marco Paniconi1b8b8b02013-12-17 15:45:30 -080091
92 // Buffer should not go negative.
clang-format4eafefe2017-09-04 12:51:20 -070093 ASSERT_GE(bits_in_buffer_model_, 0)
94 << "Buffer Underrun at frame " << pkt->data.frame.pts;
Marco Paniconi1b8b8b02013-12-17 15:45:30 -080095
James Zerncac85f82013-12-18 16:58:43 -080096 const size_t frame_size_in_bits = pkt->data.frame.sz * 8;
Marco Paniconi4864ab22014-02-06 09:23:17 -080097
James Zerncc73e1f2016-08-08 15:09:30 -070098 // Update the total encoded bits.
99 bits_total_ += frame_size_in_bits;
Marco Paniconi1b8b8b02013-12-17 15:45:30 -0800100
Marco Paniconie078c3d2013-10-02 17:13:59 -0700101 // Update the most recent pts.
102 last_pts_ = pkt->data.frame.pts;
103 ++frame_number_;
Marco Paniconi640885d2014-02-11 08:48:34 -0800104 ++tot_frame_number_;
Marco Paniconie078c3d2013-10-02 17:13:59 -0700105 }
106
107 virtual void EndPassHook(void) {
James Zerncc73e1f2016-08-08 15:09:30 -0700108 duration_ = (last_pts_ + 1) * timebase_;
109 // Effective file datarate:
110 effective_datarate_ = (bits_total_ / 1000.0) / duration_;
Marco Paniconie078c3d2013-10-02 17:13:59 -0700111 }
Marco Paniconib26ce8b2013-10-22 11:30:06 -0700112
Yaowu Xuf883b422016-08-30 14:01:10 -0700113 aom_codec_pts_t last_pts_;
Marco Paniconib26ce8b2013-10-22 11:30:06 -0700114 double timebase_;
Marco Paniconi640885d2014-02-11 08:48:34 -0800115 int frame_number_; // Counter for number of non-dropped/encoded frames.
116 int tot_frame_number_; // Counter for total number of input frames.
James Zerncc73e1f2016-08-08 15:09:30 -0700117 int64_t bits_total_;
Marco Paniconib26ce8b2013-10-22 11:30:06 -0700118 double duration_;
James Zerncc73e1f2016-08-08 15:09:30 -0700119 double effective_datarate_;
Marco Paniconib26ce8b2013-10-22 11:30:06 -0700120 int set_cpu_used_;
James Zerncac85f82013-12-18 16:58:43 -0800121 int64_t bits_in_buffer_model_;
Yaowu Xuf883b422016-08-30 14:01:10 -0700122 aom_codec_pts_t first_drop_;
Marco Paniconi1b8b8b02013-12-17 15:45:30 -0800123 int num_drops_;
JackyChena86e6e82014-09-17 13:54:48 -0700124 int denoiser_on_;
JackyChene82a3b22015-01-07 16:34:25 -0800125 int denoiser_offon_test_;
126 int denoiser_offon_period_;
Marco Paniconie078c3d2013-10-02 17:13:59 -0700127};
128
Marco75d55172016-05-25 14:19:01 -0700129// Check basic rate targeting for VBR mode.
James Zerncc73e1f2016-08-08 15:09:30 -0700130TEST_P(DatarateTestLarge, BasicRateTargetingVBR) {
Marco75d55172016-05-25 14:19:01 -0700131 cfg_.rc_min_quantizer = 0;
132 cfg_.rc_max_quantizer = 63;
133 cfg_.g_error_resilient = 0;
Yaowu Xuf883b422016-08-30 14:01:10 -0700134 cfg_.rc_end_usage = AOM_VBR;
Marco75d55172016-05-25 14:19:01 -0700135 cfg_.g_lag_in_frames = 0;
136
Yaowu Xuc27fc142016-08-22 16:08:15 -0700137 ::libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
Yaowu Xu049c64c2016-12-27 09:26:30 -0800138 30, 1, 0, 140);
Marco75d55172016-05-25 14:19:01 -0700139 for (int i = 400; i <= 800; i += 400) {
140 cfg_.rc_target_bitrate = i;
141 ResetModel();
142 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
James Zerncc73e1f2016-08-08 15:09:30 -0700143 ASSERT_GE(effective_datarate_, cfg_.rc_target_bitrate * 0.75)
Marco75d55172016-05-25 14:19:01 -0700144 << " The datarate for the file is lower than target by too much!";
James Zerncc73e1f2016-08-08 15:09:30 -0700145 ASSERT_LE(effective_datarate_, cfg_.rc_target_bitrate * 1.25)
Marco75d55172016-05-25 14:19:01 -0700146 << " The datarate for the file is greater than target by too much!";
147 }
148}
149
150// Check basic rate targeting for CBR,
James Zerncc73e1f2016-08-08 15:09:30 -0700151TEST_P(DatarateTestLarge, BasicRateTargeting) {
Marco Paniconi1b8b8b02013-12-17 15:45:30 -0800152 cfg_.rc_buf_initial_sz = 500;
153 cfg_.rc_buf_optimal_sz = 500;
154 cfg_.rc_buf_sz = 1000;
155 cfg_.rc_dropframe_thresh = 1;
Marco Paniconie078c3d2013-10-02 17:13:59 -0700156 cfg_.rc_min_quantizer = 0;
157 cfg_.rc_max_quantizer = 63;
Yaowu Xuf883b422016-08-30 14:01:10 -0700158 cfg_.rc_end_usage = AOM_CBR;
Marco Paniconi4864ab22014-02-06 09:23:17 -0800159 cfg_.g_lag_in_frames = 0;
Marco Paniconie078c3d2013-10-02 17:13:59 -0700160
Yaowu Xuc27fc142016-08-22 16:08:15 -0700161 ::libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
Marco Paniconie078c3d2013-10-02 17:13:59 -0700162 30, 1, 0, 140);
Yaowu Xu049c64c2016-12-27 09:26:30 -0800163 for (int i = 150; i < 800; i += 400) {
Marco Paniconie078c3d2013-10-02 17:13:59 -0700164 cfg_.rc_target_bitrate = i;
165 ResetModel();
166 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
James Zerncc73e1f2016-08-08 15:09:30 -0700167 ASSERT_GE(effective_datarate_, cfg_.rc_target_bitrate * 0.85)
Marco Paniconi4864ab22014-02-06 09:23:17 -0800168 << " The datarate for the file is lower than target by too much!";
James Zerncc73e1f2016-08-08 15:09:30 -0700169 ASSERT_LE(effective_datarate_, cfg_.rc_target_bitrate * 1.15)
Marco Paniconi4864ab22014-02-06 09:23:17 -0800170 << " The datarate for the file is greater than target by too much!";
Marco Paniconie078c3d2013-10-02 17:13:59 -0700171 }
172}
173
Marco75d55172016-05-25 14:19:01 -0700174// Check basic rate targeting for CBR.
James Zerncc73e1f2016-08-08 15:09:30 -0700175TEST_P(DatarateTestLarge, BasicRateTargeting444) {
Yaowu Xuc27fc142016-08-22 16:08:15 -0700176 ::libaom_test::Y4mVideoSource video("rush_hour_444.y4m", 0, 140);
Alex Conversef5949fa2014-01-17 13:52:23 -0800177
178 cfg_.g_profile = 1;
179 cfg_.g_timebase = video.timebase();
180
181 cfg_.rc_buf_initial_sz = 500;
182 cfg_.rc_buf_optimal_sz = 500;
183 cfg_.rc_buf_sz = 1000;
184 cfg_.rc_dropframe_thresh = 1;
185 cfg_.rc_min_quantizer = 0;
186 cfg_.rc_max_quantizer = 63;
Yaowu Xuf883b422016-08-30 14:01:10 -0700187 cfg_.rc_end_usage = AOM_CBR;
Alex Conversef5949fa2014-01-17 13:52:23 -0800188
Yaowu Xu049c64c2016-12-27 09:26:30 -0800189 for (int i = 250; i < 900; i += 400) {
Alex Conversef5949fa2014-01-17 13:52:23 -0800190 cfg_.rc_target_bitrate = i;
191 ResetModel();
192 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
193 ASSERT_GE(static_cast<double>(cfg_.rc_target_bitrate),
James Zerncc73e1f2016-08-08 15:09:30 -0700194 effective_datarate_ * 0.85)
Alex Conversef5949fa2014-01-17 13:52:23 -0800195 << " The datarate for the file exceeds the target by too much!";
196 ASSERT_LE(static_cast<double>(cfg_.rc_target_bitrate),
James Zerncc73e1f2016-08-08 15:09:30 -0700197 effective_datarate_ * 1.15)
Alex Conversef5949fa2014-01-17 13:52:23 -0800198 << " The datarate for the file missed the target!"
clang-format3a826f12016-08-11 17:46:05 -0700199 << cfg_.rc_target_bitrate << " " << effective_datarate_;
Alex Conversef5949fa2014-01-17 13:52:23 -0800200 }
201}
Alex Conversef5949fa2014-01-17 13:52:23 -0800202
Marco Paniconi1b8b8b02013-12-17 15:45:30 -0800203// Check that (1) the first dropped frame gets earlier and earlier
204// as the drop frame threshold is increased, and (2) that the total number of
205// frame drops does not decrease as we increase frame drop threshold.
206// Use a lower qp-max to force some frame drops.
James Zerncc73e1f2016-08-08 15:09:30 -0700207TEST_P(DatarateTestLarge, ChangingDropFrameThresh) {
Marco Paniconi1b8b8b02013-12-17 15:45:30 -0800208 cfg_.rc_buf_initial_sz = 500;
209 cfg_.rc_buf_optimal_sz = 500;
210 cfg_.rc_buf_sz = 1000;
211 cfg_.rc_undershoot_pct = 20;
212 cfg_.rc_undershoot_pct = 20;
213 cfg_.rc_dropframe_thresh = 10;
214 cfg_.rc_min_quantizer = 0;
215 cfg_.rc_max_quantizer = 50;
Yaowu Xuf883b422016-08-30 14:01:10 -0700216 cfg_.rc_end_usage = AOM_CBR;
Marco Paniconi1b8b8b02013-12-17 15:45:30 -0800217 cfg_.rc_target_bitrate = 200;
Marco Paniconi4864ab22014-02-06 09:23:17 -0800218 cfg_.g_lag_in_frames = 0;
Jingning Hanfb04a9a2018-02-20 10:19:22 -0800219 cfg_.g_error_resilient = 1;
James Zern4b00f0e2016-02-26 15:14:46 -0800220 // TODO(marpan): Investigate datarate target failures with a smaller keyframe
221 // interval (128).
222 cfg_.kf_max_dist = 9999;
Marco Paniconi1b8b8b02013-12-17 15:45:30 -0800223
Yaowu Xuc27fc142016-08-22 16:08:15 -0700224 ::libaom_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
Yaowu Xu049c64c2016-12-27 09:26:30 -0800225 30, 1, 0, 100);
Marco Paniconi1b8b8b02013-12-17 15:45:30 -0800226
227 const int kDropFrameThreshTestStep = 30;
Yaowu Xuf883b422016-08-30 14:01:10 -0700228 aom_codec_pts_t last_drop = 140;
Marco Paniconi1b8b8b02013-12-17 15:45:30 -0800229 int last_num_drops = 0;
Yaowu Xu049c64c2016-12-27 09:26:30 -0800230 for (int i = 40; i < 100; i += kDropFrameThreshTestStep) {
Marco Paniconi1b8b8b02013-12-17 15:45:30 -0800231 cfg_.rc_dropframe_thresh = i;
232 ResetModel();
233 ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
James Zerncc73e1f2016-08-08 15:09:30 -0700234 ASSERT_GE(effective_datarate_, cfg_.rc_target_bitrate * 0.85)
Marco Paniconi4864ab22014-02-06 09:23:17 -0800235 << " The datarate for the file is lower than target by too much!";
James Zerncc73e1f2016-08-08 15:09:30 -0700236 ASSERT_LE(effective_datarate_, cfg_.rc_target_bitrate * 1.15)
Marco Paniconi4864ab22014-02-06 09:23:17 -0800237 << " The datarate for the file is greater than target by too much!";
Marco Paniconi1b8b8b02013-12-17 15:45:30 -0800238 ASSERT_LE(first_drop_, last_drop)
239 << " The first dropped frame for drop_thresh " << i
240 << " > first dropped frame for drop_thresh "
241 << i - kDropFrameThreshTestStep;
Marcocb7b2a42015-11-03 08:15:04 -0800242 ASSERT_GE(num_drops_, last_num_drops * 0.85)
Marco Paniconi1b8b8b02013-12-17 15:45:30 -0800243 << " The number of dropped frames for drop_thresh " << i
244 << " < number of dropped frames for drop_thresh "
245 << i - kDropFrameThreshTestStep;
246 last_drop = first_drop_;
247 last_num_drops = num_drops_;
248 }
249}
250
Yaowu Xuf883b422016-08-30 14:01:10 -0700251AV1_INSTANTIATE_TEST_CASE(DatarateTestLarge,
252 ::testing::Values(::libaom_test::kOnePassGood,
253 ::libaom_test::kRealTime),
Yaowu Xu446d0372017-05-09 08:37:51 -0700254 ::testing::Values(2, 5));
Jim Bankoski533470c2012-10-29 19:54:06 -0700255} // namespace