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 #include <vector> 12 13 #include "testing/gtest/include/gtest/gtest.h" 14 15 #include "webrtc/base/checks.h" 16 #include "webrtc/base/scoped_ptr.h" 17 #include "webrtc/call.h" 18 #include "webrtc/common_video/interface/i420_video_frame.h" 19 #include "webrtc/common_video/interface/native_handle.h" 20 #include "webrtc/frame_callback.h" 21 #include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h" 22 #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h" 23 #include "webrtc/modules/rtp_rtcp/source/rtcp_sender.h" 24 #include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h" 25 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h" 26 #include "webrtc/system_wrappers/interface/event_wrapper.h" 27 #include "webrtc/system_wrappers/interface/ref_count.h" 28 #include "webrtc/system_wrappers/interface/sleep.h" 29 #include "webrtc/system_wrappers/interface/thread_wrapper.h" 30 #include "webrtc/system_wrappers/interface/logging.h" 31 #include "webrtc/test/call_test.h" 32 #include "webrtc/test/configurable_frame_size_encoder.h" 33 #include "webrtc/test/null_transport.h" 34 #include "webrtc/test/testsupport/perf_test.h" 35 #include "webrtc/video/send_statistics_proxy.h" 36 #include "webrtc/video/transport_adapter.h" 37 #include "webrtc/video_send_stream.h" 38 39 namespace webrtc { 40 41 enum VideoFormat { kGeneric, kVP8, }; 42 43 void ExpectEqualFrames(const I420VideoFrame& frame1, 44 const I420VideoFrame& frame2); 45 void ExpectEqualTextureFrames(const I420VideoFrame& frame1, 46 const I420VideoFrame& frame2); 47 void ExpectEqualBufferFrames(const I420VideoFrame& frame1, 48 const I420VideoFrame& frame2); 49 void ExpectEqualFramesVector(const std::vector<I420VideoFrame>& frames1, 50 const std::vector<I420VideoFrame>& frames2); 51 I420VideoFrame CreateI420VideoFrame(int width, int height, uint8_t data); 52 53 class FakeNativeHandle : public NativeHandle { 54 public: 55 FakeNativeHandle() {} 56 virtual ~FakeNativeHandle() {} 57 virtual void* GetHandle() { return nullptr; } 58 }; 59 60 class VideoSendStreamTest : public test::CallTest { 61 protected: 62 void TestNackRetransmission(uint32_t retransmit_ssrc, 63 uint8_t retransmit_payload_type); 64 void TestPacketFragmentationSize(VideoFormat format, bool with_fec); 65 }; 66 67 TEST_F(VideoSendStreamTest, CanStartStartedStream) { 68 test::NullTransport transport; 69 Call::Config call_config(&transport); 70 CreateSenderCall(call_config); 71 72 CreateSendConfig(1); 73 CreateStreams(); 74 send_stream_->Start(); 75 send_stream_->Start(); 76 DestroyStreams(); 77 } 78 79 TEST_F(VideoSendStreamTest, CanStopStoppedStream) { 80 test::NullTransport transport; 81 Call::Config call_config(&transport); 82 CreateSenderCall(call_config); 83 84 CreateSendConfig(1); 85 CreateStreams(); 86 send_stream_->Stop(); 87 send_stream_->Stop(); 88 DestroyStreams(); 89 } 90 91 TEST_F(VideoSendStreamTest, SupportsCName) { 92 static std::string kCName = "PjQatC14dGfbVwGPUOA9IH7RlsFDbWl4AhXEiDsBizo="; 93 class CNameObserver : public test::SendTest { 94 public: 95 CNameObserver() : SendTest(kDefaultTimeoutMs) {} 96 97 private: 98 Action OnSendRtcp(const uint8_t* packet, size_t length) override { 99 RTCPUtility::RTCPParserV2 parser(packet, length, true); 100 EXPECT_TRUE(parser.IsValid()); 101 102 RTCPUtility::RTCPPacketTypes packet_type = parser.Begin(); 103 while (packet_type != RTCPUtility::kRtcpNotValidCode) { 104 if (packet_type == RTCPUtility::kRtcpSdesChunkCode) { 105 EXPECT_EQ(parser.Packet().CName.CName, kCName); 106 observation_complete_->Set(); 107 } 108 109 packet_type = parser.Iterate(); 110 } 111 112 return SEND_PACKET; 113 } 114 115 void ModifyConfigs(VideoSendStream::Config* send_config, 116 std::vector<VideoReceiveStream::Config>* receive_configs, 117 VideoEncoderConfig* encoder_config) override { 118 send_config->rtp.c_name = kCName; 119 } 120 121 void PerformTest() override { 122 EXPECT_EQ(kEventSignaled, Wait()) 123 << "Timed out while waiting for RTCP with CNAME."; 124 } 125 } test; 126 127 RunBaseTest(&test); 128 } 129 130 TEST_F(VideoSendStreamTest, SupportsAbsoluteSendTime) { 131 static const uint8_t kAbsSendTimeExtensionId = 13; 132 class AbsoluteSendTimeObserver : public test::SendTest { 133 public: 134 AbsoluteSendTimeObserver() : SendTest(kDefaultTimeoutMs) { 135 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension( 136 kRtpExtensionAbsoluteSendTime, kAbsSendTimeExtensionId)); 137 } 138 139 Action OnSendRtp(const uint8_t* packet, size_t length) override { 140 RTPHeader header; 141 EXPECT_TRUE(parser_->Parse(packet, length, &header)); 142 143 EXPECT_FALSE(header.extension.hasTransmissionTimeOffset); 144 EXPECT_TRUE(header.extension.hasAbsoluteSendTime); 145 EXPECT_EQ(header.extension.transmissionTimeOffset, 0); 146 EXPECT_GT(header.extension.absoluteSendTime, 0u); 147 observation_complete_->Set(); 148 149 return SEND_PACKET; 150 } 151 152 void ModifyConfigs(VideoSendStream::Config* send_config, 153 std::vector<VideoReceiveStream::Config>* receive_configs, 154 VideoEncoderConfig* encoder_config) override { 155 send_config->rtp.extensions.push_back( 156 RtpExtension(RtpExtension::kAbsSendTime, kAbsSendTimeExtensionId)); 157 } 158 159 void PerformTest() override { 160 EXPECT_EQ(kEventSignaled, Wait()) 161 << "Timed out while waiting for single RTP packet."; 162 } 163 } test; 164 165 RunBaseTest(&test); 166 } 167 168 TEST_F(VideoSendStreamTest, SupportsTransmissionTimeOffset) { 169 static const uint8_t kTOffsetExtensionId = 13; 170 static const int kEncodeDelayMs = 5; 171 class TransmissionTimeOffsetObserver : public test::SendTest { 172 public: 173 TransmissionTimeOffsetObserver() 174 : SendTest(kDefaultTimeoutMs), 175 encoder_(Clock::GetRealTimeClock(), kEncodeDelayMs) { 176 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension( 177 kRtpExtensionTransmissionTimeOffset, kTOffsetExtensionId)); 178 } 179 180 private: 181 Action OnSendRtp(const uint8_t* packet, size_t length) override { 182 RTPHeader header; 183 EXPECT_TRUE(parser_->Parse(packet, length, &header)); 184 185 EXPECT_TRUE(header.extension.hasTransmissionTimeOffset); 186 EXPECT_FALSE(header.extension.hasAbsoluteSendTime); 187 EXPECT_GT(header.extension.transmissionTimeOffset, 0); 188 EXPECT_EQ(header.extension.absoluteSendTime, 0u); 189 observation_complete_->Set(); 190 191 return SEND_PACKET; 192 } 193 194 void ModifyConfigs(VideoSendStream::Config* send_config, 195 std::vector<VideoReceiveStream::Config>* receive_configs, 196 VideoEncoderConfig* encoder_config) override { 197 send_config->encoder_settings.encoder = &encoder_; 198 send_config->rtp.extensions.push_back( 199 RtpExtension(RtpExtension::kTOffset, kTOffsetExtensionId)); 200 } 201 202 void PerformTest() override { 203 EXPECT_EQ(kEventSignaled, Wait()) 204 << "Timed out while waiting for a single RTP packet."; 205 } 206 207 test::DelayedEncoder encoder_; 208 } test; 209 210 RunBaseTest(&test); 211 } 212 213 class FakeReceiveStatistics : public NullReceiveStatistics { 214 public: 215 FakeReceiveStatistics(uint32_t send_ssrc, 216 uint32_t last_sequence_number, 217 uint32_t cumulative_lost, 218 uint8_t fraction_lost) 219 : lossy_stats_(new LossyStatistician(last_sequence_number, 220 cumulative_lost, 221 fraction_lost)) { 222 stats_map_[send_ssrc] = lossy_stats_.get(); 223 } 224 225 StatisticianMap GetActiveStatisticians() const override { return stats_map_; } 226 227 StreamStatistician* GetStatistician(uint32_t ssrc) const override { 228 return lossy_stats_.get(); 229 } 230 231 private: 232 class LossyStatistician : public StreamStatistician { 233 public: 234 LossyStatistician(uint32_t extended_max_sequence_number, 235 uint32_t cumulative_lost, 236 uint8_t fraction_lost) { 237 stats_.fraction_lost = fraction_lost; 238 stats_.cumulative_lost = cumulative_lost; 239 stats_.extended_max_sequence_number = extended_max_sequence_number; 240 } 241 bool GetStatistics(RtcpStatistics* statistics, bool reset) override { 242 *statistics = stats_; 243 return true; 244 } 245 void GetDataCounters(size_t* bytes_received, 246 uint32_t* packets_received) const override { 247 *bytes_received = 0; 248 *packets_received = 0; 249 } 250 void GetReceiveStreamDataCounters( 251 StreamDataCounters* data_counters) const override {} 252 uint32_t BitrateReceived() const override { return 0; } 253 void ResetStatistics() override {} 254 bool IsRetransmitOfOldPacket(const RTPHeader& header, 255 int64_t min_rtt) const override { 256 return false; 257 } 258 259 bool IsPacketInOrder(uint16_t sequence_number) const override { 260 return true; 261 } 262 263 RtcpStatistics stats_; 264 }; 265 266 rtc::scoped_ptr<LossyStatistician> lossy_stats_; 267 StatisticianMap stats_map_; 268 }; 269 270 TEST_F(VideoSendStreamTest, SupportsFec) { 271 class FecObserver : public test::SendTest { 272 public: 273 FecObserver() 274 : SendTest(kDefaultTimeoutMs), 275 transport_adapter_(SendTransport()), 276 send_count_(0), 277 received_media_(false), 278 received_fec_(false) { 279 transport_adapter_.Enable(); 280 } 281 282 private: 283 Action OnSendRtp(const uint8_t* packet, size_t length) override { 284 RTPHeader header; 285 EXPECT_TRUE(parser_->Parse(packet, length, &header)); 286 287 // Send lossy receive reports to trigger FEC enabling. 288 if (send_count_++ % 2 != 0) { 289 // Receive statistics reporting having lost 50% of the packets. 290 FakeReceiveStatistics lossy_receive_stats( 291 kSendSsrcs[0], header.sequenceNumber, send_count_ / 2, 127); 292 RTCPSender rtcp_sender(0, false, Clock::GetRealTimeClock(), 293 &lossy_receive_stats, nullptr); 294 EXPECT_EQ(0, rtcp_sender.RegisterSendTransport(&transport_adapter_)); 295 296 rtcp_sender.SetRTCPStatus(kRtcpNonCompound); 297 rtcp_sender.SetRemoteSSRC(kSendSsrcs[0]); 298 299 RTCPSender::FeedbackState feedback_state; 300 301 EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr)); 302 } 303 304 EXPECT_EQ(kRedPayloadType, header.payloadType); 305 306 uint8_t encapsulated_payload_type = packet[header.headerLength]; 307 308 if (encapsulated_payload_type == kUlpfecPayloadType) { 309 received_fec_ = true; 310 } else { 311 received_media_ = true; 312 } 313 314 if (received_media_ && received_fec_) 315 observation_complete_->Set(); 316 317 return SEND_PACKET; 318 } 319 320 void ModifyConfigs(VideoSendStream::Config* send_config, 321 std::vector<VideoReceiveStream::Config>* receive_configs, 322 VideoEncoderConfig* encoder_config) override { 323 send_config->rtp.fec.red_payload_type = kRedPayloadType; 324 send_config->rtp.fec.ulpfec_payload_type = kUlpfecPayloadType; 325 } 326 327 void PerformTest() override { 328 EXPECT_TRUE(Wait()) << "Timed out waiting for FEC and media packets."; 329 } 330 331 internal::TransportAdapter transport_adapter_; 332 int send_count_; 333 bool received_media_; 334 bool received_fec_; 335 } test; 336 337 RunBaseTest(&test); 338 } 339 340 void VideoSendStreamTest::TestNackRetransmission( 341 uint32_t retransmit_ssrc, 342 uint8_t retransmit_payload_type) { 343 class NackObserver : public test::SendTest { 344 public: 345 explicit NackObserver(uint32_t retransmit_ssrc, 346 uint8_t retransmit_payload_type) 347 : SendTest(kDefaultTimeoutMs), 348 transport_adapter_(SendTransport()), 349 send_count_(0), 350 retransmit_ssrc_(retransmit_ssrc), 351 retransmit_payload_type_(retransmit_payload_type), 352 nacked_sequence_number_(-1) { 353 transport_adapter_.Enable(); 354 } 355 356 private: 357 Action OnSendRtp(const uint8_t* packet, size_t length) override { 358 RTPHeader header; 359 EXPECT_TRUE(parser_->Parse(packet, length, &header)); 360 361 // Nack second packet after receiving the third one. 362 if (++send_count_ == 3) { 363 uint16_t nack_sequence_number = header.sequenceNumber - 1; 364 nacked_sequence_number_ = nack_sequence_number; 365 NullReceiveStatistics null_stats; 366 RTCPSender rtcp_sender( 367 0, false, Clock::GetRealTimeClock(), &null_stats, nullptr); 368 EXPECT_EQ(0, rtcp_sender.RegisterSendTransport(&transport_adapter_)); 369 370 rtcp_sender.SetRTCPStatus(kRtcpNonCompound); 371 rtcp_sender.SetRemoteSSRC(kSendSsrcs[0]); 372 373 RTCPSender::FeedbackState feedback_state; 374 375 EXPECT_EQ(0, 376 rtcp_sender.SendRTCP( 377 feedback_state, kRtcpNack, 1, &nack_sequence_number)); 378 } 379 380 uint16_t sequence_number = header.sequenceNumber; 381 382 if (header.ssrc == retransmit_ssrc_ && 383 retransmit_ssrc_ != kSendSsrcs[0]) { 384 // Not kSendSsrcs[0], assume correct RTX packet. Extract sequence 385 // number. 386 const uint8_t* rtx_header = packet + header.headerLength; 387 sequence_number = (rtx_header[0] << 8) + rtx_header[1]; 388 } 389 390 if (sequence_number == nacked_sequence_number_) { 391 EXPECT_EQ(retransmit_ssrc_, header.ssrc); 392 EXPECT_EQ(retransmit_payload_type_, header.payloadType); 393 observation_complete_->Set(); 394 } 395 396 return SEND_PACKET; 397 } 398 399 void ModifyConfigs(VideoSendStream::Config* send_config, 400 std::vector<VideoReceiveStream::Config>* receive_configs, 401 VideoEncoderConfig* encoder_config) override { 402 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs; 403 send_config->rtp.rtx.payload_type = retransmit_payload_type_; 404 if (retransmit_ssrc_ != kSendSsrcs[0]) 405 send_config->rtp.rtx.ssrcs.push_back(retransmit_ssrc_); 406 } 407 408 void PerformTest() override { 409 EXPECT_EQ(kEventSignaled, Wait()) 410 << "Timed out while waiting for NACK retransmission."; 411 } 412 413 internal::TransportAdapter transport_adapter_; 414 int send_count_; 415 uint32_t retransmit_ssrc_; 416 uint8_t retransmit_payload_type_; 417 int nacked_sequence_number_; 418 } test(retransmit_ssrc, retransmit_payload_type); 419 420 RunBaseTest(&test); 421 } 422 423 TEST_F(VideoSendStreamTest, RetransmitsNack) { 424 // Normal NACKs should use the send SSRC. 425 TestNackRetransmission(kSendSsrcs[0], kFakeSendPayloadType); 426 } 427 428 TEST_F(VideoSendStreamTest, RetransmitsNackOverRtx) { 429 // NACKs over RTX should use a separate SSRC. 430 TestNackRetransmission(kSendRtxSsrcs[0], kSendRtxPayloadType); 431 } 432 433 void VideoSendStreamTest::TestPacketFragmentationSize(VideoFormat format, 434 bool with_fec) { 435 // Use a fake encoder to output a frame of every size in the range [90, 290], 436 // for each size making sure that the exact number of payload bytes received 437 // is correct and that packets are fragmented to respect max packet size. 438 static const size_t kMaxPacketSize = 128; 439 static const size_t start = 90; 440 static const size_t stop = 290; 441 442 // Observer that verifies that the expected number of packets and bytes 443 // arrive for each frame size, from start_size to stop_size. 444 class FrameFragmentationTest : public test::SendTest, 445 public EncodedFrameObserver { 446 public: 447 FrameFragmentationTest(size_t max_packet_size, 448 size_t start_size, 449 size_t stop_size, 450 bool test_generic_packetization, 451 bool use_fec) 452 : SendTest(kLongTimeoutMs), 453 transport_adapter_(SendTransport()), 454 encoder_(stop), 455 max_packet_size_(max_packet_size), 456 stop_size_(stop_size), 457 test_generic_packetization_(test_generic_packetization), 458 use_fec_(use_fec), 459 packet_count_(0), 460 accumulated_size_(0), 461 accumulated_payload_(0), 462 fec_packet_received_(false), 463 current_size_rtp_(start_size), 464 current_size_frame_(static_cast<int32_t>(start_size)) { 465 // Fragmentation required, this test doesn't make sense without it. 466 encoder_.SetFrameSize(start_size); 467 DCHECK_GT(stop_size, max_packet_size); 468 transport_adapter_.Enable(); 469 } 470 471 private: 472 Action OnSendRtp(const uint8_t* packet, size_t size) override { 473 size_t length = size; 474 RTPHeader header; 475 EXPECT_TRUE(parser_->Parse(packet, length, &header)); 476 477 EXPECT_LE(length, max_packet_size_); 478 479 if (use_fec_) { 480 uint8_t payload_type = packet[header.headerLength]; 481 bool is_fec = header.payloadType == kRedPayloadType && 482 payload_type == kUlpfecPayloadType; 483 if (is_fec) { 484 fec_packet_received_ = true; 485 return SEND_PACKET; 486 } 487 } 488 489 accumulated_size_ += length; 490 491 if (use_fec_) 492 TriggerLossReport(header); 493 494 if (test_generic_packetization_) { 495 size_t overhead = header.headerLength + header.paddingLength + 496 (1 /* Generic header */); 497 if (use_fec_) 498 overhead += 1; // RED for FEC header. 499 accumulated_payload_ += length - overhead; 500 } 501 502 // Marker bit set indicates last packet of a frame. 503 if (header.markerBit) { 504 if (use_fec_ && accumulated_payload_ == current_size_rtp_ - 1) { 505 // With FEC enabled, frame size is incremented asynchronously, so 506 // "old" frames one byte too small may arrive. Accept, but don't 507 // increase expected frame size. 508 accumulated_size_ = 0; 509 accumulated_payload_ = 0; 510 return SEND_PACKET; 511 } 512 513 EXPECT_GE(accumulated_size_, current_size_rtp_); 514 if (test_generic_packetization_) { 515 EXPECT_EQ(current_size_rtp_, accumulated_payload_); 516 } 517 518 // Last packet of frame; reset counters. 519 accumulated_size_ = 0; 520 accumulated_payload_ = 0; 521 if (current_size_rtp_ == stop_size_) { 522 // Done! (Don't increase size again, might arrive more @ stop_size). 523 observation_complete_->Set(); 524 } else { 525 // Increase next expected frame size. If testing with FEC, make sure 526 // a FEC packet has been received for this frame size before 527 // proceeding, to make sure that redundancy packets don't exceed 528 // size limit. 529 if (!use_fec_) { 530 ++current_size_rtp_; 531 } else if (fec_packet_received_) { 532 fec_packet_received_ = false; 533 ++current_size_rtp_; 534 ++current_size_frame_; 535 } 536 } 537 } 538 539 return SEND_PACKET; 540 } 541 542 void TriggerLossReport(const RTPHeader& header) { 543 // Send lossy receive reports to trigger FEC enabling. 544 if (packet_count_++ % 2 != 0) { 545 // Receive statistics reporting having lost 50% of the packets. 546 FakeReceiveStatistics lossy_receive_stats( 547 kSendSsrcs[0], header.sequenceNumber, packet_count_ / 2, 127); 548 RTCPSender rtcp_sender(0, false, Clock::GetRealTimeClock(), 549 &lossy_receive_stats, nullptr); 550 EXPECT_EQ(0, rtcp_sender.RegisterSendTransport(&transport_adapter_)); 551 552 rtcp_sender.SetRTCPStatus(kRtcpNonCompound); 553 rtcp_sender.SetRemoteSSRC(kSendSsrcs[0]); 554 555 RTCPSender::FeedbackState feedback_state; 556 557 EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr)); 558 } 559 } 560 561 virtual void EncodedFrameCallback(const EncodedFrame& encoded_frame) { 562 // Increase frame size for next encoded frame, in the context of the 563 // encoder thread. 564 if (!use_fec_ && 565 current_size_frame_.Value() < static_cast<int32_t>(stop_size_)) { 566 ++current_size_frame_; 567 } 568 encoder_.SetFrameSize(static_cast<size_t>(current_size_frame_.Value())); 569 } 570 571 Call::Config GetSenderCallConfig() override { 572 Call::Config config(SendTransport()); 573 const int kMinBitrateBps = 30000; 574 config.bitrate_config.min_bitrate_bps = kMinBitrateBps; 575 return config; 576 } 577 578 void ModifyConfigs(VideoSendStream::Config* send_config, 579 std::vector<VideoReceiveStream::Config>* receive_configs, 580 VideoEncoderConfig* encoder_config) override { 581 if (use_fec_) { 582 send_config->rtp.fec.red_payload_type = kRedPayloadType; 583 send_config->rtp.fec.ulpfec_payload_type = kUlpfecPayloadType; 584 } 585 586 if (!test_generic_packetization_) 587 send_config->encoder_settings.payload_name = "VP8"; 588 589 send_config->encoder_settings.encoder = &encoder_; 590 send_config->rtp.max_packet_size = kMaxPacketSize; 591 send_config->post_encode_callback = this; 592 593 // Add an extension header, to make the RTP header larger than the base 594 // length of 12 bytes. 595 static const uint8_t kAbsSendTimeExtensionId = 13; 596 send_config->rtp.extensions.push_back( 597 RtpExtension(RtpExtension::kAbsSendTime, kAbsSendTimeExtensionId)); 598 } 599 600 void PerformTest() override { 601 EXPECT_EQ(kEventSignaled, Wait()) 602 << "Timed out while observing incoming RTP packets."; 603 } 604 605 internal::TransportAdapter transport_adapter_; 606 test::ConfigurableFrameSizeEncoder encoder_; 607 608 const size_t max_packet_size_; 609 const size_t stop_size_; 610 const bool test_generic_packetization_; 611 const bool use_fec_; 612 613 uint32_t packet_count_; 614 size_t accumulated_size_; 615 size_t accumulated_payload_; 616 bool fec_packet_received_; 617 618 size_t current_size_rtp_; 619 Atomic32 current_size_frame_; 620 }; 621 622 // Don't auto increment if FEC is used; continue sending frame size until 623 // a FEC packet has been received. 624 FrameFragmentationTest test( 625 kMaxPacketSize, start, stop, format == kGeneric, with_fec); 626 627 RunBaseTest(&test); 628 } 629 630 // TODO(sprang): Is there any way of speeding up these tests? 631 TEST_F(VideoSendStreamTest, FragmentsGenericAccordingToMaxPacketSize) { 632 TestPacketFragmentationSize(kGeneric, false); 633 } 634 635 TEST_F(VideoSendStreamTest, FragmentsGenericAccordingToMaxPacketSizeWithFec) { 636 TestPacketFragmentationSize(kGeneric, true); 637 } 638 639 TEST_F(VideoSendStreamTest, FragmentsVp8AccordingToMaxPacketSize) { 640 TestPacketFragmentationSize(kVP8, false); 641 } 642 643 TEST_F(VideoSendStreamTest, FragmentsVp8AccordingToMaxPacketSizeWithFec) { 644 TestPacketFragmentationSize(kVP8, true); 645 } 646 647 // The test will go through a number of phases. 648 // 1. Start sending packets. 649 // 2. As soon as the RTP stream has been detected, signal a low REMB value to 650 // suspend the stream. 651 // 3. Wait until |kSuspendTimeFrames| have been captured without seeing any RTP 652 // packets. 653 // 4. Signal a high REMB and then wait for the RTP stream to start again. 654 // When the stream is detected again, and the stats show that the stream 655 // is no longer suspended, the test ends. 656 TEST_F(VideoSendStreamTest, SuspendBelowMinBitrate) { 657 static const int kSuspendTimeFrames = 60; // Suspend for 2 seconds @ 30 fps. 658 659 class RembObserver : public test::SendTest, public I420FrameCallback { 660 public: 661 RembObserver() 662 : SendTest(kDefaultTimeoutMs), 663 transport_adapter_(&transport_), 664 clock_(Clock::GetRealTimeClock()), 665 crit_(CriticalSectionWrapper::CreateCriticalSection()), 666 test_state_(kBeforeSuspend), 667 rtp_count_(0), 668 last_sequence_number_(0), 669 suspended_frame_count_(0), 670 low_remb_bps_(0), 671 high_remb_bps_(0) { 672 transport_adapter_.Enable(); 673 } 674 675 private: 676 Action OnSendRtcp(const uint8_t* packet, size_t length) override { 677 // Receive statistics reporting having lost 0% of the packets. 678 // This is needed for the send-side bitrate controller to work properly. 679 CriticalSectionScoped lock(crit_.get()); 680 SendRtcpFeedback(0); // REMB is only sent if value is > 0. 681 return SEND_PACKET; 682 } 683 684 Action OnSendRtp(const uint8_t* packet, size_t length) override { 685 CriticalSectionScoped lock(crit_.get()); 686 ++rtp_count_; 687 RTPHeader header; 688 EXPECT_TRUE(parser_->Parse(packet, length, &header)); 689 last_sequence_number_ = header.sequenceNumber; 690 691 if (test_state_ == kBeforeSuspend) { 692 // The stream has started. Try to suspend it. 693 SendRtcpFeedback(low_remb_bps_); 694 test_state_ = kDuringSuspend; 695 } else if (test_state_ == kDuringSuspend) { 696 if (header.paddingLength == 0) { 697 // Received non-padding packet during suspension period. Reset the 698 // counter. 699 suspended_frame_count_ = 0; 700 } 701 } else if (test_state_ == kWaitingForPacket) { 702 if (header.paddingLength == 0) { 703 // Non-padding packet observed. Test is almost complete. Will just 704 // have to wait for the stats to change. 705 test_state_ = kWaitingForStats; 706 } 707 } else if (test_state_ == kWaitingForStats) { 708 VideoSendStream::Stats stats = stream_->GetStats(); 709 if (stats.suspended == false) { 710 // Stats flipped to false. Test is complete. 711 observation_complete_->Set(); 712 } 713 } 714 715 return SEND_PACKET; 716 } 717 718 // This method implements the I420FrameCallback. 719 void FrameCallback(I420VideoFrame* video_frame) override { 720 CriticalSectionScoped lock(crit_.get()); 721 if (test_state_ == kDuringSuspend && 722 ++suspended_frame_count_ > kSuspendTimeFrames) { 723 VideoSendStream::Stats stats = stream_->GetStats(); 724 EXPECT_TRUE(stats.suspended); 725 SendRtcpFeedback(high_remb_bps_); 726 test_state_ = kWaitingForPacket; 727 } 728 } 729 730 void set_low_remb_bps(int value) { 731 CriticalSectionScoped lock(crit_.get()); 732 low_remb_bps_ = value; 733 } 734 735 void set_high_remb_bps(int value) { 736 CriticalSectionScoped lock(crit_.get()); 737 high_remb_bps_ = value; 738 } 739 740 void SetReceivers(PacketReceiver* send_transport_receiver, 741 PacketReceiver* receive_transport_receiver) override { 742 transport_.SetReceiver(send_transport_receiver); 743 } 744 745 void OnStreamsCreated( 746 VideoSendStream* send_stream, 747 const std::vector<VideoReceiveStream*>& receive_streams) override { 748 stream_ = send_stream; 749 } 750 751 void ModifyConfigs(VideoSendStream::Config* send_config, 752 std::vector<VideoReceiveStream::Config>* receive_configs, 753 VideoEncoderConfig* encoder_config) override { 754 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs; 755 send_config->pre_encode_callback = this; 756 send_config->suspend_below_min_bitrate = true; 757 int min_bitrate_bps = encoder_config->streams[0].min_bitrate_bps; 758 set_low_remb_bps(min_bitrate_bps - 10000); 759 int threshold_window = std::max(min_bitrate_bps / 10, 10000); 760 ASSERT_GT(encoder_config->streams[0].max_bitrate_bps, 761 min_bitrate_bps + threshold_window + 5000); 762 set_high_remb_bps(min_bitrate_bps + threshold_window + 5000); 763 } 764 765 void PerformTest() override { 766 EXPECT_EQ(kEventSignaled, Wait()) 767 << "Timed out during suspend-below-min-bitrate test."; 768 transport_.StopSending(); 769 } 770 771 enum TestState { 772 kBeforeSuspend, 773 kDuringSuspend, 774 kWaitingForPacket, 775 kWaitingForStats 776 }; 777 778 virtual void SendRtcpFeedback(int remb_value) 779 EXCLUSIVE_LOCKS_REQUIRED(crit_) { 780 FakeReceiveStatistics receive_stats( 781 kSendSsrcs[0], last_sequence_number_, rtp_count_, 0); 782 RTCPSender rtcp_sender(0, false, clock_, &receive_stats, nullptr); 783 EXPECT_EQ(0, rtcp_sender.RegisterSendTransport(&transport_adapter_)); 784 785 rtcp_sender.SetRTCPStatus(kRtcpNonCompound); 786 rtcp_sender.SetRemoteSSRC(kSendSsrcs[0]); 787 if (remb_value > 0) { 788 rtcp_sender.SetREMBStatus(true); 789 rtcp_sender.SetREMBData(remb_value, std::vector<uint32_t>()); 790 } 791 RTCPSender::FeedbackState feedback_state; 792 EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr)); 793 } 794 795 internal::TransportAdapter transport_adapter_; 796 test::DirectTransport transport_; 797 Clock* const clock_; 798 VideoSendStream* stream_; 799 800 const rtc::scoped_ptr<CriticalSectionWrapper> crit_; 801 TestState test_state_ GUARDED_BY(crit_); 802 int rtp_count_ GUARDED_BY(crit_); 803 int last_sequence_number_ GUARDED_BY(crit_); 804 int suspended_frame_count_ GUARDED_BY(crit_); 805 int low_remb_bps_ GUARDED_BY(crit_); 806 int high_remb_bps_ GUARDED_BY(crit_); 807 } test; 808 809 RunBaseTest(&test); 810 } 811 812 TEST_F(VideoSendStreamTest, NoPaddingWhenVideoIsMuted) { 813 class NoPaddingWhenVideoIsMuted : public test::SendTest { 814 public: 815 NoPaddingWhenVideoIsMuted() 816 : SendTest(kDefaultTimeoutMs), 817 clock_(Clock::GetRealTimeClock()), 818 transport_adapter_(ReceiveTransport()), 819 crit_(CriticalSectionWrapper::CreateCriticalSection()), 820 last_packet_time_ms_(-1), 821 capturer_(nullptr) { 822 transport_adapter_.Enable(); 823 } 824 825 private: 826 Action OnSendRtp(const uint8_t* packet, size_t length) override { 827 CriticalSectionScoped lock(crit_.get()); 828 last_packet_time_ms_ = clock_->TimeInMilliseconds(); 829 capturer_->Stop(); 830 return SEND_PACKET; 831 } 832 833 Action OnSendRtcp(const uint8_t* packet, size_t length) override { 834 CriticalSectionScoped lock(crit_.get()); 835 const int kVideoMutedThresholdMs = 10000; 836 if (last_packet_time_ms_ > 0 && 837 clock_->TimeInMilliseconds() - last_packet_time_ms_ > 838 kVideoMutedThresholdMs) 839 observation_complete_->Set(); 840 // Receive statistics reporting having lost 50% of the packets. 841 FakeReceiveStatistics receive_stats(kSendSsrcs[0], 1, 1, 0); 842 RTCPSender rtcp_sender(0, false, Clock::GetRealTimeClock(), 843 &receive_stats, nullptr); 844 EXPECT_EQ(0, rtcp_sender.RegisterSendTransport(&transport_adapter_)); 845 846 rtcp_sender.SetRTCPStatus(kRtcpNonCompound); 847 rtcp_sender.SetRemoteSSRC(kSendSsrcs[0]); 848 849 RTCPSender::FeedbackState feedback_state; 850 851 EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr)); 852 return SEND_PACKET; 853 } 854 855 void SetReceivers(PacketReceiver* send_transport_receiver, 856 PacketReceiver* receive_transport_receiver) override { 857 RtpRtcpObserver::SetReceivers(send_transport_receiver, 858 send_transport_receiver); 859 } 860 861 size_t GetNumStreams() const override { return 3; } 862 863 virtual void OnFrameGeneratorCapturerCreated( 864 test::FrameGeneratorCapturer* frame_generator_capturer) { 865 CriticalSectionScoped lock(crit_.get()); 866 capturer_ = frame_generator_capturer; 867 } 868 869 void PerformTest() override { 870 EXPECT_EQ(kEventSignaled, Wait()) 871 << "Timed out while waiting for RTP packets to stop being sent."; 872 } 873 874 Clock* const clock_; 875 internal::TransportAdapter transport_adapter_; 876 const rtc::scoped_ptr<CriticalSectionWrapper> crit_; 877 int64_t last_packet_time_ms_ GUARDED_BY(crit_); 878 test::FrameGeneratorCapturer* capturer_ GUARDED_BY(crit_); 879 } test; 880 881 RunBaseTest(&test); 882 } 883 884 // This test first observes "high" bitrate use at which point it sends a REMB to 885 // indicate that it should be lowered significantly. The test then observes that 886 // the bitrate observed is sinking well below the min-transmit-bitrate threshold 887 // to verify that the min-transmit bitrate respects incoming REMB. 888 // 889 // Note that the test starts at "high" bitrate and does not ramp up to "higher" 890 // bitrate since no receiver block or remb is sent in the initial phase. 891 TEST_F(VideoSendStreamTest, MinTransmitBitrateRespectsRemb) { 892 static const int kMinTransmitBitrateBps = 400000; 893 static const int kHighBitrateBps = 150000; 894 static const int kRembBitrateBps = 80000; 895 static const int kRembRespectedBitrateBps = 100000; 896 class BitrateObserver : public test::SendTest, public PacketReceiver { 897 public: 898 BitrateObserver() 899 : SendTest(kDefaultTimeoutMs), 900 feedback_transport_(ReceiveTransport()), 901 bitrate_capped_(false) { 902 RtpRtcp::Configuration config; 903 feedback_transport_.Enable(); 904 config.outgoing_transport = &feedback_transport_; 905 rtp_rtcp_.reset(RtpRtcp::CreateRtpRtcp(config)); 906 rtp_rtcp_->SetREMBStatus(true); 907 rtp_rtcp_->SetRTCPStatus(kRtcpNonCompound); 908 } 909 910 void OnStreamsCreated( 911 VideoSendStream* send_stream, 912 const std::vector<VideoReceiveStream*>& receive_streams) override { 913 stream_ = send_stream; 914 } 915 916 private: 917 DeliveryStatus DeliverPacket(const uint8_t* packet, 918 size_t length) override { 919 if (RtpHeaderParser::IsRtcp(packet, length)) 920 return DELIVERY_OK; 921 922 RTPHeader header; 923 if (!parser_->Parse(packet, length, &header)) 924 return DELIVERY_PACKET_ERROR; 925 DCHECK(stream_ != nullptr); 926 VideoSendStream::Stats stats = stream_->GetStats(); 927 if (!stats.substreams.empty()) { 928 EXPECT_EQ(1u, stats.substreams.size()); 929 int total_bitrate_bps = 930 stats.substreams.begin()->second.total_bitrate_bps; 931 test::PrintResult("bitrate_stats_", 932 "min_transmit_bitrate_low_remb", 933 "bitrate_bps", 934 static_cast<size_t>(total_bitrate_bps), 935 "bps", 936 false); 937 if (total_bitrate_bps > kHighBitrateBps) { 938 rtp_rtcp_->SetREMBData(kRembBitrateBps, 939 std::vector<uint32_t>(1, header.ssrc)); 940 rtp_rtcp_->Process(); 941 bitrate_capped_ = true; 942 } else if (bitrate_capped_ && 943 total_bitrate_bps < kRembRespectedBitrateBps) { 944 observation_complete_->Set(); 945 } 946 } 947 return DELIVERY_OK; 948 } 949 950 void SetReceivers(PacketReceiver* send_transport_receiver, 951 PacketReceiver* receive_transport_receiver) override { 952 RtpRtcpObserver::SetReceivers(this, send_transport_receiver); 953 } 954 955 void ModifyConfigs(VideoSendStream::Config* send_config, 956 std::vector<VideoReceiveStream::Config>* receive_configs, 957 VideoEncoderConfig* encoder_config) override { 958 encoder_config->min_transmit_bitrate_bps = kMinTransmitBitrateBps; 959 } 960 961 void PerformTest() override { 962 EXPECT_EQ(kEventSignaled, Wait()) 963 << "Timeout while waiting for low bitrate stats after REMB."; 964 } 965 966 rtc::scoped_ptr<RtpRtcp> rtp_rtcp_; 967 internal::TransportAdapter feedback_transport_; 968 VideoSendStream* stream_; 969 bool bitrate_capped_; 970 } test; 971 972 RunBaseTest(&test); 973 } 974 975 TEST_F(VideoSendStreamTest, CanReconfigureToUseStartBitrateAbovePreviousMax) { 976 class StartBitrateObserver : public test::FakeEncoder { 977 public: 978 StartBitrateObserver() 979 : FakeEncoder(Clock::GetRealTimeClock()), start_bitrate_kbps_(0) {} 980 int32_t InitEncode(const VideoCodec* config, 981 int32_t number_of_cores, 982 size_t max_payload_size) override { 983 rtc::CritScope lock(&crit_); 984 start_bitrate_kbps_ = config->startBitrate; 985 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size); 986 } 987 988 int32_t SetRates(uint32_t new_target_bitrate, uint32_t framerate) override { 989 rtc::CritScope lock(&crit_); 990 start_bitrate_kbps_ = new_target_bitrate; 991 return FakeEncoder::SetRates(new_target_bitrate, framerate); 992 } 993 994 int GetStartBitrateKbps() const { 995 rtc::CritScope lock(&crit_); 996 return start_bitrate_kbps_; 997 } 998 999 private: 1000 mutable rtc::CriticalSection crit_; 1001 int start_bitrate_kbps_ GUARDED_BY(crit_); 1002 }; 1003 1004 test::NullTransport transport; 1005 CreateSenderCall(Call::Config(&transport)); 1006 1007 CreateSendConfig(1); 1008 1009 Call::Config::BitrateConfig bitrate_config; 1010 bitrate_config.start_bitrate_bps = 1011 2 * encoder_config_.streams[0].max_bitrate_bps; 1012 sender_call_->SetBitrateConfig(bitrate_config); 1013 1014 StartBitrateObserver encoder; 1015 send_config_.encoder_settings.encoder = &encoder; 1016 1017 CreateStreams(); 1018 1019 EXPECT_EQ(encoder_config_.streams[0].max_bitrate_bps / 1000, 1020 encoder.GetStartBitrateKbps()); 1021 1022 encoder_config_.streams[0].max_bitrate_bps = 1023 2 * bitrate_config.start_bitrate_bps; 1024 send_stream_->ReconfigureVideoEncoder(encoder_config_); 1025 1026 // New bitrate should be reconfigured above the previous max. As there's no 1027 // network connection this shouldn't be flaky, as no bitrate should've been 1028 // reported in between. 1029 EXPECT_EQ(bitrate_config.start_bitrate_bps / 1000, 1030 encoder.GetStartBitrateKbps()); 1031 1032 DestroyStreams(); 1033 } 1034 1035 TEST_F(VideoSendStreamTest, CapturesTextureAndI420VideoFrames) { 1036 class FrameObserver : public I420FrameCallback { 1037 public: 1038 FrameObserver() : output_frame_event_(EventWrapper::Create()) {} 1039 1040 void FrameCallback(I420VideoFrame* video_frame) override { 1041 output_frames_.push_back(*video_frame); 1042 output_frame_event_->Set(); 1043 } 1044 1045 void WaitOutputFrame() { 1046 const unsigned long kWaitFrameTimeoutMs = 3000; 1047 EXPECT_EQ(kEventSignaled, output_frame_event_->Wait(kWaitFrameTimeoutMs)) 1048 << "Timeout while waiting for output frames."; 1049 } 1050 1051 const std::vector<I420VideoFrame>& output_frames() const { 1052 return output_frames_; 1053 } 1054 1055 private: 1056 // Delivered output frames. 1057 std::vector<I420VideoFrame> output_frames_; 1058 1059 // Indicate an output frame has arrived. 1060 rtc::scoped_ptr<EventWrapper> output_frame_event_; 1061 }; 1062 1063 // Initialize send stream. 1064 test::NullTransport transport; 1065 CreateSenderCall(Call::Config(&transport)); 1066 1067 CreateSendConfig(1); 1068 FrameObserver observer; 1069 send_config_.pre_encode_callback = &observer; 1070 CreateStreams(); 1071 1072 // Prepare five input frames. Send ordinary I420VideoFrame and texture frames 1073 // alternatively. 1074 std::vector<I420VideoFrame> input_frames; 1075 int width = static_cast<int>(encoder_config_.streams[0].width); 1076 int height = static_cast<int>(encoder_config_.streams[0].height); 1077 webrtc::RefCountImpl<FakeNativeHandle>* handle1 = 1078 new webrtc::RefCountImpl<FakeNativeHandle>(); 1079 webrtc::RefCountImpl<FakeNativeHandle>* handle2 = 1080 new webrtc::RefCountImpl<FakeNativeHandle>(); 1081 webrtc::RefCountImpl<FakeNativeHandle>* handle3 = 1082 new webrtc::RefCountImpl<FakeNativeHandle>(); 1083 input_frames.push_back(I420VideoFrame(handle1, width, height, 1, 1)); 1084 input_frames.push_back(I420VideoFrame(handle2, width, height, 2, 2)); 1085 input_frames.push_back(CreateI420VideoFrame(width, height, 3)); 1086 input_frames.push_back(CreateI420VideoFrame(width, height, 4)); 1087 input_frames.push_back(I420VideoFrame(handle3, width, height, 5, 5)); 1088 1089 send_stream_->Start(); 1090 for (size_t i = 0; i < input_frames.size(); i++) { 1091 send_stream_->Input()->IncomingCapturedFrame(input_frames[i]); 1092 // Do not send the next frame too fast, so the frame dropper won't drop it. 1093 if (i < input_frames.size() - 1) 1094 SleepMs(1000 / encoder_config_.streams[0].max_framerate); 1095 // Wait until the output frame is received before sending the next input 1096 // frame. Or the previous input frame may be replaced without delivering. 1097 observer.WaitOutputFrame(); 1098 } 1099 send_stream_->Stop(); 1100 1101 // Test if the input and output frames are the same. render_time_ms and 1102 // timestamp are not compared because capturer sets those values. 1103 ExpectEqualFramesVector(input_frames, observer.output_frames()); 1104 1105 DestroyStreams(); 1106 } 1107 1108 void ExpectEqualFrames(const I420VideoFrame& frame1, 1109 const I420VideoFrame& frame2) { 1110 if (frame1.native_handle() != nullptr || frame2.native_handle() != nullptr) 1111 ExpectEqualTextureFrames(frame1, frame2); 1112 else 1113 ExpectEqualBufferFrames(frame1, frame2); 1114 } 1115 1116 void ExpectEqualTextureFrames(const I420VideoFrame& frame1, 1117 const I420VideoFrame& frame2) { 1118 EXPECT_EQ(frame1.native_handle(), frame2.native_handle()); 1119 EXPECT_EQ(frame1.width(), frame2.width()); 1120 EXPECT_EQ(frame1.height(), frame2.height()); 1121 EXPECT_EQ(frame1.render_time_ms(), frame2.render_time_ms()); 1122 } 1123 1124 void ExpectEqualBufferFrames(const I420VideoFrame& frame1, 1125 const I420VideoFrame& frame2) { 1126 EXPECT_EQ(frame1.width(), frame2.width()); 1127 EXPECT_EQ(frame1.height(), frame2.height()); 1128 EXPECT_EQ(frame1.stride(kYPlane), frame2.stride(kYPlane)); 1129 EXPECT_EQ(frame1.stride(kUPlane), frame2.stride(kUPlane)); 1130 EXPECT_EQ(frame1.stride(kVPlane), frame2.stride(kVPlane)); 1131 EXPECT_EQ(frame1.render_time_ms(), frame2.render_time_ms()); 1132 ASSERT_EQ(frame1.allocated_size(kYPlane), frame2.allocated_size(kYPlane)); 1133 EXPECT_EQ(0, 1134 memcmp(frame1.buffer(kYPlane), 1135 frame2.buffer(kYPlane), 1136 frame1.allocated_size(kYPlane))); 1137 ASSERT_EQ(frame1.allocated_size(kUPlane), frame2.allocated_size(kUPlane)); 1138 EXPECT_EQ(0, 1139 memcmp(frame1.buffer(kUPlane), 1140 frame2.buffer(kUPlane), 1141 frame1.allocated_size(kUPlane))); 1142 ASSERT_EQ(frame1.allocated_size(kVPlane), frame2.allocated_size(kVPlane)); 1143 EXPECT_EQ(0, 1144 memcmp(frame1.buffer(kVPlane), 1145 frame2.buffer(kVPlane), 1146 frame1.allocated_size(kVPlane))); 1147 } 1148 1149 void ExpectEqualFramesVector(const std::vector<I420VideoFrame>& frames1, 1150 const std::vector<I420VideoFrame>& frames2) { 1151 EXPECT_EQ(frames1.size(), frames2.size()); 1152 for (size_t i = 0; i < std::min(frames1.size(), frames2.size()); ++i) 1153 ExpectEqualFrames(frames1[i], frames2[i]); 1154 } 1155 1156 I420VideoFrame CreateI420VideoFrame(int width, int height, uint8_t data) { 1157 const int kSizeY = width * height * 2; 1158 rtc::scoped_ptr<uint8_t[]> buffer(new uint8_t[kSizeY]); 1159 memset(buffer.get(), data, kSizeY); 1160 I420VideoFrame frame; 1161 frame.CreateFrame(buffer.get(), buffer.get(), buffer.get(), width, height, 1162 width, width / 2, width / 2); 1163 frame.set_timestamp(data); 1164 frame.set_render_time_ms(data); 1165 return frame; 1166 } 1167 1168 TEST_F(VideoSendStreamTest, EncoderIsProperlyInitializedAndDestroyed) { 1169 class EncoderStateObserver : public test::SendTest, public VideoEncoder { 1170 public: 1171 EncoderStateObserver() 1172 : SendTest(kDefaultTimeoutMs), 1173 crit_(CriticalSectionWrapper::CreateCriticalSection()), 1174 initialized_(false), 1175 callback_registered_(false), 1176 num_releases_(0), 1177 released_(false) {} 1178 1179 bool IsReleased() { 1180 CriticalSectionScoped lock(crit_.get()); 1181 return released_; 1182 } 1183 1184 bool IsReadyForEncode() { 1185 CriticalSectionScoped lock(crit_.get()); 1186 return initialized_ && callback_registered_; 1187 } 1188 1189 size_t num_releases() { 1190 CriticalSectionScoped lock(crit_.get()); 1191 return num_releases_; 1192 } 1193 1194 private: 1195 int32_t InitEncode(const VideoCodec* codecSettings, 1196 int32_t numberOfCores, 1197 size_t maxPayloadSize) override { 1198 CriticalSectionScoped lock(crit_.get()); 1199 EXPECT_FALSE(initialized_); 1200 initialized_ = true; 1201 released_ = false; 1202 return 0; 1203 } 1204 1205 int32_t Encode(const I420VideoFrame& inputImage, 1206 const CodecSpecificInfo* codecSpecificInfo, 1207 const std::vector<VideoFrameType>* frame_types) override { 1208 EXPECT_TRUE(IsReadyForEncode()); 1209 1210 observation_complete_->Set(); 1211 return 0; 1212 } 1213 1214 int32_t RegisterEncodeCompleteCallback( 1215 EncodedImageCallback* callback) override { 1216 CriticalSectionScoped lock(crit_.get()); 1217 EXPECT_TRUE(initialized_); 1218 callback_registered_ = true; 1219 return 0; 1220 } 1221 1222 int32_t Release() override { 1223 CriticalSectionScoped lock(crit_.get()); 1224 EXPECT_TRUE(IsReadyForEncode()); 1225 EXPECT_FALSE(released_); 1226 initialized_ = false; 1227 callback_registered_ = false; 1228 released_ = true; 1229 ++num_releases_; 1230 return 0; 1231 } 1232 1233 int32_t SetChannelParameters(uint32_t packetLoss, int64_t rtt) override { 1234 EXPECT_TRUE(IsReadyForEncode()); 1235 return 0; 1236 } 1237 1238 int32_t SetRates(uint32_t newBitRate, uint32_t frameRate) override { 1239 EXPECT_TRUE(IsReadyForEncode()); 1240 return 0; 1241 } 1242 1243 void OnStreamsCreated( 1244 VideoSendStream* send_stream, 1245 const std::vector<VideoReceiveStream*>& receive_streams) override { 1246 // Encoder initialization should be done in stream construction before 1247 // starting. 1248 EXPECT_TRUE(IsReadyForEncode()); 1249 stream_ = send_stream; 1250 } 1251 1252 void ModifyConfigs(VideoSendStream::Config* send_config, 1253 std::vector<VideoReceiveStream::Config>* receive_configs, 1254 VideoEncoderConfig* encoder_config) override { 1255 send_config->encoder_settings.encoder = this; 1256 encoder_config_ = *encoder_config; 1257 } 1258 1259 void PerformTest() override { 1260 EXPECT_EQ(kEventSignaled, Wait()) 1261 << "Timed out while waiting for Encode."; 1262 EXPECT_EQ(0u, num_releases()); 1263 stream_->ReconfigureVideoEncoder(encoder_config_); 1264 EXPECT_EQ(0u, num_releases()); 1265 stream_->Stop(); 1266 // Encoder should not be released before destroying the VideoSendStream. 1267 EXPECT_FALSE(IsReleased()); 1268 EXPECT_TRUE(IsReadyForEncode()); 1269 stream_->Start(); 1270 // Sanity check, make sure we still encode frames with this encoder. 1271 EXPECT_EQ(kEventSignaled, Wait()) 1272 << "Timed out while waiting for Encode."; 1273 } 1274 1275 rtc::scoped_ptr<CriticalSectionWrapper> crit_; 1276 VideoSendStream* stream_; 1277 bool initialized_ GUARDED_BY(crit_); 1278 bool callback_registered_ GUARDED_BY(crit_); 1279 size_t num_releases_ GUARDED_BY(crit_); 1280 bool released_ GUARDED_BY(crit_); 1281 VideoEncoderConfig encoder_config_; 1282 } test_encoder; 1283 1284 RunBaseTest(&test_encoder); 1285 1286 EXPECT_TRUE(test_encoder.IsReleased()); 1287 EXPECT_EQ(1u, test_encoder.num_releases()); 1288 } 1289 1290 TEST_F(VideoSendStreamTest, EncoderSetupPropagatesCommonEncoderConfigValues) { 1291 class VideoCodecConfigObserver : public test::SendTest, 1292 public test::FakeEncoder { 1293 public: 1294 VideoCodecConfigObserver() 1295 : SendTest(kDefaultTimeoutMs), 1296 FakeEncoder(Clock::GetRealTimeClock()), 1297 num_initializations_(0) {} 1298 1299 private: 1300 void ModifyConfigs(VideoSendStream::Config* send_config, 1301 std::vector<VideoReceiveStream::Config>* receive_configs, 1302 VideoEncoderConfig* encoder_config) override { 1303 send_config->encoder_settings.encoder = this; 1304 encoder_config_ = *encoder_config; 1305 } 1306 1307 void OnStreamsCreated( 1308 VideoSendStream* send_stream, 1309 const std::vector<VideoReceiveStream*>& receive_streams) override { 1310 stream_ = send_stream; 1311 } 1312 1313 int32_t InitEncode(const VideoCodec* config, 1314 int32_t number_of_cores, 1315 size_t max_payload_size) override { 1316 if (num_initializations_ == 0) { 1317 // Verify default values. 1318 EXPECT_EQ(kRealtimeVideo, config->mode); 1319 } else { 1320 // Verify that changed values are propagated. 1321 EXPECT_EQ(kScreensharing, config->mode); 1322 } 1323 ++num_initializations_; 1324 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size); 1325 } 1326 1327 void PerformTest() override { 1328 EXPECT_EQ(1u, num_initializations_) << "VideoEncoder not initialized."; 1329 1330 encoder_config_.content_type = VideoEncoderConfig::kScreenshare; 1331 stream_->ReconfigureVideoEncoder(encoder_config_); 1332 EXPECT_EQ(2u, num_initializations_) 1333 << "ReconfigureVideoEncoder did not reinitialize the encoder with " 1334 "new encoder settings."; 1335 } 1336 1337 size_t num_initializations_; 1338 VideoSendStream* stream_; 1339 VideoEncoderConfig encoder_config_; 1340 } test; 1341 1342 RunBaseTest(&test); 1343 } 1344 1345 static const size_t kVideoCodecConfigObserverNumberOfTemporalLayers = 4; 1346 template <typename T> 1347 class VideoCodecConfigObserver : public test::SendTest, 1348 public test::FakeEncoder { 1349 1350 public: 1351 VideoCodecConfigObserver(VideoCodecType video_codec_type, 1352 const char* codec_name) 1353 : SendTest(VideoSendStreamTest::kDefaultTimeoutMs), 1354 FakeEncoder(Clock::GetRealTimeClock()), 1355 video_codec_type_(video_codec_type), 1356 codec_name_(codec_name), 1357 num_initializations_(0) { 1358 memset(&encoder_settings_, 0, sizeof(encoder_settings_)); 1359 } 1360 1361 private: 1362 void ModifyConfigs(VideoSendStream::Config* send_config, 1363 std::vector<VideoReceiveStream::Config>* receive_configs, 1364 VideoEncoderConfig* encoder_config) override { 1365 send_config->encoder_settings.encoder = this; 1366 send_config->encoder_settings.payload_name = codec_name_; 1367 1368 for (size_t i = 0; i < encoder_config->streams.size(); ++i) { 1369 encoder_config->streams[i].temporal_layer_thresholds_bps.resize( 1370 kVideoCodecConfigObserverNumberOfTemporalLayers - 1); 1371 } 1372 1373 encoder_config->encoder_specific_settings = &encoder_settings_; 1374 encoder_config_ = *encoder_config; 1375 } 1376 1377 void OnStreamsCreated( 1378 VideoSendStream* send_stream, 1379 const std::vector<VideoReceiveStream*>& receive_streams) override { 1380 stream_ = send_stream; 1381 } 1382 1383 int32_t InitEncode(const VideoCodec* config, 1384 int32_t number_of_cores, 1385 size_t max_payload_size) override { 1386 EXPECT_EQ(video_codec_type_, config->codecType); 1387 VerifyCodecSpecifics(*config); 1388 ++num_initializations_; 1389 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size); 1390 } 1391 1392 void VerifyCodecSpecifics(const VideoCodec& config) const; 1393 1394 void PerformTest() override { 1395 EXPECT_EQ(1u, num_initializations_) << "VideoEncoder not initialized."; 1396 1397 encoder_settings_.frameDroppingOn = true; 1398 stream_->ReconfigureVideoEncoder(encoder_config_); 1399 EXPECT_EQ(2u, num_initializations_) 1400 << "ReconfigureVideoEncoder did not reinitialize the encoder with " 1401 "new encoder settings."; 1402 } 1403 1404 int32_t Encode(const I420VideoFrame& input_image, 1405 const CodecSpecificInfo* codec_specific_info, 1406 const std::vector<VideoFrameType>* frame_types) override { 1407 // Silently skip the encode, FakeEncoder::Encode doesn't produce VP8. 1408 return 0; 1409 } 1410 1411 T encoder_settings_; 1412 const VideoCodecType video_codec_type_; 1413 const char* const codec_name_; 1414 size_t num_initializations_; 1415 VideoSendStream* stream_; 1416 VideoEncoderConfig encoder_config_; 1417 }; 1418 1419 template <> 1420 void VideoCodecConfigObserver<VideoCodecH264>::VerifyCodecSpecifics( 1421 const VideoCodec& config) const { 1422 EXPECT_EQ(0, memcmp(&config.codecSpecific.H264, &encoder_settings_, 1423 sizeof(encoder_settings_))); 1424 } 1425 template <> 1426 void VideoCodecConfigObserver<VideoCodecVP8>::VerifyCodecSpecifics( 1427 const VideoCodec& config) const { 1428 // Check that the number of temporal layers has propagated properly to 1429 // VideoCodec. 1430 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers, 1431 config.codecSpecific.VP8.numberOfTemporalLayers); 1432 1433 for (unsigned char i = 0; i < config.numberOfSimulcastStreams; ++i) { 1434 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers, 1435 config.simulcastStream[i].numberOfTemporalLayers); 1436 } 1437 1438 // Set expected temporal layers as they should have been set when 1439 // reconfiguring the encoder and not match the set config. 1440 VideoCodecVP8 encoder_settings = encoder_settings_; 1441 encoder_settings.numberOfTemporalLayers = 1442 kVideoCodecConfigObserverNumberOfTemporalLayers; 1443 EXPECT_EQ(0, memcmp(&config.codecSpecific.VP8, &encoder_settings, 1444 sizeof(encoder_settings_))); 1445 } 1446 template <> 1447 void VideoCodecConfigObserver<VideoCodecVP9>::VerifyCodecSpecifics( 1448 const VideoCodec& config) const { 1449 // Check that the number of temporal layers has propagated properly to 1450 // VideoCodec. 1451 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers, 1452 config.codecSpecific.VP9.numberOfTemporalLayers); 1453 1454 for (unsigned char i = 0; i < config.numberOfSimulcastStreams; ++i) { 1455 EXPECT_EQ(kVideoCodecConfigObserverNumberOfTemporalLayers, 1456 config.simulcastStream[i].numberOfTemporalLayers); 1457 } 1458 1459 // Set expected temporal layers as they should have been set when 1460 // reconfiguring the encoder and not match the set config. 1461 VideoCodecVP9 encoder_settings = encoder_settings_; 1462 encoder_settings.numberOfTemporalLayers = 1463 kVideoCodecConfigObserverNumberOfTemporalLayers; 1464 EXPECT_EQ(0, memcmp(&config.codecSpecific.VP9, &encoder_settings, 1465 sizeof(encoder_settings_))); 1466 } 1467 1468 TEST_F(VideoSendStreamTest, EncoderSetupPropagatesVp8Config) { 1469 VideoCodecConfigObserver<VideoCodecVP8> test(kVideoCodecVP8, "VP8"); 1470 RunBaseTest(&test); 1471 } 1472 1473 TEST_F(VideoSendStreamTest, EncoderSetupPropagatesVp9Config) { 1474 VideoCodecConfigObserver<VideoCodecVP9> test(kVideoCodecVP9, "VP9"); 1475 RunBaseTest(&test); 1476 } 1477 1478 TEST_F(VideoSendStreamTest, EncoderSetupPropagatesH264Config) { 1479 VideoCodecConfigObserver<VideoCodecH264> test(kVideoCodecH264, "H264"); 1480 RunBaseTest(&test); 1481 } 1482 1483 TEST_F(VideoSendStreamTest, RtcpSenderReportContainsMediaBytesSent) { 1484 class RtcpSenderReportTest : public test::SendTest { 1485 public: 1486 RtcpSenderReportTest() : SendTest(kDefaultTimeoutMs), 1487 rtp_packets_sent_(0), 1488 media_bytes_sent_(0) {} 1489 1490 private: 1491 Action OnSendRtp(const uint8_t* packet, size_t length) override { 1492 RTPHeader header; 1493 EXPECT_TRUE(parser_->Parse(packet, length, &header)); 1494 ++rtp_packets_sent_; 1495 media_bytes_sent_ += length - header.headerLength - header.paddingLength; 1496 return SEND_PACKET; 1497 } 1498 1499 Action OnSendRtcp(const uint8_t* packet, size_t length) override { 1500 RTCPUtility::RTCPParserV2 parser(packet, length, true); 1501 EXPECT_TRUE(parser.IsValid()); 1502 1503 RTCPUtility::RTCPPacketTypes packet_type = parser.Begin(); 1504 while (packet_type != RTCPUtility::kRtcpNotValidCode) { 1505 if (packet_type == RTCPUtility::kRtcpSrCode) { 1506 // Only compare sent media bytes if SenderPacketCount matches the 1507 // number of sent rtp packets (a new rtp packet could be sent before 1508 // the rtcp packet). 1509 if (parser.Packet().SR.SenderOctetCount > 0 && 1510 parser.Packet().SR.SenderPacketCount == rtp_packets_sent_) { 1511 EXPECT_EQ(media_bytes_sent_, parser.Packet().SR.SenderOctetCount); 1512 observation_complete_->Set(); 1513 } 1514 } 1515 packet_type = parser.Iterate(); 1516 } 1517 1518 return SEND_PACKET; 1519 } 1520 1521 void PerformTest() override { 1522 EXPECT_EQ(kEventSignaled, Wait()) 1523 << "Timed out while waiting for RTCP sender report."; 1524 } 1525 1526 size_t rtp_packets_sent_; 1527 size_t media_bytes_sent_; 1528 } test; 1529 1530 RunBaseTest(&test); 1531 } 1532 1533 TEST_F(VideoSendStreamTest, TranslatesTwoLayerScreencastToTargetBitrate) { 1534 static const int kScreencastTargetBitrateKbps = 200; 1535 class ScreencastTargetBitrateTest : public test::SendTest, 1536 public test::FakeEncoder { 1537 public: 1538 ScreencastTargetBitrateTest() 1539 : SendTest(kDefaultTimeoutMs), 1540 test::FakeEncoder(Clock::GetRealTimeClock()) {} 1541 1542 private: 1543 int32_t InitEncode(const VideoCodec* config, 1544 int32_t number_of_cores, 1545 size_t max_payload_size) override { 1546 EXPECT_EQ(static_cast<unsigned int>(kScreencastTargetBitrateKbps), 1547 config->targetBitrate); 1548 observation_complete_->Set(); 1549 return test::FakeEncoder::InitEncode( 1550 config, number_of_cores, max_payload_size); 1551 } 1552 void ModifyConfigs(VideoSendStream::Config* send_config, 1553 std::vector<VideoReceiveStream::Config>* receive_configs, 1554 VideoEncoderConfig* encoder_config) override { 1555 send_config->encoder_settings.encoder = this; 1556 EXPECT_EQ(1u, encoder_config->streams.size()); 1557 EXPECT_TRUE( 1558 encoder_config->streams[0].temporal_layer_thresholds_bps.empty()); 1559 encoder_config->streams[0].temporal_layer_thresholds_bps.push_back( 1560 kScreencastTargetBitrateKbps * 1000); 1561 encoder_config->content_type = VideoEncoderConfig::kScreenshare; 1562 } 1563 1564 void PerformTest() override { 1565 EXPECT_EQ(kEventSignaled, Wait()) 1566 << "Timed out while waiting for the encoder to be initialized."; 1567 } 1568 } test; 1569 1570 RunBaseTest(&test); 1571 } 1572 1573 TEST_F(VideoSendStreamTest, ReconfigureBitratesSetsEncoderBitratesCorrectly) { 1574 // These are chosen to be "kind of odd" to not be accidentally checked against 1575 // default values. 1576 static const int kMinBitrateKbps = 137; 1577 static const int kStartBitrateKbps = 345; 1578 static const int kLowerMaxBitrateKbps = 312; 1579 static const int kMaxBitrateKbps = 413; 1580 static const int kIncreasedStartBitrateKbps = 451; 1581 static const int kIncreasedMaxBitrateKbps = 597; 1582 class EncoderBitrateThresholdObserver : public test::SendTest, 1583 public test::FakeEncoder { 1584 public: 1585 EncoderBitrateThresholdObserver() 1586 : SendTest(kDefaultTimeoutMs), 1587 FakeEncoder(Clock::GetRealTimeClock()), 1588 num_initializations_(0) {} 1589 1590 private: 1591 int32_t InitEncode(const VideoCodec* codecSettings, 1592 int32_t numberOfCores, 1593 size_t maxPayloadSize) override { 1594 if (num_initializations_ == 0) { 1595 EXPECT_EQ(static_cast<unsigned int>(kMinBitrateKbps), 1596 codecSettings->minBitrate); 1597 EXPECT_EQ(static_cast<unsigned int>(kStartBitrateKbps), 1598 codecSettings->startBitrate); 1599 EXPECT_EQ(static_cast<unsigned int>(kMaxBitrateKbps), 1600 codecSettings->maxBitrate); 1601 observation_complete_->Set(); 1602 } else if (num_initializations_ == 1) { 1603 EXPECT_EQ(static_cast<unsigned int>(kLowerMaxBitrateKbps), 1604 codecSettings->maxBitrate); 1605 // The start bitrate should be kept (-1) and capped to the max bitrate. 1606 // Since this is not an end-to-end call no receiver should have been 1607 // returning a REMB that could lower this estimate. 1608 EXPECT_EQ(codecSettings->startBitrate, codecSettings->maxBitrate); 1609 } else if (num_initializations_ == 2) { 1610 EXPECT_EQ(static_cast<unsigned int>(kIncreasedMaxBitrateKbps), 1611 codecSettings->maxBitrate); 1612 EXPECT_EQ(static_cast<unsigned int>(kIncreasedStartBitrateKbps), 1613 codecSettings->startBitrate); 1614 } 1615 ++num_initializations_; 1616 return FakeEncoder::InitEncode(codecSettings, numberOfCores, 1617 maxPayloadSize); 1618 } 1619 1620 Call::Config GetSenderCallConfig() override { 1621 Call::Config config(SendTransport()); 1622 config.bitrate_config.min_bitrate_bps = kMinBitrateKbps * 1000; 1623 config.bitrate_config.start_bitrate_bps = kStartBitrateKbps * 1000; 1624 config.bitrate_config.max_bitrate_bps = kMaxBitrateKbps * 1000; 1625 return config; 1626 } 1627 1628 void ModifyConfigs(VideoSendStream::Config* send_config, 1629 std::vector<VideoReceiveStream::Config>* receive_configs, 1630 VideoEncoderConfig* encoder_config) override { 1631 send_config->encoder_settings.encoder = this; 1632 // Set bitrates lower/higher than min/max to make sure they are properly 1633 // capped. 1634 encoder_config->streams.front().min_bitrate_bps = kMinBitrateKbps * 1000; 1635 encoder_config->streams.front().max_bitrate_bps = kMaxBitrateKbps * 1000; 1636 encoder_config_ = *encoder_config; 1637 } 1638 1639 void OnCallsCreated(Call* sender_call, Call* receiver_call) override { 1640 call_ = sender_call; 1641 } 1642 1643 void OnStreamsCreated( 1644 VideoSendStream* send_stream, 1645 const std::vector<VideoReceiveStream*>& receive_streams) override { 1646 send_stream_ = send_stream; 1647 } 1648 1649 void PerformTest() override { 1650 Call::Config::BitrateConfig bitrate_config; 1651 bitrate_config.start_bitrate_bps = kIncreasedStartBitrateKbps * 1000; 1652 bitrate_config.max_bitrate_bps = kIncreasedMaxBitrateKbps * 1000; 1653 call_->SetBitrateConfig(bitrate_config); 1654 EXPECT_EQ(kEventSignaled, Wait()) 1655 << "Timed out while waiting encoder to be configured."; 1656 encoder_config_.streams[0].min_bitrate_bps = 0; 1657 encoder_config_.streams[0].max_bitrate_bps = kLowerMaxBitrateKbps * 1000; 1658 send_stream_->ReconfigureVideoEncoder(encoder_config_); 1659 EXPECT_EQ(2, num_initializations_) 1660 << "Encoder should have been reconfigured with the new value."; 1661 encoder_config_.streams[0].target_bitrate_bps = 1662 encoder_config_.streams[0].min_bitrate_bps; 1663 encoder_config_.streams[0].max_bitrate_bps = 1664 kIncreasedMaxBitrateKbps * 1000; 1665 send_stream_->ReconfigureVideoEncoder(encoder_config_); 1666 EXPECT_EQ(3, num_initializations_) 1667 << "Encoder should have been reconfigured with the new value."; 1668 } 1669 1670 int num_initializations_; 1671 webrtc::Call* call_; 1672 webrtc::VideoSendStream* send_stream_; 1673 webrtc::VideoEncoderConfig encoder_config_; 1674 } test; 1675 1676 RunBaseTest(&test); 1677 } 1678 1679 TEST_F(VideoSendStreamTest, ReportsSentResolution) { 1680 static const size_t kNumStreams = 3; 1681 // Unusual resolutions to make sure that they are the ones being reported. 1682 static const struct { 1683 int width; 1684 int height; 1685 } kEncodedResolution[kNumStreams] = { 1686 {241, 181}, {300, 121}, {121, 221}}; 1687 class ScreencastTargetBitrateTest : public test::SendTest, 1688 public test::FakeEncoder { 1689 public: 1690 ScreencastTargetBitrateTest() 1691 : SendTest(kDefaultTimeoutMs), 1692 test::FakeEncoder(Clock::GetRealTimeClock()) {} 1693 1694 private: 1695 int32_t Encode(const I420VideoFrame& input_image, 1696 const CodecSpecificInfo* codecSpecificInfo, 1697 const std::vector<VideoFrameType>* frame_types) override { 1698 CodecSpecificInfo specifics; 1699 memset(&specifics, 0, sizeof(specifics)); 1700 specifics.codecType = kVideoCodecGeneric; 1701 1702 uint8_t buffer[16] = {0}; 1703 EncodedImage encoded(buffer, sizeof(buffer), sizeof(buffer)); 1704 encoded._timeStamp = input_image.timestamp(); 1705 encoded.capture_time_ms_ = input_image.render_time_ms(); 1706 1707 for (size_t i = 0; i < kNumStreams; ++i) { 1708 specifics.codecSpecific.generic.simulcast_idx = static_cast<uint8_t>(i); 1709 encoded._frameType = (*frame_types)[i]; 1710 encoded._encodedWidth = kEncodedResolution[i].width; 1711 encoded._encodedHeight = kEncodedResolution[i].height; 1712 DCHECK(callback_ != nullptr); 1713 if (callback_->Encoded(encoded, &specifics, nullptr) != 0) 1714 return -1; 1715 } 1716 1717 observation_complete_->Set(); 1718 return 0; 1719 } 1720 void ModifyConfigs(VideoSendStream::Config* send_config, 1721 std::vector<VideoReceiveStream::Config>* receive_configs, 1722 VideoEncoderConfig* encoder_config) override { 1723 send_config->encoder_settings.encoder = this; 1724 EXPECT_EQ(kNumStreams, encoder_config->streams.size()); 1725 } 1726 1727 size_t GetNumStreams() const override { return kNumStreams; } 1728 1729 void PerformTest() override { 1730 EXPECT_EQ(kEventSignaled, Wait()) 1731 << "Timed out while waiting for the encoder to send one frame."; 1732 VideoSendStream::Stats stats = send_stream_->GetStats(); 1733 1734 for (size_t i = 0; i < kNumStreams; ++i) { 1735 ASSERT_TRUE(stats.substreams.find(kSendSsrcs[i]) != 1736 stats.substreams.end()) 1737 << "No stats for SSRC: " << kSendSsrcs[i] 1738 << ", stats should exist as soon as frames have been encoded."; 1739 VideoSendStream::StreamStats ssrc_stats = 1740 stats.substreams[kSendSsrcs[i]]; 1741 EXPECT_EQ(kEncodedResolution[i].width, ssrc_stats.width); 1742 EXPECT_EQ(kEncodedResolution[i].height, ssrc_stats.height); 1743 } 1744 } 1745 1746 void OnStreamsCreated( 1747 VideoSendStream* send_stream, 1748 const std::vector<VideoReceiveStream*>& receive_streams) override { 1749 send_stream_ = send_stream; 1750 } 1751 1752 VideoSendStream* send_stream_; 1753 } test; 1754 1755 RunBaseTest(&test); 1756 } 1757 } // namespace webrtc 1758