1 /* 2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. 3 * 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 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 #include <algorithm> // max 11 12 #include "testing/gtest/include/gtest/gtest.h" 13 14 #include "webrtc/call.h" 15 #include "webrtc/common_video/interface/i420_video_frame.h" 16 #include "webrtc/frame_callback.h" 17 #include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h" 18 #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h" 19 #include "webrtc/modules/rtp_rtcp/source/rtcp_sender.h" 20 #include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h" 21 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h" 22 #include "webrtc/system_wrappers/interface/event_wrapper.h" 23 #include "webrtc/system_wrappers/interface/scoped_ptr.h" 24 #include "webrtc/system_wrappers/interface/sleep.h" 25 #include "webrtc/system_wrappers/interface/thread_wrapper.h" 26 #include "webrtc/test/direct_transport.h" 27 #include "webrtc/test/configurable_frame_size_encoder.h" 28 #include "webrtc/test/encoder_settings.h" 29 #include "webrtc/test/fake_encoder.h" 30 #include "webrtc/test/frame_generator_capturer.h" 31 #include "webrtc/test/null_transport.h" 32 #include "webrtc/test/rtp_rtcp_observer.h" 33 #include "webrtc/test/testsupport/perf_test.h" 34 #include "webrtc/video/transport_adapter.h" 35 #include "webrtc/video_send_stream.h" 36 37 namespace webrtc { 38 39 enum VideoFormat { kGeneric, kVP8, }; 40 41 class VideoSendStreamTest : public ::testing::Test { 42 public: 43 VideoSendStreamTest() 44 : send_stream_(NULL), fake_encoder_(Clock::GetRealTimeClock()) {} 45 46 protected: 47 void RunSendTest(Call* call, 48 test::RtpRtcpObserver* observer) { 49 send_stream_ = 50 call->CreateVideoSendStream(send_config_, video_streams_, NULL); 51 scoped_ptr<test::FrameGeneratorCapturer> frame_generator_capturer( 52 test::FrameGeneratorCapturer::Create( 53 send_stream_->Input(), 320, 240, 30, Clock::GetRealTimeClock())); 54 send_stream_->Start(); 55 frame_generator_capturer->Start(); 56 57 EXPECT_EQ(kEventSignaled, observer->Wait()); 58 59 observer->StopSending(); 60 frame_generator_capturer->Stop(); 61 send_stream_->Stop(); 62 call->DestroyVideoSendStream(send_stream_); 63 } 64 65 void CreateTestConfig(Call* call, size_t num_streams) { 66 assert(num_streams <= kNumSendSsrcs); 67 send_config_ = call->GetDefaultSendConfig(); 68 send_config_.encoder_settings.encoder = &fake_encoder_; 69 send_config_.encoder_settings.payload_name = "FAKE"; 70 send_config_.encoder_settings.payload_type = kFakeSendPayloadType; 71 video_streams_ = test::CreateVideoStreams(num_streams); 72 send_config_.encoder_settings.payload_type = kFakeSendPayloadType; 73 for (size_t i = 0; i < num_streams; ++i) 74 send_config_.rtp.ssrcs.push_back(kSendSsrcs[i]); 75 } 76 77 void TestNackRetransmission(uint32_t retransmit_ssrc, 78 uint8_t retransmit_payload_type); 79 80 void TestPacketFragmentationSize(VideoFormat format, bool with_fec); 81 82 void SendsSetSsrcs(size_t num_ssrcs, bool send_single_ssrc_first); 83 84 enum { kNumSendSsrcs = 3 }; 85 static const uint8_t kSendPayloadType; 86 static const uint8_t kSendRtxPayloadType; 87 static const uint8_t kFakeSendPayloadType; 88 static const uint32_t kSendSsrc; 89 static const uint32_t kSendRtxSsrc; 90 static const uint32_t kSendSsrcs[kNumSendSsrcs]; 91 92 VideoSendStream::Config send_config_; 93 std::vector<VideoStream> video_streams_; 94 VideoSendStream* send_stream_; 95 test::FakeEncoder fake_encoder_; 96 }; 97 98 const uint8_t VideoSendStreamTest::kSendPayloadType = 100; 99 const uint8_t VideoSendStreamTest::kFakeSendPayloadType = 125; 100 const uint8_t VideoSendStreamTest::kSendRtxPayloadType = 98; 101 const uint32_t VideoSendStreamTest::kSendRtxSsrc = 0xBADCAFE; 102 const uint32_t VideoSendStreamTest::kSendSsrcs[kNumSendSsrcs] = { 103 0xC0FFED, 0xC0FFEE, 0xC0FFEF}; 104 const uint32_t VideoSendStreamTest::kSendSsrc = 105 VideoSendStreamTest::kSendSsrcs[0]; 106 107 void VideoSendStreamTest::SendsSetSsrcs(size_t num_ssrcs, 108 bool send_single_ssrc_first) { 109 class SendSsrcObserver : public test::RtpRtcpObserver { 110 public: 111 SendSsrcObserver(const uint32_t* ssrcs, 112 size_t num_ssrcs, 113 bool send_single_ssrc_first) 114 : RtpRtcpObserver(30 * 1000), 115 ssrcs_to_observe_(num_ssrcs), 116 expect_single_ssrc_(send_single_ssrc_first) { 117 for (size_t i = 0; i < num_ssrcs; ++i) 118 valid_ssrcs_[ssrcs[i]] = true; 119 } 120 121 virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE { 122 RTPHeader header; 123 EXPECT_TRUE(parser_->Parse(packet, static_cast<int>(length), &header)); 124 125 // TODO(pbos): Reenable this part of the test when #1695 is resolved and 126 // all SSRCs are allocated on startup. This test was observed 127 // to fail on TSan as the codec gets set before the SSRCs are 128 // set up and some frames are sent on a random-generated SSRC 129 // before the correct SSRC gets set. 130 // EXPECT_TRUE(valid_ssrcs_[header.ssrc]) 131 // << "Received unknown SSRC: " << header.ssrc; 132 // 133 // if (!valid_ssrcs_[header.ssrc]) 134 // observation_complete_->Set(); 135 136 if (!is_observed_[header.ssrc]) { 137 is_observed_[header.ssrc] = true; 138 --ssrcs_to_observe_; 139 if (expect_single_ssrc_) { 140 expect_single_ssrc_ = false; 141 observation_complete_->Set(); 142 } 143 } 144 145 if (ssrcs_to_observe_ == 0) 146 observation_complete_->Set(); 147 148 return SEND_PACKET; 149 } 150 151 private: 152 std::map<uint32_t, bool> valid_ssrcs_; 153 std::map<uint32_t, bool> is_observed_; 154 size_t ssrcs_to_observe_; 155 bool expect_single_ssrc_; 156 } observer(kSendSsrcs, num_ssrcs, send_single_ssrc_first); 157 158 Call::Config call_config(observer.SendTransport()); 159 scoped_ptr<Call> call(Call::Create(call_config)); 160 161 CreateTestConfig(call.get(), num_ssrcs); 162 163 if (num_ssrcs > 1) { 164 // Set low simulcast bitrates to not have to wait for bandwidth ramp-up. 165 for (size_t i = 0; i < video_streams_.size(); ++i) { 166 video_streams_[i].min_bitrate_bps = 10000; 167 video_streams_[i].target_bitrate_bps = 10000; 168 video_streams_[i].max_bitrate_bps = 10000; 169 } 170 } 171 172 std::vector<VideoStream> all_streams = video_streams_; 173 if (send_single_ssrc_first) 174 video_streams_.resize(1); 175 176 send_stream_ = 177 call->CreateVideoSendStream(send_config_, video_streams_, NULL); 178 scoped_ptr<test::FrameGeneratorCapturer> frame_generator_capturer( 179 test::FrameGeneratorCapturer::Create( 180 send_stream_->Input(), 320, 240, 30, Clock::GetRealTimeClock())); 181 send_stream_->Start(); 182 frame_generator_capturer->Start(); 183 184 EXPECT_EQ(kEventSignaled, observer.Wait()) 185 << "Timed out while waiting for " 186 << (send_single_ssrc_first ? "first SSRC." : "SSRCs."); 187 188 if (send_single_ssrc_first) { 189 // Set full simulcast and continue with the rest of the SSRCs. 190 send_stream_->ReconfigureVideoEncoder(all_streams, NULL); 191 EXPECT_EQ(kEventSignaled, observer.Wait()) 192 << "Timed out while waiting on additional SSRCs."; 193 } 194 195 observer.StopSending(); 196 frame_generator_capturer->Stop(); 197 send_stream_->Stop(); 198 call->DestroyVideoSendStream(send_stream_); 199 } 200 201 TEST_F(VideoSendStreamTest, CanStartStartedStream) { 202 test::NullTransport transport; 203 Call::Config call_config(&transport); 204 scoped_ptr<Call> call(Call::Create(call_config)); 205 206 CreateTestConfig(call.get(), 1); 207 VideoSendStream* stream = 208 call->CreateVideoSendStream(send_config_, video_streams_, NULL); 209 stream->Start(); 210 stream->Start(); 211 call->DestroyVideoSendStream(stream); 212 } 213 214 TEST_F(VideoSendStreamTest, CanStopStoppedStream) { 215 test::NullTransport transport; 216 Call::Config call_config(&transport); 217 scoped_ptr<Call> call(Call::Create(call_config)); 218 219 CreateTestConfig(call.get(), 1); 220 VideoSendStream* stream = 221 call->CreateVideoSendStream(send_config_, video_streams_, NULL); 222 stream->Stop(); 223 stream->Stop(); 224 call->DestroyVideoSendStream(stream); 225 } 226 227 TEST_F(VideoSendStreamTest, SendsSetSsrc) { SendsSetSsrcs(1, false); } 228 229 TEST_F(VideoSendStreamTest, DISABLED_SendsSetSimulcastSsrcs) { 230 SendsSetSsrcs(kNumSendSsrcs, false); 231 } 232 233 TEST_F(VideoSendStreamTest, DISABLED_CanSwitchToUseAllSsrcs) { 234 SendsSetSsrcs(kNumSendSsrcs, true); 235 } 236 237 TEST_F(VideoSendStreamTest, SupportsCName) { 238 static std::string kCName = "PjQatC14dGfbVwGPUOA9IH7RlsFDbWl4AhXEiDsBizo="; 239 class CNameObserver : public test::RtpRtcpObserver { 240 public: 241 CNameObserver() : RtpRtcpObserver(30 * 1000) {} 242 243 virtual Action OnSendRtcp(const uint8_t* packet, size_t length) OVERRIDE { 244 RTCPUtility::RTCPParserV2 parser(packet, length, true); 245 EXPECT_TRUE(parser.IsValid()); 246 247 RTCPUtility::RTCPPacketTypes packet_type = parser.Begin(); 248 while (packet_type != RTCPUtility::kRtcpNotValidCode) { 249 if (packet_type == RTCPUtility::kRtcpSdesChunkCode) { 250 EXPECT_EQ(parser.Packet().CName.CName, kCName); 251 observation_complete_->Set(); 252 } 253 254 packet_type = parser.Iterate(); 255 } 256 257 return SEND_PACKET; 258 } 259 } observer; 260 261 Call::Config call_config(observer.SendTransport()); 262 scoped_ptr<Call> call(Call::Create(call_config)); 263 264 CreateTestConfig(call.get(), 1); 265 send_config_.rtp.c_name = kCName; 266 267 RunSendTest(call.get(), &observer); 268 } 269 270 TEST_F(VideoSendStreamTest, SupportsAbsoluteSendTime) { 271 static const uint8_t kAbsSendTimeExtensionId = 13; 272 class AbsoluteSendTimeObserver : public test::RtpRtcpObserver { 273 public: 274 AbsoluteSendTimeObserver() : RtpRtcpObserver(30 * 1000) { 275 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension( 276 kRtpExtensionAbsoluteSendTime, kAbsSendTimeExtensionId)); 277 } 278 279 virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE { 280 RTPHeader header; 281 EXPECT_TRUE(parser_->Parse(packet, static_cast<int>(length), &header)); 282 283 EXPECT_FALSE(header.extension.hasTransmissionTimeOffset); 284 EXPECT_TRUE(header.extension.hasAbsoluteSendTime); 285 EXPECT_EQ(header.extension.transmissionTimeOffset, 0); 286 EXPECT_GT(header.extension.absoluteSendTime, 0u); 287 observation_complete_->Set(); 288 289 return SEND_PACKET; 290 } 291 } observer; 292 293 Call::Config call_config(observer.SendTransport()); 294 scoped_ptr<Call> call(Call::Create(call_config)); 295 296 CreateTestConfig(call.get(), 1); 297 send_config_.rtp.extensions.push_back( 298 RtpExtension(RtpExtension::kAbsSendTime, kAbsSendTimeExtensionId)); 299 300 RunSendTest(call.get(), &observer); 301 } 302 303 TEST_F(VideoSendStreamTest, SupportsTransmissionTimeOffset) { 304 static const uint8_t kTOffsetExtensionId = 13; 305 class DelayedEncoder : public test::FakeEncoder { 306 public: 307 explicit DelayedEncoder(Clock* clock) : test::FakeEncoder(clock) {} 308 virtual int32_t Encode(const I420VideoFrame& input_image, 309 const CodecSpecificInfo* codec_specific_info, 310 const std::vector<VideoFrameType>* frame_types) 311 OVERRIDE { 312 // A delay needs to be introduced to assure that we get a timestamp 313 // offset. 314 SleepMs(5); 315 return FakeEncoder::Encode(input_image, codec_specific_info, frame_types); 316 } 317 } encoder(Clock::GetRealTimeClock()); 318 319 class TransmissionTimeOffsetObserver : public test::RtpRtcpObserver { 320 public: 321 TransmissionTimeOffsetObserver() : RtpRtcpObserver(30 * 1000) { 322 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension( 323 kRtpExtensionTransmissionTimeOffset, kTOffsetExtensionId)); 324 } 325 326 virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE { 327 RTPHeader header; 328 EXPECT_TRUE(parser_->Parse(packet, static_cast<int>(length), &header)); 329 330 EXPECT_TRUE(header.extension.hasTransmissionTimeOffset); 331 EXPECT_FALSE(header.extension.hasAbsoluteSendTime); 332 EXPECT_GT(header.extension.transmissionTimeOffset, 0); 333 EXPECT_EQ(header.extension.absoluteSendTime, 0u); 334 observation_complete_->Set(); 335 336 return SEND_PACKET; 337 } 338 } observer; 339 340 Call::Config call_config(observer.SendTransport()); 341 scoped_ptr<Call> call(Call::Create(call_config)); 342 343 CreateTestConfig(call.get(), 1); 344 send_config_.encoder_settings.encoder = &encoder; 345 send_config_.rtp.extensions.push_back( 346 RtpExtension(RtpExtension::kTOffset, kTOffsetExtensionId)); 347 348 RunSendTest(call.get(), &observer); 349 } 350 351 class FakeReceiveStatistics : public NullReceiveStatistics { 352 public: 353 FakeReceiveStatistics(uint32_t send_ssrc, 354 uint32_t last_sequence_number, 355 uint32_t cumulative_lost, 356 uint8_t fraction_lost) 357 : lossy_stats_(new LossyStatistician(last_sequence_number, 358 cumulative_lost, 359 fraction_lost)) { 360 stats_map_[send_ssrc] = lossy_stats_.get(); 361 } 362 363 virtual StatisticianMap GetActiveStatisticians() const OVERRIDE { 364 return stats_map_; 365 } 366 367 virtual StreamStatistician* GetStatistician(uint32_t ssrc) const OVERRIDE { 368 return lossy_stats_.get(); 369 } 370 371 private: 372 class LossyStatistician : public StreamStatistician { 373 public: 374 LossyStatistician(uint32_t extended_max_sequence_number, 375 uint32_t cumulative_lost, 376 uint8_t fraction_lost) { 377 stats_.fraction_lost = fraction_lost; 378 stats_.cumulative_lost = cumulative_lost; 379 stats_.extended_max_sequence_number = extended_max_sequence_number; 380 } 381 virtual bool GetStatistics(RtcpStatistics* statistics, 382 bool reset) OVERRIDE { 383 *statistics = stats_; 384 return true; 385 } 386 virtual void GetDataCounters(uint32_t* bytes_received, 387 uint32_t* packets_received) const OVERRIDE { 388 *bytes_received = 0; 389 *packets_received = 0; 390 } 391 virtual uint32_t BitrateReceived() const OVERRIDE { return 0; } 392 virtual void ResetStatistics() OVERRIDE {} 393 virtual bool IsRetransmitOfOldPacket(const RTPHeader& header, 394 int min_rtt) const OVERRIDE { 395 return false; 396 } 397 398 virtual bool IsPacketInOrder(uint16_t sequence_number) const OVERRIDE { 399 return true; 400 } 401 402 RtcpStatistics stats_; 403 }; 404 405 scoped_ptr<LossyStatistician> lossy_stats_; 406 StatisticianMap stats_map_; 407 }; 408 409 TEST_F(VideoSendStreamTest, SwapsI420VideoFrames) { 410 static const size_t kWidth = 320; 411 static const size_t kHeight = 240; 412 413 test::NullTransport transport; 414 Call::Config call_config(&transport); 415 scoped_ptr<Call> call(Call::Create(call_config)); 416 417 CreateTestConfig(call.get(), 1); 418 VideoSendStream* video_send_stream = 419 call->CreateVideoSendStream(send_config_, video_streams_, NULL); 420 video_send_stream->Start(); 421 422 I420VideoFrame frame; 423 frame.CreateEmptyFrame( 424 kWidth, kHeight, kWidth, (kWidth + 1) / 2, (kWidth + 1) / 2); 425 uint8_t* old_y_buffer = frame.buffer(kYPlane); 426 427 video_send_stream->Input()->SwapFrame(&frame); 428 429 EXPECT_NE(frame.buffer(kYPlane), old_y_buffer); 430 431 call->DestroyVideoSendStream(video_send_stream); 432 } 433 434 TEST_F(VideoSendStreamTest, SupportsFec) { 435 static const int kRedPayloadType = 118; 436 static const int kUlpfecPayloadType = 119; 437 class FecObserver : public test::RtpRtcpObserver { 438 public: 439 FecObserver() 440 : RtpRtcpObserver(30 * 1000), 441 transport_adapter_(SendTransport()), 442 send_count_(0), 443 received_media_(false), 444 received_fec_(false) { 445 transport_adapter_.Enable(); 446 } 447 448 virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE { 449 RTPHeader header; 450 EXPECT_TRUE(parser_->Parse(packet, static_cast<int>(length), &header)); 451 452 // Send lossy receive reports to trigger FEC enabling. 453 if (send_count_++ % 2 != 0) { 454 // Receive statistics reporting having lost 50% of the packets. 455 FakeReceiveStatistics lossy_receive_stats( 456 kSendSsrc, header.sequenceNumber, send_count_ / 2, 127); 457 RTCPSender rtcp_sender( 458 0, false, Clock::GetRealTimeClock(), &lossy_receive_stats); 459 EXPECT_EQ(0, rtcp_sender.RegisterSendTransport(&transport_adapter_)); 460 461 rtcp_sender.SetRTCPStatus(kRtcpNonCompound); 462 rtcp_sender.SetRemoteSSRC(kSendSsrc); 463 464 RTCPSender::FeedbackState feedback_state; 465 466 EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr)); 467 } 468 469 EXPECT_EQ(kRedPayloadType, header.payloadType); 470 471 uint8_t encapsulated_payload_type = packet[header.headerLength]; 472 473 if (encapsulated_payload_type == kUlpfecPayloadType) { 474 received_fec_ = true; 475 } else { 476 received_media_ = true; 477 } 478 479 if (received_media_ && received_fec_) 480 observation_complete_->Set(); 481 482 return SEND_PACKET; 483 } 484 485 private: 486 internal::TransportAdapter transport_adapter_; 487 int send_count_; 488 bool received_media_; 489 bool received_fec_; 490 } observer; 491 492 Call::Config call_config(observer.SendTransport()); 493 scoped_ptr<Call> call(Call::Create(call_config)); 494 495 observer.SetReceivers(call->Receiver(), NULL); 496 497 CreateTestConfig(call.get(), 1); 498 send_config_.rtp.fec.red_payload_type = kRedPayloadType; 499 send_config_.rtp.fec.ulpfec_payload_type = kUlpfecPayloadType; 500 501 RunSendTest(call.get(), &observer); 502 } 503 504 void VideoSendStreamTest::TestNackRetransmission( 505 uint32_t retransmit_ssrc, 506 uint8_t retransmit_payload_type) { 507 class NackObserver : public test::RtpRtcpObserver { 508 public: 509 explicit NackObserver(uint32_t retransmit_ssrc, 510 uint8_t retransmit_payload_type) 511 : RtpRtcpObserver(30 * 1000), 512 transport_adapter_(SendTransport()), 513 send_count_(0), 514 retransmit_ssrc_(retransmit_ssrc), 515 retransmit_payload_type_(retransmit_payload_type), 516 nacked_sequence_number_(-1) { 517 transport_adapter_.Enable(); 518 } 519 520 virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE { 521 RTPHeader header; 522 EXPECT_TRUE(parser_->Parse(packet, static_cast<int>(length), &header)); 523 524 // Nack second packet after receiving the third one. 525 if (++send_count_ == 3) { 526 uint16_t nack_sequence_number = header.sequenceNumber - 1; 527 nacked_sequence_number_ = nack_sequence_number; 528 NullReceiveStatistics null_stats; 529 RTCPSender rtcp_sender( 530 0, false, Clock::GetRealTimeClock(), &null_stats); 531 EXPECT_EQ(0, rtcp_sender.RegisterSendTransport(&transport_adapter_)); 532 533 rtcp_sender.SetRTCPStatus(kRtcpNonCompound); 534 rtcp_sender.SetRemoteSSRC(kSendSsrc); 535 536 RTCPSender::FeedbackState feedback_state; 537 538 EXPECT_EQ(0, 539 rtcp_sender.SendRTCP( 540 feedback_state, kRtcpNack, 1, &nack_sequence_number)); 541 } 542 543 uint16_t sequence_number = header.sequenceNumber; 544 545 if (header.ssrc == retransmit_ssrc_ && retransmit_ssrc_ != kSendSsrc) { 546 // Not kSendSsrc, assume correct RTX packet. Extract sequence number. 547 const uint8_t* rtx_header = packet + header.headerLength; 548 sequence_number = (rtx_header[0] << 8) + rtx_header[1]; 549 } 550 551 if (sequence_number == nacked_sequence_number_) { 552 EXPECT_EQ(retransmit_ssrc_, header.ssrc); 553 EXPECT_EQ(retransmit_payload_type_, header.payloadType); 554 observation_complete_->Set(); 555 } 556 557 return SEND_PACKET; 558 } 559 560 private: 561 internal::TransportAdapter transport_adapter_; 562 int send_count_; 563 uint32_t retransmit_ssrc_; 564 uint8_t retransmit_payload_type_; 565 int nacked_sequence_number_; 566 } observer(retransmit_ssrc, retransmit_payload_type); 567 568 Call::Config call_config(observer.SendTransport()); 569 scoped_ptr<Call> call(Call::Create(call_config)); 570 observer.SetReceivers(call->Receiver(), NULL); 571 572 CreateTestConfig(call.get(), 1); 573 send_config_.rtp.nack.rtp_history_ms = 1000; 574 send_config_.rtp.rtx.payload_type = retransmit_payload_type; 575 if (retransmit_ssrc != kSendSsrc) 576 send_config_.rtp.rtx.ssrcs.push_back(retransmit_ssrc); 577 578 RunSendTest(call.get(), &observer); 579 } 580 581 TEST_F(VideoSendStreamTest, RetransmitsNack) { 582 // Normal NACKs should use the send SSRC. 583 TestNackRetransmission(kSendSsrc, kFakeSendPayloadType); 584 } 585 586 TEST_F(VideoSendStreamTest, RetransmitsNackOverRtx) { 587 // NACKs over RTX should use a separate SSRC. 588 TestNackRetransmission(kSendRtxSsrc, kSendRtxPayloadType); 589 } 590 591 void VideoSendStreamTest::TestPacketFragmentationSize(VideoFormat format, 592 bool with_fec) { 593 static const int kRedPayloadType = 118; 594 static const int kUlpfecPayloadType = 119; 595 // Observer that verifies that the expected number of packets and bytes 596 // arrive for each frame size, from start_size to stop_size. 597 class FrameFragmentationObserver : public test::RtpRtcpObserver, 598 public EncodedFrameObserver { 599 public: 600 FrameFragmentationObserver(uint32_t max_packet_size, 601 uint32_t start_size, 602 uint32_t stop_size, 603 test::ConfigurableFrameSizeEncoder* encoder, 604 bool test_generic_packetization, 605 bool use_fec) 606 : RtpRtcpObserver(120 * 1000), // Timeout after two minutes. 607 transport_adapter_(SendTransport()), 608 encoder_(encoder), 609 max_packet_size_(max_packet_size), 610 stop_size_(stop_size), 611 test_generic_packetization_(test_generic_packetization), 612 use_fec_(use_fec), 613 packet_count_(0), 614 accumulated_size_(0), 615 accumulated_payload_(0), 616 fec_packet_received_(false), 617 current_size_rtp_(start_size), 618 current_size_frame_(start_size) { 619 // Fragmentation required, this test doesn't make sense without it. 620 assert(stop_size > max_packet_size); 621 transport_adapter_.Enable(); 622 } 623 624 virtual Action OnSendRtp(const uint8_t* packet, size_t size) OVERRIDE { 625 uint32_t length = static_cast<int>(size); 626 RTPHeader header; 627 EXPECT_TRUE(parser_->Parse(packet, length, &header)); 628 629 EXPECT_LE(length, max_packet_size_); 630 631 if (use_fec_) { 632 uint8_t payload_type = packet[header.headerLength]; 633 bool is_fec = header.payloadType == kRedPayloadType && 634 payload_type == kUlpfecPayloadType; 635 if (is_fec) { 636 fec_packet_received_ = true; 637 return SEND_PACKET; 638 } 639 } 640 641 accumulated_size_ += length; 642 643 if (use_fec_) 644 TriggerLossReport(header); 645 646 if (test_generic_packetization_) { 647 uint32_t overhead = header.headerLength + header.paddingLength + 648 (1 /* Generic header */); 649 if (use_fec_) 650 overhead += 1; // RED for FEC header. 651 accumulated_payload_ += length - overhead; 652 } 653 654 // Marker bit set indicates last packet of a frame. 655 if (header.markerBit) { 656 if (use_fec_ && accumulated_payload_ == current_size_rtp_ - 1) { 657 // With FEC enabled, frame size is incremented asynchronously, so 658 // "old" frames one byte too small may arrive. Accept, but don't 659 // increase expected frame size. 660 accumulated_size_ = 0; 661 accumulated_payload_ = 0; 662 return SEND_PACKET; 663 } 664 665 EXPECT_GE(accumulated_size_, current_size_rtp_); 666 if (test_generic_packetization_) { 667 EXPECT_EQ(current_size_rtp_, accumulated_payload_); 668 } 669 670 // Last packet of frame; reset counters. 671 accumulated_size_ = 0; 672 accumulated_payload_ = 0; 673 if (current_size_rtp_ == stop_size_) { 674 // Done! (Don't increase size again, might arrive more @ stop_size). 675 observation_complete_->Set(); 676 } else { 677 // Increase next expected frame size. If testing with FEC, make sure 678 // a FEC packet has been received for this frame size before 679 // proceeding, to make sure that redundancy packets don't exceed 680 // size limit. 681 if (!use_fec_) { 682 ++current_size_rtp_; 683 } else if (fec_packet_received_) { 684 fec_packet_received_ = false; 685 ++current_size_rtp_; 686 ++current_size_frame_; 687 } 688 } 689 } 690 691 return SEND_PACKET; 692 } 693 694 void TriggerLossReport(const RTPHeader& header) { 695 // Send lossy receive reports to trigger FEC enabling. 696 if (packet_count_++ % 2 != 0) { 697 // Receive statistics reporting having lost 50% of the packets. 698 FakeReceiveStatistics lossy_receive_stats( 699 kSendSsrc, header.sequenceNumber, packet_count_ / 2, 127); 700 RTCPSender rtcp_sender( 701 0, false, Clock::GetRealTimeClock(), &lossy_receive_stats); 702 EXPECT_EQ(0, rtcp_sender.RegisterSendTransport(&transport_adapter_)); 703 704 rtcp_sender.SetRTCPStatus(kRtcpNonCompound); 705 rtcp_sender.SetRemoteSSRC(kSendSsrc); 706 707 RTCPSender::FeedbackState feedback_state; 708 709 EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr)); 710 } 711 } 712 713 virtual void EncodedFrameCallback(const EncodedFrame& encoded_frame) { 714 // Increase frame size for next encoded frame, in the context of the 715 // encoder thread. 716 if (!use_fec_ && 717 current_size_frame_.Value() < static_cast<int32_t>(stop_size_)) { 718 ++current_size_frame_; 719 } 720 encoder_->SetFrameSize(current_size_frame_.Value()); 721 } 722 723 private: 724 internal::TransportAdapter transport_adapter_; 725 test::ConfigurableFrameSizeEncoder* const encoder_; 726 727 const uint32_t max_packet_size_; 728 const uint32_t stop_size_; 729 const bool test_generic_packetization_; 730 const bool use_fec_; 731 732 uint32_t packet_count_; 733 uint32_t accumulated_size_; 734 uint32_t accumulated_payload_; 735 bool fec_packet_received_; 736 737 uint32_t current_size_rtp_; 738 Atomic32 current_size_frame_; 739 }; 740 741 // Use a fake encoder to output a frame of every size in the range [90, 290], 742 // for each size making sure that the exact number of payload bytes received 743 // is correct and that packets are fragmented to respect max packet size. 744 static const uint32_t kMaxPacketSize = 128; 745 static const uint32_t start = 90; 746 static const uint32_t stop = 290; 747 748 // Don't auto increment if FEC is used; continue sending frame size until 749 // a FEC packet has been received. 750 test::ConfigurableFrameSizeEncoder encoder(stop); 751 encoder.SetFrameSize(start); 752 753 FrameFragmentationObserver observer( 754 kMaxPacketSize, start, stop, &encoder, format == kGeneric, with_fec); 755 Call::Config call_config(observer.SendTransport()); 756 scoped_ptr<Call> call(Call::Create(call_config)); 757 758 observer.SetReceivers(call->Receiver(), NULL); 759 760 CreateTestConfig(call.get(), 1); 761 if (with_fec) { 762 send_config_.rtp.fec.red_payload_type = kRedPayloadType; 763 send_config_.rtp.fec.ulpfec_payload_type = kUlpfecPayloadType; 764 } 765 766 if (format == kVP8) 767 send_config_.encoder_settings.payload_name = "VP8"; 768 769 send_config_.encoder_settings.encoder = &encoder; 770 send_config_.rtp.max_packet_size = kMaxPacketSize; 771 send_config_.post_encode_callback = &observer; 772 773 // Add an extension header, to make the RTP header larger than the base 774 // length of 12 bytes. 775 static const uint8_t kAbsSendTimeExtensionId = 13; 776 send_config_.rtp.extensions.push_back( 777 RtpExtension(RtpExtension::kAbsSendTime, kAbsSendTimeExtensionId)); 778 779 RunSendTest(call.get(), &observer); 780 } 781 782 // TODO(sprang): Is there any way of speeding up these tests? 783 TEST_F(VideoSendStreamTest, FragmentsGenericAccordingToMaxPacketSize) { 784 TestPacketFragmentationSize(kGeneric, false); 785 } 786 787 TEST_F(VideoSendStreamTest, FragmentsGenericAccordingToMaxPacketSizeWithFec) { 788 TestPacketFragmentationSize(kGeneric, true); 789 } 790 791 TEST_F(VideoSendStreamTest, FragmentsVp8AccordingToMaxPacketSize) { 792 TestPacketFragmentationSize(kVP8, false); 793 } 794 795 TEST_F(VideoSendStreamTest, FragmentsVp8AccordingToMaxPacketSizeWithFec) { 796 TestPacketFragmentationSize(kVP8, true); 797 } 798 799 // The test will go through a number of phases. 800 // 1. Start sending packets. 801 // 2. As soon as the RTP stream has been detected, signal a low REMB value to 802 // suspend the stream. 803 // 3. Wait until |kSuspendTimeFrames| have been captured without seeing any RTP 804 // packets. 805 // 4. Signal a high REMB and then wait for the RTP stream to start again. 806 // When the stream is detected again, and the stats show that the stream 807 // is no longer suspended, the test ends. 808 TEST_F(VideoSendStreamTest, SuspendBelowMinBitrate) { 809 static const int kSuspendTimeFrames = 60; // Suspend for 2 seconds @ 30 fps. 810 811 class RembObserver : public test::RtpRtcpObserver, public I420FrameCallback { 812 public: 813 RembObserver(VideoSendStream** send_stream_ptr) 814 : RtpRtcpObserver(30 * 1000), // Timeout after 30 seconds. 815 transport_adapter_(&transport_), 816 clock_(Clock::GetRealTimeClock()), 817 send_stream_ptr_(send_stream_ptr), 818 crit_(CriticalSectionWrapper::CreateCriticalSection()), 819 test_state_(kBeforeSuspend), 820 rtp_count_(0), 821 last_sequence_number_(0), 822 suspended_frame_count_(0), 823 low_remb_bps_(0), 824 high_remb_bps_(0) { 825 transport_adapter_.Enable(); 826 } 827 828 void SetReceiver(PacketReceiver* receiver) { 829 transport_.SetReceiver(receiver); 830 } 831 832 virtual Action OnSendRtcp(const uint8_t* packet, size_t length) OVERRIDE { 833 // Receive statistics reporting having lost 0% of the packets. 834 // This is needed for the send-side bitrate controller to work properly. 835 CriticalSectionScoped lock(crit_.get()); 836 SendRtcpFeedback(0); // REMB is only sent if value is > 0. 837 return SEND_PACKET; 838 } 839 840 virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE { 841 CriticalSectionScoped lock(crit_.get()); 842 ++rtp_count_; 843 RTPHeader header; 844 EXPECT_TRUE(parser_->Parse(packet, static_cast<int>(length), &header)); 845 last_sequence_number_ = header.sequenceNumber; 846 847 if (test_state_ == kBeforeSuspend) { 848 // The stream has started. Try to suspend it. 849 SendRtcpFeedback(low_remb_bps_); 850 test_state_ = kDuringSuspend; 851 } else if (test_state_ == kDuringSuspend) { 852 if (header.paddingLength == 0) { 853 // Received non-padding packet during suspension period. Reset the 854 // counter. 855 suspended_frame_count_ = 0; 856 } 857 } else if (test_state_ == kWaitingForPacket) { 858 if (header.paddingLength == 0) { 859 // Non-padding packet observed. Test is almost complete. Will just 860 // have to wait for the stats to change. 861 test_state_ = kWaitingForStats; 862 } 863 } else if (test_state_ == kWaitingForStats) { 864 assert(*send_stream_ptr_); 865 VideoSendStream::Stats stats = (*send_stream_ptr_)->GetStats(); 866 if (stats.suspended == false) { 867 // Stats flipped to false. Test is complete. 868 observation_complete_->Set(); 869 } 870 } 871 872 return SEND_PACKET; 873 } 874 875 // This method implements the I420FrameCallback. 876 void FrameCallback(I420VideoFrame* video_frame) OVERRIDE { 877 CriticalSectionScoped lock(crit_.get()); 878 if (test_state_ == kDuringSuspend && 879 ++suspended_frame_count_ > kSuspendTimeFrames) { 880 assert(*send_stream_ptr_); 881 VideoSendStream::Stats stats = (*send_stream_ptr_)->GetStats(); 882 EXPECT_TRUE(stats.suspended); 883 SendRtcpFeedback(high_remb_bps_); 884 test_state_ = kWaitingForPacket; 885 } 886 } 887 888 void set_low_remb_bps(int value) { 889 CriticalSectionScoped lock(crit_.get()); 890 low_remb_bps_ = value; 891 } 892 893 void set_high_remb_bps(int value) { 894 CriticalSectionScoped lock(crit_.get()); 895 high_remb_bps_ = value; 896 } 897 898 void Stop() { transport_.StopSending(); } 899 900 private: 901 enum TestState { 902 kBeforeSuspend, 903 kDuringSuspend, 904 kWaitingForPacket, 905 kWaitingForStats 906 }; 907 908 virtual void SendRtcpFeedback(int remb_value) 909 EXCLUSIVE_LOCKS_REQUIRED(crit_) { 910 FakeReceiveStatistics receive_stats( 911 kSendSsrc, last_sequence_number_, rtp_count_, 0); 912 RTCPSender rtcp_sender(0, false, clock_, &receive_stats); 913 EXPECT_EQ(0, rtcp_sender.RegisterSendTransport(&transport_adapter_)); 914 915 rtcp_sender.SetRTCPStatus(kRtcpNonCompound); 916 rtcp_sender.SetRemoteSSRC(kSendSsrc); 917 if (remb_value > 0) { 918 rtcp_sender.SetREMBStatus(true); 919 rtcp_sender.SetREMBData(remb_value, 0, NULL); 920 } 921 RTCPSender::FeedbackState feedback_state; 922 EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr)); 923 } 924 925 internal::TransportAdapter transport_adapter_; 926 test::DirectTransport transport_; 927 Clock* const clock_; 928 VideoSendStream** const send_stream_ptr_; 929 930 const scoped_ptr<CriticalSectionWrapper> crit_; 931 TestState test_state_ GUARDED_BY(crit_); 932 int rtp_count_ GUARDED_BY(crit_); 933 int last_sequence_number_ GUARDED_BY(crit_); 934 int suspended_frame_count_ GUARDED_BY(crit_); 935 int low_remb_bps_ GUARDED_BY(crit_); 936 int high_remb_bps_ GUARDED_BY(crit_); 937 } observer(&send_stream_); 938 // Note that |send_stream_| is created in RunSendTest(), called below. This 939 // is why a pointer to |send_stream_| must be provided here. 940 941 Call::Config call_config(observer.SendTransport()); 942 scoped_ptr<Call> call(Call::Create(call_config)); 943 observer.SetReceiver(call->Receiver()); 944 945 CreateTestConfig(call.get(), 1); 946 send_config_.rtp.nack.rtp_history_ms = 1000; 947 send_config_.pre_encode_callback = &observer; 948 send_config_.suspend_below_min_bitrate = true; 949 int min_bitrate_bps = video_streams_[0].min_bitrate_bps; 950 observer.set_low_remb_bps(min_bitrate_bps - 10000); 951 int threshold_window = std::max(min_bitrate_bps / 10, 10000); 952 ASSERT_GT(video_streams_[0].max_bitrate_bps, 953 min_bitrate_bps + threshold_window + 5000); 954 observer.set_high_remb_bps(min_bitrate_bps + threshold_window + 5000); 955 956 RunSendTest(call.get(), &observer); 957 observer.Stop(); 958 } 959 960 TEST_F(VideoSendStreamTest, NoPaddingWhenVideoIsMuted) { 961 class PacketObserver : public test::RtpRtcpObserver { 962 public: 963 PacketObserver() 964 : RtpRtcpObserver(30 * 1000), // Timeout after 30 seconds. 965 clock_(Clock::GetRealTimeClock()), 966 transport_adapter_(ReceiveTransport()), 967 crit_(CriticalSectionWrapper::CreateCriticalSection()), 968 last_packet_time_ms_(-1), 969 capturer_(NULL) { 970 transport_adapter_.Enable(); 971 } 972 973 void SetCapturer(test::FrameGeneratorCapturer* capturer) { 974 CriticalSectionScoped lock(crit_.get()); 975 capturer_ = capturer; 976 } 977 978 virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE { 979 CriticalSectionScoped lock(crit_.get()); 980 last_packet_time_ms_ = clock_->TimeInMilliseconds(); 981 capturer_->Stop(); 982 return SEND_PACKET; 983 } 984 985 virtual Action OnSendRtcp(const uint8_t* packet, size_t length) OVERRIDE { 986 CriticalSectionScoped lock(crit_.get()); 987 const int kVideoMutedThresholdMs = 10000; 988 if (last_packet_time_ms_ > 0 && 989 clock_->TimeInMilliseconds() - last_packet_time_ms_ > 990 kVideoMutedThresholdMs) 991 observation_complete_->Set(); 992 // Receive statistics reporting having lost 50% of the packets. 993 FakeReceiveStatistics receive_stats(kSendSsrcs[0], 1, 1, 0); 994 RTCPSender rtcp_sender( 995 0, false, Clock::GetRealTimeClock(), &receive_stats); 996 EXPECT_EQ(0, rtcp_sender.RegisterSendTransport(&transport_adapter_)); 997 998 rtcp_sender.SetRTCPStatus(kRtcpNonCompound); 999 rtcp_sender.SetRemoteSSRC(kSendSsrcs[0]); 1000 1001 RTCPSender::FeedbackState feedback_state; 1002 1003 EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr)); 1004 return SEND_PACKET; 1005 } 1006 1007 private: 1008 Clock* const clock_; 1009 internal::TransportAdapter transport_adapter_; 1010 const scoped_ptr<CriticalSectionWrapper> crit_; 1011 int64_t last_packet_time_ms_ GUARDED_BY(crit_); 1012 test::FrameGeneratorCapturer* capturer_ GUARDED_BY(crit_); 1013 } observer; 1014 1015 Call::Config call_config(observer.SendTransport()); 1016 scoped_ptr<Call> call(Call::Create(call_config)); 1017 observer.SetReceivers(call->Receiver(), call->Receiver()); 1018 1019 CreateTestConfig(call.get(), 3); 1020 1021 send_stream_ = 1022 call->CreateVideoSendStream(send_config_, video_streams_, NULL); 1023 scoped_ptr<test::FrameGeneratorCapturer> frame_generator_capturer( 1024 test::FrameGeneratorCapturer::Create( 1025 send_stream_->Input(), 320, 240, 30, Clock::GetRealTimeClock())); 1026 observer.SetCapturer(frame_generator_capturer.get()); 1027 send_stream_->Start(); 1028 frame_generator_capturer->Start(); 1029 1030 EXPECT_EQ(kEventSignaled, observer.Wait()) 1031 << "Timed out while waiting for RTP packets to stop being sent."; 1032 1033 observer.StopSending(); 1034 frame_generator_capturer->Stop(); 1035 send_stream_->Stop(); 1036 call->DestroyVideoSendStream(send_stream_); 1037 } 1038 1039 TEST_F(VideoSendStreamTest, ProducesStats) { 1040 static const std::string kCName = 1041 "PjQatC14dGfbVwGPUOA9IH7RlsFDbWl4AhXEiDsBizo="; 1042 static const uint32_t kTimeoutMs = 30 * 1000; 1043 class StatsObserver : public test::RtpRtcpObserver { 1044 public: 1045 StatsObserver() 1046 : RtpRtcpObserver(kTimeoutMs), 1047 stream_(NULL), 1048 event_(EventWrapper::Create()) {} 1049 1050 virtual Action OnSendRtcp(const uint8_t* packet, size_t length) OVERRIDE { 1051 event_->Set(); 1052 1053 return SEND_PACKET; 1054 } 1055 1056 bool WaitForFilledStats() { 1057 Clock* clock = Clock::GetRealTimeClock(); 1058 int64_t now = clock->TimeInMilliseconds(); 1059 int64_t stop_time = now + kTimeoutMs; 1060 while (now < stop_time) { 1061 int64_t time_left = stop_time - now; 1062 if (time_left > 0 && event_->Wait(time_left) == kEventSignaled && 1063 CheckStats()) { 1064 return true; 1065 } 1066 now = clock->TimeInMilliseconds(); 1067 } 1068 return false; 1069 } 1070 1071 bool CheckStats() { 1072 VideoSendStream::Stats stats = stream_->GetStats(); 1073 // Check that all applicable data sources have been used. 1074 if (stats.input_frame_rate > 0 && stats.encode_frame_rate > 0 && 1075 stats.avg_delay_ms > 0 && stats.c_name == kCName && 1076 !stats.substreams.empty()) { 1077 uint32_t ssrc = stats.substreams.begin()->first; 1078 EXPECT_NE( 1079 config_.rtp.ssrcs.end(), 1080 std::find( 1081 config_.rtp.ssrcs.begin(), config_.rtp.ssrcs.end(), ssrc)); 1082 // Check for data populated by various sources. RTCP excluded as this 1083 // data is received from remote side. Tested in call tests instead. 1084 const StreamStats& entry = stats.substreams[ssrc]; 1085 if (entry.key_frames > 0u && entry.bitrate_bps > 0 && 1086 entry.rtp_stats.packets > 0u) { 1087 return true; 1088 } 1089 } 1090 return false; 1091 } 1092 1093 void SetConfig(const VideoSendStream::Config& config) { config_ = config; } 1094 1095 void SetSendStream(VideoSendStream* stream) { stream_ = stream; } 1096 1097 VideoSendStream* stream_; 1098 VideoSendStream::Config config_; 1099 scoped_ptr<EventWrapper> event_; 1100 } observer; 1101 1102 Call::Config call_config(observer.SendTransport()); 1103 scoped_ptr<Call> call(Call::Create(call_config)); 1104 1105 CreateTestConfig(call.get(), 1); 1106 send_config_.rtp.c_name = kCName; 1107 observer.SetConfig(send_config_); 1108 1109 send_stream_ = 1110 call->CreateVideoSendStream(send_config_, video_streams_, NULL); 1111 observer.SetSendStream(send_stream_); 1112 scoped_ptr<test::FrameGeneratorCapturer> frame_generator_capturer( 1113 test::FrameGeneratorCapturer::Create( 1114 send_stream_->Input(), 320, 240, 30, Clock::GetRealTimeClock())); 1115 send_stream_->Start(); 1116 frame_generator_capturer->Start(); 1117 1118 EXPECT_TRUE(observer.WaitForFilledStats()) 1119 << "Timed out waiting for filled statistics."; 1120 1121 observer.StopSending(); 1122 frame_generator_capturer->Stop(); 1123 send_stream_->Stop(); 1124 call->DestroyVideoSendStream(send_stream_); 1125 } 1126 1127 // This test first observes "high" bitrate use at which point it sends a REMB to 1128 // indicate that it should be lowered significantly. The test then observes that 1129 // the bitrate observed is sinking well below the min-transmit-bitrate threshold 1130 // to verify that the min-transmit bitrate respects incoming REMB. 1131 // 1132 // Note that the test starts at "high" bitrate and does not ramp up to "higher" 1133 // bitrate since no receiver block or remb is sent in the initial phase. 1134 TEST_F(VideoSendStreamTest, MinTransmitBitrateRespectsRemb) { 1135 static const int kMinTransmitBitrateBps = 400000; 1136 static const int kHighBitrateBps = 150000; 1137 static const int kRembBitrateBps = 80000; 1138 static const int kRembRespectedBitrateBps = 100000; 1139 class BitrateObserver: public test::RtpRtcpObserver, public PacketReceiver { 1140 public: 1141 BitrateObserver() 1142 : RtpRtcpObserver(30 * 1000), 1143 feedback_transport_(ReceiveTransport()), 1144 send_stream_(NULL), 1145 bitrate_capped_(false) { 1146 RtpRtcp::Configuration config; 1147 feedback_transport_.Enable(); 1148 config.outgoing_transport = &feedback_transport_; 1149 rtp_rtcp_.reset(RtpRtcp::CreateRtpRtcp(config)); 1150 rtp_rtcp_->SetREMBStatus(true); 1151 rtp_rtcp_->SetRTCPStatus(kRtcpNonCompound); 1152 } 1153 1154 void SetSendStream(VideoSendStream* send_stream) { 1155 send_stream_ = send_stream; 1156 } 1157 1158 private: 1159 virtual DeliveryStatus DeliverPacket(const uint8_t* packet, 1160 size_t length) OVERRIDE { 1161 if (RtpHeaderParser::IsRtcp(packet, static_cast<int>(length))) 1162 return DELIVERY_OK; 1163 1164 RTPHeader header; 1165 if (!parser_->Parse(packet, static_cast<int>(length), &header)) 1166 return DELIVERY_PACKET_ERROR; 1167 assert(send_stream_ != NULL); 1168 VideoSendStream::Stats stats = send_stream_->GetStats(); 1169 if (!stats.substreams.empty()) { 1170 EXPECT_EQ(1u, stats.substreams.size()); 1171 int bitrate_bps = stats.substreams.begin()->second.bitrate_bps; 1172 test::PrintResult( 1173 "bitrate_stats_", 1174 "min_transmit_bitrate_low_remb", 1175 "bitrate_bps", 1176 static_cast<size_t>(bitrate_bps), 1177 "bps", 1178 false); 1179 if (bitrate_bps > kHighBitrateBps) { 1180 rtp_rtcp_->SetREMBData(kRembBitrateBps, 1, &header.ssrc); 1181 rtp_rtcp_->Process(); 1182 bitrate_capped_ = true; 1183 } else if (bitrate_capped_ && 1184 bitrate_bps < kRembRespectedBitrateBps) { 1185 observation_complete_->Set(); 1186 } 1187 } 1188 return DELIVERY_OK; 1189 } 1190 1191 scoped_ptr<RtpRtcp> rtp_rtcp_; 1192 internal::TransportAdapter feedback_transport_; 1193 VideoSendStream* send_stream_; 1194 bool bitrate_capped_; 1195 } observer; 1196 1197 Call::Config call_config(observer.SendTransport()); 1198 scoped_ptr<Call> call(Call::Create(call_config)); 1199 observer.SetReceivers(&observer, call->Receiver()); 1200 1201 CreateTestConfig(call.get(), 1); 1202 send_config_.rtp.min_transmit_bitrate_bps = kMinTransmitBitrateBps; 1203 send_stream_ = 1204 call->CreateVideoSendStream(send_config_, video_streams_, NULL); 1205 observer.SetSendStream(send_stream_); 1206 1207 scoped_ptr<test::FrameGeneratorCapturer> frame_generator_capturer( 1208 test::FrameGeneratorCapturer::Create( 1209 send_stream_->Input(), 320, 240, 30, Clock::GetRealTimeClock())); 1210 send_stream_->Start(); 1211 frame_generator_capturer->Start(); 1212 1213 EXPECT_EQ(kEventSignaled, observer.Wait()) 1214 << "Timeout while waiting for low bitrate stats after REMB."; 1215 1216 observer.StopSending(); 1217 frame_generator_capturer->Stop(); 1218 send_stream_->Stop(); 1219 call->DestroyVideoSendStream(send_stream_); 1220 } 1221 1222 } // namespace webrtc 1223