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

Side by Side Diff: webrtc/modules/video_coding/codecs/vp8/screenshare_layers_unittest.cc

Issue 1734793003: Add stats (histograms) for vp8 screenshare layers (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Prevent incorrect teardown order Created 4 years, 9 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
1 /* 1 /*
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include <memory> 11 #include <memory>
12 #include <vector> 12 #include <vector>
13 13
14 #include "gtest/gtest.h" 14 #include "gtest/gtest.h"
15 #include "vpx/vpx_encoder.h" 15 #include "vpx/vpx_encoder.h"
16 #include "vpx/vp8cx.h" 16 #include "vpx/vp8cx.h"
17 #include "webrtc/modules/video_coding/include/video_codec_interface.h" 17 #include "webrtc/modules/video_coding/include/video_codec_interface.h"
18 #include "webrtc/modules/video_coding/codecs/vp8/screenshare_layers.h" 18 #include "webrtc/modules/video_coding/codecs/vp8/screenshare_layers.h"
19 #include "webrtc/modules/video_coding/utility/mock/mock_frame_dropper.h" 19 #include "webrtc/modules/video_coding/utility/mock/mock_frame_dropper.h"
20 #include "webrtc/system_wrappers/include/clock.h"
21 #include "webrtc/system_wrappers/include/metrics.h"
22 #include "webrtc/test/histogram.h"
20 23
21 using ::testing::_; 24 using ::testing::_;
22 using ::testing::NiceMock; 25 using ::testing::NiceMock;
23 using ::testing::Return; 26 using ::testing::Return;
24 27
25 namespace webrtc { 28 namespace webrtc {
26 29
27 // 5 frames per second at 90 kHz. 30 // 5 frames per second at 90 kHz.
28 const uint32_t kTimestampDelta5Fps = 90000 / 5; 31 const uint32_t kTimestampDelta5Fps = 90000 / 5;
29 const int kDefaultQp = 54; 32 const int kDefaultQp = 54;
30 const int kDefaultTl0BitrateKbps = 200; 33 const int kDefaultTl0BitrateKbps = 200;
31 const int kDefaultTl1BitrateKbps = 2000; 34 const int kDefaultTl1BitrateKbps = 2000;
32 const int kFrameRate = 5; 35 const int kFrameRate = 5;
33 const int kSyncPeriodSeconds = 5; 36 const int kSyncPeriodSeconds = 5;
34 const int kMaxSyncPeriodSeconds = 10; 37 const int kMaxSyncPeriodSeconds = 10;
35 38
36 class ScreenshareLayerTest : public ::testing::Test { 39 class ScreenshareLayerTest : public ::testing::Test {
37 protected: 40 protected:
38 ScreenshareLayerTest() : min_qp_(2), max_qp_(kDefaultQp), frame_size_(-1) {} 41 ScreenshareLayerTest()
42 : min_qp_(2), max_qp_(kDefaultQp), frame_size_(-1), clock_(1) {}
39 virtual ~ScreenshareLayerTest() {} 43 virtual ~ScreenshareLayerTest() {}
40 44
45 void SetUp() override { layers_.reset(new ScreenshareLayers(2, 0, &clock_)); }
46
41 void EncodeFrame(uint32_t timestamp, 47 void EncodeFrame(uint32_t timestamp,
42 bool base_sync, 48 bool base_sync,
43 CodecSpecificInfoVP8* vp8_info, 49 CodecSpecificInfoVP8* vp8_info,
44 int* flags) { 50 int* flags) {
45 *flags = layers_->EncodeFlags(timestamp); 51 *flags = layers_->EncodeFlags(timestamp);
46 if (*flags == -1) 52 if (*flags == -1)
47 return; 53 return;
48 layers_->PopulateCodecSpecific(base_sync, vp8_info, timestamp); 54 layers_->PopulateCodecSpecific(base_sync, vp8_info, timestamp);
49 ASSERT_NE(-1, frame_size_); 55 ASSERT_NE(-1, frame_size_);
50 layers_->FrameEncoded(frame_size_, timestamp, kDefaultQp); 56 layers_->FrameEncoded(frame_size_, timestamp, kDefaultQp);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 return timestamp; 104 return timestamp;
99 } 105 }
100 } 106 }
101 ADD_FAILURE() << "Did not get a frame of TL" << layer << " in time."; 107 ADD_FAILURE() << "Did not get a frame of TL" << layer << " in time.";
102 return 0; 108 return 0;
103 } 109 }
104 110
105 int min_qp_; 111 int min_qp_;
106 int max_qp_; 112 int max_qp_;
107 int frame_size_; 113 int frame_size_;
114 SimulatedClock clock_;
108 std::unique_ptr<ScreenshareLayers> layers_; 115 std::unique_ptr<ScreenshareLayers> layers_;
109 }; 116 };
110 117
111 TEST_F(ScreenshareLayerTest, 1Layer) { 118 TEST_F(ScreenshareLayerTest, 1Layer) {
112 layers_.reset(new ScreenshareLayers(1, 0)); 119 layers_.reset(new ScreenshareLayers(1, 0, &clock_));
113 ConfigureBitrates(); 120 ConfigureBitrates();
114 int flags = 0; 121 int flags = 0;
115 uint32_t timestamp = 0; 122 uint32_t timestamp = 0;
116 CodecSpecificInfoVP8 vp8_info; 123 CodecSpecificInfoVP8 vp8_info;
117 // One layer screenshare should not use the frame dropper as all frames will 124 // One layer screenshare should not use the frame dropper as all frames will
118 // belong to the base layer. 125 // belong to the base layer.
119 const int kSingleLayerFlags = 0; 126 const int kSingleLayerFlags = 0;
120 flags = layers_->EncodeFlags(timestamp); 127 flags = layers_->EncodeFlags(timestamp);
121 EXPECT_EQ(kSingleLayerFlags, flags); 128 EXPECT_EQ(kSingleLayerFlags, flags);
122 layers_->PopulateCodecSpecific(false, &vp8_info, timestamp); 129 layers_->PopulateCodecSpecific(false, &vp8_info, timestamp);
123 EXPECT_EQ(static_cast<uint8_t>(kNoTemporalIdx), vp8_info.temporalIdx); 130 EXPECT_EQ(static_cast<uint8_t>(kNoTemporalIdx), vp8_info.temporalIdx);
124 EXPECT_FALSE(vp8_info.layerSync); 131 EXPECT_FALSE(vp8_info.layerSync);
125 EXPECT_EQ(kNoTl0PicIdx, vp8_info.tl0PicIdx); 132 EXPECT_EQ(kNoTl0PicIdx, vp8_info.tl0PicIdx);
126 layers_->FrameEncoded(frame_size_, timestamp, kDefaultQp); 133 layers_->FrameEncoded(frame_size_, timestamp, kDefaultQp);
127 flags = layers_->EncodeFlags(timestamp); 134 flags = layers_->EncodeFlags(timestamp);
128 EXPECT_EQ(kSingleLayerFlags, flags); 135 EXPECT_EQ(kSingleLayerFlags, flags);
129 timestamp += kTimestampDelta5Fps; 136 timestamp += kTimestampDelta5Fps;
130 layers_->PopulateCodecSpecific(false, &vp8_info, timestamp); 137 layers_->PopulateCodecSpecific(false, &vp8_info, timestamp);
131 EXPECT_EQ(static_cast<uint8_t>(kNoTemporalIdx), vp8_info.temporalIdx); 138 EXPECT_EQ(static_cast<uint8_t>(kNoTemporalIdx), vp8_info.temporalIdx);
132 EXPECT_FALSE(vp8_info.layerSync); 139 EXPECT_FALSE(vp8_info.layerSync);
133 EXPECT_EQ(kNoTl0PicIdx, vp8_info.tl0PicIdx); 140 EXPECT_EQ(kNoTl0PicIdx, vp8_info.tl0PicIdx);
134 layers_->FrameEncoded(frame_size_, timestamp, kDefaultQp); 141 layers_->FrameEncoded(frame_size_, timestamp, kDefaultQp);
135 } 142 }
136 143
137 TEST_F(ScreenshareLayerTest, 2Layer) { 144 TEST_F(ScreenshareLayerTest, 2Layer) {
138 layers_.reset(new ScreenshareLayers(2, 0));
139 ConfigureBitrates(); 145 ConfigureBitrates();
140 int flags = 0; 146 int flags = 0;
141 uint32_t timestamp = 0; 147 uint32_t timestamp = 0;
142 uint8_t expected_tl0_idx = 0; 148 uint8_t expected_tl0_idx = 0;
143 CodecSpecificInfoVP8 vp8_info; 149 CodecSpecificInfoVP8 vp8_info;
144 EncodeFrame(timestamp, false, &vp8_info, &flags); 150 EncodeFrame(timestamp, false, &vp8_info, &flags);
145 EXPECT_EQ(ScreenshareLayers::kTl0Flags, flags); 151 EXPECT_EQ(ScreenshareLayers::kTl0Flags, flags);
146 EXPECT_EQ(0, vp8_info.temporalIdx); 152 EXPECT_EQ(0, vp8_info.temporalIdx);
147 EXPECT_FALSE(vp8_info.layerSync); 153 EXPECT_FALSE(vp8_info.layerSync);
148 ++expected_tl0_idx; 154 ++expected_tl0_idx;
(...skipping 29 matching lines...) Expand all
178 184
179 timestamp += kTimestampDelta5Fps; 185 timestamp += kTimestampDelta5Fps;
180 EncodeFrame(timestamp, false, &vp8_info, &flags); 186 EncodeFrame(timestamp, false, &vp8_info, &flags);
181 EXPECT_EQ(ScreenshareLayers::kTl1Flags, flags); 187 EXPECT_EQ(ScreenshareLayers::kTl1Flags, flags);
182 EXPECT_EQ(1, vp8_info.temporalIdx); 188 EXPECT_EQ(1, vp8_info.temporalIdx);
183 EXPECT_FALSE(vp8_info.layerSync); 189 EXPECT_FALSE(vp8_info.layerSync);
184 EXPECT_EQ(expected_tl0_idx, vp8_info.tl0PicIdx); 190 EXPECT_EQ(expected_tl0_idx, vp8_info.tl0PicIdx);
185 } 191 }
186 192
187 TEST_F(ScreenshareLayerTest, 2LayersPeriodicSync) { 193 TEST_F(ScreenshareLayerTest, 2LayersPeriodicSync) {
188 layers_.reset(new ScreenshareLayers(2, 0));
189 ConfigureBitrates(); 194 ConfigureBitrates();
190 int flags = 0; 195 int flags = 0;
191 uint32_t timestamp = 0; 196 uint32_t timestamp = 0;
192 CodecSpecificInfoVP8 vp8_info; 197 CodecSpecificInfoVP8 vp8_info;
193 std::vector<int> sync_times; 198 std::vector<int> sync_times;
194 199
195 const int kNumFrames = kSyncPeriodSeconds * kFrameRate * 2 - 1; 200 const int kNumFrames = kSyncPeriodSeconds * kFrameRate * 2 - 1;
196 for (int i = 0; i < kNumFrames; ++i) { 201 for (int i = 0; i < kNumFrames; ++i) {
197 timestamp += kTimestampDelta5Fps; 202 timestamp += kTimestampDelta5Fps;
198 EncodeFrame(timestamp, false, &vp8_info, &flags); 203 EncodeFrame(timestamp, false, &vp8_info, &flags);
199 if (vp8_info.temporalIdx == 1 && vp8_info.layerSync) { 204 if (vp8_info.temporalIdx == 1 && vp8_info.layerSync) {
200 sync_times.push_back(timestamp); 205 sync_times.push_back(timestamp);
201 } 206 }
202 } 207 }
203 208
204 ASSERT_EQ(2u, sync_times.size()); 209 ASSERT_EQ(2u, sync_times.size());
205 EXPECT_GE(sync_times[1] - sync_times[0], 90000 * kSyncPeriodSeconds); 210 EXPECT_GE(sync_times[1] - sync_times[0], 90000 * kSyncPeriodSeconds);
206 } 211 }
207 212
208 TEST_F(ScreenshareLayerTest, 2LayersSyncAfterTimeout) { 213 TEST_F(ScreenshareLayerTest, 2LayersSyncAfterTimeout) {
209 layers_.reset(new ScreenshareLayers(2, 0));
210 ConfigureBitrates(); 214 ConfigureBitrates();
211 uint32_t timestamp = 0; 215 uint32_t timestamp = 0;
212 CodecSpecificInfoVP8 vp8_info; 216 CodecSpecificInfoVP8 vp8_info;
213 std::vector<int> sync_times; 217 std::vector<int> sync_times;
214 218
215 const int kNumFrames = kMaxSyncPeriodSeconds * kFrameRate * 2 - 1; 219 const int kNumFrames = kMaxSyncPeriodSeconds * kFrameRate * 2 - 1;
216 for (int i = 0; i < kNumFrames; ++i) { 220 for (int i = 0; i < kNumFrames; ++i) {
217 timestamp += kTimestampDelta5Fps; 221 timestamp += kTimestampDelta5Fps;
218 layers_->EncodeFlags(timestamp); 222 layers_->EncodeFlags(timestamp);
219 layers_->PopulateCodecSpecific(false, &vp8_info, timestamp); 223 layers_->PopulateCodecSpecific(false, &vp8_info, timestamp);
220 224
221 // Simulate TL1 being at least 8 qp steps better. 225 // Simulate TL1 being at least 8 qp steps better.
222 if (vp8_info.temporalIdx == 0) { 226 if (vp8_info.temporalIdx == 0) {
223 layers_->FrameEncoded(frame_size_, timestamp, kDefaultQp); 227 layers_->FrameEncoded(frame_size_, timestamp, kDefaultQp);
224 } else { 228 } else {
225 layers_->FrameEncoded(frame_size_, timestamp, kDefaultQp - 8); 229 layers_->FrameEncoded(frame_size_, timestamp, kDefaultQp - 8);
226 } 230 }
227 231
228 if (vp8_info.temporalIdx == 1 && vp8_info.layerSync) 232 if (vp8_info.temporalIdx == 1 && vp8_info.layerSync)
229 sync_times.push_back(timestamp); 233 sync_times.push_back(timestamp);
230 } 234 }
231 235
232 ASSERT_EQ(2u, sync_times.size()); 236 ASSERT_EQ(2u, sync_times.size());
233 EXPECT_GE(sync_times[1] - sync_times[0], 90000 * kMaxSyncPeriodSeconds); 237 EXPECT_GE(sync_times[1] - sync_times[0], 90000 * kMaxSyncPeriodSeconds);
234 } 238 }
235 239
236 TEST_F(ScreenshareLayerTest, 2LayersSyncAfterSimilarQP) { 240 TEST_F(ScreenshareLayerTest, 2LayersSyncAfterSimilarQP) {
237 layers_.reset(new ScreenshareLayers(2, 0));
238 ConfigureBitrates(); 241 ConfigureBitrates();
239 uint32_t timestamp = 0; 242 uint32_t timestamp = 0;
240 CodecSpecificInfoVP8 vp8_info; 243 CodecSpecificInfoVP8 vp8_info;
241 std::vector<int> sync_times; 244 std::vector<int> sync_times;
242 245
243 const int kNumFrames = (kSyncPeriodSeconds + 246 const int kNumFrames = (kSyncPeriodSeconds +
244 ((kMaxSyncPeriodSeconds - kSyncPeriodSeconds) / 2)) * 247 ((kMaxSyncPeriodSeconds - kSyncPeriodSeconds) / 2)) *
245 kFrameRate; 248 kFrameRate;
246 for (int i = 0; i < kNumFrames; ++i) { 249 for (int i = 0; i < kNumFrames; ++i) {
247 timestamp += kTimestampDelta5Fps; 250 timestamp += kTimestampDelta5Fps;
(...skipping 29 matching lines...) Expand all
277 EXPECT_TRUE(vp8_info.layerSync); 280 EXPECT_TRUE(vp8_info.layerSync);
278 EXPECT_EQ(ScreenshareLayers::kTl1SyncFlags, flags); 281 EXPECT_EQ(ScreenshareLayers::kTl1SyncFlags, flags);
279 return; 282 return;
280 } 283 }
281 } 284 }
282 } 285 }
283 ADD_FAILURE() << "No TL1 frame arrived within time limit."; 286 ADD_FAILURE() << "No TL1 frame arrived within time limit.";
284 } 287 }
285 288
286 TEST_F(ScreenshareLayerTest, 2LayersToggling) { 289 TEST_F(ScreenshareLayerTest, 2LayersToggling) {
287 layers_.reset(new ScreenshareLayers(2, 0));
288 ConfigureBitrates(); 290 ConfigureBitrates();
289 int flags = 0; 291 int flags = 0;
290 CodecSpecificInfoVP8 vp8_info; 292 CodecSpecificInfoVP8 vp8_info;
291 uint32_t timestamp = RunGracePeriod(); 293 uint32_t timestamp = RunGracePeriod();
292 294
293 // Insert 50 frames. 2/5 should be TL0. 295 // Insert 50 frames. 2/5 should be TL0.
294 int tl0_frames = 0; 296 int tl0_frames = 0;
295 int tl1_frames = 0; 297 int tl1_frames = 0;
296 for (int i = 0; i < 50; ++i) { 298 for (int i = 0; i < 50; ++i) {
297 timestamp += kTimestampDelta5Fps; 299 timestamp += kTimestampDelta5Fps;
298 EncodeFrame(timestamp, false, &vp8_info, &flags); 300 EncodeFrame(timestamp, false, &vp8_info, &flags);
299 switch (vp8_info.temporalIdx) { 301 switch (vp8_info.temporalIdx) {
300 case 0: 302 case 0:
301 ++tl0_frames; 303 ++tl0_frames;
302 break; 304 break;
303 case 1: 305 case 1:
304 ++tl1_frames; 306 ++tl1_frames;
305 break; 307 break;
306 default: 308 default:
307 abort(); 309 abort();
308 } 310 }
309 } 311 }
310 EXPECT_EQ(20, tl0_frames); 312 EXPECT_EQ(20, tl0_frames);
311 EXPECT_EQ(30, tl1_frames); 313 EXPECT_EQ(30, tl1_frames);
312 } 314 }
313 315
314 TEST_F(ScreenshareLayerTest, AllFitsLayer0) { 316 TEST_F(ScreenshareLayerTest, AllFitsLayer0) {
315 layers_.reset(new ScreenshareLayers(2, 0));
316 ConfigureBitrates(); 317 ConfigureBitrates();
317 frame_size_ = ((kDefaultTl0BitrateKbps * 1000) / 8) / kFrameRate; 318 frame_size_ = ((kDefaultTl0BitrateKbps * 1000) / 8) / kFrameRate;
318 319
319 int flags = 0; 320 int flags = 0;
320 uint32_t timestamp = 0; 321 uint32_t timestamp = 0;
321 CodecSpecificInfoVP8 vp8_info; 322 CodecSpecificInfoVP8 vp8_info;
322 // Insert 50 frames, small enough that all fits in TL0. 323 // Insert 50 frames, small enough that all fits in TL0.
323 for (int i = 0; i < 50; ++i) { 324 for (int i = 0; i < 50; ++i) {
324 EncodeFrame(timestamp, false, &vp8_info, &flags); 325 EncodeFrame(timestamp, false, &vp8_info, &flags);
325 timestamp += kTimestampDelta5Fps; 326 timestamp += kTimestampDelta5Fps;
326 EXPECT_EQ(ScreenshareLayers::kTl0Flags, flags); 327 EXPECT_EQ(ScreenshareLayers::kTl0Flags, flags);
327 EXPECT_EQ(0, vp8_info.temporalIdx); 328 EXPECT_EQ(0, vp8_info.temporalIdx);
328 } 329 }
329 } 330 }
330 331
331 TEST_F(ScreenshareLayerTest, TooHighBitrate) { 332 TEST_F(ScreenshareLayerTest, TooHighBitrate) {
332 layers_.reset(new ScreenshareLayers(2, 0));
333 ConfigureBitrates(); 333 ConfigureBitrates();
334 frame_size_ = 2 * ((kDefaultTl1BitrateKbps * 1000) / 8) / kFrameRate; 334 frame_size_ = 2 * ((kDefaultTl1BitrateKbps * 1000) / 8) / kFrameRate;
335 int flags = 0; 335 int flags = 0;
336 CodecSpecificInfoVP8 vp8_info; 336 CodecSpecificInfoVP8 vp8_info;
337 uint32_t timestamp = RunGracePeriod(); 337 uint32_t timestamp = RunGracePeriod();
338 338
339 // Insert 100 frames. Half should be dropped. 339 // Insert 100 frames. Half should be dropped.
340 int tl0_frames = 0; 340 int tl0_frames = 0;
341 int tl1_frames = 0; 341 int tl1_frames = 0;
342 int dropped_frames = 0; 342 int dropped_frames = 0;
(...skipping 15 matching lines...) Expand all
358 } 358 }
359 } 359 }
360 } 360 }
361 361
362 EXPECT_EQ(5, tl0_frames); 362 EXPECT_EQ(5, tl0_frames);
363 EXPECT_EQ(45, tl1_frames); 363 EXPECT_EQ(45, tl1_frames);
364 EXPECT_EQ(50, dropped_frames); 364 EXPECT_EQ(50, dropped_frames);
365 } 365 }
366 366
367 TEST_F(ScreenshareLayerTest, TargetBitrateCappedByTL0) { 367 TEST_F(ScreenshareLayerTest, TargetBitrateCappedByTL0) {
368 layers_.reset(new ScreenshareLayers(2, 0));
369
370 vpx_codec_enc_cfg_t cfg; 368 vpx_codec_enc_cfg_t cfg;
371 layers_->ConfigureBitrates(100, 1000, 5, &cfg); 369 layers_->ConfigureBitrates(100, 1000, 5, &cfg);
372 370
373 EXPECT_EQ(static_cast<unsigned int>( 371 EXPECT_EQ(static_cast<unsigned int>(
374 ScreenshareLayers::kMaxTL0FpsReduction * 100 + 0.5), 372 ScreenshareLayers::kMaxTL0FpsReduction * 100 + 0.5),
375 cfg.rc_target_bitrate); 373 cfg.rc_target_bitrate);
376 } 374 }
377 375
378 TEST_F(ScreenshareLayerTest, TargetBitrateCappedByTL1) { 376 TEST_F(ScreenshareLayerTest, TargetBitrateCappedByTL1) {
379 layers_.reset(new ScreenshareLayers(2, 0));
380 vpx_codec_enc_cfg_t cfg; 377 vpx_codec_enc_cfg_t cfg;
381 layers_->ConfigureBitrates(100, 450, 5, &cfg); 378 layers_->ConfigureBitrates(100, 450, 5, &cfg);
382 379
383 EXPECT_EQ(static_cast<unsigned int>( 380 EXPECT_EQ(static_cast<unsigned int>(
384 450 / ScreenshareLayers::kAcceptableTargetOvershoot), 381 450 / ScreenshareLayers::kAcceptableTargetOvershoot),
385 cfg.rc_target_bitrate); 382 cfg.rc_target_bitrate);
386 } 383 }
387 384
388 TEST_F(ScreenshareLayerTest, TargetBitrateBelowTL0) { 385 TEST_F(ScreenshareLayerTest, TargetBitrateBelowTL0) {
389 layers_.reset(new ScreenshareLayers(2, 0));
390 vpx_codec_enc_cfg_t cfg; 386 vpx_codec_enc_cfg_t cfg;
391 layers_->ConfigureBitrates(100, 100, 5, &cfg); 387 layers_->ConfigureBitrates(100, 100, 5, &cfg);
392 388
393 EXPECT_EQ(100U, cfg.rc_target_bitrate); 389 EXPECT_EQ(100U, cfg.rc_target_bitrate);
394 } 390 }
395 391
396 TEST_F(ScreenshareLayerTest, EncoderDrop) { 392 TEST_F(ScreenshareLayerTest, EncoderDrop) {
397 layers_.reset(new ScreenshareLayers(2, 0));
398 ConfigureBitrates(); 393 ConfigureBitrates();
399 CodecSpecificInfoVP8 vp8_info; 394 CodecSpecificInfoVP8 vp8_info;
400 vpx_codec_enc_cfg_t cfg; 395 vpx_codec_enc_cfg_t cfg;
401 cfg.rc_max_quantizer = kDefaultQp; 396 cfg.rc_max_quantizer = kDefaultQp;
402 397
403 uint32_t timestamp = RunGracePeriod(); 398 uint32_t timestamp = RunGracePeriod();
404 timestamp = SkipUntilTl(0, timestamp); 399 timestamp = SkipUntilTl(0, timestamp);
405 400
406 // Size 0 indicates dropped frame. 401 // Size 0 indicates dropped frame.
407 layers_->FrameEncoded(0, timestamp, kDefaultQp); 402 layers_->FrameEncoded(0, timestamp, kDefaultQp);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
439 layers_->FrameEncoded(frame_size_, timestamp, kDefaultQp); 434 layers_->FrameEncoded(frame_size_, timestamp, kDefaultQp);
440 435
441 layers_->EncodeFlags(timestamp); 436 layers_->EncodeFlags(timestamp);
442 timestamp += kTimestampDelta5Fps; 437 timestamp += kTimestampDelta5Fps;
443 EXPECT_TRUE(layers_->UpdateConfiguration(&cfg)); 438 EXPECT_TRUE(layers_->UpdateConfiguration(&cfg));
444 layers_->PopulateCodecSpecific(false, &vp8_info, timestamp); 439 layers_->PopulateCodecSpecific(false, &vp8_info, timestamp);
445 EXPECT_EQ(cfg.rc_max_quantizer, static_cast<unsigned int>(kDefaultQp)); 440 EXPECT_EQ(cfg.rc_max_quantizer, static_cast<unsigned int>(kDefaultQp));
446 layers_->FrameEncoded(frame_size_, timestamp, kDefaultQp); 441 layers_->FrameEncoded(frame_size_, timestamp, kDefaultQp);
447 } 442 }
448 443
444 TEST_F(ScreenshareLayerTest, UpdatesHistograms) {
445 ConfigureBitrates();
446 vpx_codec_enc_cfg_t cfg;
447 cfg.rc_max_quantizer = kDefaultQp;
448 bool trigger_drop = false;
449 bool dropped_frame = false;
450 bool overshoot = false;
451 const int kTl0Qp = 35;
452 const int kTl1Qp = 30;
453 for (int64_t timestamp = 0;
454 timestamp < kTimestampDelta5Fps * 5 * metrics::kMinRunTimeInSeconds;
455 timestamp += kTimestampDelta5Fps) {
456 int flags = layers_->EncodeFlags(timestamp);
457 if (flags != -1)
458 layers_->UpdateConfiguration(&cfg);
459
460 if (timestamp >= kTimestampDelta5Fps * 5 && !overshoot && flags != -1) {
461 // Simulate one overshoot.
462 layers_->FrameEncoded(0, timestamp, 0);
463 overshoot = true;
464 flags = layers_->EncodeFlags(timestamp);
465 }
466
467 if (flags == ScreenshareLayers::kTl0Flags) {
468 if (timestamp >= kTimestampDelta5Fps * 20 && !trigger_drop) {
469 // Simulate a too large frame, to cause frame drop.
470 layers_->FrameEncoded(frame_size_ * 5, timestamp, kTl0Qp);
471 trigger_drop = true;
472 } else {
473 layers_->FrameEncoded(frame_size_, timestamp, kTl0Qp);
474 }
475 } else if (flags == ScreenshareLayers::kTl1Flags ||
476 flags == ScreenshareLayers::kTl1SyncFlags) {
477 layers_->FrameEncoded(frame_size_, timestamp, kTl1Qp);
478 } else if (flags == -1) {
479 dropped_frame = true;
480 } else {
481 RTC_NOTREACHED() << "Unexpected flags";
482 }
483 clock_.AdvanceTimeMilliseconds(1000 / 5);
484 }
485
486 EXPECT_TRUE(overshoot);
487 EXPECT_TRUE(dropped_frame);
488
489 layers_.reset(); // Histograms are reported on destruction.
490
491 EXPECT_EQ(1, test::NumHistogramSamples(
492 "WebRTC.Video.Screenshare.Layer0.FrameRate"));
493 EXPECT_EQ(1, test::NumHistogramSamples(
494 "WebRTC.Video.Screenshare.Layer1.FrameRate"));
495 EXPECT_EQ(
496 1, test::NumHistogramSamples("WebRTC.Video.Screenshare.FramesPerDrop"));
497 EXPECT_EQ(1, test::NumHistogramSamples(
498 "WebRTC.Video.Screenshare.FramesPerOvershoot"));
499 EXPECT_EQ(1, test::NumHistogramSamples("WebRTC.Video.Screenshare.Layer0.Qp"));
500 EXPECT_EQ(1, test::NumHistogramSamples("WebRTC.Video.Screenshare.Layer1.Qp"));
501 EXPECT_EQ(1, test::NumHistogramSamples(
502 "WebRTC.Video.Screenshare.Layer0.TargetBitrate"));
503 EXPECT_EQ(1, test::NumHistogramSamples(
504 "WebRTC.Video.Screenshare.Layer1.TargetBitrate"));
505
506 EXPECT_GT(
507 test::LastHistogramSample("WebRTC.Video.Screenshare.Layer0.FrameRate"),
508 1);
509 EXPECT_GT(
510 test::LastHistogramSample("WebRTC.Video.Screenshare.Layer1.FrameRate"),
511 1);
512 EXPECT_GT(test::LastHistogramSample("WebRTC.Video.Screenshare.FramesPerDrop"),
513 1);
514 EXPECT_GT(
515 test::LastHistogramSample("WebRTC.Video.Screenshare.FramesPerOvershoot"),
516 1);
517 EXPECT_EQ(kTl0Qp,
518 test::LastHistogramSample("WebRTC.Video.Screenshare.Layer0.Qp"));
519 EXPECT_EQ(kTl1Qp,
520 test::LastHistogramSample("WebRTC.Video.Screenshare.Layer1.Qp"));
521 EXPECT_EQ(kDefaultTl0BitrateKbps,
522 test::LastHistogramSample(
523 "WebRTC.Video.Screenshare.Layer0.TargetBitrate"));
524 EXPECT_EQ(kDefaultTl1BitrateKbps,
525 test::LastHistogramSample(
526 "WebRTC.Video.Screenshare.Layer1.TargetBitrate"));
527 }
528
449 } // namespace webrtc 529 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698