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 |
(...skipping 19 matching lines...) Expand all Loading... |
30 | 30 |
31 // 5 frames per second at 90 kHz. | 31 // 5 frames per second at 90 kHz. |
32 const uint32_t kTimestampDelta5Fps = 90000 / 5; | 32 const uint32_t kTimestampDelta5Fps = 90000 / 5; |
33 const int kDefaultQp = 54; | 33 const int kDefaultQp = 54; |
34 const int kDefaultTl0BitrateKbps = 200; | 34 const int kDefaultTl0BitrateKbps = 200; |
35 const int kDefaultTl1BitrateKbps = 2000; | 35 const int kDefaultTl1BitrateKbps = 2000; |
36 const int kFrameRate = 5; | 36 const int kFrameRate = 5; |
37 const int kSyncPeriodSeconds = 5; | 37 const int kSyncPeriodSeconds = 5; |
38 const int kMaxSyncPeriodSeconds = 10; | 38 const int kMaxSyncPeriodSeconds = 10; |
39 | 39 |
| 40 // Expected flags for corresponding temporal layers. |
| 41 const int kTl0Flags = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF | |
| 42 VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF; |
| 43 const int kTl1Flags = |
| 44 VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST; |
| 45 const int kTl1SyncFlags = VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_REF_GF | |
| 46 VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST; |
| 47 |
40 class ScreenshareLayerTest : public ::testing::Test { | 48 class ScreenshareLayerTest : public ::testing::Test { |
41 protected: | 49 protected: |
42 ScreenshareLayerTest() | 50 ScreenshareLayerTest() |
43 : min_qp_(2), max_qp_(kDefaultQp), frame_size_(-1), clock_(1) {} | 51 : min_qp_(2), max_qp_(kDefaultQp), frame_size_(-1), clock_(1) {} |
44 virtual ~ScreenshareLayerTest() {} | 52 virtual ~ScreenshareLayerTest() {} |
45 | 53 |
46 void SetUp() override { layers_.reset(new ScreenshareLayers(2, 0, &clock_)); } | 54 void SetUp() override { layers_.reset(new ScreenshareLayers(2, 0, &clock_)); } |
47 | 55 |
48 void EncodeFrame(uint32_t timestamp, | 56 void EncodeFrame(uint32_t timestamp, |
49 bool base_sync, | 57 bool base_sync, |
50 CodecSpecificInfoVP8* vp8_info, | 58 CodecSpecificInfoVP8* vp8_info, |
51 int* flags) { | 59 int* flags) { |
52 *flags = layers_->EncodeFlags(timestamp); | 60 *flags = layers_->EncodeFlags(timestamp); |
53 if (*flags == -1) | 61 if (*flags == -1) |
54 return; | 62 return; |
55 layers_->PopulateCodecSpecific(base_sync, vp8_info, timestamp); | 63 layers_->PopulateCodecSpecific(base_sync, vp8_info, timestamp); |
56 ASSERT_NE(-1, frame_size_); | 64 ASSERT_NE(-1, frame_size_); |
57 layers_->FrameEncoded(frame_size_, timestamp, kDefaultQp); | 65 layers_->FrameEncoded(frame_size_, kDefaultQp); |
58 } | 66 } |
59 | 67 |
60 void ConfigureBitrates() { | 68 void ConfigureBitrates() { |
61 vpx_codec_enc_cfg_t vpx_cfg; | 69 vpx_codec_enc_cfg_t vpx_cfg; |
62 memset(&vpx_cfg, 0, sizeof(vpx_codec_enc_cfg_t)); | 70 memset(&vpx_cfg, 0, sizeof(vpx_codec_enc_cfg_t)); |
63 vpx_cfg.rc_min_quantizer = min_qp_; | 71 vpx_cfg.rc_min_quantizer = min_qp_; |
64 vpx_cfg.rc_max_quantizer = max_qp_; | 72 vpx_cfg.rc_max_quantizer = max_qp_; |
65 EXPECT_THAT(layers_->OnRatesUpdated(kDefaultTl0BitrateKbps, | 73 EXPECT_THAT(layers_->OnRatesUpdated(kDefaultTl0BitrateKbps, |
66 kDefaultTl1BitrateKbps, kFrameRate), | 74 kDefaultTl1BitrateKbps, kFrameRate), |
67 ElementsAre(kDefaultTl0BitrateKbps, | 75 ElementsAre(kDefaultTl0BitrateKbps, |
(...skipping 28 matching lines...) Expand all Loading... |
96 return 0; | 104 return 0; |
97 } | 105 } |
98 | 106 |
99 int SkipUntilTl(int layer, int timestamp) { | 107 int SkipUntilTl(int layer, int timestamp) { |
100 CodecSpecificInfoVP8 vp8_info; | 108 CodecSpecificInfoVP8 vp8_info; |
101 for (int i = 0; i < 5; ++i) { | 109 for (int i = 0; i < 5; ++i) { |
102 layers_->EncodeFlags(timestamp); | 110 layers_->EncodeFlags(timestamp); |
103 timestamp += kTimestampDelta5Fps; | 111 timestamp += kTimestampDelta5Fps; |
104 layers_->PopulateCodecSpecific(false, &vp8_info, timestamp); | 112 layers_->PopulateCodecSpecific(false, &vp8_info, timestamp); |
105 if (vp8_info.temporalIdx != layer) { | 113 if (vp8_info.temporalIdx != layer) { |
106 layers_->FrameEncoded(frame_size_, timestamp, kDefaultQp); | 114 layers_->FrameEncoded(frame_size_, kDefaultQp); |
107 } else { | 115 } else { |
108 return timestamp; | 116 return timestamp; |
109 } | 117 } |
110 } | 118 } |
111 ADD_FAILURE() << "Did not get a frame of TL" << layer << " in time."; | 119 ADD_FAILURE() << "Did not get a frame of TL" << layer << " in time."; |
112 return 0; | 120 return 0; |
113 } | 121 } |
114 | 122 |
115 vpx_codec_enc_cfg_t GetConfig() { | 123 vpx_codec_enc_cfg_t GetConfig() { |
116 vpx_codec_enc_cfg_t cfg; | 124 vpx_codec_enc_cfg_t cfg; |
(...skipping 18 matching lines...) Expand all Loading... |
135 CodecSpecificInfoVP8 vp8_info; | 143 CodecSpecificInfoVP8 vp8_info; |
136 // One layer screenshare should not use the frame dropper as all frames will | 144 // One layer screenshare should not use the frame dropper as all frames will |
137 // belong to the base layer. | 145 // belong to the base layer. |
138 const int kSingleLayerFlags = 0; | 146 const int kSingleLayerFlags = 0; |
139 flags = layers_->EncodeFlags(timestamp); | 147 flags = layers_->EncodeFlags(timestamp); |
140 EXPECT_EQ(kSingleLayerFlags, flags); | 148 EXPECT_EQ(kSingleLayerFlags, flags); |
141 layers_->PopulateCodecSpecific(false, &vp8_info, timestamp); | 149 layers_->PopulateCodecSpecific(false, &vp8_info, timestamp); |
142 EXPECT_EQ(static_cast<uint8_t>(kNoTemporalIdx), vp8_info.temporalIdx); | 150 EXPECT_EQ(static_cast<uint8_t>(kNoTemporalIdx), vp8_info.temporalIdx); |
143 EXPECT_FALSE(vp8_info.layerSync); | 151 EXPECT_FALSE(vp8_info.layerSync); |
144 EXPECT_EQ(kNoTl0PicIdx, vp8_info.tl0PicIdx); | 152 EXPECT_EQ(kNoTl0PicIdx, vp8_info.tl0PicIdx); |
145 layers_->FrameEncoded(frame_size_, timestamp, kDefaultQp); | 153 layers_->FrameEncoded(frame_size_, kDefaultQp); |
146 flags = layers_->EncodeFlags(timestamp); | 154 flags = layers_->EncodeFlags(timestamp); |
147 EXPECT_EQ(kSingleLayerFlags, flags); | 155 EXPECT_EQ(kSingleLayerFlags, flags); |
148 timestamp += kTimestampDelta5Fps; | 156 timestamp += kTimestampDelta5Fps; |
149 layers_->PopulateCodecSpecific(false, &vp8_info, timestamp); | 157 layers_->PopulateCodecSpecific(false, &vp8_info, timestamp); |
150 EXPECT_EQ(static_cast<uint8_t>(kNoTemporalIdx), vp8_info.temporalIdx); | 158 EXPECT_EQ(static_cast<uint8_t>(kNoTemporalIdx), vp8_info.temporalIdx); |
151 EXPECT_FALSE(vp8_info.layerSync); | 159 EXPECT_FALSE(vp8_info.layerSync); |
152 EXPECT_EQ(kNoTl0PicIdx, vp8_info.tl0PicIdx); | 160 EXPECT_EQ(kNoTl0PicIdx, vp8_info.tl0PicIdx); |
153 layers_->FrameEncoded(frame_size_, timestamp, kDefaultQp); | 161 layers_->FrameEncoded(frame_size_, kDefaultQp); |
154 } | 162 } |
155 | 163 |
156 TEST_F(ScreenshareLayerTest, 2Layer) { | 164 TEST_F(ScreenshareLayerTest, 2Layer) { |
157 ConfigureBitrates(); | 165 ConfigureBitrates(); |
158 int flags = 0; | 166 int flags = 0; |
159 uint32_t timestamp = 0; | 167 uint32_t timestamp = 0; |
160 uint8_t expected_tl0_idx = 0; | 168 uint8_t expected_tl0_idx = 0; |
161 CodecSpecificInfoVP8 vp8_info; | 169 CodecSpecificInfoVP8 vp8_info; |
162 EncodeFrame(timestamp, false, &vp8_info, &flags); | 170 EncodeFrame(timestamp, false, &vp8_info, &flags); |
163 EXPECT_EQ(ScreenshareLayers::kTl0Flags, flags); | 171 EXPECT_EQ(kTl0Flags, flags); |
164 EXPECT_EQ(0, vp8_info.temporalIdx); | 172 EXPECT_EQ(0, vp8_info.temporalIdx); |
165 EXPECT_FALSE(vp8_info.layerSync); | 173 EXPECT_FALSE(vp8_info.layerSync); |
166 ++expected_tl0_idx; | 174 ++expected_tl0_idx; |
167 EXPECT_EQ(expected_tl0_idx, vp8_info.tl0PicIdx); | 175 EXPECT_EQ(expected_tl0_idx, vp8_info.tl0PicIdx); |
168 | 176 |
169 // Insert 5 frames, cover grace period. All should be in TL0. | 177 // Insert 5 frames, cover grace period. All should be in TL0. |
170 for (int i = 0; i < 5; ++i) { | 178 for (int i = 0; i < 5; ++i) { |
171 timestamp += kTimestampDelta5Fps; | 179 timestamp += kTimestampDelta5Fps; |
172 EncodeFrame(timestamp, false, &vp8_info, &flags); | 180 EncodeFrame(timestamp, false, &vp8_info, &flags); |
173 EXPECT_EQ(0, vp8_info.temporalIdx); | 181 EXPECT_EQ(0, vp8_info.temporalIdx); |
174 EXPECT_FALSE(vp8_info.layerSync); | 182 EXPECT_FALSE(vp8_info.layerSync); |
175 ++expected_tl0_idx; | 183 ++expected_tl0_idx; |
176 EXPECT_EQ(expected_tl0_idx, vp8_info.tl0PicIdx); | 184 EXPECT_EQ(expected_tl0_idx, vp8_info.tl0PicIdx); |
177 } | 185 } |
178 | 186 |
179 // First frame in TL0. | 187 // First frame in TL0. |
180 timestamp += kTimestampDelta5Fps; | 188 timestamp += kTimestampDelta5Fps; |
181 EncodeFrame(timestamp, false, &vp8_info, &flags); | 189 EncodeFrame(timestamp, false, &vp8_info, &flags); |
182 EXPECT_EQ(ScreenshareLayers::kTl0Flags, flags); | 190 EXPECT_EQ(kTl0Flags, flags); |
183 EXPECT_EQ(0, vp8_info.temporalIdx); | 191 EXPECT_EQ(0, vp8_info.temporalIdx); |
184 EXPECT_FALSE(vp8_info.layerSync); | 192 EXPECT_FALSE(vp8_info.layerSync); |
185 ++expected_tl0_idx; | 193 ++expected_tl0_idx; |
186 EXPECT_EQ(expected_tl0_idx, vp8_info.tl0PicIdx); | 194 EXPECT_EQ(expected_tl0_idx, vp8_info.tl0PicIdx); |
187 | 195 |
188 // Drop two frames from TL0, thus being coded in TL1. | 196 // Drop two frames from TL0, thus being coded in TL1. |
189 timestamp += kTimestampDelta5Fps; | 197 timestamp += kTimestampDelta5Fps; |
190 EncodeFrame(timestamp, false, &vp8_info, &flags); | 198 EncodeFrame(timestamp, false, &vp8_info, &flags); |
191 // First frame is sync frame. | 199 // First frame is sync frame. |
192 EXPECT_EQ(ScreenshareLayers::kTl1SyncFlags, flags); | 200 EXPECT_EQ(kTl1SyncFlags, flags); |
193 EXPECT_EQ(1, vp8_info.temporalIdx); | 201 EXPECT_EQ(1, vp8_info.temporalIdx); |
194 EXPECT_TRUE(vp8_info.layerSync); | 202 EXPECT_TRUE(vp8_info.layerSync); |
195 EXPECT_EQ(expected_tl0_idx, vp8_info.tl0PicIdx); | 203 EXPECT_EQ(expected_tl0_idx, vp8_info.tl0PicIdx); |
196 | 204 |
197 timestamp += kTimestampDelta5Fps; | 205 timestamp += kTimestampDelta5Fps; |
198 EncodeFrame(timestamp, false, &vp8_info, &flags); | 206 EncodeFrame(timestamp, false, &vp8_info, &flags); |
199 EXPECT_EQ(ScreenshareLayers::kTl1Flags, flags); | 207 EXPECT_EQ(kTl1Flags, flags); |
200 EXPECT_EQ(1, vp8_info.temporalIdx); | 208 EXPECT_EQ(1, vp8_info.temporalIdx); |
201 EXPECT_FALSE(vp8_info.layerSync); | 209 EXPECT_FALSE(vp8_info.layerSync); |
202 EXPECT_EQ(expected_tl0_idx, vp8_info.tl0PicIdx); | 210 EXPECT_EQ(expected_tl0_idx, vp8_info.tl0PicIdx); |
203 } | 211 } |
204 | 212 |
205 TEST_F(ScreenshareLayerTest, 2LayersPeriodicSync) { | 213 TEST_F(ScreenshareLayerTest, 2LayersPeriodicSync) { |
206 ConfigureBitrates(); | 214 ConfigureBitrates(); |
207 int flags = 0; | 215 int flags = 0; |
208 uint32_t timestamp = 0; | 216 uint32_t timestamp = 0; |
209 CodecSpecificInfoVP8 vp8_info; | 217 CodecSpecificInfoVP8 vp8_info; |
(...skipping 19 matching lines...) Expand all Loading... |
229 std::vector<int> sync_times; | 237 std::vector<int> sync_times; |
230 | 238 |
231 const int kNumFrames = kMaxSyncPeriodSeconds * kFrameRate * 2 - 1; | 239 const int kNumFrames = kMaxSyncPeriodSeconds * kFrameRate * 2 - 1; |
232 for (int i = 0; i < kNumFrames; ++i) { | 240 for (int i = 0; i < kNumFrames; ++i) { |
233 timestamp += kTimestampDelta5Fps; | 241 timestamp += kTimestampDelta5Fps; |
234 layers_->EncodeFlags(timestamp); | 242 layers_->EncodeFlags(timestamp); |
235 layers_->PopulateCodecSpecific(false, &vp8_info, timestamp); | 243 layers_->PopulateCodecSpecific(false, &vp8_info, timestamp); |
236 | 244 |
237 // Simulate TL1 being at least 8 qp steps better. | 245 // Simulate TL1 being at least 8 qp steps better. |
238 if (vp8_info.temporalIdx == 0) { | 246 if (vp8_info.temporalIdx == 0) { |
239 layers_->FrameEncoded(frame_size_, timestamp, kDefaultQp); | 247 layers_->FrameEncoded(frame_size_, kDefaultQp); |
240 } else { | 248 } else { |
241 layers_->FrameEncoded(frame_size_, timestamp, kDefaultQp - 8); | 249 layers_->FrameEncoded(frame_size_, kDefaultQp - 8); |
242 } | 250 } |
243 | 251 |
244 if (vp8_info.temporalIdx == 1 && vp8_info.layerSync) | 252 if (vp8_info.temporalIdx == 1 && vp8_info.layerSync) |
245 sync_times.push_back(timestamp); | 253 sync_times.push_back(timestamp); |
246 } | 254 } |
247 | 255 |
248 ASSERT_EQ(2u, sync_times.size()); | 256 ASSERT_EQ(2u, sync_times.size()); |
249 EXPECT_GE(sync_times[1] - sync_times[0], 90000 * kMaxSyncPeriodSeconds); | 257 EXPECT_GE(sync_times[1] - sync_times[0], 90000 * kMaxSyncPeriodSeconds); |
250 } | 258 } |
251 | 259 |
252 TEST_F(ScreenshareLayerTest, 2LayersSyncAfterSimilarQP) { | 260 TEST_F(ScreenshareLayerTest, 2LayersSyncAfterSimilarQP) { |
253 ConfigureBitrates(); | 261 ConfigureBitrates(); |
254 uint32_t timestamp = 0; | 262 uint32_t timestamp = 0; |
255 CodecSpecificInfoVP8 vp8_info; | 263 CodecSpecificInfoVP8 vp8_info; |
256 std::vector<int> sync_times; | 264 std::vector<int> sync_times; |
257 | 265 |
258 const int kNumFrames = (kSyncPeriodSeconds + | 266 const int kNumFrames = (kSyncPeriodSeconds + |
259 ((kMaxSyncPeriodSeconds - kSyncPeriodSeconds) / 2)) * | 267 ((kMaxSyncPeriodSeconds - kSyncPeriodSeconds) / 2)) * |
260 kFrameRate; | 268 kFrameRate; |
261 for (int i = 0; i < kNumFrames; ++i) { | 269 for (int i = 0; i < kNumFrames; ++i) { |
262 timestamp += kTimestampDelta5Fps; | 270 timestamp += kTimestampDelta5Fps; |
263 layers_->EncodeFlags(timestamp); | 271 layers_->EncodeFlags(timestamp); |
264 layers_->PopulateCodecSpecific(false, &vp8_info, timestamp); | 272 layers_->PopulateCodecSpecific(false, &vp8_info, timestamp); |
265 | 273 |
266 // Simulate TL1 being at least 8 qp steps better. | 274 // Simulate TL1 being at least 8 qp steps better. |
267 if (vp8_info.temporalIdx == 0) { | 275 if (vp8_info.temporalIdx == 0) { |
268 layers_->FrameEncoded(frame_size_, timestamp, kDefaultQp); | 276 layers_->FrameEncoded(frame_size_, kDefaultQp); |
269 } else { | 277 } else { |
270 layers_->FrameEncoded(frame_size_, timestamp, kDefaultQp - 8); | 278 layers_->FrameEncoded(frame_size_, kDefaultQp - 8); |
271 } | 279 } |
272 | 280 |
273 if (vp8_info.temporalIdx == 1 && vp8_info.layerSync) | 281 if (vp8_info.temporalIdx == 1 && vp8_info.layerSync) |
274 sync_times.push_back(timestamp); | 282 sync_times.push_back(timestamp); |
275 } | 283 } |
276 | 284 |
277 ASSERT_EQ(1u, sync_times.size()); | 285 ASSERT_EQ(1u, sync_times.size()); |
278 | 286 |
279 bool bumped_tl0_quality = false; | 287 bool bumped_tl0_quality = false; |
280 for (int i = 0; i < 3; ++i) { | 288 for (int i = 0; i < 3; ++i) { |
281 timestamp += kTimestampDelta5Fps; | 289 timestamp += kTimestampDelta5Fps; |
282 int flags = layers_->EncodeFlags(timestamp); | 290 int flags = layers_->EncodeFlags(timestamp); |
283 layers_->PopulateCodecSpecific(false, &vp8_info, timestamp); | 291 layers_->PopulateCodecSpecific(false, &vp8_info, timestamp); |
284 | 292 |
285 if (vp8_info.temporalIdx == 0) { | 293 if (vp8_info.temporalIdx == 0) { |
286 // Bump TL0 to same quality as TL1. | 294 // Bump TL0 to same quality as TL1. |
287 layers_->FrameEncoded(frame_size_, timestamp, kDefaultQp - 8); | 295 layers_->FrameEncoded(frame_size_, kDefaultQp - 8); |
288 bumped_tl0_quality = true; | 296 bumped_tl0_quality = true; |
289 } else { | 297 } else { |
290 layers_->FrameEncoded(frame_size_, timestamp, kDefaultQp - 8); | 298 layers_->FrameEncoded(frame_size_, kDefaultQp - 8); |
291 if (bumped_tl0_quality) { | 299 if (bumped_tl0_quality) { |
292 EXPECT_TRUE(vp8_info.layerSync); | 300 EXPECT_TRUE(vp8_info.layerSync); |
293 EXPECT_EQ(ScreenshareLayers::kTl1SyncFlags, flags); | 301 EXPECT_EQ(kTl1SyncFlags, flags); |
294 return; | 302 return; |
295 } | 303 } |
296 } | 304 } |
297 } | 305 } |
298 ADD_FAILURE() << "No TL1 frame arrived within time limit."; | 306 ADD_FAILURE() << "No TL1 frame arrived within time limit."; |
299 } | 307 } |
300 | 308 |
301 TEST_F(ScreenshareLayerTest, 2LayersToggling) { | 309 TEST_F(ScreenshareLayerTest, 2LayersToggling) { |
302 ConfigureBitrates(); | 310 ConfigureBitrates(); |
303 int flags = 0; | 311 int flags = 0; |
(...skipping 25 matching lines...) Expand all Loading... |
329 ConfigureBitrates(); | 337 ConfigureBitrates(); |
330 frame_size_ = ((kDefaultTl0BitrateKbps * 1000) / 8) / kFrameRate; | 338 frame_size_ = ((kDefaultTl0BitrateKbps * 1000) / 8) / kFrameRate; |
331 | 339 |
332 int flags = 0; | 340 int flags = 0; |
333 uint32_t timestamp = 0; | 341 uint32_t timestamp = 0; |
334 CodecSpecificInfoVP8 vp8_info; | 342 CodecSpecificInfoVP8 vp8_info; |
335 // Insert 50 frames, small enough that all fits in TL0. | 343 // Insert 50 frames, small enough that all fits in TL0. |
336 for (int i = 0; i < 50; ++i) { | 344 for (int i = 0; i < 50; ++i) { |
337 EncodeFrame(timestamp, false, &vp8_info, &flags); | 345 EncodeFrame(timestamp, false, &vp8_info, &flags); |
338 timestamp += kTimestampDelta5Fps; | 346 timestamp += kTimestampDelta5Fps; |
339 EXPECT_EQ(ScreenshareLayers::kTl0Flags, flags); | 347 EXPECT_EQ(kTl0Flags, flags); |
340 EXPECT_EQ(0, vp8_info.temporalIdx); | 348 EXPECT_EQ(0, vp8_info.temporalIdx); |
341 } | 349 } |
342 } | 350 } |
343 | 351 |
344 TEST_F(ScreenshareLayerTest, TooHighBitrate) { | 352 TEST_F(ScreenshareLayerTest, TooHighBitrate) { |
345 ConfigureBitrates(); | 353 ConfigureBitrates(); |
346 frame_size_ = 2 * ((kDefaultTl1BitrateKbps * 1000) / 8) / kFrameRate; | 354 frame_size_ = 2 * ((kDefaultTl1BitrateKbps * 1000) / 8) / kFrameRate; |
347 int flags = 0; | 355 int flags = 0; |
348 CodecSpecificInfoVP8 vp8_info; | 356 CodecSpecificInfoVP8 vp8_info; |
349 uint32_t timestamp = RunGracePeriod(); | 357 uint32_t timestamp = RunGracePeriod(); |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
418 ConfigureBitrates(); | 426 ConfigureBitrates(); |
419 CodecSpecificInfoVP8 vp8_info; | 427 CodecSpecificInfoVP8 vp8_info; |
420 vpx_codec_enc_cfg_t cfg = GetConfig(); | 428 vpx_codec_enc_cfg_t cfg = GetConfig(); |
421 // Updates cfg with current target bitrate. | 429 // Updates cfg with current target bitrate. |
422 EXPECT_TRUE(layers_->UpdateConfiguration(&cfg)); | 430 EXPECT_TRUE(layers_->UpdateConfiguration(&cfg)); |
423 | 431 |
424 uint32_t timestamp = RunGracePeriod(); | 432 uint32_t timestamp = RunGracePeriod(); |
425 timestamp = SkipUntilTl(0, timestamp); | 433 timestamp = SkipUntilTl(0, timestamp); |
426 | 434 |
427 // Size 0 indicates dropped frame. | 435 // Size 0 indicates dropped frame. |
428 layers_->FrameEncoded(0, timestamp, kDefaultQp); | 436 layers_->FrameEncoded(0, kDefaultQp); |
429 timestamp += kTimestampDelta5Fps; | 437 timestamp += kTimestampDelta5Fps; |
430 EXPECT_FALSE(layers_->UpdateConfiguration(&cfg)); | 438 EXPECT_FALSE(layers_->UpdateConfiguration(&cfg)); |
431 EXPECT_EQ(ScreenshareLayers::kTl0Flags, layers_->EncodeFlags(timestamp)); | 439 EXPECT_EQ(kTl0Flags, layers_->EncodeFlags(timestamp)); |
432 layers_->PopulateCodecSpecific(false, &vp8_info, timestamp); | 440 layers_->PopulateCodecSpecific(false, &vp8_info, timestamp); |
433 layers_->FrameEncoded(frame_size_, timestamp, kDefaultQp); | 441 layers_->FrameEncoded(frame_size_, kDefaultQp); |
434 | 442 |
435 timestamp = SkipUntilTl(0, timestamp); | 443 timestamp = SkipUntilTl(0, timestamp); |
436 EXPECT_TRUE(layers_->UpdateConfiguration(&cfg)); | 444 EXPECT_TRUE(layers_->UpdateConfiguration(&cfg)); |
437 EXPECT_LT(cfg.rc_max_quantizer, static_cast<unsigned int>(kDefaultQp)); | 445 EXPECT_LT(cfg.rc_max_quantizer, static_cast<unsigned int>(kDefaultQp)); |
438 layers_->FrameEncoded(frame_size_, timestamp, kDefaultQp); | 446 layers_->FrameEncoded(frame_size_, kDefaultQp); |
439 | 447 |
440 layers_->EncodeFlags(timestamp); | 448 layers_->EncodeFlags(timestamp); |
441 timestamp += kTimestampDelta5Fps; | 449 timestamp += kTimestampDelta5Fps; |
442 EXPECT_TRUE(layers_->UpdateConfiguration(&cfg)); | 450 EXPECT_TRUE(layers_->UpdateConfiguration(&cfg)); |
443 layers_->PopulateCodecSpecific(false, &vp8_info, timestamp); | 451 layers_->PopulateCodecSpecific(false, &vp8_info, timestamp); |
444 EXPECT_EQ(cfg.rc_max_quantizer, static_cast<unsigned int>(kDefaultQp)); | 452 EXPECT_EQ(cfg.rc_max_quantizer, static_cast<unsigned int>(kDefaultQp)); |
445 layers_->FrameEncoded(frame_size_, timestamp, kDefaultQp); | 453 layers_->FrameEncoded(frame_size_, kDefaultQp); |
446 | 454 |
447 // Next drop in TL1. | 455 // Next drop in TL1. |
448 | 456 |
449 timestamp = SkipUntilTl(1, timestamp); | 457 timestamp = SkipUntilTl(1, timestamp); |
450 layers_->FrameEncoded(0, timestamp, kDefaultQp); | 458 layers_->FrameEncoded(0, kDefaultQp); |
451 timestamp += kTimestampDelta5Fps; | 459 timestamp += kTimestampDelta5Fps; |
452 EXPECT_FALSE(layers_->UpdateConfiguration(&cfg)); | 460 EXPECT_FALSE(layers_->UpdateConfiguration(&cfg)); |
453 EXPECT_EQ(ScreenshareLayers::kTl1Flags, layers_->EncodeFlags(timestamp)); | 461 EXPECT_EQ(kTl1Flags, layers_->EncodeFlags(timestamp)); |
454 layers_->PopulateCodecSpecific(false, &vp8_info, timestamp); | 462 layers_->PopulateCodecSpecific(false, &vp8_info, timestamp); |
455 layers_->FrameEncoded(frame_size_, timestamp, kDefaultQp); | 463 layers_->FrameEncoded(frame_size_, kDefaultQp); |
456 | 464 |
457 timestamp = SkipUntilTl(1, timestamp); | 465 timestamp = SkipUntilTl(1, timestamp); |
458 EXPECT_TRUE(layers_->UpdateConfiguration(&cfg)); | 466 EXPECT_TRUE(layers_->UpdateConfiguration(&cfg)); |
459 EXPECT_LT(cfg.rc_max_quantizer, static_cast<unsigned int>(kDefaultQp)); | 467 EXPECT_LT(cfg.rc_max_quantizer, static_cast<unsigned int>(kDefaultQp)); |
460 layers_->FrameEncoded(frame_size_, timestamp, kDefaultQp); | 468 layers_->FrameEncoded(frame_size_, kDefaultQp); |
461 | 469 |
462 layers_->EncodeFlags(timestamp); | 470 layers_->EncodeFlags(timestamp); |
463 timestamp += kTimestampDelta5Fps; | 471 timestamp += kTimestampDelta5Fps; |
464 EXPECT_TRUE(layers_->UpdateConfiguration(&cfg)); | 472 EXPECT_TRUE(layers_->UpdateConfiguration(&cfg)); |
465 layers_->PopulateCodecSpecific(false, &vp8_info, timestamp); | 473 layers_->PopulateCodecSpecific(false, &vp8_info, timestamp); |
466 EXPECT_EQ(cfg.rc_max_quantizer, static_cast<unsigned int>(kDefaultQp)); | 474 EXPECT_EQ(cfg.rc_max_quantizer, static_cast<unsigned int>(kDefaultQp)); |
467 layers_->FrameEncoded(frame_size_, timestamp, kDefaultQp); | 475 layers_->FrameEncoded(frame_size_, kDefaultQp); |
468 } | 476 } |
469 | 477 |
470 TEST_F(ScreenshareLayerTest, RespectsMaxIntervalBetweenFrames) { | 478 TEST_F(ScreenshareLayerTest, RespectsMaxIntervalBetweenFrames) { |
471 const int kLowBitrateKbps = 50; | 479 const int kLowBitrateKbps = 50; |
472 const int kLargeFrameSizeBytes = 100000; | 480 const int kLargeFrameSizeBytes = 100000; |
473 const uint32_t kStartTimestamp = 1234; | 481 const uint32_t kStartTimestamp = 1234; |
474 | 482 |
475 vpx_codec_enc_cfg_t cfg = GetConfig(); | 483 vpx_codec_enc_cfg_t cfg = GetConfig(); |
476 layers_->OnRatesUpdated(kLowBitrateKbps, kLowBitrateKbps, 5); | 484 layers_->OnRatesUpdated(kLowBitrateKbps, kLowBitrateKbps, 5); |
477 layers_->UpdateConfiguration(&cfg); | 485 layers_->UpdateConfiguration(&cfg); |
478 | 486 |
479 EXPECT_EQ(ScreenshareLayers::kTl0Flags, | 487 EXPECT_EQ(kTl0Flags, layers_->EncodeFlags(kStartTimestamp)); |
480 layers_->EncodeFlags(kStartTimestamp)); | 488 layers_->FrameEncoded(kLargeFrameSizeBytes, kDefaultQp); |
481 layers_->FrameEncoded(kLargeFrameSizeBytes, kStartTimestamp, kDefaultQp); | |
482 | 489 |
483 const uint32_t kTwoSecondsLater = | 490 const uint32_t kTwoSecondsLater = |
484 kStartTimestamp + (ScreenshareLayers::kMaxFrameIntervalMs * 90); | 491 kStartTimestamp + (ScreenshareLayers::kMaxFrameIntervalMs * 90); |
485 | 492 |
486 // Sanity check, repayment time should exceed kMaxFrameIntervalMs. | 493 // Sanity check, repayment time should exceed kMaxFrameIntervalMs. |
487 ASSERT_GT(kStartTimestamp + 90 * (kLargeFrameSizeBytes * 8) / kLowBitrateKbps, | 494 ASSERT_GT(kStartTimestamp + 90 * (kLargeFrameSizeBytes * 8) / kLowBitrateKbps, |
488 kStartTimestamp + (ScreenshareLayers::kMaxFrameIntervalMs * 90)); | 495 kStartTimestamp + (ScreenshareLayers::kMaxFrameIntervalMs * 90)); |
489 | 496 |
490 EXPECT_EQ(-1, layers_->EncodeFlags(kTwoSecondsLater)); | 497 EXPECT_EQ(-1, layers_->EncodeFlags(kTwoSecondsLater)); |
491 // More than two seconds has passed since last frame, one should be emitted | 498 // More than two seconds has passed since last frame, one should be emitted |
492 // even if bitrate target is then exceeded. | 499 // even if bitrate target is then exceeded. |
493 EXPECT_EQ(ScreenshareLayers::kTl0Flags, | 500 EXPECT_EQ(kTl0Flags, layers_->EncodeFlags(kTwoSecondsLater + 90)); |
494 layers_->EncodeFlags(kTwoSecondsLater + 90)); | |
495 } | 501 } |
496 | 502 |
497 TEST_F(ScreenshareLayerTest, UpdatesHistograms) { | 503 TEST_F(ScreenshareLayerTest, UpdatesHistograms) { |
498 metrics::Reset(); | 504 metrics::Reset(); |
499 ConfigureBitrates(); | 505 ConfigureBitrates(); |
500 vpx_codec_enc_cfg_t cfg = GetConfig(); | 506 vpx_codec_enc_cfg_t cfg = GetConfig(); |
501 bool trigger_drop = false; | 507 bool trigger_drop = false; |
502 bool dropped_frame = false; | 508 bool dropped_frame = false; |
503 bool overshoot = false; | 509 bool overshoot = false; |
504 const int kTl0Qp = 35; | 510 const int kTl0Qp = 35; |
505 const int kTl1Qp = 30; | 511 const int kTl1Qp = 30; |
506 for (int64_t timestamp = 0; | 512 for (int64_t timestamp = 0; |
507 timestamp < kTimestampDelta5Fps * 5 * metrics::kMinRunTimeInSeconds; | 513 timestamp < kTimestampDelta5Fps * 5 * metrics::kMinRunTimeInSeconds; |
508 timestamp += kTimestampDelta5Fps) { | 514 timestamp += kTimestampDelta5Fps) { |
509 int flags = layers_->EncodeFlags(timestamp); | 515 int flags = layers_->EncodeFlags(timestamp); |
510 if (flags != -1) | 516 if (flags != -1) |
511 layers_->UpdateConfiguration(&cfg); | 517 layers_->UpdateConfiguration(&cfg); |
512 | 518 |
513 if (timestamp >= kTimestampDelta5Fps * 5 && !overshoot && flags != -1) { | 519 if (timestamp >= kTimestampDelta5Fps * 5 && !overshoot && flags != -1) { |
514 // Simulate one overshoot. | 520 // Simulate one overshoot. |
515 layers_->FrameEncoded(0, timestamp, 0); | 521 layers_->FrameEncoded(0, 0); |
516 overshoot = true; | 522 overshoot = true; |
517 flags = layers_->EncodeFlags(timestamp); | 523 flags = layers_->EncodeFlags(timestamp); |
518 } | 524 } |
519 | 525 |
520 if (flags == ScreenshareLayers::kTl0Flags) { | 526 if (flags == kTl0Flags) { |
521 if (timestamp >= kTimestampDelta5Fps * 20 && !trigger_drop) { | 527 if (timestamp >= kTimestampDelta5Fps * 20 && !trigger_drop) { |
522 // Simulate a too large frame, to cause frame drop. | 528 // Simulate a too large frame, to cause frame drop. |
523 layers_->FrameEncoded(frame_size_ * 5, timestamp, kTl0Qp); | 529 layers_->FrameEncoded(frame_size_ * 5, kTl0Qp); |
524 trigger_drop = true; | 530 trigger_drop = true; |
525 } else { | 531 } else { |
526 layers_->FrameEncoded(frame_size_, timestamp, kTl0Qp); | 532 layers_->FrameEncoded(frame_size_, kTl0Qp); |
527 } | 533 } |
528 } else if (flags == ScreenshareLayers::kTl1Flags || | 534 } else if (flags == kTl1Flags || flags == kTl1SyncFlags) { |
529 flags == ScreenshareLayers::kTl1SyncFlags) { | 535 layers_->FrameEncoded(frame_size_, kTl1Qp); |
530 layers_->FrameEncoded(frame_size_, timestamp, kTl1Qp); | |
531 } else if (flags == -1) { | 536 } else if (flags == -1) { |
532 dropped_frame = true; | 537 dropped_frame = true; |
533 } else { | 538 } else { |
534 RTC_NOTREACHED() << "Unexpected flags"; | 539 RTC_NOTREACHED() << "Unexpected flags"; |
535 } | 540 } |
536 clock_.AdvanceTimeMilliseconds(1000 / 5); | 541 clock_.AdvanceTimeMilliseconds(1000 / 5); |
537 } | 542 } |
538 | 543 |
539 EXPECT_TRUE(overshoot); | 544 EXPECT_TRUE(overshoot); |
540 EXPECT_TRUE(dropped_frame); | 545 EXPECT_TRUE(dropped_frame); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
586 uint32_t timestamp = 1234; | 591 uint32_t timestamp = 1234; |
587 int num_input_frames = 0; | 592 int num_input_frames = 0; |
588 int num_discarded_frames = 0; | 593 int num_discarded_frames = 0; |
589 | 594 |
590 // Send at regular rate - no drops expected. | 595 // Send at regular rate - no drops expected. |
591 for (int64_t i = 0; i < kTestSpanMs; i += kFrameIntervalsMs) { | 596 for (int64_t i = 0; i < kTestSpanMs; i += kFrameIntervalsMs) { |
592 if (layers_->EncodeFlags(timestamp) == -1) { | 597 if (layers_->EncodeFlags(timestamp) == -1) { |
593 ++num_discarded_frames; | 598 ++num_discarded_frames; |
594 } else { | 599 } else { |
595 size_t frame_size_bytes = kDefaultTl0BitrateKbps * kFrameIntervalsMs / 8; | 600 size_t frame_size_bytes = kDefaultTl0BitrateKbps * kFrameIntervalsMs / 8; |
596 layers_->FrameEncoded(frame_size_bytes, timestamp, kDefaultQp); | 601 layers_->FrameEncoded(frame_size_bytes, kDefaultQp); |
597 } | 602 } |
598 timestamp += kFrameIntervalsMs * 90; | 603 timestamp += kFrameIntervalsMs * 90; |
599 clock_.AdvanceTimeMilliseconds(kFrameIntervalsMs); | 604 clock_.AdvanceTimeMilliseconds(kFrameIntervalsMs); |
600 ++num_input_frames; | 605 ++num_input_frames; |
601 } | 606 } |
602 EXPECT_EQ(0, num_discarded_frames); | 607 EXPECT_EQ(0, num_discarded_frames); |
603 | 608 |
604 // Send at twice the configured rate - drop every other frame. | 609 // Send at twice the configured rate - drop every other frame. |
605 num_input_frames = 0; | 610 num_input_frames = 0; |
606 num_discarded_frames = 0; | 611 num_discarded_frames = 0; |
607 for (int64_t i = 0; i < kTestSpanMs; i += kFrameIntervalsMs / 2) { | 612 for (int64_t i = 0; i < kTestSpanMs; i += kFrameIntervalsMs / 2) { |
608 if (layers_->EncodeFlags(timestamp) == -1) { | 613 if (layers_->EncodeFlags(timestamp) == -1) { |
609 ++num_discarded_frames; | 614 ++num_discarded_frames; |
610 } else { | 615 } else { |
611 size_t frame_size_bytes = kDefaultTl0BitrateKbps * kFrameIntervalsMs / 8; | 616 size_t frame_size_bytes = kDefaultTl0BitrateKbps * kFrameIntervalsMs / 8; |
612 layers_->FrameEncoded(frame_size_bytes, timestamp, kDefaultQp); | 617 layers_->FrameEncoded(frame_size_bytes, kDefaultQp); |
613 } | 618 } |
614 timestamp += kFrameIntervalsMs * 90 / 2; | 619 timestamp += kFrameIntervalsMs * 90 / 2; |
615 clock_.AdvanceTimeMilliseconds(kFrameIntervalsMs / 2); | 620 clock_.AdvanceTimeMilliseconds(kFrameIntervalsMs / 2); |
616 ++num_input_frames; | 621 ++num_input_frames; |
617 } | 622 } |
618 | 623 |
619 // Allow for some rounding errors in the measurements. | 624 // Allow for some rounding errors in the measurements. |
620 EXPECT_NEAR(num_discarded_frames, num_input_frames / 2, 2); | 625 EXPECT_NEAR(num_discarded_frames, num_input_frames / 2, 2); |
621 } | 626 } |
622 } // namespace webrtc | 627 } // namespace webrtc |
OLD | NEW |