Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(103)

Side by Side Diff: webrtc/modules/video_coding/utility/simulcast_state_unittest.cc

Issue 1913073002: Extract common simulcast logic from VP8 wrapper and simulcast adapter (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Address comments, added tests Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 * Copyright (c) 2016 The WebRTC 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
11 #include "webrtc/modules/video_coding/utility/simulcast_state.h"
12
13 #include <algorithm>
14 #include <memory>
15 #include <vector>
16
17 #include "testing/gtest/include/gtest/gtest.h"
18
19 namespace webrtc {
20 namespace {
21 const int kMaxStreams = kMaxSimulcastStreams;
22 } // namespace
23
24 class SimulcastStateTest : public ::testing::Test {
25 public:
26 SimulcastStateTest() {}
27 virtual ~SimulcastStateTest() {}
28
29 void SetUp() override {
30 memset(&codec_, 0, sizeof(VideoCodec));
31 codec_.codecType = kVideoCodecVP8;
32 codec_.numberOfSimulcastStreams = 0;
33 codec_.minBitrate = 60;
34 codec_.targetBitrate = 600;
35 codec_.maxBitrate = 2400;
36 codec_.startBitrate = 300;
37 }
38
39 void ExpectState(
40 const std::vector<SimulcastState::Stream>& expected_streams) {
41 const std::vector<SimulcastState::Stream>& actual_streams =
42 simulcast_state_->Streams();
43 ASSERT_EQ(expected_streams.size(), actual_streams.size());
44 const int num_streams = expected_streams.size();
45 ASSERT_LE(num_streams, kMaxStreams);
46 for (int i = 0; i < num_streams; ++i) {
47 const SimulcastState::Stream& expected = expected_streams[i];
48 const SimulcastState::Stream& actual = actual_streams[i];
49 EXPECT_EQ(i, expected.idx);
50 EXPECT_EQ(i, actual.idx);
51 EXPECT_EQ(expected.allocated_rate_bps, actual.allocated_rate_bps);
52 EXPECT_EQ(expected.sending, actual.sending);
53 EXPECT_EQ(expected.keyframe_request, actual.keyframe_request);
54 }
55 }
56
57 void TestRateAllocation() {
58 int spillover_bps = 0;
59 int margin_bps = 0;
60 std::vector<SimulcastState::Stream> expected_streams;
61 for (int i = 0; i < codec_.numberOfSimulcastStreams; ++i) {
62 SimulcastState::Stream stream(i, &codec_, 0);
63 stream.sending = i == 0;
64 stream.keyframe_request = stream.sending;
65 stream.allocated_rate_bps =
66 stream.sending ? stream.config.minBitrate * 1000 : 0;
67 expected_streams.push_back(stream);
68 }
69
70 simulcast_state_.reset(new SimulcastState(codec_));
71 simulcast_state_->AllocateBitrate(0);
72 EXPECT_TRUE(simulcast_state_->GetAndResetKeyFrameRequest(0));
73 expected_streams[0].keyframe_request = false;
74
75 int top_layer = 0;
76 for (uint32_t i = 1; i < codec_.maxBitrate; ++i) {
77 simulcast_state_->AllocateBitrate(i * 1000);
78 ExpectState(expected_streams);
79
80 // Always allocate enough bitrate for the lowest stream.
81 if (top_layer == 0 && i < codec_.simulcastStream[0].minBitrate) {
82 expected_streams[0].allocated_rate_bps =
83 codec_.simulcastStream[0].minBitrate * 1000;
84 continue;
85 }
86
87 const int min_bitrate =
88 expected_streams[top_layer].config.minBitrate * 1000;
89 const int target_bitrate =
90 expected_streams[top_layer].config.targetBitrate * 1000;
91 const int max_bitrate =
92 expected_streams[top_layer].config.maxBitrate * 1000;
93
94 if (top_layer > 0 &&
95 expected_streams[top_layer].allocated_rate_bps == min_bitrate) {
96 // Update and reset key frame status on first updater after enabling
97 // layer.
98 EXPECT_TRUE(simulcast_state_->GetAndResetKeyFrameRequest(top_layer));
99 expected_streams[top_layer].keyframe_request = false;
100 }
101
102 // First fill up the top layer until target_bitrate.
103 if (expected_streams[top_layer].allocated_rate_bps < target_bitrate) {
104 expected_streams[top_layer].allocated_rate_bps += 1000;
105 continue;
106 }
107
108 // We have allocated up to the target bitrate. Anything above this may
109 // be reallocated to a higher layer once it has enough bitrate to reach
110 // its min_bitrate.
111 margin_bps += 1000;
112 if (expected_streams[top_layer].allocated_rate_bps < max_bitrate) {
113 expected_streams[top_layer].allocated_rate_bps += 1000;
114 } else {
115 // TODO(sprang): When we enable allocating extra bits to layers other
116 // than the top one, traverse down and do that here.
117 spillover_bps += 1000;
118 }
119
120 // Check if there is enough bitrate to enable the next layer.
121 if (top_layer + 1 < codec_.numberOfSimulcastStreams &&
122 margin_bps >= static_cast<int>(
123 expected_streams[top_layer + 1].config.minBitrate) *
124 1000) {
125 ++top_layer;
126 expected_streams[top_layer].sending = true;
127 expected_streams[top_layer].keyframe_request = true;
128
129 // Steal margin bits from the lower layers.
130 // TODO(sprang): Loop over j when we enable allocating extra bits to
131 // layers other than the top one.
132 int j = top_layer - 1;
133 int available_margin =
134 expected_streams[j].allocated_rate_bps -
135 (expected_streams[j].config.targetBitrate * 1000);
136 int consumed_margin = std::min(available_margin, margin_bps);
137 expected_streams[j].allocated_rate_bps -= consumed_margin;
138 margin_bps -= consumed_margin;
139
140 if (margin_bps > 0 && spillover_bps > 0) {
141 // The rest of the needed margin is in allocated spillover.
142 EXPECT_EQ(margin_bps, spillover_bps);
143 spillover_bps = 0;
144 margin_bps = 0;
145 } else {
146 EXPECT_EQ(0, margin_bps);
147 }
148
149 expected_streams[top_layer].allocated_rate_bps =
150 expected_streams[top_layer].config.minBitrate * 1000;
151 }
152 }
153 }
154
155 VideoCodec codec_;
156 std::unique_ptr<SimulcastState> simulcast_state_;
157 };
158
159 TEST_F(SimulcastStateTest, NoSimulcast) {
160 simulcast_state_.reset(new SimulcastState(codec_));
161
162 SimulcastState::Stream expected_stream(0, &codec_,
163 codec_.startBitrate * 1000);
164 std::vector<SimulcastState::Stream> expected_streams;
165 expected_streams.push_back(expected_stream);
166
167 ExpectState(expected_streams);
168
169 for (uint32_t i = 0; i < codec_.maxBitrate + 1; ++i) {
170 simulcast_state_->AllocateBitrate(i * 1000);
171 if (i < codec_.minBitrate) {
172 expected_streams[0].allocated_rate_bps = codec_.minBitrate * 1000;
173 } else if (i > codec_.maxBitrate) {
174 expected_streams[0].allocated_rate_bps = codec_.maxBitrate * 1000;
175 } else {
176 expected_streams[0].allocated_rate_bps = i * 1000;
177 }
178 ExpectState(expected_streams);
179 }
180 }
181
182 TEST_F(SimulcastStateTest, MultipleStreamsRates) {
183 for (int num_streams = 1; num_streams < kMaxStreams; ++num_streams) {
184 codec_.numberOfSimulcastStreams = num_streams;
185 codec_.startBitrate = 0;
186
187 for (int i = 0; i < num_streams; ++i) {
188 codec_.simulcastStream[i].minBitrate =
189 ((i + 1) * codec_.minBitrate) / kMaxStreams;
190 codec_.simulcastStream[i].targetBitrate =
191 ((i + 1) * codec_.targetBitrate) / kMaxStreams;
192 codec_.simulcastStream[i].maxBitrate =
193 ((i + 1) * codec_.maxBitrate) / kMaxStreams;
194 }
195
196 TestRateAllocation();
197 }
198 }
199
200 TEST_F(SimulcastStateTest, NextMinLargerThanMax) {
201 codec_.startBitrate = 0;
202 codec_.numberOfSimulcastStreams = 2;
203 codec_.simulcastStream[0].minBitrate = 10;
204 codec_.simulcastStream[0].targetBitrate = 100;
205 codec_.simulcastStream[0].maxBitrate = 200;
206 codec_.simulcastStream[1].minBitrate = 300;
207 codec_.simulcastStream[1].targetBitrate = 400;
208 codec_.simulcastStream[1].maxBitrate = 500;
209
210 TestRateAllocation();
211 }
212
213 TEST_F(SimulcastStateTest, LargerMinButLowerMax) {
214 codec_.startBitrate = 0;
215 codec_.numberOfSimulcastStreams = 3;
216 codec_.simulcastStream[0].minBitrate = 100;
217 codec_.simulcastStream[0].targetBitrate = 200;
218 codec_.simulcastStream[0].maxBitrate = 600;
219 codec_.simulcastStream[1].minBitrate = 200;
220 codec_.simulcastStream[1].targetBitrate = 300;
221 codec_.simulcastStream[1].maxBitrate = 400;
222 codec_.simulcastStream[2].minBitrate = 300;
223 codec_.simulcastStream[2].targetBitrate = 600;
224 codec_.simulcastStream[2].maxBitrate = 800;
225
226 TestRateAllocation();
227 }
228
229 TEST_F(SimulcastStateTest, SetsSendingAndKeyframeStates) {
230 codec_.startBitrate = 0;
231 codec_.numberOfSimulcastStreams = 3;
232
233 codec_.simulcastStream[0].minBitrate = 100;
234 codec_.simulcastStream[0].targetBitrate = 200;
235 codec_.simulcastStream[0].maxBitrate = 600;
236 const int kFirstCutoff = codec_.simulcastStream[0].minBitrate * 1000;
237
238 codec_.simulcastStream[1].minBitrate = 300;
239 codec_.simulcastStream[1].targetBitrate = 600;
240 codec_.simulcastStream[1].maxBitrate = 1200;
241 const int kSecondCutoff = (codec_.simulcastStream[0].targetBitrate +
242 codec_.simulcastStream[1].minBitrate) *
243 1000;
244
245 codec_.simulcastStream[2].minBitrate = 500;
246 codec_.simulcastStream[2].targetBitrate = 800;
247 codec_.simulcastStream[2].maxBitrate = 1500;
248 const int kThirdCutoff = (codec_.simulcastStream[0].targetBitrate +
249 codec_.simulcastStream[1].targetBitrate +
250 codec_.simulcastStream[2].minBitrate) *
251 1000;
252
253 simulcast_state_.reset(new SimulcastState(codec_));
254
255 simulcast_state_->AllocateBitrate(kFirstCutoff);
256 EXPECT_TRUE(simulcast_state_->GetAndResetKeyFrameRequest(0));
257 EXPECT_TRUE(simulcast_state_->IsSending(0));
258 EXPECT_FALSE(simulcast_state_->GetAndResetKeyFrameRequest(1));
259 EXPECT_FALSE(simulcast_state_->IsSending(1));
260 EXPECT_FALSE(simulcast_state_->GetAndResetKeyFrameRequest(2));
261 EXPECT_FALSE(simulcast_state_->IsSending(2));
262
263 simulcast_state_->AllocateBitrate(kSecondCutoff);
264 EXPECT_FALSE(simulcast_state_->GetAndResetKeyFrameRequest(0));
265 EXPECT_TRUE(simulcast_state_->IsSending(0));
266 EXPECT_TRUE(simulcast_state_->GetAndResetKeyFrameRequest(1));
267 EXPECT_TRUE(simulcast_state_->IsSending(1));
268 EXPECT_FALSE(simulcast_state_->GetAndResetKeyFrameRequest(2));
269 EXPECT_FALSE(simulcast_state_->IsSending(2));
270
271 simulcast_state_->AllocateBitrate(kThirdCutoff);
272 EXPECT_FALSE(simulcast_state_->GetAndResetKeyFrameRequest(0));
273 EXPECT_TRUE(simulcast_state_->IsSending(0));
274 EXPECT_FALSE(simulcast_state_->GetAndResetKeyFrameRequest(1));
275 EXPECT_TRUE(simulcast_state_->IsSending(1));
276 EXPECT_TRUE(simulcast_state_->GetAndResetKeyFrameRequest(2));
277 EXPECT_TRUE(simulcast_state_->IsSending(2));
278
279 simulcast_state_->AllocateBitrate(kSecondCutoff);
280 EXPECT_FALSE(simulcast_state_->GetAndResetKeyFrameRequest(0));
281 EXPECT_TRUE(simulcast_state_->IsSending(0));
282 EXPECT_FALSE(simulcast_state_->GetAndResetKeyFrameRequest(1));
283 EXPECT_TRUE(simulcast_state_->IsSending(1));
284 EXPECT_FALSE(simulcast_state_->GetAndResetKeyFrameRequest(2));
285 EXPECT_FALSE(simulcast_state_->IsSending(2));
286
287 simulcast_state_->AllocateBitrate(kFirstCutoff);
288 EXPECT_FALSE(simulcast_state_->GetAndResetKeyFrameRequest(0));
289 EXPECT_TRUE(simulcast_state_->IsSending(0));
290 EXPECT_FALSE(simulcast_state_->GetAndResetKeyFrameRequest(1));
291 EXPECT_FALSE(simulcast_state_->IsSending(1));
292 EXPECT_FALSE(simulcast_state_->GetAndResetKeyFrameRequest(2));
293 EXPECT_FALSE(simulcast_state_->IsSending(2));
294
295 simulcast_state_->AllocateBitrate(kThirdCutoff);
296 EXPECT_FALSE(simulcast_state_->GetAndResetKeyFrameRequest(0));
297 EXPECT_TRUE(simulcast_state_->IsSending(0));
298 EXPECT_TRUE(simulcast_state_->GetAndResetKeyFrameRequest(1));
299 EXPECT_TRUE(simulcast_state_->IsSending(1));
300 EXPECT_TRUE(simulcast_state_->GetAndResetKeyFrameRequest(2));
301 EXPECT_TRUE(simulcast_state_->IsSending(2));
302 }
303
304 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698