]> granicus.if.org Git - libvpx/blob - test/ratectrl_rtc_test.cc
Add file for rate control interface test.
[libvpx] / test / ratectrl_rtc_test.cc
1 /*
2  *  Copyright (c) 2020 The WebM project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 #include "vp9/ratectrl_rtc.h"
11
12 #include <fstream>  // NOLINT
13 #include <string>
14
15 #include "./vpx_config.h"
16 #include "third_party/googletest/src/include/gtest/gtest.h"
17 #include "test/codec_factory.h"
18 #include "test/encode_test_driver.h"
19 #include "test/util.h"
20 #include "test/video_source.h"
21 #include "vpx/vpx_codec.h"
22 #include "vpx_ports/bitops.h"
23
24 namespace {
25
26 const size_t kNumFrame = 850;
27
28 struct FrameInfo {
29   friend std::istream &operator>>(std::istream &is, FrameInfo &info) {
30     is >> info.frame_id >> info.spatial_id >> info.temporal_id >> info.base_q >>
31         info.target_bandwidth >> info.buffer_level >> info.filter_level_ >>
32         info.bytes_used;
33     return is;
34   }
35   int frame_id;
36   int spatial_id;
37   int temporal_id;
38   // Base QP
39   int base_q;
40   size_t target_bandwidth;
41   size_t buffer_level;
42   // Loopfilter level
43   int filter_level_;
44   // Frame size for current frame, used for pose encode update
45   size_t bytes_used;
46 };
47
48 // This test runs the rate control interface and compare against ground truth
49 // generated by encoders.
50 // Settings for the encoder:
51 // For 1 layer:
52 //
53 // examples/vpx_temporal_svc_encoder gipsrec_motion1.1280_720.yuv out vp9
54 //    1280 720 1 30 7 0 0 1 0 1000
55 //
56 // For SVC (3 temporal layers, 3 spatial layers):
57 //
58 // examples/vp9_spatial_svc_encoder -f 10000 -w 1280 -h 720 -t 1/30 -sl 3
59 // -k 10000 -bl 100,140,200,250,350,500,450,630,900 -b 1600 --rc-end-usage=1
60 // --lag-in-frames=0 --passes=1 --speed=7 --threads=1
61 // --temporal-layering-mode=3 -aq 1 -rcstat 1
62 // gipsrec_motion1.1280_720.yuv -o out.webm
63 //
64 // - AQ_Mode 0
65 // - Disable golden refresh
66 // - Bitrate x 2 at frame/superframe 200
67 // - Bitrate / 4 at frame/superframe 400
68 //
69 // The generated file includes:
70 // frame number, spatial layer ID, temporal layer ID, base QP, target
71 // bandwidth, buffer level, loopfilter level, encoded frame size
72 // TODO(jianj): Remove golden files, and run actual encoding in this test.
73 class RcInterfaceTest : public ::testing::Test {
74  public:
75   explicit RcInterfaceTest() {}
76
77   virtual ~RcInterfaceTest() {}
78
79  protected:
80   void RunOneLayer() {
81     SetConfigOneLayer();
82     rc_api_ = libvpx::VP9RateControlRTC::Create(rc_cfg_);
83     FrameInfo frame_info;
84     libvpx::VP9FrameParamsQpRTC frame_params;
85     frame_params.frame_type = KEY_FRAME;
86     frame_params.spatial_layer_id = 0;
87     frame_params.temporal_layer_id = 0;
88     std::ifstream one_layer_file;
89     one_layer_file.open(libvpx_test::GetDataPath() +
90                         "/rc_interface_test_one_layer");
91     ASSERT_EQ(one_layer_file.rdstate() & std::ifstream::failbit, 0);
92     for (size_t i = 0; i < kNumFrame; i++) {
93       one_layer_file >> frame_info;
94       if (frame_info.frame_id > 0) frame_params.frame_type = INTER_FRAME;
95       if (frame_info.frame_id == 200) {
96         rc_cfg_.target_bandwidth = rc_cfg_.target_bandwidth * 2;
97         rc_api_->UpdateRateControl(rc_cfg_);
98       } else if (frame_info.frame_id == 400) {
99         rc_cfg_.target_bandwidth = rc_cfg_.target_bandwidth / 4;
100         rc_api_->UpdateRateControl(rc_cfg_);
101       }
102       ASSERT_EQ(frame_info.spatial_id, 0);
103       ASSERT_EQ(frame_info.temporal_id, 0);
104       rc_api_->ComputeQP(frame_params);
105       ASSERT_EQ(rc_api_->GetQP(), frame_info.base_q);
106       ASSERT_EQ(rc_api_->GetLoopfilterLevel(), frame_info.filter_level_);
107       rc_api_->PostEncodeUpdate(frame_info.bytes_used);
108     }
109   }
110
111   void RunSVC() {
112     SetConfigSVC();
113     rc_api_ = libvpx::VP9RateControlRTC::Create(rc_cfg_);
114     FrameInfo frame_info;
115     libvpx::VP9FrameParamsQpRTC frame_params;
116     frame_params.frame_type = KEY_FRAME;
117     std::ifstream svc_file;
118     svc_file.open(std::string(std::getenv("LIBVPX_TEST_DATA_PATH")) +
119                   "/rc_interface_test_svc");
120     ASSERT_EQ(svc_file.rdstate() & std::ifstream::failbit, 0);
121     for (size_t i = 0; i < kNumFrame * rc_cfg_.ss_number_layers; i++) {
122       svc_file >> frame_info;
123       if (frame_info.frame_id > 0) frame_params.frame_type = INTER_FRAME;
124       if (frame_info.frame_id == 200 * rc_cfg_.ss_number_layers) {
125         for (int layer = 0;
126              layer < rc_cfg_.ss_number_layers * rc_cfg_.ts_number_layers;
127              layer++)
128           rc_cfg_.layer_target_bitrate[layer] *= 2;
129         rc_cfg_.target_bandwidth *= 2;
130         rc_api_->UpdateRateControl(rc_cfg_);
131       } else if (frame_info.frame_id == 400 * rc_cfg_.ss_number_layers) {
132         for (int layer = 0;
133              layer < rc_cfg_.ss_number_layers * rc_cfg_.ts_number_layers;
134              layer++)
135           rc_cfg_.layer_target_bitrate[layer] /= 4;
136         rc_cfg_.target_bandwidth /= 4;
137         rc_api_->UpdateRateControl(rc_cfg_);
138       }
139       frame_params.spatial_layer_id = frame_info.spatial_id;
140       frame_params.temporal_layer_id = frame_info.temporal_id;
141       rc_api_->ComputeQP(frame_params);
142       ASSERT_EQ(rc_api_->GetQP(), frame_info.base_q);
143       ASSERT_EQ(rc_api_->GetLoopfilterLevel(), frame_info.filter_level_);
144       rc_api_->PostEncodeUpdate(frame_info.bytes_used);
145     }
146   }
147
148  private:
149   void SetConfigOneLayer() {
150     rc_cfg_.width = 1280;
151     rc_cfg_.height = 720;
152     rc_cfg_.max_quantizer = 52;
153     rc_cfg_.min_quantizer = 2;
154     rc_cfg_.target_bandwidth = 1000;
155     rc_cfg_.buf_initial_sz = 600;
156     rc_cfg_.buf_optimal_sz = 600;
157     rc_cfg_.buf_sz = 1000;
158     rc_cfg_.undershoot_pct = 50;
159     rc_cfg_.overshoot_pct = 50;
160     rc_cfg_.max_intra_bitrate_pct = 1000;
161     rc_cfg_.framerate = 30.0;
162     rc_cfg_.ss_number_layers = 1;
163     rc_cfg_.ts_number_layers = 1;
164     rc_cfg_.scaling_factor_num[0] = 1;
165     rc_cfg_.scaling_factor_den[0] = 1;
166     rc_cfg_.layer_target_bitrate[0] = 1000;
167     rc_cfg_.max_quantizers[0] = 52;
168     rc_cfg_.min_quantizers[0] = 2;
169   }
170
171   void SetConfigSVC() {
172     rc_cfg_.width = 1280;
173     rc_cfg_.height = 720;
174     rc_cfg_.max_quantizer = 56;
175     rc_cfg_.min_quantizer = 2;
176     rc_cfg_.target_bandwidth = 1600;
177     rc_cfg_.buf_initial_sz = 500;
178     rc_cfg_.buf_optimal_sz = 600;
179     rc_cfg_.buf_sz = 1000;
180     rc_cfg_.undershoot_pct = 50;
181     rc_cfg_.overshoot_pct = 50;
182     rc_cfg_.max_intra_bitrate_pct = 900;
183     rc_cfg_.framerate = 30.0;
184     rc_cfg_.ss_number_layers = 3;
185     rc_cfg_.ts_number_layers = 3;
186
187     rc_cfg_.scaling_factor_num[0] = 1;
188     rc_cfg_.scaling_factor_den[0] = 4;
189     rc_cfg_.scaling_factor_num[1] = 2;
190     rc_cfg_.scaling_factor_den[1] = 4;
191     rc_cfg_.scaling_factor_num[2] = 4;
192     rc_cfg_.scaling_factor_den[2] = 4;
193
194     rc_cfg_.ts_rate_decimator[0] = 4;
195     rc_cfg_.ts_rate_decimator[1] = 2;
196     rc_cfg_.ts_rate_decimator[2] = 1;
197
198     rc_cfg_.layer_target_bitrate[0] = 100;
199     rc_cfg_.layer_target_bitrate[1] = 140;
200     rc_cfg_.layer_target_bitrate[2] = 200;
201     rc_cfg_.layer_target_bitrate[3] = 250;
202     rc_cfg_.layer_target_bitrate[4] = 350;
203     rc_cfg_.layer_target_bitrate[5] = 500;
204     rc_cfg_.layer_target_bitrate[6] = 450;
205     rc_cfg_.layer_target_bitrate[7] = 630;
206     rc_cfg_.layer_target_bitrate[8] = 900;
207
208     for (int sl = 0; sl < rc_cfg_.ss_number_layers; ++sl) {
209       for (int tl = 0; tl < rc_cfg_.ts_number_layers; ++tl) {
210         const int i = sl * rc_cfg_.ts_number_layers + tl;
211         rc_cfg_.max_quantizers[i] = 56;
212         rc_cfg_.min_quantizers[i] = 2;
213       }
214     }
215   }
216
217   std::unique_ptr<libvpx::VP9RateControlRTC> rc_api_;
218   libvpx::VP9RateControlRtcConfig rc_cfg_;
219 };
220
221 TEST_F(RcInterfaceTest, OneLayer) { RunOneLayer(); }
222
223 TEST_F(RcInterfaceTest, SVC) { RunSVC(); }
224 }  // namespace
225
226 int main(int argc, char **argv) {
227   ::testing::InitGoogleTest(&argc, argv);
228   return RUN_ALL_TESTS();
229 }