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 "webrtc/modules/video_coding/codecs/vp8/include/vp8.h" | 14 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h" |
15 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8_common_types.h" | 15 #include "webrtc/modules/video_coding/codecs/vp8/include/vp8_common_types.h" |
16 #include "webrtc/modules/video_coding/codecs/vp8/temporal_layers.h" | 16 #include "webrtc/modules/video_coding/codecs/vp8/temporal_layers.h" |
17 #include "webrtc/modules/video_coding/include/mock/mock_vcm_callbacks.h" | 17 #include "webrtc/modules/video_coding/include/mock/mock_vcm_callbacks.h" |
18 #include "webrtc/modules/video_coding/include/mock/mock_video_codec_interface.h" | 18 #include "webrtc/modules/video_coding/include/mock/mock_video_codec_interface.h" |
19 #include "webrtc/modules/video_coding/include/video_coding.h" | 19 #include "webrtc/modules/video_coding/include/video_coding.h" |
20 #include "webrtc/modules/video_coding/test/test_util.h" | 20 #include "webrtc/modules/video_coding/test/test_util.h" |
21 #include "webrtc/modules/video_coding/video_coding_impl.h" | 21 #include "webrtc/modules/video_coding/video_coding_impl.h" |
| 22 #include "webrtc/modules/video_coding/utility/default_video_bitrate_allocator.h" |
| 23 #include "webrtc/modules/video_coding/utility/simulcast_rate_allocator.h" |
22 #include "webrtc/system_wrappers/include/clock.h" | 24 #include "webrtc/system_wrappers/include/clock.h" |
23 #include "webrtc/test/frame_generator.h" | 25 #include "webrtc/test/frame_generator.h" |
24 #include "webrtc/test/gtest.h" | 26 #include "webrtc/test/gtest.h" |
25 #include "webrtc/test/testsupport/fileutils.h" | 27 #include "webrtc/test/testsupport/fileutils.h" |
26 | 28 |
27 using ::testing::_; | 29 using ::testing::_; |
28 using ::testing::AllOf; | 30 using ::testing::AllOf; |
29 using ::testing::ElementsAre; | 31 using ::testing::ElementsAre; |
30 using ::testing::ElementsAreArray; | 32 using ::testing::ElementsAreArray; |
31 using ::testing::Field; | 33 using ::testing::Field; |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
189 | 191 |
190 SimulatedClock clock_; | 192 SimulatedClock clock_; |
191 EncodedImageCallbackImpl encoded_frame_callback_; | 193 EncodedImageCallbackImpl encoded_frame_callback_; |
192 // Used by subclassing tests, need to outlive sender_. | 194 // Used by subclassing tests, need to outlive sender_. |
193 std::unique_ptr<VideoEncoder> encoder_; | 195 std::unique_ptr<VideoEncoder> encoder_; |
194 std::unique_ptr<VideoSender> sender_; | 196 std::unique_ptr<VideoSender> sender_; |
195 std::unique_ptr<FrameGenerator> generator_; | 197 std::unique_ptr<FrameGenerator> generator_; |
196 }; | 198 }; |
197 | 199 |
198 class TestVideoSenderWithMockEncoder : public TestVideoSender { | 200 class TestVideoSenderWithMockEncoder : public TestVideoSender { |
| 201 public: |
| 202 TestVideoSenderWithMockEncoder() {} |
| 203 ~TestVideoSenderWithMockEncoder() override {} |
| 204 |
199 protected: | 205 protected: |
200 void SetUp() override { | 206 void SetUp() override { |
201 TestVideoSender::SetUp(); | 207 TestVideoSender::SetUp(); |
202 sender_->RegisterExternalEncoder(&encoder_, kUnusedPayloadType, false); | 208 sender_->RegisterExternalEncoder(&encoder_, kUnusedPayloadType, false); |
203 VideoCodingModule::Codec(kVideoCodecVP8, &settings_); | 209 VideoCodingModule::Codec(kVideoCodecVP8, &settings_); |
204 settings_.numberOfSimulcastStreams = kNumberOfStreams; | 210 settings_.numberOfSimulcastStreams = kNumberOfStreams; |
205 ConfigureStream(kDefaultWidth / 4, kDefaultHeight / 4, 100, | 211 ConfigureStream(kDefaultWidth / 4, kDefaultHeight / 4, 100, |
206 &settings_.simulcastStream[0]); | 212 &settings_.simulcastStream[0]); |
207 ConfigureStream(kDefaultWidth / 2, kDefaultHeight / 2, 500, | 213 ConfigureStream(kDefaultWidth / 2, kDefaultHeight / 2, 500, |
208 &settings_.simulcastStream[1]); | 214 &settings_.simulcastStream[1]); |
209 ConfigureStream(kDefaultWidth, kDefaultHeight, 1200, | 215 ConfigureStream(kDefaultWidth, kDefaultHeight, 1200, |
210 &settings_.simulcastStream[2]); | 216 &settings_.simulcastStream[2]); |
211 settings_.plType = kUnusedPayloadType; // Use the mocked encoder. | 217 settings_.plType = kUnusedPayloadType; // Use the mocked encoder. |
212 generator_.reset( | 218 generator_.reset( |
213 new EmptyFrameGenerator(settings_.width, settings_.height)); | 219 new EmptyFrameGenerator(settings_.width, settings_.height)); |
214 EXPECT_EQ(0, sender_->RegisterSendCodec(&settings_, 1, 1200)); | 220 EXPECT_EQ(0, sender_->RegisterSendCodec(&settings_, 1, 1200)); |
| 221 rate_allocator_.reset(new DefaultVideoBitrateAllocator(settings_)); |
215 } | 222 } |
216 | 223 |
217 void TearDown() override { sender_.reset(); } | 224 void TearDown() override { sender_.reset(); } |
218 | 225 |
219 void ExpectIntraRequest(int stream) { | 226 void ExpectIntraRequest(int stream) { |
220 ExpectEncodeWithFrameTypes(stream, false); | 227 ExpectEncodeWithFrameTypes(stream, false); |
221 } | 228 } |
222 | 229 |
223 void ExpectInitialKeyFrames() { | 230 void ExpectInitialKeyFrames() { |
224 ExpectEncodeWithFrameTypes(-1, true); | 231 ExpectEncodeWithFrameTypes(-1, true); |
(...skipping 29 matching lines...) Expand all Loading... |
254 assert(stream); | 261 assert(stream); |
255 stream->width = width; | 262 stream->width = width; |
256 stream->height = height; | 263 stream->height = height; |
257 stream->maxBitrate = max_bitrate; | 264 stream->maxBitrate = max_bitrate; |
258 stream->numberOfTemporalLayers = kNumberOfLayers; | 265 stream->numberOfTemporalLayers = kNumberOfLayers; |
259 stream->qpMax = 45; | 266 stream->qpMax = 45; |
260 } | 267 } |
261 | 268 |
262 VideoCodec settings_; | 269 VideoCodec settings_; |
263 NiceMock<MockVideoEncoder> encoder_; | 270 NiceMock<MockVideoEncoder> encoder_; |
| 271 std::unique_ptr<DefaultVideoBitrateAllocator> rate_allocator_; |
264 }; | 272 }; |
265 | 273 |
266 TEST_F(TestVideoSenderWithMockEncoder, TestIntraRequests) { | 274 TEST_F(TestVideoSenderWithMockEncoder, TestIntraRequests) { |
267 // Initial request should be all keyframes. | 275 // Initial request should be all keyframes. |
268 ExpectInitialKeyFrames(); | 276 ExpectInitialKeyFrames(); |
269 AddFrame(); | 277 AddFrame(); |
270 EXPECT_EQ(0, sender_->IntraFrameRequest(0)); | 278 EXPECT_EQ(0, sender_->IntraFrameRequest(0)); |
271 ExpectIntraRequest(0); | 279 ExpectIntraRequest(0); |
272 AddFrame(); | 280 AddFrame(); |
273 ExpectIntraRequest(-1); | 281 ExpectIntraRequest(-1); |
(...skipping 10 matching lines...) Expand all Loading... |
284 AddFrame(); | 292 AddFrame(); |
285 ExpectIntraRequest(-1); | 293 ExpectIntraRequest(-1); |
286 AddFrame(); | 294 AddFrame(); |
287 | 295 |
288 EXPECT_EQ(-1, sender_->IntraFrameRequest(3)); | 296 EXPECT_EQ(-1, sender_->IntraFrameRequest(3)); |
289 ExpectIntraRequest(-1); | 297 ExpectIntraRequest(-1); |
290 AddFrame(); | 298 AddFrame(); |
291 } | 299 } |
292 | 300 |
293 TEST_F(TestVideoSenderWithMockEncoder, TestSetRate) { | 301 TEST_F(TestVideoSenderWithMockEncoder, TestSetRate) { |
294 const uint32_t new_bitrate = settings_.startBitrate + 300; | 302 const uint32_t new_bitrate_kbps = settings_.startBitrate + 300; |
295 EXPECT_CALL(encoder_, SetRates(new_bitrate, _)).Times(1).WillOnce(Return(0)); | 303 BitrateAllocation new_rate_allocation = rate_allocator_->GetAllocation( |
296 sender_->SetChannelParameters(new_bitrate * 1000, 0, 200); | 304 new_bitrate_kbps * 1000, settings_.maxFramerate); |
| 305 EXPECT_CALL(encoder_, SetRateAllocation(new_rate_allocation, _)) |
| 306 .Times(1) |
| 307 .WillOnce(Return(0)); |
| 308 sender_->SetChannelParameters(new_bitrate_kbps * 1000, 0, 200, |
| 309 rate_allocator_.get()); |
297 AddFrame(); | 310 AddFrame(); |
298 | 311 |
299 // Expect no call to encoder_.SetRates if the new bitrate is zero. | 312 // Expect no call to encoder_.SetRates if the new bitrate is zero. |
300 EXPECT_CALL(encoder_, SetRates(new_bitrate, _)).Times(0); | 313 EXPECT_CALL(encoder_, SetRateAllocation(_, _)).Times(0); |
301 sender_->SetChannelParameters(0, 0, 200); | 314 sender_->SetChannelParameters(0, 0, 200, rate_allocator_.get()); |
302 AddFrame(); | 315 AddFrame(); |
303 } | 316 } |
304 | 317 |
305 TEST_F(TestVideoSenderWithMockEncoder, TestIntraRequestsInternalCapture) { | 318 TEST_F(TestVideoSenderWithMockEncoder, TestIntraRequestsInternalCapture) { |
306 // De-register current external encoder. | 319 // De-register current external encoder. |
307 sender_->RegisterExternalEncoder(nullptr, kUnusedPayloadType, false); | 320 sender_->RegisterExternalEncoder(nullptr, kUnusedPayloadType, false); |
308 // Register encoder with internal capture. | 321 // Register encoder with internal capture. |
309 sender_->RegisterExternalEncoder(&encoder_, kUnusedPayloadType, true); | 322 sender_->RegisterExternalEncoder(&encoder_, kUnusedPayloadType, true); |
310 EXPECT_EQ(0, sender_->RegisterSendCodec(&settings_, 1, 1200)); | 323 EXPECT_EQ(0, sender_->RegisterSendCodec(&settings_, 1, 1200)); |
311 // Initial request should be all keyframes. | 324 // Initial request should be all keyframes. |
(...skipping 10 matching lines...) Expand all Loading... |
322 } | 335 } |
323 | 336 |
324 TEST_F(TestVideoSenderWithMockEncoder, TestEncoderParametersForInternalSource) { | 337 TEST_F(TestVideoSenderWithMockEncoder, TestEncoderParametersForInternalSource) { |
325 // De-register current external encoder. | 338 // De-register current external encoder. |
326 sender_->RegisterExternalEncoder(nullptr, kUnusedPayloadType, false); | 339 sender_->RegisterExternalEncoder(nullptr, kUnusedPayloadType, false); |
327 // Register encoder with internal capture. | 340 // Register encoder with internal capture. |
328 sender_->RegisterExternalEncoder(&encoder_, kUnusedPayloadType, true); | 341 sender_->RegisterExternalEncoder(&encoder_, kUnusedPayloadType, true); |
329 EXPECT_EQ(0, sender_->RegisterSendCodec(&settings_, 1, 1200)); | 342 EXPECT_EQ(0, sender_->RegisterSendCodec(&settings_, 1, 1200)); |
330 // Update encoder bitrate parameters. We expect that to immediately call | 343 // Update encoder bitrate parameters. We expect that to immediately call |
331 // SetRates on the encoder without waiting for AddFrame processing. | 344 // SetRates on the encoder without waiting for AddFrame processing. |
332 const uint32_t new_bitrate = settings_.startBitrate + 300; | 345 const uint32_t new_bitrate_kbps = settings_.startBitrate + 300; |
333 EXPECT_CALL(encoder_, SetRates(new_bitrate, _)).Times(1).WillOnce(Return(0)); | 346 BitrateAllocation new_rate_allocation = rate_allocator_->GetAllocation( |
334 sender_->SetChannelParameters(new_bitrate * 1000, 0, 200); | 347 new_bitrate_kbps * 1000, settings_.maxFramerate); |
| 348 EXPECT_CALL(encoder_, SetRateAllocation(new_rate_allocation, _)) |
| 349 .Times(1) |
| 350 .WillOnce(Return(0)); |
| 351 sender_->SetChannelParameters(new_bitrate_kbps * 1000, 0, 200, |
| 352 rate_allocator_.get()); |
335 } | 353 } |
336 | 354 |
337 TEST_F(TestVideoSenderWithMockEncoder, EncoderFramerateUpdatedViaProcess) { | 355 TEST_F(TestVideoSenderWithMockEncoder, EncoderFramerateUpdatedViaProcess) { |
338 sender_->SetChannelParameters(settings_.startBitrate * 1000, 0, 200); | 356 sender_->SetChannelParameters(settings_.startBitrate * 1000, 0, 200, |
| 357 rate_allocator_.get()); |
339 const int64_t kRateStatsWindowMs = 2000; | 358 const int64_t kRateStatsWindowMs = 2000; |
340 const uint32_t kInputFps = 20; | 359 const uint32_t kInputFps = 20; |
341 int64_t start_time = clock_.TimeInMilliseconds(); | 360 int64_t start_time = clock_.TimeInMilliseconds(); |
342 while (clock_.TimeInMilliseconds() < start_time + kRateStatsWindowMs) { | 361 while (clock_.TimeInMilliseconds() < start_time + kRateStatsWindowMs) { |
343 AddFrame(); | 362 AddFrame(); |
344 clock_.AdvanceTimeMilliseconds(1000 / kInputFps); | 363 clock_.AdvanceTimeMilliseconds(1000 / kInputFps); |
345 } | 364 } |
346 EXPECT_CALL(encoder_, SetRates(_, kInputFps)).Times(1).WillOnce(Return(0)); | 365 EXPECT_CALL(encoder_, SetRateAllocation(_, kInputFps)) |
| 366 .Times(1) |
| 367 .WillOnce(Return(0)); |
347 sender_->Process(); | 368 sender_->Process(); |
348 AddFrame(); | 369 AddFrame(); |
349 } | 370 } |
350 | 371 |
351 TEST_F(TestVideoSenderWithMockEncoder, | 372 TEST_F(TestVideoSenderWithMockEncoder, |
352 NoRedundantSetChannelParameterOrSetRatesCalls) { | 373 NoRedundantSetChannelParameterOrSetRatesCalls) { |
353 const uint8_t kLossRate = 4; | 374 const uint8_t kLossRate = 4; |
354 const uint8_t kRtt = 200; | 375 const uint8_t kRtt = 200; |
355 const int64_t kRateStatsWindowMs = 2000; | 376 const int64_t kRateStatsWindowMs = 2000; |
356 const uint32_t kInputFps = 20; | 377 const uint32_t kInputFps = 20; |
357 int64_t start_time = clock_.TimeInMilliseconds(); | 378 int64_t start_time = clock_.TimeInMilliseconds(); |
358 // Expect initial call to SetChannelParameters. Rates are initialized through | 379 // Expect initial call to SetChannelParameters. Rates are initialized through |
359 // InitEncode and expects no additional call before the framerate (or bitrate) | 380 // InitEncode and expects no additional call before the framerate (or bitrate) |
360 // updates. | 381 // updates. |
361 EXPECT_CALL(encoder_, SetChannelParameters(kLossRate, kRtt)) | 382 EXPECT_CALL(encoder_, SetChannelParameters(kLossRate, kRtt)) |
362 .Times(1) | 383 .Times(1) |
363 .WillOnce(Return(0)); | 384 .WillOnce(Return(0)); |
364 sender_->SetChannelParameters(settings_.startBitrate * 1000, kLossRate, kRtt); | 385 sender_->SetChannelParameters(settings_.startBitrate * 1000, kLossRate, kRtt, |
| 386 rate_allocator_.get()); |
365 while (clock_.TimeInMilliseconds() < start_time + kRateStatsWindowMs) { | 387 while (clock_.TimeInMilliseconds() < start_time + kRateStatsWindowMs) { |
366 AddFrame(); | 388 AddFrame(); |
367 clock_.AdvanceTimeMilliseconds(1000 / kInputFps); | 389 clock_.AdvanceTimeMilliseconds(1000 / kInputFps); |
368 } | 390 } |
369 // After process, input framerate should be updated but not ChannelParameters | 391 // After process, input framerate should be updated but not ChannelParameters |
370 // as they are the same as before. | 392 // as they are the same as before. |
371 EXPECT_CALL(encoder_, SetRates(_, kInputFps)).Times(1).WillOnce(Return(0)); | 393 EXPECT_CALL(encoder_, SetRateAllocation(_, kInputFps)) |
| 394 .Times(1) |
| 395 .WillOnce(Return(0)); |
372 sender_->Process(); | 396 sender_->Process(); |
373 AddFrame(); | 397 AddFrame(); |
374 // Call to SetChannelParameters with changed bitrate should call encoder | 398 // Call to SetChannelParameters with changed bitrate should call encoder |
375 // SetRates but not encoder SetChannelParameters (that are unchanged). | 399 // SetRates but not encoder SetChannelParameters (that are unchanged). |
376 EXPECT_CALL(encoder_, SetRates(2 * settings_.startBitrate, kInputFps)) | 400 uint32_t new_bitrate_bps = 2 * settings_.startBitrate * 1000; |
| 401 BitrateAllocation new_rate_allocation = |
| 402 rate_allocator_->GetAllocation(new_bitrate_bps, kInputFps); |
| 403 EXPECT_CALL(encoder_, SetRateAllocation(new_rate_allocation, kInputFps)) |
377 .Times(1) | 404 .Times(1) |
378 .WillOnce(Return(0)); | 405 .WillOnce(Return(0)); |
379 sender_->SetChannelParameters(2 * settings_.startBitrate * 1000, kLossRate, | 406 sender_->SetChannelParameters(new_bitrate_bps, kLossRate, kRtt, |
380 kRtt); | 407 rate_allocator_.get()); |
381 AddFrame(); | 408 AddFrame(); |
382 } | 409 } |
383 | 410 |
384 class TestVideoSenderWithVp8 : public TestVideoSender { | 411 class TestVideoSenderWithVp8 : public TestVideoSender { |
385 public: | 412 public: |
386 TestVideoSenderWithVp8() | 413 TestVideoSenderWithVp8() |
387 : codec_bitrate_kbps_(300), available_bitrate_kbps_(1000) {} | 414 : codec_bitrate_kbps_(300), available_bitrate_kbps_(1000) {} |
388 | 415 |
389 void SetUp() override { | 416 void SetUp() override { |
390 TestVideoSender::SetUp(); | 417 TestVideoSender::SetUp(); |
391 | 418 |
392 const char* input_video = "foreman_cif"; | 419 const char* input_video = "foreman_cif"; |
393 const int width = 352; | 420 const int width = 352; |
394 const int height = 288; | 421 const int height = 288; |
395 generator_.reset(FrameGenerator::CreateFromYuvFile( | 422 generator_.reset(FrameGenerator::CreateFromYuvFile( |
396 std::vector<std::string>(1, test::ResourcePath(input_video, "yuv")), | 423 std::vector<std::string>(1, test::ResourcePath(input_video, "yuv")), |
397 width, height, 1)); | 424 width, height, 1)); |
398 | 425 |
399 codec_ = MakeVp8VideoCodec(width, height, 3); | 426 codec_ = MakeVp8VideoCodec(width, height, 3); |
400 codec_.minBitrate = 10; | 427 codec_.minBitrate = 10; |
401 codec_.startBitrate = codec_bitrate_kbps_; | 428 codec_.startBitrate = codec_bitrate_kbps_; |
402 codec_.maxBitrate = codec_bitrate_kbps_; | 429 codec_.maxBitrate = codec_bitrate_kbps_; |
| 430 |
| 431 rate_allocator_.reset(new SimulcastRateAllocator(codec_)); |
| 432 tl_factory_.reset(new TemporalLayersFactory()); |
| 433 tl_factory_->SetListener(rate_allocator_.get()); |
| 434 codec_.codecSpecific.VP8.tl_factory = tl_factory_.get(); |
| 435 |
403 encoder_.reset(VP8Encoder::Create()); | 436 encoder_.reset(VP8Encoder::Create()); |
404 sender_->RegisterExternalEncoder(encoder_.get(), codec_.plType, false); | 437 sender_->RegisterExternalEncoder(encoder_.get(), codec_.plType, false); |
405 EXPECT_EQ(0, sender_->RegisterSendCodec(&codec_, 1, 1200)); | 438 EXPECT_EQ(0, sender_->RegisterSendCodec(&codec_, 1, 1200)); |
406 } | 439 } |
407 | 440 |
408 static VideoCodec MakeVp8VideoCodec(int width, | 441 static VideoCodec MakeVp8VideoCodec(int width, |
409 int height, | 442 int height, |
410 int temporal_layers) { | 443 int temporal_layers) { |
411 VideoCodec codec; | 444 VideoCodec codec; |
412 VideoCodingModule::Codec(kVideoCodecVP8, &codec); | 445 VideoCodingModule::Codec(kVideoCodecVP8, &codec); |
413 codec.width = width; | 446 codec.width = width; |
414 codec.height = height; | 447 codec.height = height; |
415 codec.codecSpecific.VP8.numberOfTemporalLayers = temporal_layers; | 448 codec.codecSpecific.VP8.numberOfTemporalLayers = temporal_layers; |
416 return codec; | 449 return codec; |
417 } | 450 } |
418 | 451 |
419 void InsertFrames(float framerate, float seconds) { | 452 void InsertFrames(float framerate, float seconds) { |
420 for (int i = 0; i < seconds * framerate; ++i) { | 453 for (int i = 0; i < seconds * framerate; ++i) { |
421 clock_.AdvanceTimeMilliseconds(1000.0f / framerate); | 454 clock_.AdvanceTimeMilliseconds(1000.0f / framerate); |
422 AddFrame(); | 455 AddFrame(); |
423 // SetChannelParameters needs to be called frequently to propagate | 456 // SetChannelParameters needs to be called frequently to propagate |
424 // framerate from the media optimization into the encoder. | 457 // framerate from the media optimization into the encoder. |
425 // Note: SetChannelParameters fails if less than 2 frames are in the | 458 // Note: SetChannelParameters fails if less than 2 frames are in the |
426 // buffer since it will fail to calculate the framerate. | 459 // buffer since it will fail to calculate the framerate. |
427 if (i != 0) { | 460 if (i != 0) { |
428 EXPECT_EQ(VCM_OK, sender_->SetChannelParameters( | 461 EXPECT_EQ(VCM_OK, |
429 available_bitrate_kbps_ * 1000, 0, 200)); | 462 sender_->SetChannelParameters(available_bitrate_kbps_ * 1000, |
| 463 0, 200, rate_allocator_.get())); |
430 } | 464 } |
431 } | 465 } |
432 } | 466 } |
433 | 467 |
434 Vp8StreamInfo SimulateWithFramerate(float framerate) { | 468 Vp8StreamInfo SimulateWithFramerate(float framerate) { |
435 const float short_simulation_interval = 5.0; | 469 const float short_simulation_interval = 5.0; |
436 const float long_simulation_interval = 10.0; | 470 const float long_simulation_interval = 10.0; |
437 // It appears that this 5 seconds simulation is needed to allow | 471 // It appears that this 5 seconds simulation is needed to allow |
438 // bitrate and framerate to stabilize. | 472 // bitrate and framerate to stabilize. |
439 InsertFrames(framerate, short_simulation_interval); | 473 InsertFrames(framerate, short_simulation_interval); |
440 encoded_frame_callback_.Reset(); | 474 encoded_frame_callback_.Reset(); |
441 | 475 |
442 InsertFrames(framerate, long_simulation_interval); | 476 InsertFrames(framerate, long_simulation_interval); |
443 return encoded_frame_callback_.CalculateVp8StreamInfo(); | 477 return encoded_frame_callback_.CalculateVp8StreamInfo(); |
444 } | 478 } |
445 | 479 |
446 protected: | 480 protected: |
447 VideoCodec codec_; | 481 VideoCodec codec_; |
448 int codec_bitrate_kbps_; | 482 int codec_bitrate_kbps_; |
449 int available_bitrate_kbps_; | 483 int available_bitrate_kbps_; |
| 484 std::unique_ptr<SimulcastRateAllocator> rate_allocator_; |
| 485 std::unique_ptr<TemporalLayersFactory> tl_factory_; |
450 }; | 486 }; |
451 | 487 |
452 #if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS) | 488 #if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS) |
453 #define MAYBE_FixedTemporalLayersStrategy DISABLED_FixedTemporalLayersStrategy | 489 #define MAYBE_FixedTemporalLayersStrategy DISABLED_FixedTemporalLayersStrategy |
454 #else | 490 #else |
455 #define MAYBE_FixedTemporalLayersStrategy FixedTemporalLayersStrategy | 491 #define MAYBE_FixedTemporalLayersStrategy FixedTemporalLayersStrategy |
456 #endif | 492 #endif |
457 TEST_F(TestVideoSenderWithVp8, MAYBE_FixedTemporalLayersStrategy) { | 493 TEST_F(TestVideoSenderWithVp8, MAYBE_FixedTemporalLayersStrategy) { |
458 const int low_b = codec_bitrate_kbps_ * kVp8LayerRateAlloction[2][0]; | 494 const int low_b = codec_bitrate_kbps_ * kVp8LayerRateAlloction[2][0]; |
459 const int mid_b = codec_bitrate_kbps_ * kVp8LayerRateAlloction[2][1]; | 495 const int mid_b = codec_bitrate_kbps_ * kVp8LayerRateAlloction[2][1]; |
460 const int high_b = codec_bitrate_kbps_ * kVp8LayerRateAlloction[2][2]; | 496 const int high_b = codec_bitrate_kbps_ * kVp8LayerRateAlloction[2][2]; |
461 { | 497 { |
462 Vp8StreamInfo expected = {{7.5, 15.0, 30.0}, {low_b, mid_b, high_b}}; | 498 Vp8StreamInfo expected = {{7.5, 15.0, 30.0}, {low_b, mid_b, high_b}}; |
463 EXPECT_THAT(SimulateWithFramerate(30.0), MatchesVp8StreamInfo(expected)); | 499 EXPECT_THAT(SimulateWithFramerate(30.0), MatchesVp8StreamInfo(expected)); |
464 } | 500 } |
465 { | 501 { |
466 Vp8StreamInfo expected = {{3.75, 7.5, 15.0}, {low_b, mid_b, high_b}}; | 502 Vp8StreamInfo expected = {{3.75, 7.5, 15.0}, {low_b, mid_b, high_b}}; |
467 EXPECT_THAT(SimulateWithFramerate(15.0), MatchesVp8StreamInfo(expected)); | 503 EXPECT_THAT(SimulateWithFramerate(15.0), MatchesVp8StreamInfo(expected)); |
468 } | 504 } |
469 } | 505 } |
470 | 506 |
471 #if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS) | 507 #if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS) |
472 #define MAYBE_RealTimeTemporalLayersStrategy \ | 508 #define MAYBE_RealTimeTemporalLayersStrategy \ |
473 DISABLED_RealTimeTemporalLayersStrategy | 509 DISABLED_RealTimeTemporalLayersStrategy |
474 #else | 510 #else |
475 #define MAYBE_RealTimeTemporalLayersStrategy RealTimeTemporalLayersStrategy | 511 #define MAYBE_RealTimeTemporalLayersStrategy RealTimeTemporalLayersStrategy |
476 #endif | 512 #endif |
477 TEST_F(TestVideoSenderWithVp8, MAYBE_RealTimeTemporalLayersStrategy) { | 513 TEST_F(TestVideoSenderWithVp8, MAYBE_RealTimeTemporalLayersStrategy) { |
478 VideoCodec codec = MakeVp8VideoCodec(352, 288, 3); | 514 VideoCodec codec = MakeVp8VideoCodec(352, 288, 3); |
479 RealTimeTemporalLayersFactory realtime_tl_factory; | |
480 codec.codecSpecific.VP8.tl_factory = &realtime_tl_factory; | |
481 codec.minBitrate = 10; | 515 codec.minBitrate = 10; |
482 codec.startBitrate = codec_bitrate_kbps_; | 516 codec.startBitrate = codec_bitrate_kbps_; |
483 codec.maxBitrate = codec_bitrate_kbps_; | 517 codec.maxBitrate = codec_bitrate_kbps_; |
| 518 |
| 519 rate_allocator_.reset(new SimulcastRateAllocator(codec)); |
| 520 tl_factory_.reset(new RealTimeTemporalLayersFactory()); |
| 521 tl_factory_->SetListener(rate_allocator_.get()); |
| 522 codec.codecSpecific.VP8.tl_factory = tl_factory_.get(); |
| 523 |
484 EXPECT_EQ(0, sender_->RegisterSendCodec(&codec, 1, 1200)); | 524 EXPECT_EQ(0, sender_->RegisterSendCodec(&codec, 1, 1200)); |
485 | 525 |
486 const int low_b = codec_bitrate_kbps_ * 0.4; | 526 const int low_b = codec_bitrate_kbps_ * 0.4; |
487 const int mid_b = codec_bitrate_kbps_ * 0.6; | 527 const int mid_b = codec_bitrate_kbps_ * 0.6; |
488 const int high_b = codec_bitrate_kbps_; | 528 const int high_b = codec_bitrate_kbps_; |
489 | 529 |
490 { | 530 { |
491 Vp8StreamInfo expected = {{7.5, 15.0, 30.0}, {low_b, mid_b, high_b}}; | 531 Vp8StreamInfo expected = {{7.5, 15.0, 30.0}, {low_b, mid_b, high_b}}; |
492 EXPECT_THAT(SimulateWithFramerate(30.0), MatchesVp8StreamInfo(expected)); | 532 EXPECT_THAT(SimulateWithFramerate(30.0), MatchesVp8StreamInfo(expected)); |
493 } | 533 } |
(...skipping 11 matching lines...) Expand all Loading... |
505 } | 545 } |
506 { | 546 { |
507 // TODO(andresp): Find out why this fails with framerate = 7.5 | 547 // TODO(andresp): Find out why this fails with framerate = 7.5 |
508 Vp8StreamInfo expected = {{7.0, 7.0, 7.0}, {high_b, high_b, high_b}}; | 548 Vp8StreamInfo expected = {{7.0, 7.0, 7.0}, {high_b, high_b, high_b}}; |
509 EXPECT_THAT(SimulateWithFramerate(7.0), MatchesVp8StreamInfo(expected)); | 549 EXPECT_THAT(SimulateWithFramerate(7.0), MatchesVp8StreamInfo(expected)); |
510 } | 550 } |
511 } | 551 } |
512 } // namespace | 552 } // namespace |
513 } // namespace vcm | 553 } // namespace vcm |
514 } // namespace webrtc | 554 } // namespace webrtc |
OLD | NEW |