| 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 |