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