OLD | NEW |
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 "vpx/vp8cx.h" | 14 #include "vpx/vp8cx.h" |
15 #include "vpx/vpx_encoder.h" | 15 #include "vpx/vpx_encoder.h" |
16 #include "webrtc/modules/video_coding/codecs/vp8/screenshare_layers.h" | 16 #include "webrtc/modules/video_coding/codecs/vp8/screenshare_layers.h" |
| 17 #include "webrtc/modules/video_coding/codecs/vp8/vp8_impl.h" |
17 #include "webrtc/modules/video_coding/include/video_codec_interface.h" | 18 #include "webrtc/modules/video_coding/include/video_codec_interface.h" |
18 #include "webrtc/modules/video_coding/utility/mock/mock_frame_dropper.h" | 19 #include "webrtc/modules/video_coding/utility/mock/mock_frame_dropper.h" |
19 #include "webrtc/system_wrappers/include/clock.h" | 20 #include "webrtc/system_wrappers/include/clock.h" |
20 #include "webrtc/system_wrappers/include/metrics.h" | 21 #include "webrtc/system_wrappers/include/metrics.h" |
21 #include "webrtc/system_wrappers/include/metrics_default.h" | 22 #include "webrtc/system_wrappers/include/metrics_default.h" |
22 #include "webrtc/test/gtest.h" | 23 #include "webrtc/test/gtest.h" |
23 | 24 |
24 using ::testing::_; | 25 using ::testing::_; |
25 using ::testing::ElementsAre; | 26 using ::testing::ElementsAre; |
26 using ::testing::NiceMock; | 27 using ::testing::NiceMock; |
(...skipping 23 matching lines...) Expand all Loading... |
50 ScreenshareLayerTest() | 51 ScreenshareLayerTest() |
51 : min_qp_(2), max_qp_(kDefaultQp), frame_size_(-1), clock_(1) {} | 52 : min_qp_(2), max_qp_(kDefaultQp), frame_size_(-1), clock_(1) {} |
52 virtual ~ScreenshareLayerTest() {} | 53 virtual ~ScreenshareLayerTest() {} |
53 | 54 |
54 void SetUp() override { layers_.reset(new ScreenshareLayers(2, 0, &clock_)); } | 55 void SetUp() override { layers_.reset(new ScreenshareLayers(2, 0, &clock_)); } |
55 | 56 |
56 void EncodeFrame(uint32_t timestamp, | 57 void EncodeFrame(uint32_t timestamp, |
57 bool base_sync, | 58 bool base_sync, |
58 CodecSpecificInfoVP8* vp8_info, | 59 CodecSpecificInfoVP8* vp8_info, |
59 int* flags) { | 60 int* flags) { |
60 *flags = layers_->EncodeFlags(timestamp); | 61 TemporalReferences tl_config = layers_->UpdateLayerConfig(timestamp); |
61 if (*flags == -1) | 62 if (tl_config.drop_frame) { |
| 63 *flags = -1; |
62 return; | 64 return; |
| 65 } |
| 66 *flags = VP8EncoderImpl::EncodeFlags(tl_config); |
63 layers_->PopulateCodecSpecific(base_sync, vp8_info, timestamp); | 67 layers_->PopulateCodecSpecific(base_sync, vp8_info, timestamp); |
64 ASSERT_NE(-1, frame_size_); | 68 ASSERT_NE(-1, frame_size_); |
65 layers_->FrameEncoded(frame_size_, kDefaultQp); | 69 layers_->FrameEncoded(frame_size_, kDefaultQp); |
66 } | 70 } |
67 | 71 |
68 void ConfigureBitrates() { | 72 void ConfigureBitrates() { |
69 vpx_codec_enc_cfg_t vpx_cfg; | 73 vpx_codec_enc_cfg_t vpx_cfg; |
70 memset(&vpx_cfg, 0, sizeof(vpx_codec_enc_cfg_t)); | 74 memset(&vpx_cfg, 0, sizeof(vpx_codec_enc_cfg_t)); |
71 vpx_cfg.rc_min_quantizer = min_qp_; | 75 vpx_cfg.rc_min_quantizer = min_qp_; |
72 vpx_cfg.rc_max_quantizer = max_qp_; | 76 vpx_cfg.rc_max_quantizer = max_qp_; |
(...skipping 27 matching lines...) Expand all Loading... |
100 if (got_tl0 && got_tl1) | 104 if (got_tl0 && got_tl1) |
101 return timestamp; | 105 return timestamp; |
102 } | 106 } |
103 ADD_FAILURE() << "Frames from both layers not received in time."; | 107 ADD_FAILURE() << "Frames from both layers not received in time."; |
104 return 0; | 108 return 0; |
105 } | 109 } |
106 | 110 |
107 int SkipUntilTl(int layer, int timestamp) { | 111 int SkipUntilTl(int layer, int timestamp) { |
108 CodecSpecificInfoVP8 vp8_info; | 112 CodecSpecificInfoVP8 vp8_info; |
109 for (int i = 0; i < 5; ++i) { | 113 for (int i = 0; i < 5; ++i) { |
110 layers_->EncodeFlags(timestamp); | 114 TemporalReferences tl_config = layers_->UpdateLayerConfig(timestamp); |
| 115 VP8EncoderImpl::EncodeFlags(tl_config); |
111 timestamp += kTimestampDelta5Fps; | 116 timestamp += kTimestampDelta5Fps; |
112 layers_->PopulateCodecSpecific(false, &vp8_info, timestamp); | 117 layers_->PopulateCodecSpecific(false, &vp8_info, timestamp); |
113 if (vp8_info.temporalIdx != layer) { | 118 if (vp8_info.temporalIdx != layer) { |
114 layers_->FrameEncoded(frame_size_, kDefaultQp); | 119 layers_->FrameEncoded(frame_size_, kDefaultQp); |
115 } else { | 120 } else { |
116 return timestamp; | 121 return timestamp; |
117 } | 122 } |
118 } | 123 } |
119 ADD_FAILURE() << "Did not get a frame of TL" << layer << " in time."; | 124 ADD_FAILURE() << "Did not get a frame of TL" << layer << " in time."; |
120 return 0; | 125 return 0; |
(...skipping 16 matching lines...) Expand all Loading... |
137 | 142 |
138 TEST_F(ScreenshareLayerTest, 1Layer) { | 143 TEST_F(ScreenshareLayerTest, 1Layer) { |
139 layers_.reset(new ScreenshareLayers(1, 0, &clock_)); | 144 layers_.reset(new ScreenshareLayers(1, 0, &clock_)); |
140 ConfigureBitrates(); | 145 ConfigureBitrates(); |
141 int flags = 0; | 146 int flags = 0; |
142 uint32_t timestamp = 0; | 147 uint32_t timestamp = 0; |
143 CodecSpecificInfoVP8 vp8_info; | 148 CodecSpecificInfoVP8 vp8_info; |
144 // One layer screenshare should not use the frame dropper as all frames will | 149 // One layer screenshare should not use the frame dropper as all frames will |
145 // belong to the base layer. | 150 // belong to the base layer. |
146 const int kSingleLayerFlags = 0; | 151 const int kSingleLayerFlags = 0; |
147 flags = layers_->EncodeFlags(timestamp); | 152 flags = VP8EncoderImpl::EncodeFlags(layers_->UpdateLayerConfig(timestamp)); |
148 EXPECT_EQ(kSingleLayerFlags, flags); | 153 EXPECT_EQ(kSingleLayerFlags, flags); |
149 layers_->PopulateCodecSpecific(false, &vp8_info, timestamp); | 154 layers_->PopulateCodecSpecific(false, &vp8_info, timestamp); |
150 EXPECT_EQ(static_cast<uint8_t>(kNoTemporalIdx), vp8_info.temporalIdx); | 155 EXPECT_EQ(static_cast<uint8_t>(kNoTemporalIdx), vp8_info.temporalIdx); |
151 EXPECT_FALSE(vp8_info.layerSync); | 156 EXPECT_FALSE(vp8_info.layerSync); |
152 EXPECT_EQ(kNoTl0PicIdx, vp8_info.tl0PicIdx); | 157 EXPECT_EQ(kNoTl0PicIdx, vp8_info.tl0PicIdx); |
153 layers_->FrameEncoded(frame_size_, kDefaultQp); | 158 layers_->FrameEncoded(frame_size_, kDefaultQp); |
154 flags = layers_->EncodeFlags(timestamp); | 159 flags = VP8EncoderImpl::EncodeFlags(layers_->UpdateLayerConfig(timestamp)); |
155 EXPECT_EQ(kSingleLayerFlags, flags); | 160 EXPECT_EQ(kSingleLayerFlags, flags); |
156 timestamp += kTimestampDelta5Fps; | 161 timestamp += kTimestampDelta5Fps; |
157 layers_->PopulateCodecSpecific(false, &vp8_info, timestamp); | 162 layers_->PopulateCodecSpecific(false, &vp8_info, timestamp); |
158 EXPECT_EQ(static_cast<uint8_t>(kNoTemporalIdx), vp8_info.temporalIdx); | 163 EXPECT_EQ(static_cast<uint8_t>(kNoTemporalIdx), vp8_info.temporalIdx); |
159 EXPECT_FALSE(vp8_info.layerSync); | 164 EXPECT_FALSE(vp8_info.layerSync); |
160 EXPECT_EQ(kNoTl0PicIdx, vp8_info.tl0PicIdx); | 165 EXPECT_EQ(kNoTl0PicIdx, vp8_info.tl0PicIdx); |
161 layers_->FrameEncoded(frame_size_, kDefaultQp); | 166 layers_->FrameEncoded(frame_size_, kDefaultQp); |
162 } | 167 } |
163 | 168 |
164 TEST_F(ScreenshareLayerTest, 2Layer) { | 169 TEST_F(ScreenshareLayerTest, 2Layer) { |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
232 | 237 |
233 TEST_F(ScreenshareLayerTest, 2LayersSyncAfterTimeout) { | 238 TEST_F(ScreenshareLayerTest, 2LayersSyncAfterTimeout) { |
234 ConfigureBitrates(); | 239 ConfigureBitrates(); |
235 uint32_t timestamp = 0; | 240 uint32_t timestamp = 0; |
236 CodecSpecificInfoVP8 vp8_info; | 241 CodecSpecificInfoVP8 vp8_info; |
237 std::vector<int> sync_times; | 242 std::vector<int> sync_times; |
238 | 243 |
239 const int kNumFrames = kMaxSyncPeriodSeconds * kFrameRate * 2 - 1; | 244 const int kNumFrames = kMaxSyncPeriodSeconds * kFrameRate * 2 - 1; |
240 for (int i = 0; i < kNumFrames; ++i) { | 245 for (int i = 0; i < kNumFrames; ++i) { |
241 timestamp += kTimestampDelta5Fps; | 246 timestamp += kTimestampDelta5Fps; |
242 layers_->EncodeFlags(timestamp); | 247 layers_->UpdateLayerConfig(timestamp); |
243 layers_->PopulateCodecSpecific(false, &vp8_info, timestamp); | 248 layers_->PopulateCodecSpecific(false, &vp8_info, timestamp); |
244 | 249 |
245 // Simulate TL1 being at least 8 qp steps better. | 250 // Simulate TL1 being at least 8 qp steps better. |
246 if (vp8_info.temporalIdx == 0) { | 251 if (vp8_info.temporalIdx == 0) { |
247 layers_->FrameEncoded(frame_size_, kDefaultQp); | 252 layers_->FrameEncoded(frame_size_, kDefaultQp); |
248 } else { | 253 } else { |
249 layers_->FrameEncoded(frame_size_, kDefaultQp - 8); | 254 layers_->FrameEncoded(frame_size_, kDefaultQp - 8); |
250 } | 255 } |
251 | 256 |
252 if (vp8_info.temporalIdx == 1 && vp8_info.layerSync) | 257 if (vp8_info.temporalIdx == 1 && vp8_info.layerSync) |
253 sync_times.push_back(timestamp); | 258 sync_times.push_back(timestamp); |
254 } | 259 } |
255 | 260 |
256 ASSERT_EQ(2u, sync_times.size()); | 261 ASSERT_EQ(2u, sync_times.size()); |
257 EXPECT_GE(sync_times[1] - sync_times[0], 90000 * kMaxSyncPeriodSeconds); | 262 EXPECT_GE(sync_times[1] - sync_times[0], 90000 * kMaxSyncPeriodSeconds); |
258 } | 263 } |
259 | 264 |
260 TEST_F(ScreenshareLayerTest, 2LayersSyncAfterSimilarQP) { | 265 TEST_F(ScreenshareLayerTest, 2LayersSyncAfterSimilarQP) { |
261 ConfigureBitrates(); | 266 ConfigureBitrates(); |
262 uint32_t timestamp = 0; | 267 uint32_t timestamp = 0; |
263 CodecSpecificInfoVP8 vp8_info; | 268 CodecSpecificInfoVP8 vp8_info; |
264 std::vector<int> sync_times; | 269 std::vector<int> sync_times; |
265 | 270 |
266 const int kNumFrames = (kSyncPeriodSeconds + | 271 const int kNumFrames = (kSyncPeriodSeconds + |
267 ((kMaxSyncPeriodSeconds - kSyncPeriodSeconds) / 2)) * | 272 ((kMaxSyncPeriodSeconds - kSyncPeriodSeconds) / 2)) * |
268 kFrameRate; | 273 kFrameRate; |
269 for (int i = 0; i < kNumFrames; ++i) { | 274 for (int i = 0; i < kNumFrames; ++i) { |
270 timestamp += kTimestampDelta5Fps; | 275 timestamp += kTimestampDelta5Fps; |
271 layers_->EncodeFlags(timestamp); | 276 layers_->UpdateLayerConfig(timestamp); |
272 layers_->PopulateCodecSpecific(false, &vp8_info, timestamp); | 277 layers_->PopulateCodecSpecific(false, &vp8_info, timestamp); |
273 | 278 |
274 // Simulate TL1 being at least 8 qp steps better. | 279 // Simulate TL1 being at least 8 qp steps better. |
275 if (vp8_info.temporalIdx == 0) { | 280 if (vp8_info.temporalIdx == 0) { |
276 layers_->FrameEncoded(frame_size_, kDefaultQp); | 281 layers_->FrameEncoded(frame_size_, kDefaultQp); |
277 } else { | 282 } else { |
278 layers_->FrameEncoded(frame_size_, kDefaultQp - 8); | 283 layers_->FrameEncoded(frame_size_, kDefaultQp - 8); |
279 } | 284 } |
280 | 285 |
281 if (vp8_info.temporalIdx == 1 && vp8_info.layerSync) | 286 if (vp8_info.temporalIdx == 1 && vp8_info.layerSync) |
282 sync_times.push_back(timestamp); | 287 sync_times.push_back(timestamp); |
283 } | 288 } |
284 | 289 |
285 ASSERT_EQ(1u, sync_times.size()); | 290 ASSERT_EQ(1u, sync_times.size()); |
286 | 291 |
287 bool bumped_tl0_quality = false; | 292 bool bumped_tl0_quality = false; |
288 for (int i = 0; i < 3; ++i) { | 293 for (int i = 0; i < 3; ++i) { |
289 timestamp += kTimestampDelta5Fps; | 294 timestamp += kTimestampDelta5Fps; |
290 int flags = layers_->EncodeFlags(timestamp); | 295 TemporalReferences tl_config = layers_->UpdateLayerConfig(timestamp); |
| 296 int flags = VP8EncoderImpl::EncodeFlags(tl_config); |
291 layers_->PopulateCodecSpecific(false, &vp8_info, timestamp); | 297 layers_->PopulateCodecSpecific(false, &vp8_info, timestamp); |
292 | 298 |
293 if (vp8_info.temporalIdx == 0) { | 299 if (vp8_info.temporalIdx == 0) { |
294 // Bump TL0 to same quality as TL1. | 300 // Bump TL0 to same quality as TL1. |
295 layers_->FrameEncoded(frame_size_, kDefaultQp - 8); | 301 layers_->FrameEncoded(frame_size_, kDefaultQp - 8); |
296 bumped_tl0_quality = true; | 302 bumped_tl0_quality = true; |
297 } else { | 303 } else { |
298 layers_->FrameEncoded(frame_size_, kDefaultQp - 8); | 304 layers_->FrameEncoded(frame_size_, kDefaultQp - 8); |
299 if (bumped_tl0_quality) { | 305 if (bumped_tl0_quality) { |
300 EXPECT_TRUE(vp8_info.layerSync); | 306 EXPECT_TRUE(vp8_info.layerSync); |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
429 // Updates cfg with current target bitrate. | 435 // Updates cfg with current target bitrate. |
430 EXPECT_TRUE(layers_->UpdateConfiguration(&cfg)); | 436 EXPECT_TRUE(layers_->UpdateConfiguration(&cfg)); |
431 | 437 |
432 uint32_t timestamp = RunGracePeriod(); | 438 uint32_t timestamp = RunGracePeriod(); |
433 timestamp = SkipUntilTl(0, timestamp); | 439 timestamp = SkipUntilTl(0, timestamp); |
434 | 440 |
435 // Size 0 indicates dropped frame. | 441 // Size 0 indicates dropped frame. |
436 layers_->FrameEncoded(0, kDefaultQp); | 442 layers_->FrameEncoded(0, kDefaultQp); |
437 timestamp += kTimestampDelta5Fps; | 443 timestamp += kTimestampDelta5Fps; |
438 EXPECT_FALSE(layers_->UpdateConfiguration(&cfg)); | 444 EXPECT_FALSE(layers_->UpdateConfiguration(&cfg)); |
439 EXPECT_EQ(kTl0Flags, layers_->EncodeFlags(timestamp)); | 445 EXPECT_EQ(kTl0Flags, |
| 446 VP8EncoderImpl::EncodeFlags(layers_->UpdateLayerConfig(timestamp))); |
440 layers_->PopulateCodecSpecific(false, &vp8_info, timestamp); | 447 layers_->PopulateCodecSpecific(false, &vp8_info, timestamp); |
441 layers_->FrameEncoded(frame_size_, kDefaultQp); | 448 layers_->FrameEncoded(frame_size_, kDefaultQp); |
442 | 449 |
443 timestamp = SkipUntilTl(0, timestamp); | 450 timestamp = SkipUntilTl(0, timestamp); |
444 EXPECT_TRUE(layers_->UpdateConfiguration(&cfg)); | 451 EXPECT_TRUE(layers_->UpdateConfiguration(&cfg)); |
445 EXPECT_LT(cfg.rc_max_quantizer, static_cast<unsigned int>(kDefaultQp)); | 452 EXPECT_LT(cfg.rc_max_quantizer, static_cast<unsigned int>(kDefaultQp)); |
446 layers_->FrameEncoded(frame_size_, kDefaultQp); | 453 layers_->FrameEncoded(frame_size_, kDefaultQp); |
447 | 454 |
448 layers_->EncodeFlags(timestamp); | 455 layers_->UpdateLayerConfig(timestamp); |
449 timestamp += kTimestampDelta5Fps; | 456 timestamp += kTimestampDelta5Fps; |
450 EXPECT_TRUE(layers_->UpdateConfiguration(&cfg)); | 457 EXPECT_TRUE(layers_->UpdateConfiguration(&cfg)); |
451 layers_->PopulateCodecSpecific(false, &vp8_info, timestamp); | 458 layers_->PopulateCodecSpecific(false, &vp8_info, timestamp); |
452 EXPECT_EQ(cfg.rc_max_quantizer, static_cast<unsigned int>(kDefaultQp)); | 459 EXPECT_EQ(cfg.rc_max_quantizer, static_cast<unsigned int>(kDefaultQp)); |
453 layers_->FrameEncoded(frame_size_, kDefaultQp); | 460 layers_->FrameEncoded(frame_size_, kDefaultQp); |
454 | 461 |
455 // Next drop in TL1. | 462 // Next drop in TL1. |
456 | 463 |
457 timestamp = SkipUntilTl(1, timestamp); | 464 timestamp = SkipUntilTl(1, timestamp); |
458 layers_->FrameEncoded(0, kDefaultQp); | 465 layers_->FrameEncoded(0, kDefaultQp); |
459 timestamp += kTimestampDelta5Fps; | 466 timestamp += kTimestampDelta5Fps; |
460 EXPECT_FALSE(layers_->UpdateConfiguration(&cfg)); | 467 EXPECT_FALSE(layers_->UpdateConfiguration(&cfg)); |
461 EXPECT_EQ(kTl1Flags, layers_->EncodeFlags(timestamp)); | 468 EXPECT_EQ(kTl1Flags, |
| 469 VP8EncoderImpl::EncodeFlags(layers_->UpdateLayerConfig(timestamp))); |
462 layers_->PopulateCodecSpecific(false, &vp8_info, timestamp); | 470 layers_->PopulateCodecSpecific(false, &vp8_info, timestamp); |
463 layers_->FrameEncoded(frame_size_, kDefaultQp); | 471 layers_->FrameEncoded(frame_size_, kDefaultQp); |
464 | 472 |
465 timestamp = SkipUntilTl(1, timestamp); | 473 timestamp = SkipUntilTl(1, timestamp); |
466 EXPECT_TRUE(layers_->UpdateConfiguration(&cfg)); | 474 EXPECT_TRUE(layers_->UpdateConfiguration(&cfg)); |
467 EXPECT_LT(cfg.rc_max_quantizer, static_cast<unsigned int>(kDefaultQp)); | 475 EXPECT_LT(cfg.rc_max_quantizer, static_cast<unsigned int>(kDefaultQp)); |
468 layers_->FrameEncoded(frame_size_, kDefaultQp); | 476 layers_->FrameEncoded(frame_size_, kDefaultQp); |
469 | 477 |
470 layers_->EncodeFlags(timestamp); | 478 layers_->UpdateLayerConfig(timestamp); |
471 timestamp += kTimestampDelta5Fps; | 479 timestamp += kTimestampDelta5Fps; |
472 EXPECT_TRUE(layers_->UpdateConfiguration(&cfg)); | 480 EXPECT_TRUE(layers_->UpdateConfiguration(&cfg)); |
473 layers_->PopulateCodecSpecific(false, &vp8_info, timestamp); | 481 layers_->PopulateCodecSpecific(false, &vp8_info, timestamp); |
474 EXPECT_EQ(cfg.rc_max_quantizer, static_cast<unsigned int>(kDefaultQp)); | 482 EXPECT_EQ(cfg.rc_max_quantizer, static_cast<unsigned int>(kDefaultQp)); |
475 layers_->FrameEncoded(frame_size_, kDefaultQp); | 483 layers_->FrameEncoded(frame_size_, kDefaultQp); |
476 } | 484 } |
477 | 485 |
478 TEST_F(ScreenshareLayerTest, RespectsMaxIntervalBetweenFrames) { | 486 TEST_F(ScreenshareLayerTest, RespectsMaxIntervalBetweenFrames) { |
479 const int kLowBitrateKbps = 50; | 487 const int kLowBitrateKbps = 50; |
480 const int kLargeFrameSizeBytes = 100000; | 488 const int kLargeFrameSizeBytes = 100000; |
481 const uint32_t kStartTimestamp = 1234; | 489 const uint32_t kStartTimestamp = 1234; |
482 | 490 |
483 vpx_codec_enc_cfg_t cfg = GetConfig(); | 491 vpx_codec_enc_cfg_t cfg = GetConfig(); |
484 layers_->OnRatesUpdated(kLowBitrateKbps, kLowBitrateKbps, 5); | 492 layers_->OnRatesUpdated(kLowBitrateKbps, kLowBitrateKbps, 5); |
485 layers_->UpdateConfiguration(&cfg); | 493 layers_->UpdateConfiguration(&cfg); |
486 | 494 |
487 EXPECT_EQ(kTl0Flags, layers_->EncodeFlags(kStartTimestamp)); | 495 EXPECT_EQ(kTl0Flags, VP8EncoderImpl::EncodeFlags( |
| 496 layers_->UpdateLayerConfig(kStartTimestamp))); |
488 layers_->FrameEncoded(kLargeFrameSizeBytes, kDefaultQp); | 497 layers_->FrameEncoded(kLargeFrameSizeBytes, kDefaultQp); |
489 | 498 |
490 const uint32_t kTwoSecondsLater = | 499 const uint32_t kTwoSecondsLater = |
491 kStartTimestamp + (ScreenshareLayers::kMaxFrameIntervalMs * 90); | 500 kStartTimestamp + (ScreenshareLayers::kMaxFrameIntervalMs * 90); |
492 | 501 |
493 // Sanity check, repayment time should exceed kMaxFrameIntervalMs. | 502 // Sanity check, repayment time should exceed kMaxFrameIntervalMs. |
494 ASSERT_GT(kStartTimestamp + 90 * (kLargeFrameSizeBytes * 8) / kLowBitrateKbps, | 503 ASSERT_GT(kStartTimestamp + 90 * (kLargeFrameSizeBytes * 8) / kLowBitrateKbps, |
495 kStartTimestamp + (ScreenshareLayers::kMaxFrameIntervalMs * 90)); | 504 kStartTimestamp + (ScreenshareLayers::kMaxFrameIntervalMs * 90)); |
496 | 505 |
497 EXPECT_EQ(-1, layers_->EncodeFlags(kTwoSecondsLater)); | 506 EXPECT_TRUE(layers_->UpdateLayerConfig(kTwoSecondsLater).drop_frame); |
498 // More than two seconds has passed since last frame, one should be emitted | 507 // More than two seconds has passed since last frame, one should be emitted |
499 // even if bitrate target is then exceeded. | 508 // even if bitrate target is then exceeded. |
500 EXPECT_EQ(kTl0Flags, layers_->EncodeFlags(kTwoSecondsLater + 90)); | 509 EXPECT_EQ(kTl0Flags, VP8EncoderImpl::EncodeFlags( |
| 510 layers_->UpdateLayerConfig(kTwoSecondsLater + 90))); |
501 } | 511 } |
502 | 512 |
503 TEST_F(ScreenshareLayerTest, UpdatesHistograms) { | 513 TEST_F(ScreenshareLayerTest, UpdatesHistograms) { |
504 metrics::Reset(); | 514 metrics::Reset(); |
505 ConfigureBitrates(); | 515 ConfigureBitrates(); |
506 vpx_codec_enc_cfg_t cfg = GetConfig(); | 516 vpx_codec_enc_cfg_t cfg = GetConfig(); |
507 bool trigger_drop = false; | 517 bool trigger_drop = false; |
508 bool dropped_frame = false; | 518 bool dropped_frame = false; |
509 bool overshoot = false; | 519 bool overshoot = false; |
510 const int kTl0Qp = 35; | 520 const int kTl0Qp = 35; |
511 const int kTl1Qp = 30; | 521 const int kTl1Qp = 30; |
512 for (int64_t timestamp = 0; | 522 for (int64_t timestamp = 0; |
513 timestamp < kTimestampDelta5Fps * 5 * metrics::kMinRunTimeInSeconds; | 523 timestamp < kTimestampDelta5Fps * 5 * metrics::kMinRunTimeInSeconds; |
514 timestamp += kTimestampDelta5Fps) { | 524 timestamp += kTimestampDelta5Fps) { |
515 int flags = layers_->EncodeFlags(timestamp); | 525 TemporalReferences tl_config = layers_->UpdateLayerConfig(timestamp); |
| 526 if (tl_config.drop_frame) { |
| 527 dropped_frame = true; |
| 528 continue; |
| 529 } |
| 530 int flags = VP8EncoderImpl::EncodeFlags(tl_config); |
516 if (flags != -1) | 531 if (flags != -1) |
517 layers_->UpdateConfiguration(&cfg); | 532 layers_->UpdateConfiguration(&cfg); |
518 | 533 |
519 if (timestamp >= kTimestampDelta5Fps * 5 && !overshoot && flags != -1) { | 534 if (timestamp >= kTimestampDelta5Fps * 5 && !overshoot && flags != -1) { |
520 // Simulate one overshoot. | 535 // Simulate one overshoot. |
521 layers_->FrameEncoded(0, 0); | 536 layers_->FrameEncoded(0, 0); |
522 overshoot = true; | 537 overshoot = true; |
523 flags = layers_->EncodeFlags(timestamp); | 538 flags = |
| 539 VP8EncoderImpl::EncodeFlags(layers_->UpdateLayerConfig(timestamp)); |
524 } | 540 } |
525 | 541 |
526 if (flags == kTl0Flags) { | 542 if (flags == kTl0Flags) { |
527 if (timestamp >= kTimestampDelta5Fps * 20 && !trigger_drop) { | 543 if (timestamp >= kTimestampDelta5Fps * 20 && !trigger_drop) { |
528 // Simulate a too large frame, to cause frame drop. | 544 // Simulate a too large frame, to cause frame drop. |
529 layers_->FrameEncoded(frame_size_ * 5, kTl0Qp); | 545 layers_->FrameEncoded(frame_size_ * 5, kTl0Qp); |
530 trigger_drop = true; | 546 trigger_drop = true; |
531 } else { | 547 } else { |
532 layers_->FrameEncoded(frame_size_, kTl0Qp); | 548 layers_->FrameEncoded(frame_size_, kTl0Qp); |
533 } | 549 } |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
587 | 603 |
588 int64_t kTestSpanMs = 2000; | 604 int64_t kTestSpanMs = 2000; |
589 int64_t kFrameIntervalsMs = 1000 / kFrameRate; | 605 int64_t kFrameIntervalsMs = 1000 / kFrameRate; |
590 | 606 |
591 uint32_t timestamp = 1234; | 607 uint32_t timestamp = 1234; |
592 int num_input_frames = 0; | 608 int num_input_frames = 0; |
593 int num_discarded_frames = 0; | 609 int num_discarded_frames = 0; |
594 | 610 |
595 // Send at regular rate - no drops expected. | 611 // Send at regular rate - no drops expected. |
596 for (int64_t i = 0; i < kTestSpanMs; i += kFrameIntervalsMs) { | 612 for (int64_t i = 0; i < kTestSpanMs; i += kFrameIntervalsMs) { |
597 if (layers_->EncodeFlags(timestamp) == -1) { | 613 if (layers_->UpdateLayerConfig(timestamp).drop_frame) { |
598 ++num_discarded_frames; | 614 ++num_discarded_frames; |
599 } else { | 615 } else { |
600 size_t frame_size_bytes = kDefaultTl0BitrateKbps * kFrameIntervalsMs / 8; | 616 size_t frame_size_bytes = kDefaultTl0BitrateKbps * kFrameIntervalsMs / 8; |
601 layers_->FrameEncoded(frame_size_bytes, kDefaultQp); | 617 layers_->FrameEncoded(frame_size_bytes, kDefaultQp); |
602 } | 618 } |
603 timestamp += kFrameIntervalsMs * 90; | 619 timestamp += kFrameIntervalsMs * 90; |
604 clock_.AdvanceTimeMilliseconds(kFrameIntervalsMs); | 620 clock_.AdvanceTimeMilliseconds(kFrameIntervalsMs); |
605 ++num_input_frames; | 621 ++num_input_frames; |
606 } | 622 } |
607 EXPECT_EQ(0, num_discarded_frames); | 623 EXPECT_EQ(0, num_discarded_frames); |
608 | 624 |
609 // Send at twice the configured rate - drop every other frame. | 625 // Send at twice the configured rate - drop every other frame. |
610 num_input_frames = 0; | 626 num_input_frames = 0; |
611 num_discarded_frames = 0; | 627 num_discarded_frames = 0; |
612 for (int64_t i = 0; i < kTestSpanMs; i += kFrameIntervalsMs / 2) { | 628 for (int64_t i = 0; i < kTestSpanMs; i += kFrameIntervalsMs / 2) { |
613 if (layers_->EncodeFlags(timestamp) == -1) { | 629 if (layers_->UpdateLayerConfig(timestamp).drop_frame) { |
614 ++num_discarded_frames; | 630 ++num_discarded_frames; |
615 } else { | 631 } else { |
616 size_t frame_size_bytes = kDefaultTl0BitrateKbps * kFrameIntervalsMs / 8; | 632 size_t frame_size_bytes = kDefaultTl0BitrateKbps * kFrameIntervalsMs / 8; |
617 layers_->FrameEncoded(frame_size_bytes, kDefaultQp); | 633 layers_->FrameEncoded(frame_size_bytes, kDefaultQp); |
618 } | 634 } |
619 timestamp += kFrameIntervalsMs * 90 / 2; | 635 timestamp += kFrameIntervalsMs * 90 / 2; |
620 clock_.AdvanceTimeMilliseconds(kFrameIntervalsMs / 2); | 636 clock_.AdvanceTimeMilliseconds(kFrameIntervalsMs / 2); |
621 ++num_input_frames; | 637 ++num_input_frames; |
622 } | 638 } |
623 | 639 |
624 // Allow for some rounding errors in the measurements. | 640 // Allow for some rounding errors in the measurements. |
625 EXPECT_NEAR(num_discarded_frames, num_input_frames / 2, 2); | 641 EXPECT_NEAR(num_discarded_frames, num_input_frames / 2, 2); |
626 } | 642 } |
627 } // namespace webrtc | 643 } // namespace webrtc |
OLD | NEW |