xref: /aosp_15_r20/external/libaom/test/datarate_test.h (revision 77c1e3ccc04c968bd2bc212e87364f250e820521)
1*77c1e3ccSAndroid Build Coastguard Worker /*
2*77c1e3ccSAndroid Build Coastguard Worker  * Copyright (c) 2019, Alliance for Open Media. All rights reserved.
3*77c1e3ccSAndroid Build Coastguard Worker  *
4*77c1e3ccSAndroid Build Coastguard Worker  * This source code is subject to the terms of the BSD 2 Clause License and
5*77c1e3ccSAndroid Build Coastguard Worker  * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6*77c1e3ccSAndroid Build Coastguard Worker  * was not distributed with this source code in the LICENSE file, you can
7*77c1e3ccSAndroid Build Coastguard Worker  * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8*77c1e3ccSAndroid Build Coastguard Worker  * Media Patent License 1.0 was not distributed with this source code in the
9*77c1e3ccSAndroid Build Coastguard Worker  * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
10*77c1e3ccSAndroid Build Coastguard Worker  */
11*77c1e3ccSAndroid Build Coastguard Worker 
12*77c1e3ccSAndroid Build Coastguard Worker #include "config/aom_config.h"
13*77c1e3ccSAndroid Build Coastguard Worker 
14*77c1e3ccSAndroid Build Coastguard Worker #include "gtest/gtest.h"
15*77c1e3ccSAndroid Build Coastguard Worker #include "test/codec_factory.h"
16*77c1e3ccSAndroid Build Coastguard Worker #include "test/encode_test_driver.h"
17*77c1e3ccSAndroid Build Coastguard Worker #include "test/i420_video_source.h"
18*77c1e3ccSAndroid Build Coastguard Worker #include "test/util.h"
19*77c1e3ccSAndroid Build Coastguard Worker #include "test/y4m_video_source.h"
20*77c1e3ccSAndroid Build Coastguard Worker #include "aom/aom_codec.h"
21*77c1e3ccSAndroid Build Coastguard Worker 
22*77c1e3ccSAndroid Build Coastguard Worker namespace datarate_test {
23*77c1e3ccSAndroid Build Coastguard Worker namespace {
24*77c1e3ccSAndroid Build Coastguard Worker class DatarateTest : public ::libaom_test::EncoderTest {
25*77c1e3ccSAndroid Build Coastguard Worker  public:
DatarateTest(const::libaom_test::CodecFactory * codec)26*77c1e3ccSAndroid Build Coastguard Worker   explicit DatarateTest(const ::libaom_test::CodecFactory *codec)
27*77c1e3ccSAndroid Build Coastguard Worker       : EncoderTest(codec), set_cpu_used_(0), aq_mode_(0),
28*77c1e3ccSAndroid Build Coastguard Worker         speed_change_test_(false) {}
29*77c1e3ccSAndroid Build Coastguard Worker 
30*77c1e3ccSAndroid Build Coastguard Worker  protected:
31*77c1e3ccSAndroid Build Coastguard Worker   ~DatarateTest() override = default;
32*77c1e3ccSAndroid Build Coastguard Worker 
ResetModel()33*77c1e3ccSAndroid Build Coastguard Worker   virtual void ResetModel() {
34*77c1e3ccSAndroid Build Coastguard Worker     last_pts_ = 0;
35*77c1e3ccSAndroid Build Coastguard Worker     bits_in_buffer_model_ = cfg_.rc_target_bitrate * cfg_.rc_buf_initial_sz;
36*77c1e3ccSAndroid Build Coastguard Worker     frame_number_ = 0;
37*77c1e3ccSAndroid Build Coastguard Worker     tot_frame_number_ = 0;
38*77c1e3ccSAndroid Build Coastguard Worker     first_drop_ = 0;
39*77c1e3ccSAndroid Build Coastguard Worker     num_drops_ = 0;
40*77c1e3ccSAndroid Build Coastguard Worker     // Denoiser is off by default.
41*77c1e3ccSAndroid Build Coastguard Worker     denoiser_on_ = 0;
42*77c1e3ccSAndroid Build Coastguard Worker     bits_total_ = 0;
43*77c1e3ccSAndroid Build Coastguard Worker     denoiser_offon_test_ = 0;
44*77c1e3ccSAndroid Build Coastguard Worker     denoiser_offon_period_ = -1;
45*77c1e3ccSAndroid Build Coastguard Worker     tile_columns_ = 0;
46*77c1e3ccSAndroid Build Coastguard Worker     tile_rows_ = 0;
47*77c1e3ccSAndroid Build Coastguard Worker     auto_tiles_ = false;
48*77c1e3ccSAndroid Build Coastguard Worker     screen_mode_ = false;
49*77c1e3ccSAndroid Build Coastguard Worker     max_perc_spike_ = 1.0;
50*77c1e3ccSAndroid Build Coastguard Worker     max_perc_spike_high_ = 1.0;
51*77c1e3ccSAndroid Build Coastguard Worker     num_spikes_ = 0;
52*77c1e3ccSAndroid Build Coastguard Worker     num_spikes_high_ = 0;
53*77c1e3ccSAndroid Build Coastguard Worker     frame_update_bitrate_ = 0;
54*77c1e3ccSAndroid Build Coastguard Worker     for (int i = 0; i < 3; i++) {
55*77c1e3ccSAndroid Build Coastguard Worker       target_bitrate_update_[i] = 0;
56*77c1e3ccSAndroid Build Coastguard Worker       frame_number_dynamic_[i] = 0;
57*77c1e3ccSAndroid Build Coastguard Worker       bits_total_dynamic_[i] = 0;
58*77c1e3ccSAndroid Build Coastguard Worker       effective_datarate_dynamic_[i] = 0.0;
59*77c1e3ccSAndroid Build Coastguard Worker     }
60*77c1e3ccSAndroid Build Coastguard Worker   }
61*77c1e3ccSAndroid Build Coastguard Worker 
PreEncodeFrameHook(::libaom_test::VideoSource * video,::libaom_test::Encoder * encoder)62*77c1e3ccSAndroid Build Coastguard Worker   void PreEncodeFrameHook(::libaom_test::VideoSource *video,
63*77c1e3ccSAndroid Build Coastguard Worker                           ::libaom_test::Encoder *encoder) override {
64*77c1e3ccSAndroid Build Coastguard Worker     if (video->frame() == 0) {
65*77c1e3ccSAndroid Build Coastguard Worker       encoder->Control(AOME_SET_CPUUSED, set_cpu_used_);
66*77c1e3ccSAndroid Build Coastguard Worker       encoder->Control(AV1E_SET_AQ_MODE, aq_mode_);
67*77c1e3ccSAndroid Build Coastguard Worker       if (auto_tiles_) {
68*77c1e3ccSAndroid Build Coastguard Worker         encoder->Control(AV1E_SET_AUTO_TILES, 1);
69*77c1e3ccSAndroid Build Coastguard Worker       } else {
70*77c1e3ccSAndroid Build Coastguard Worker         encoder->Control(AV1E_SET_TILE_COLUMNS, tile_columns_);
71*77c1e3ccSAndroid Build Coastguard Worker         encoder->Control(AV1E_SET_TILE_ROWS, tile_rows_);
72*77c1e3ccSAndroid Build Coastguard Worker       }
73*77c1e3ccSAndroid Build Coastguard Worker       encoder->Control(AV1E_SET_ROW_MT, 1);
74*77c1e3ccSAndroid Build Coastguard Worker       if (cfg_.g_usage == AOM_USAGE_REALTIME) {
75*77c1e3ccSAndroid Build Coastguard Worker         encoder->Control(AV1E_SET_ENABLE_GLOBAL_MOTION, 0);
76*77c1e3ccSAndroid Build Coastguard Worker         encoder->Control(AV1E_SET_ENABLE_WARPED_MOTION, 0);
77*77c1e3ccSAndroid Build Coastguard Worker         encoder->Control(AV1E_SET_ENABLE_RESTORATION, 0);
78*77c1e3ccSAndroid Build Coastguard Worker         encoder->Control(AV1E_SET_ENABLE_OBMC, 0);
79*77c1e3ccSAndroid Build Coastguard Worker         encoder->Control(AV1E_SET_DELTAQ_MODE, 0);
80*77c1e3ccSAndroid Build Coastguard Worker         encoder->Control(AV1E_SET_ENABLE_TPL_MODEL, 0);
81*77c1e3ccSAndroid Build Coastguard Worker         encoder->Control(AV1E_SET_ENABLE_CDEF, 1);
82*77c1e3ccSAndroid Build Coastguard Worker         encoder->Control(AV1E_SET_COEFF_COST_UPD_FREQ, 2);
83*77c1e3ccSAndroid Build Coastguard Worker         encoder->Control(AV1E_SET_MODE_COST_UPD_FREQ, 2);
84*77c1e3ccSAndroid Build Coastguard Worker         encoder->Control(AV1E_SET_MV_COST_UPD_FREQ, 2);
85*77c1e3ccSAndroid Build Coastguard Worker         encoder->Control(AV1E_SET_DV_COST_UPD_FREQ, 2);
86*77c1e3ccSAndroid Build Coastguard Worker         encoder->Control(AV1E_SET_POSTENCODE_DROP_RTC, 1);
87*77c1e3ccSAndroid Build Coastguard Worker       }
88*77c1e3ccSAndroid Build Coastguard Worker       if (screen_mode_) {
89*77c1e3ccSAndroid Build Coastguard Worker         encoder->Control(AV1E_SET_TUNE_CONTENT, AOM_CONTENT_SCREEN);
90*77c1e3ccSAndroid Build Coastguard Worker         encoder->Control(AV1E_SET_ENABLE_PALETTE, 1);
91*77c1e3ccSAndroid Build Coastguard Worker         encoder->Control(AV1E_SET_ENABLE_INTRABC, 0);
92*77c1e3ccSAndroid Build Coastguard Worker       }
93*77c1e3ccSAndroid Build Coastguard Worker     }
94*77c1e3ccSAndroid Build Coastguard Worker 
95*77c1e3ccSAndroid Build Coastguard Worker     if (speed_change_test_) {
96*77c1e3ccSAndroid Build Coastguard Worker       if (video->frame() == 0) {
97*77c1e3ccSAndroid Build Coastguard Worker         encoder->Control(AOME_SET_CPUUSED, 8);
98*77c1e3ccSAndroid Build Coastguard Worker       } else if (video->frame() == 30) {
99*77c1e3ccSAndroid Build Coastguard Worker         encoder->Control(AOME_SET_CPUUSED, 7);
100*77c1e3ccSAndroid Build Coastguard Worker       } else if (video->frame() == 60) {
101*77c1e3ccSAndroid Build Coastguard Worker         encoder->Control(AOME_SET_CPUUSED, 6);
102*77c1e3ccSAndroid Build Coastguard Worker       } else if (video->frame() == 90) {
103*77c1e3ccSAndroid Build Coastguard Worker         encoder->Control(AOME_SET_CPUUSED, 7);
104*77c1e3ccSAndroid Build Coastguard Worker       }
105*77c1e3ccSAndroid Build Coastguard Worker     }
106*77c1e3ccSAndroid Build Coastguard Worker 
107*77c1e3ccSAndroid Build Coastguard Worker     if (frame_update_bitrate_ > 0) {
108*77c1e3ccSAndroid Build Coastguard Worker       if (frame_number_ == frame_update_bitrate_) {
109*77c1e3ccSAndroid Build Coastguard Worker         cfg_.rc_target_bitrate = target_bitrate_update_[1];
110*77c1e3ccSAndroid Build Coastguard Worker         encoder->Config(&cfg_);
111*77c1e3ccSAndroid Build Coastguard Worker       } else if (frame_number_ == 2 * frame_update_bitrate_) {
112*77c1e3ccSAndroid Build Coastguard Worker         cfg_.rc_target_bitrate = target_bitrate_update_[2];
113*77c1e3ccSAndroid Build Coastguard Worker         encoder->Config(&cfg_);
114*77c1e3ccSAndroid Build Coastguard Worker       }
115*77c1e3ccSAndroid Build Coastguard Worker     }
116*77c1e3ccSAndroid Build Coastguard Worker 
117*77c1e3ccSAndroid Build Coastguard Worker     if (denoiser_offon_test_) {
118*77c1e3ccSAndroid Build Coastguard Worker       ASSERT_GT(denoiser_offon_period_, 0)
119*77c1e3ccSAndroid Build Coastguard Worker           << "denoiser_offon_period_ is not positive.";
120*77c1e3ccSAndroid Build Coastguard Worker       if ((video->frame() + 1) % denoiser_offon_period_ == 0) {
121*77c1e3ccSAndroid Build Coastguard Worker         // Flip denoiser_on_ periodically
122*77c1e3ccSAndroid Build Coastguard Worker         denoiser_on_ ^= 1;
123*77c1e3ccSAndroid Build Coastguard Worker       }
124*77c1e3ccSAndroid Build Coastguard Worker     }
125*77c1e3ccSAndroid Build Coastguard Worker 
126*77c1e3ccSAndroid Build Coastguard Worker     encoder->Control(AV1E_SET_NOISE_SENSITIVITY, denoiser_on_);
127*77c1e3ccSAndroid Build Coastguard Worker 
128*77c1e3ccSAndroid Build Coastguard Worker     const aom_rational_t tb = video->timebase();
129*77c1e3ccSAndroid Build Coastguard Worker     timebase_ = static_cast<double>(tb.num) / tb.den;
130*77c1e3ccSAndroid Build Coastguard Worker     duration_ = 0;
131*77c1e3ccSAndroid Build Coastguard Worker   }
132*77c1e3ccSAndroid Build Coastguard Worker 
FramePktHook(const aom_codec_cx_pkt_t * pkt)133*77c1e3ccSAndroid Build Coastguard Worker   void FramePktHook(const aom_codec_cx_pkt_t *pkt) override {
134*77c1e3ccSAndroid Build Coastguard Worker     // Time since last timestamp = duration.
135*77c1e3ccSAndroid Build Coastguard Worker     aom_codec_pts_t duration = pkt->data.frame.pts - last_pts_;
136*77c1e3ccSAndroid Build Coastguard Worker 
137*77c1e3ccSAndroid Build Coastguard Worker     if (duration > 1) {
138*77c1e3ccSAndroid Build Coastguard Worker       // If first drop not set and we have a drop set it to this time.
139*77c1e3ccSAndroid Build Coastguard Worker       if (!first_drop_) first_drop_ = last_pts_ + 1;
140*77c1e3ccSAndroid Build Coastguard Worker       // Update the number of frame drops.
141*77c1e3ccSAndroid Build Coastguard Worker       num_drops_ += static_cast<int>(duration - 1);
142*77c1e3ccSAndroid Build Coastguard Worker       // Update counter for total number of frames (#frames input to encoder).
143*77c1e3ccSAndroid Build Coastguard Worker       // Needed for setting the proper layer_id below.
144*77c1e3ccSAndroid Build Coastguard Worker       tot_frame_number_ += static_cast<int>(duration - 1);
145*77c1e3ccSAndroid Build Coastguard Worker     }
146*77c1e3ccSAndroid Build Coastguard Worker 
147*77c1e3ccSAndroid Build Coastguard Worker     // Add to the buffer the bits we'd expect from a constant bitrate server.
148*77c1e3ccSAndroid Build Coastguard Worker     bits_in_buffer_model_ += static_cast<int64_t>(
149*77c1e3ccSAndroid Build Coastguard Worker         duration * timebase_ * cfg_.rc_target_bitrate * 1000);
150*77c1e3ccSAndroid Build Coastguard Worker 
151*77c1e3ccSAndroid Build Coastguard Worker     // Buffer should not go negative.
152*77c1e3ccSAndroid Build Coastguard Worker     ASSERT_GE(bits_in_buffer_model_, 0)
153*77c1e3ccSAndroid Build Coastguard Worker         << "Buffer Underrun at frame " << pkt->data.frame.pts;
154*77c1e3ccSAndroid Build Coastguard Worker 
155*77c1e3ccSAndroid Build Coastguard Worker     const size_t frame_size_in_bits = pkt->data.frame.sz * 8;
156*77c1e3ccSAndroid Build Coastguard Worker 
157*77c1e3ccSAndroid Build Coastguard Worker     // Update the total encoded bits.
158*77c1e3ccSAndroid Build Coastguard Worker     bits_total_ += frame_size_in_bits;
159*77c1e3ccSAndroid Build Coastguard Worker 
160*77c1e3ccSAndroid Build Coastguard Worker     // Update the most recent pts.
161*77c1e3ccSAndroid Build Coastguard Worker     last_pts_ = pkt->data.frame.pts;
162*77c1e3ccSAndroid Build Coastguard Worker     ++frame_number_;
163*77c1e3ccSAndroid Build Coastguard Worker     ++tot_frame_number_;
164*77c1e3ccSAndroid Build Coastguard Worker     const int per_frame_bandwidth = (cfg_.rc_target_bitrate * 1000) / 30;
165*77c1e3ccSAndroid Build Coastguard Worker     if (frame_size_in_bits > max_perc_spike_ * per_frame_bandwidth &&
166*77c1e3ccSAndroid Build Coastguard Worker         frame_number_ > 1)
167*77c1e3ccSAndroid Build Coastguard Worker       num_spikes_++;
168*77c1e3ccSAndroid Build Coastguard Worker     if (frame_size_in_bits > max_perc_spike_high_ * per_frame_bandwidth &&
169*77c1e3ccSAndroid Build Coastguard Worker         frame_number_ > 1)
170*77c1e3ccSAndroid Build Coastguard Worker       num_spikes_high_++;
171*77c1e3ccSAndroid Build Coastguard Worker 
172*77c1e3ccSAndroid Build Coastguard Worker     if (frame_update_bitrate_ > 0) {
173*77c1e3ccSAndroid Build Coastguard Worker       if (frame_number_ < frame_update_bitrate_) {
174*77c1e3ccSAndroid Build Coastguard Worker         bits_total_dynamic_[0] += frame_size_in_bits;
175*77c1e3ccSAndroid Build Coastguard Worker         frame_number_dynamic_[0]++;
176*77c1e3ccSAndroid Build Coastguard Worker       } else if (frame_number_ >= frame_update_bitrate_ &&
177*77c1e3ccSAndroid Build Coastguard Worker                  frame_number_ < 2 * frame_update_bitrate_) {
178*77c1e3ccSAndroid Build Coastguard Worker         bits_total_dynamic_[1] += frame_size_in_bits;
179*77c1e3ccSAndroid Build Coastguard Worker         frame_number_dynamic_[1]++;
180*77c1e3ccSAndroid Build Coastguard Worker       } else {
181*77c1e3ccSAndroid Build Coastguard Worker         bits_total_dynamic_[2] += frame_size_in_bits;
182*77c1e3ccSAndroid Build Coastguard Worker         frame_number_dynamic_[2]++;
183*77c1e3ccSAndroid Build Coastguard Worker       }
184*77c1e3ccSAndroid Build Coastguard Worker     }
185*77c1e3ccSAndroid Build Coastguard Worker   }
186*77c1e3ccSAndroid Build Coastguard Worker 
EndPassHook()187*77c1e3ccSAndroid Build Coastguard Worker   void EndPassHook() override {
188*77c1e3ccSAndroid Build Coastguard Worker     duration_ = (last_pts_ + 1) * timebase_;
189*77c1e3ccSAndroid Build Coastguard Worker     // Effective file datarate:
190*77c1e3ccSAndroid Build Coastguard Worker     effective_datarate_ = (bits_total_ / 1000.0) / duration_;
191*77c1e3ccSAndroid Build Coastguard Worker     if (frame_update_bitrate_ > 0) {
192*77c1e3ccSAndroid Build Coastguard Worker       for (int i = 0; i < 3; i++)
193*77c1e3ccSAndroid Build Coastguard Worker         effective_datarate_dynamic_[i] =
194*77c1e3ccSAndroid Build Coastguard Worker             30 * (bits_total_dynamic_[i] / 1000.0) / frame_number_dynamic_[i];
195*77c1e3ccSAndroid Build Coastguard Worker     }
196*77c1e3ccSAndroid Build Coastguard Worker   }
197*77c1e3ccSAndroid Build Coastguard Worker 
198*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_pts_t last_pts_;
199*77c1e3ccSAndroid Build Coastguard Worker   double timebase_;
200*77c1e3ccSAndroid Build Coastguard Worker   int frame_number_;      // Counter for number of non-dropped/encoded frames.
201*77c1e3ccSAndroid Build Coastguard Worker   int tot_frame_number_;  // Counter for total number of input frames.
202*77c1e3ccSAndroid Build Coastguard Worker   int64_t bits_total_;
203*77c1e3ccSAndroid Build Coastguard Worker   double duration_;
204*77c1e3ccSAndroid Build Coastguard Worker   double effective_datarate_;
205*77c1e3ccSAndroid Build Coastguard Worker   int set_cpu_used_;
206*77c1e3ccSAndroid Build Coastguard Worker   int64_t bits_in_buffer_model_;
207*77c1e3ccSAndroid Build Coastguard Worker   aom_codec_pts_t first_drop_;
208*77c1e3ccSAndroid Build Coastguard Worker   int num_drops_;
209*77c1e3ccSAndroid Build Coastguard Worker   int denoiser_on_;
210*77c1e3ccSAndroid Build Coastguard Worker   int denoiser_offon_test_;
211*77c1e3ccSAndroid Build Coastguard Worker   int denoiser_offon_period_;
212*77c1e3ccSAndroid Build Coastguard Worker   unsigned int aq_mode_;
213*77c1e3ccSAndroid Build Coastguard Worker   bool speed_change_test_;
214*77c1e3ccSAndroid Build Coastguard Worker   int tile_columns_;
215*77c1e3ccSAndroid Build Coastguard Worker   int tile_rows_;
216*77c1e3ccSAndroid Build Coastguard Worker   bool auto_tiles_;
217*77c1e3ccSAndroid Build Coastguard Worker   bool screen_mode_;
218*77c1e3ccSAndroid Build Coastguard Worker   double max_perc_spike_;
219*77c1e3ccSAndroid Build Coastguard Worker   double max_perc_spike_high_;
220*77c1e3ccSAndroid Build Coastguard Worker   int num_spikes_;
221*77c1e3ccSAndroid Build Coastguard Worker   int num_spikes_high_;
222*77c1e3ccSAndroid Build Coastguard Worker   // These are use for test with dynamic bitrate change.
223*77c1e3ccSAndroid Build Coastguard Worker   // Used to verify that the encoder can respond and hit bitrate that is updated
224*77c1e3ccSAndroid Build Coastguard Worker   // during the sequence.
225*77c1e3ccSAndroid Build Coastguard Worker   int frame_update_bitrate_;
226*77c1e3ccSAndroid Build Coastguard Worker   int target_bitrate_update_[3];
227*77c1e3ccSAndroid Build Coastguard Worker   double effective_datarate_dynamic_[3];
228*77c1e3ccSAndroid Build Coastguard Worker   int64_t bits_total_dynamic_[3];
229*77c1e3ccSAndroid Build Coastguard Worker   int frame_number_dynamic_[3];
230*77c1e3ccSAndroid Build Coastguard Worker };
231*77c1e3ccSAndroid Build Coastguard Worker 
232*77c1e3ccSAndroid Build Coastguard Worker }  // namespace
233*77c1e3ccSAndroid Build Coastguard Worker }  // namespace datarate_test
234