2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
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.
10 #include <algorithm> // max
12 #include "testing/gtest/include/gtest/gtest.h"
14 #include "webrtc/call.h"
15 #include "webrtc/common_video/interface/i420_video_frame.h"
16 #include "webrtc/common_video/interface/native_handle.h"
17 #include "webrtc/common_video/interface/texture_video_frame.h"
18 #include "webrtc/frame_callback.h"
19 #include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
20 #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
21 #include "webrtc/modules/rtp_rtcp/source/rtcp_sender.h"
22 #include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
23 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
24 #include "webrtc/system_wrappers/interface/event_wrapper.h"
25 #include "webrtc/system_wrappers/interface/ref_count.h"
26 #include "webrtc/system_wrappers/interface/scoped_ptr.h"
27 #include "webrtc/system_wrappers/interface/scoped_vector.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/transport_adapter.h"
36 #include "webrtc/video_send_stream.h"
40 enum VideoFormat { kGeneric, kVP8, };
42 void ExpectEqualFrames(const I420VideoFrame& frame1,
43 const I420VideoFrame& frame2);
44 void ExpectEqualTextureFrames(const I420VideoFrame& frame1,
45 const I420VideoFrame& frame2);
46 void ExpectEqualBufferFrames(const I420VideoFrame& frame1,
47 const I420VideoFrame& frame2);
48 void ExpectEqualFramesVector(const std::vector<I420VideoFrame*>& frames1,
49 const std::vector<I420VideoFrame*>& frames2);
50 I420VideoFrame* CreateI420VideoFrame(int width, int height, uint8_t data);
52 class FakeNativeHandle : public NativeHandle {
55 virtual ~FakeNativeHandle() {}
56 virtual void* GetHandle() { return NULL; }
59 class VideoSendStreamTest : public test::CallTest {
61 void TestNackRetransmission(uint32_t retransmit_ssrc,
62 uint8_t retransmit_payload_type);
63 void TestPacketFragmentationSize(VideoFormat format, bool with_fec);
66 TEST_F(VideoSendStreamTest, CanStartStartedStream) {
67 test::NullTransport transport;
68 Call::Config call_config(&transport);
69 CreateSenderCall(call_config);
73 send_stream_->Start();
74 send_stream_->Start();
78 TEST_F(VideoSendStreamTest, CanStopStoppedStream) {
79 test::NullTransport transport;
80 Call::Config call_config(&transport);
81 CreateSenderCall(call_config);
90 TEST_F(VideoSendStreamTest, SupportsCName) {
91 static std::string kCName = "PjQatC14dGfbVwGPUOA9IH7RlsFDbWl4AhXEiDsBizo=";
92 class CNameObserver : public test::SendTest {
94 CNameObserver() : SendTest(kDefaultTimeoutMs) {}
97 virtual Action OnSendRtcp(const uint8_t* packet, size_t length) OVERRIDE {
98 RTCPUtility::RTCPParserV2 parser(packet, length, true);
99 EXPECT_TRUE(parser.IsValid());
101 RTCPUtility::RTCPPacketTypes packet_type = parser.Begin();
102 while (packet_type != RTCPUtility::kRtcpNotValidCode) {
103 if (packet_type == RTCPUtility::kRtcpSdesChunkCode) {
104 EXPECT_EQ(parser.Packet().CName.CName, kCName);
105 observation_complete_->Set();
108 packet_type = parser.Iterate();
114 virtual void ModifyConfigs(
115 VideoSendStream::Config* send_config,
116 std::vector<VideoReceiveStream::Config>* receive_configs,
117 std::vector<VideoStream>* video_streams) OVERRIDE {
118 send_config->rtp.c_name = kCName;
121 virtual void PerformTest() OVERRIDE {
122 EXPECT_EQ(kEventSignaled, Wait())
123 << "Timed out while waiting for RTCP with CNAME.";
130 TEST_F(VideoSendStreamTest, SupportsAbsoluteSendTime) {
131 static const uint8_t kAbsSendTimeExtensionId = 13;
132 class AbsoluteSendTimeObserver : public test::SendTest {
134 AbsoluteSendTimeObserver() : SendTest(kDefaultTimeoutMs) {
135 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
136 kRtpExtensionAbsoluteSendTime, kAbsSendTimeExtensionId));
139 virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE {
141 EXPECT_TRUE(parser_->Parse(packet, length, &header));
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();
152 virtual void ModifyConfigs(
153 VideoSendStream::Config* send_config,
154 std::vector<VideoReceiveStream::Config>* receive_configs,
155 std::vector<VideoStream>* video_streams) OVERRIDE {
156 send_config->rtp.extensions.push_back(
157 RtpExtension(RtpExtension::kAbsSendTime, kAbsSendTimeExtensionId));
160 virtual void PerformTest() OVERRIDE {
161 EXPECT_EQ(kEventSignaled, Wait())
162 << "Timed out while waiting for single RTP packet.";
169 TEST_F(VideoSendStreamTest, SupportsTransmissionTimeOffset) {
170 static const uint8_t kTOffsetExtensionId = 13;
171 class TransmissionTimeOffsetObserver : public test::SendTest {
173 TransmissionTimeOffsetObserver()
174 : SendTest(kDefaultTimeoutMs), encoder_(Clock::GetRealTimeClock()) {
175 EXPECT_TRUE(parser_->RegisterRtpHeaderExtension(
176 kRtpExtensionTransmissionTimeOffset, kTOffsetExtensionId));
180 virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE {
182 EXPECT_TRUE(parser_->Parse(packet, length, &header));
184 EXPECT_TRUE(header.extension.hasTransmissionTimeOffset);
185 EXPECT_FALSE(header.extension.hasAbsoluteSendTime);
186 EXPECT_GT(header.extension.transmissionTimeOffset, 0);
187 EXPECT_EQ(header.extension.absoluteSendTime, 0u);
188 observation_complete_->Set();
193 virtual void ModifyConfigs(
194 VideoSendStream::Config* send_config,
195 std::vector<VideoReceiveStream::Config>* receive_configs,
196 std::vector<VideoStream>* video_streams) OVERRIDE {
197 send_config->encoder_settings.encoder = &encoder_;
198 send_config->rtp.extensions.push_back(
199 RtpExtension(RtpExtension::kTOffset, kTOffsetExtensionId));
202 virtual void PerformTest() OVERRIDE {
203 EXPECT_EQ(kEventSignaled, Wait())
204 << "Timed out while waiting single RTP packet.";
207 class DelayedEncoder : public test::FakeEncoder {
209 explicit DelayedEncoder(Clock* clock) : test::FakeEncoder(clock) {}
210 virtual int32_t Encode(
211 const I420VideoFrame& input_image,
212 const CodecSpecificInfo* codec_specific_info,
213 const std::vector<VideoFrameType>* frame_types) OVERRIDE {
214 // A delay needs to be introduced to assure that we get a timestamp
217 return FakeEncoder::Encode(
218 input_image, codec_specific_info, frame_types);
222 DelayedEncoder encoder_;
228 class FakeReceiveStatistics : public NullReceiveStatistics {
230 FakeReceiveStatistics(uint32_t send_ssrc,
231 uint32_t last_sequence_number,
232 uint32_t cumulative_lost,
233 uint8_t fraction_lost)
234 : lossy_stats_(new LossyStatistician(last_sequence_number,
237 stats_map_[send_ssrc] = lossy_stats_.get();
240 virtual StatisticianMap GetActiveStatisticians() const OVERRIDE {
244 virtual StreamStatistician* GetStatistician(uint32_t ssrc) const OVERRIDE {
245 return lossy_stats_.get();
249 class LossyStatistician : public StreamStatistician {
251 LossyStatistician(uint32_t extended_max_sequence_number,
252 uint32_t cumulative_lost,
253 uint8_t fraction_lost) {
254 stats_.fraction_lost = fraction_lost;
255 stats_.cumulative_lost = cumulative_lost;
256 stats_.extended_max_sequence_number = extended_max_sequence_number;
258 virtual bool GetStatistics(RtcpStatistics* statistics,
259 bool reset) OVERRIDE {
260 *statistics = stats_;
263 virtual void GetDataCounters(uint32_t* bytes_received,
264 uint32_t* packets_received) const OVERRIDE {
266 *packets_received = 0;
268 virtual uint32_t BitrateReceived() const OVERRIDE { return 0; }
269 virtual void ResetStatistics() OVERRIDE {}
270 virtual bool IsRetransmitOfOldPacket(const RTPHeader& header,
271 int min_rtt) const OVERRIDE {
275 virtual bool IsPacketInOrder(uint16_t sequence_number) const OVERRIDE {
279 RtcpStatistics stats_;
282 scoped_ptr<LossyStatistician> lossy_stats_;
283 StatisticianMap stats_map_;
286 TEST_F(VideoSendStreamTest, SwapsI420VideoFrames) {
287 static const size_t kWidth = 320;
288 static const size_t kHeight = 240;
290 test::NullTransport transport;
291 Call::Config call_config(&transport);
292 CreateSenderCall(call_config);
296 send_stream_->Start();
298 I420VideoFrame frame;
299 frame.CreateEmptyFrame(
300 kWidth, kHeight, kWidth, (kWidth + 1) / 2, (kWidth + 1) / 2);
301 uint8_t* old_y_buffer = frame.buffer(kYPlane);
303 send_stream_->Input()->SwapFrame(&frame);
305 EXPECT_NE(frame.buffer(kYPlane), old_y_buffer);
310 TEST_F(VideoSendStreamTest, SupportsFec) {
311 static const int kRedPayloadType = 118;
312 static const int kUlpfecPayloadType = 119;
313 class FecObserver : public test::SendTest {
316 : SendTest(kDefaultTimeoutMs),
317 transport_adapter_(SendTransport()),
319 received_media_(false),
320 received_fec_(false) {
321 transport_adapter_.Enable();
325 virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE {
327 EXPECT_TRUE(parser_->Parse(packet, length, &header));
329 // Send lossy receive reports to trigger FEC enabling.
330 if (send_count_++ % 2 != 0) {
331 // Receive statistics reporting having lost 50% of the packets.
332 FakeReceiveStatistics lossy_receive_stats(
333 kSendSsrcs[0], header.sequenceNumber, send_count_ / 2, 127);
334 RTCPSender rtcp_sender(
335 0, false, Clock::GetRealTimeClock(), &lossy_receive_stats);
336 EXPECT_EQ(0, rtcp_sender.RegisterSendTransport(&transport_adapter_));
338 rtcp_sender.SetRTCPStatus(kRtcpNonCompound);
339 rtcp_sender.SetRemoteSSRC(kSendSsrcs[0]);
341 RTCPSender::FeedbackState feedback_state;
343 EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr));
346 EXPECT_EQ(kRedPayloadType, header.payloadType);
348 uint8_t encapsulated_payload_type = packet[header.headerLength];
350 if (encapsulated_payload_type == kUlpfecPayloadType) {
351 received_fec_ = true;
353 received_media_ = true;
356 if (received_media_ && received_fec_)
357 observation_complete_->Set();
362 virtual void ModifyConfigs(
363 VideoSendStream::Config* send_config,
364 std::vector<VideoReceiveStream::Config>* receive_configs,
365 std::vector<VideoStream>* video_streams) OVERRIDE {
366 send_config->rtp.fec.red_payload_type = kRedPayloadType;
367 send_config->rtp.fec.ulpfec_payload_type = kUlpfecPayloadType;
370 virtual void PerformTest() OVERRIDE {
371 EXPECT_TRUE(Wait()) << "Timed out waiting for FEC and media packets.";
374 internal::TransportAdapter transport_adapter_;
376 bool received_media_;
383 void VideoSendStreamTest::TestNackRetransmission(
384 uint32_t retransmit_ssrc,
385 uint8_t retransmit_payload_type) {
386 class NackObserver : public test::SendTest {
388 explicit NackObserver(uint32_t retransmit_ssrc,
389 uint8_t retransmit_payload_type)
390 : SendTest(kDefaultTimeoutMs),
391 transport_adapter_(SendTransport()),
393 retransmit_ssrc_(retransmit_ssrc),
394 retransmit_payload_type_(retransmit_payload_type),
395 nacked_sequence_number_(-1) {
396 transport_adapter_.Enable();
400 virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE {
402 EXPECT_TRUE(parser_->Parse(packet, length, &header));
404 // Nack second packet after receiving the third one.
405 if (++send_count_ == 3) {
406 uint16_t nack_sequence_number = header.sequenceNumber - 1;
407 nacked_sequence_number_ = nack_sequence_number;
408 NullReceiveStatistics null_stats;
409 RTCPSender rtcp_sender(
410 0, false, Clock::GetRealTimeClock(), &null_stats);
411 EXPECT_EQ(0, rtcp_sender.RegisterSendTransport(&transport_adapter_));
413 rtcp_sender.SetRTCPStatus(kRtcpNonCompound);
414 rtcp_sender.SetRemoteSSRC(kSendSsrcs[0]);
416 RTCPSender::FeedbackState feedback_state;
419 rtcp_sender.SendRTCP(
420 feedback_state, kRtcpNack, 1, &nack_sequence_number));
423 uint16_t sequence_number = header.sequenceNumber;
425 if (header.ssrc == retransmit_ssrc_ &&
426 retransmit_ssrc_ != kSendSsrcs[0]) {
427 // Not kSendSsrcs[0], assume correct RTX packet. Extract sequence
429 const uint8_t* rtx_header = packet + header.headerLength;
430 sequence_number = (rtx_header[0] << 8) + rtx_header[1];
433 if (sequence_number == nacked_sequence_number_) {
434 EXPECT_EQ(retransmit_ssrc_, header.ssrc);
435 EXPECT_EQ(retransmit_payload_type_, header.payloadType);
436 observation_complete_->Set();
442 virtual void ModifyConfigs(
443 VideoSendStream::Config* send_config,
444 std::vector<VideoReceiveStream::Config>* receive_configs,
445 std::vector<VideoStream>* video_streams) OVERRIDE {
446 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
447 send_config->rtp.rtx.payload_type = retransmit_payload_type_;
448 if (retransmit_ssrc_ != kSendSsrcs[0])
449 send_config->rtp.rtx.ssrcs.push_back(retransmit_ssrc_);
452 virtual void PerformTest() OVERRIDE {
453 EXPECT_EQ(kEventSignaled, Wait())
454 << "Timed out while waiting for NACK retransmission.";
457 internal::TransportAdapter transport_adapter_;
459 uint32_t retransmit_ssrc_;
460 uint8_t retransmit_payload_type_;
461 int nacked_sequence_number_;
462 } test(retransmit_ssrc, retransmit_payload_type);
467 TEST_F(VideoSendStreamTest, RetransmitsNack) {
468 // Normal NACKs should use the send SSRC.
469 TestNackRetransmission(kSendSsrcs[0], kFakeSendPayloadType);
472 TEST_F(VideoSendStreamTest, RetransmitsNackOverRtx) {
473 // NACKs over RTX should use a separate SSRC.
474 TestNackRetransmission(kSendRtxSsrcs[0], kSendRtxPayloadType);
477 void VideoSendStreamTest::TestPacketFragmentationSize(VideoFormat format,
479 // Use a fake encoder to output a frame of every size in the range [90, 290],
480 // for each size making sure that the exact number of payload bytes received
481 // is correct and that packets are fragmented to respect max packet size.
482 static const uint32_t kMaxPacketSize = 128;
483 static const uint32_t start = 90;
484 static const uint32_t stop = 290;
486 static const int kRedPayloadType = 118;
487 static const int kUlpfecPayloadType = 119;
488 // Observer that verifies that the expected number of packets and bytes
489 // arrive for each frame size, from start_size to stop_size.
490 class FrameFragmentationTest : public test::SendTest,
491 public EncodedFrameObserver {
493 FrameFragmentationTest(uint32_t max_packet_size,
496 bool test_generic_packetization,
498 : SendTest(kLongTimeoutMs),
499 transport_adapter_(SendTransport()),
501 max_packet_size_(max_packet_size),
502 stop_size_(stop_size),
503 test_generic_packetization_(test_generic_packetization),
506 accumulated_size_(0),
507 accumulated_payload_(0),
508 fec_packet_received_(false),
509 current_size_rtp_(start_size),
510 current_size_frame_(start_size) {
511 // Fragmentation required, this test doesn't make sense without it.
512 encoder_.SetFrameSize(start);
513 assert(stop_size > max_packet_size);
514 transport_adapter_.Enable();
518 virtual Action OnSendRtp(const uint8_t* packet, size_t size) OVERRIDE {
519 uint32_t length = static_cast<int>(size);
521 EXPECT_TRUE(parser_->Parse(packet, length, &header));
523 EXPECT_LE(length, max_packet_size_);
526 uint8_t payload_type = packet[header.headerLength];
527 bool is_fec = header.payloadType == kRedPayloadType &&
528 payload_type == kUlpfecPayloadType;
530 fec_packet_received_ = true;
535 accumulated_size_ += length;
538 TriggerLossReport(header);
540 if (test_generic_packetization_) {
541 uint32_t overhead = header.headerLength + header.paddingLength +
542 (1 /* Generic header */);
544 overhead += 1; // RED for FEC header.
545 accumulated_payload_ += length - overhead;
548 // Marker bit set indicates last packet of a frame.
549 if (header.markerBit) {
550 if (use_fec_ && accumulated_payload_ == current_size_rtp_ - 1) {
551 // With FEC enabled, frame size is incremented asynchronously, so
552 // "old" frames one byte too small may arrive. Accept, but don't
553 // increase expected frame size.
554 accumulated_size_ = 0;
555 accumulated_payload_ = 0;
559 EXPECT_GE(accumulated_size_, current_size_rtp_);
560 if (test_generic_packetization_) {
561 EXPECT_EQ(current_size_rtp_, accumulated_payload_);
564 // Last packet of frame; reset counters.
565 accumulated_size_ = 0;
566 accumulated_payload_ = 0;
567 if (current_size_rtp_ == stop_size_) {
568 // Done! (Don't increase size again, might arrive more @ stop_size).
569 observation_complete_->Set();
571 // Increase next expected frame size. If testing with FEC, make sure
572 // a FEC packet has been received for this frame size before
573 // proceeding, to make sure that redundancy packets don't exceed
577 } else if (fec_packet_received_) {
578 fec_packet_received_ = false;
580 ++current_size_frame_;
588 void TriggerLossReport(const RTPHeader& header) {
589 // Send lossy receive reports to trigger FEC enabling.
590 if (packet_count_++ % 2 != 0) {
591 // Receive statistics reporting having lost 50% of the packets.
592 FakeReceiveStatistics lossy_receive_stats(
593 kSendSsrcs[0], header.sequenceNumber, packet_count_ / 2, 127);
594 RTCPSender rtcp_sender(
595 0, false, Clock::GetRealTimeClock(), &lossy_receive_stats);
596 EXPECT_EQ(0, rtcp_sender.RegisterSendTransport(&transport_adapter_));
598 rtcp_sender.SetRTCPStatus(kRtcpNonCompound);
599 rtcp_sender.SetRemoteSSRC(kSendSsrcs[0]);
601 RTCPSender::FeedbackState feedback_state;
603 EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr));
607 virtual void EncodedFrameCallback(const EncodedFrame& encoded_frame) {
608 // Increase frame size for next encoded frame, in the context of the
611 current_size_frame_.Value() < static_cast<int32_t>(stop_size_)) {
612 ++current_size_frame_;
614 encoder_.SetFrameSize(current_size_frame_.Value());
617 virtual void ModifyConfigs(
618 VideoSendStream::Config* send_config,
619 std::vector<VideoReceiveStream::Config>* receive_configs,
620 std::vector<VideoStream>* video_streams) OVERRIDE {
622 send_config->rtp.fec.red_payload_type = kRedPayloadType;
623 send_config->rtp.fec.ulpfec_payload_type = kUlpfecPayloadType;
626 if (!test_generic_packetization_)
627 send_config->encoder_settings.payload_name = "VP8";
629 send_config->encoder_settings.encoder = &encoder_;
630 send_config->rtp.max_packet_size = kMaxPacketSize;
631 send_config->post_encode_callback = this;
633 // Add an extension header, to make the RTP header larger than the base
634 // length of 12 bytes.
635 static const uint8_t kAbsSendTimeExtensionId = 13;
636 send_config->rtp.extensions.push_back(
637 RtpExtension(RtpExtension::kAbsSendTime, kAbsSendTimeExtensionId));
640 virtual void PerformTest() OVERRIDE {
641 EXPECT_EQ(kEventSignaled, Wait())
642 << "Timed out while observing incoming RTP packets.";
645 internal::TransportAdapter transport_adapter_;
646 test::ConfigurableFrameSizeEncoder encoder_;
648 const uint32_t max_packet_size_;
649 const uint32_t stop_size_;
650 const bool test_generic_packetization_;
653 uint32_t packet_count_;
654 uint32_t accumulated_size_;
655 uint32_t accumulated_payload_;
656 bool fec_packet_received_;
658 uint32_t current_size_rtp_;
659 Atomic32 current_size_frame_;
662 // Don't auto increment if FEC is used; continue sending frame size until
663 // a FEC packet has been received.
664 FrameFragmentationTest test(
665 kMaxPacketSize, start, stop, format == kGeneric, with_fec);
670 // TODO(sprang): Is there any way of speeding up these tests?
671 TEST_F(VideoSendStreamTest, FragmentsGenericAccordingToMaxPacketSize) {
672 TestPacketFragmentationSize(kGeneric, false);
675 TEST_F(VideoSendStreamTest, FragmentsGenericAccordingToMaxPacketSizeWithFec) {
676 TestPacketFragmentationSize(kGeneric, true);
679 TEST_F(VideoSendStreamTest, FragmentsVp8AccordingToMaxPacketSize) {
680 TestPacketFragmentationSize(kVP8, false);
683 TEST_F(VideoSendStreamTest, FragmentsVp8AccordingToMaxPacketSizeWithFec) {
684 TestPacketFragmentationSize(kVP8, true);
687 // The test will go through a number of phases.
688 // 1. Start sending packets.
689 // 2. As soon as the RTP stream has been detected, signal a low REMB value to
690 // suspend the stream.
691 // 3. Wait until |kSuspendTimeFrames| have been captured without seeing any RTP
693 // 4. Signal a high REMB and then wait for the RTP stream to start again.
694 // When the stream is detected again, and the stats show that the stream
695 // is no longer suspended, the test ends.
696 TEST_F(VideoSendStreamTest, SuspendBelowMinBitrate) {
697 static const int kSuspendTimeFrames = 60; // Suspend for 2 seconds @ 30 fps.
699 class RembObserver : public test::SendTest, public I420FrameCallback {
702 : SendTest(kDefaultTimeoutMs),
703 transport_adapter_(&transport_),
704 clock_(Clock::GetRealTimeClock()),
705 crit_(CriticalSectionWrapper::CreateCriticalSection()),
706 test_state_(kBeforeSuspend),
708 last_sequence_number_(0),
709 suspended_frame_count_(0),
712 transport_adapter_.Enable();
716 virtual Action OnSendRtcp(const uint8_t* packet, size_t length) OVERRIDE {
717 // Receive statistics reporting having lost 0% of the packets.
718 // This is needed for the send-side bitrate controller to work properly.
719 CriticalSectionScoped lock(crit_.get());
720 SendRtcpFeedback(0); // REMB is only sent if value is > 0.
724 virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE {
725 CriticalSectionScoped lock(crit_.get());
728 EXPECT_TRUE(parser_->Parse(packet, length, &header));
729 last_sequence_number_ = header.sequenceNumber;
731 if (test_state_ == kBeforeSuspend) {
732 // The stream has started. Try to suspend it.
733 SendRtcpFeedback(low_remb_bps_);
734 test_state_ = kDuringSuspend;
735 } else if (test_state_ == kDuringSuspend) {
736 if (header.paddingLength == 0) {
737 // Received non-padding packet during suspension period. Reset the
739 suspended_frame_count_ = 0;
741 } else if (test_state_ == kWaitingForPacket) {
742 if (header.paddingLength == 0) {
743 // Non-padding packet observed. Test is almost complete. Will just
744 // have to wait for the stats to change.
745 test_state_ = kWaitingForStats;
747 } else if (test_state_ == kWaitingForStats) {
748 VideoSendStream::Stats stats = stream_->GetStats();
749 if (stats.suspended == false) {
750 // Stats flipped to false. Test is complete.
751 observation_complete_->Set();
758 // This method implements the I420FrameCallback.
759 void FrameCallback(I420VideoFrame* video_frame) OVERRIDE {
760 CriticalSectionScoped lock(crit_.get());
761 if (test_state_ == kDuringSuspend &&
762 ++suspended_frame_count_ > kSuspendTimeFrames) {
763 VideoSendStream::Stats stats = stream_->GetStats();
764 EXPECT_TRUE(stats.suspended);
765 SendRtcpFeedback(high_remb_bps_);
766 test_state_ = kWaitingForPacket;
770 void set_low_remb_bps(int value) {
771 CriticalSectionScoped lock(crit_.get());
772 low_remb_bps_ = value;
775 void set_high_remb_bps(int value) {
776 CriticalSectionScoped lock(crit_.get());
777 high_remb_bps_ = value;
780 virtual void SetReceivers(
781 PacketReceiver* send_transport_receiver,
782 PacketReceiver* receive_transport_receiver) OVERRIDE {
783 transport_.SetReceiver(send_transport_receiver);
786 virtual void OnStreamsCreated(
787 VideoSendStream* send_stream,
788 const std::vector<VideoReceiveStream*>& receive_streams) OVERRIDE {
789 stream_ = send_stream;
792 virtual void ModifyConfigs(
793 VideoSendStream::Config* send_config,
794 std::vector<VideoReceiveStream::Config>* receive_configs,
795 std::vector<VideoStream>* video_streams) OVERRIDE {
796 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
797 send_config->pre_encode_callback = this;
798 send_config->suspend_below_min_bitrate = true;
799 int min_bitrate_bps = (*video_streams)[0].min_bitrate_bps;
800 set_low_remb_bps(min_bitrate_bps - 10000);
801 int threshold_window = std::max(min_bitrate_bps / 10, 10000);
802 ASSERT_GT((*video_streams)[0].max_bitrate_bps,
803 min_bitrate_bps + threshold_window + 5000);
804 set_high_remb_bps(min_bitrate_bps + threshold_window + 5000);
807 virtual void PerformTest() OVERRIDE {
808 EXPECT_EQ(kEventSignaled, Wait())
809 << "Timed out during suspend-below-min-bitrate test.";
810 transport_.StopSending();
820 virtual void SendRtcpFeedback(int remb_value)
821 EXCLUSIVE_LOCKS_REQUIRED(crit_) {
822 FakeReceiveStatistics receive_stats(
823 kSendSsrcs[0], last_sequence_number_, rtp_count_, 0);
824 RTCPSender rtcp_sender(0, false, clock_, &receive_stats);
825 EXPECT_EQ(0, rtcp_sender.RegisterSendTransport(&transport_adapter_));
827 rtcp_sender.SetRTCPStatus(kRtcpNonCompound);
828 rtcp_sender.SetRemoteSSRC(kSendSsrcs[0]);
829 if (remb_value > 0) {
830 rtcp_sender.SetREMBStatus(true);
831 rtcp_sender.SetREMBData(remb_value, 0, NULL);
833 RTCPSender::FeedbackState feedback_state;
834 EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr));
837 internal::TransportAdapter transport_adapter_;
838 test::DirectTransport transport_;
840 VideoSendStream* stream_;
842 const scoped_ptr<CriticalSectionWrapper> crit_;
843 TestState test_state_ GUARDED_BY(crit_);
844 int rtp_count_ GUARDED_BY(crit_);
845 int last_sequence_number_ GUARDED_BY(crit_);
846 int suspended_frame_count_ GUARDED_BY(crit_);
847 int low_remb_bps_ GUARDED_BY(crit_);
848 int high_remb_bps_ GUARDED_BY(crit_);
854 TEST_F(VideoSendStreamTest, NoPaddingWhenVideoIsMuted) {
855 class NoPaddingWhenVideoIsMuted : public test::SendTest {
857 NoPaddingWhenVideoIsMuted()
858 : SendTest(kDefaultTimeoutMs),
859 clock_(Clock::GetRealTimeClock()),
860 transport_adapter_(ReceiveTransport()),
861 crit_(CriticalSectionWrapper::CreateCriticalSection()),
862 last_packet_time_ms_(-1),
864 transport_adapter_.Enable();
868 virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE {
869 CriticalSectionScoped lock(crit_.get());
870 last_packet_time_ms_ = clock_->TimeInMilliseconds();
875 virtual Action OnSendRtcp(const uint8_t* packet, size_t length) OVERRIDE {
876 CriticalSectionScoped lock(crit_.get());
877 const int kVideoMutedThresholdMs = 10000;
878 if (last_packet_time_ms_ > 0 &&
879 clock_->TimeInMilliseconds() - last_packet_time_ms_ >
880 kVideoMutedThresholdMs)
881 observation_complete_->Set();
882 // Receive statistics reporting having lost 50% of the packets.
883 FakeReceiveStatistics receive_stats(kSendSsrcs[0], 1, 1, 0);
884 RTCPSender rtcp_sender(
885 0, false, Clock::GetRealTimeClock(), &receive_stats);
886 EXPECT_EQ(0, rtcp_sender.RegisterSendTransport(&transport_adapter_));
888 rtcp_sender.SetRTCPStatus(kRtcpNonCompound);
889 rtcp_sender.SetRemoteSSRC(kSendSsrcs[0]);
891 RTCPSender::FeedbackState feedback_state;
893 EXPECT_EQ(0, rtcp_sender.SendRTCP(feedback_state, kRtcpRr));
897 virtual void SetReceivers(
898 PacketReceiver* send_transport_receiver,
899 PacketReceiver* receive_transport_receiver) OVERRIDE {
900 RtpRtcpObserver::SetReceivers(send_transport_receiver,
901 send_transport_receiver);
904 virtual size_t GetNumStreams() const OVERRIDE { return 3; }
906 virtual void OnFrameGeneratorCapturerCreated(
907 test::FrameGeneratorCapturer* frame_generator_capturer) {
908 CriticalSectionScoped lock(crit_.get());
909 capturer_ = frame_generator_capturer;
912 virtual void PerformTest() OVERRIDE {
913 EXPECT_EQ(kEventSignaled, Wait())
914 << "Timed out while waiting for RTP packets to stop being sent.";
918 internal::TransportAdapter transport_adapter_;
919 const scoped_ptr<CriticalSectionWrapper> crit_;
920 int64_t last_packet_time_ms_ GUARDED_BY(crit_);
921 test::FrameGeneratorCapturer* capturer_ GUARDED_BY(crit_);
927 TEST_F(VideoSendStreamTest, ProducesStats) {
928 class ProducesStats : public test::SendTest {
931 : SendTest(kDefaultTimeoutMs),
933 event_(EventWrapper::Create()) {}
935 virtual Action OnSendRtcp(const uint8_t* packet, size_t length) OVERRIDE {
942 bool WaitForFilledStats() {
943 Clock* clock = Clock::GetRealTimeClock();
944 int64_t now = clock->TimeInMilliseconds();
945 int64_t stop_time = now + kDefaultTimeoutMs;
946 while (now < stop_time) {
947 int64_t time_left = stop_time - now;
948 if (time_left > 0 && event_->Wait(time_left) == kEventSignaled &&
952 now = clock->TimeInMilliseconds();
958 VideoSendStream::Stats stats = stream_->GetStats();
959 // Check that all applicable data sources have been used.
960 if (stats.input_frame_rate > 0 && stats.encode_frame_rate > 0
961 && !stats.substreams.empty()) {
962 uint32_t ssrc = stats.substreams.begin()->first;
964 config_.rtp.ssrcs.end(),
966 config_.rtp.ssrcs.begin(), config_.rtp.ssrcs.end(), ssrc));
967 // Check for data populated by various sources. RTCP excluded as this
968 // data is received from remote side. Tested in call tests instead.
969 const StreamStats& entry = stats.substreams[ssrc];
970 if (entry.key_frames > 0u && entry.bitrate_bps > 0 &&
971 entry.rtp_stats.packets > 0u && entry.avg_delay_ms > 0 &&
972 entry.max_delay_ms > 0) {
979 void SetConfig(const VideoSendStream::Config& config) { config_ = config; }
981 virtual void ModifyConfigs(
982 VideoSendStream::Config* send_config,
983 std::vector<VideoReceiveStream::Config>* receive_configs,
984 std::vector<VideoStream>* video_streams) OVERRIDE {
985 SetConfig(*send_config);
988 virtual void OnStreamsCreated(
989 VideoSendStream* send_stream,
990 const std::vector<VideoReceiveStream*>& receive_streams) OVERRIDE {
991 stream_ = send_stream;
994 virtual void PerformTest() OVERRIDE {
995 EXPECT_TRUE(WaitForFilledStats())
996 << "Timed out waiting for filled statistics.";
999 VideoSendStream* stream_;
1000 VideoSendStream::Config config_;
1001 scoped_ptr<EventWrapper> event_;
1007 // This test first observes "high" bitrate use at which point it sends a REMB to
1008 // indicate that it should be lowered significantly. The test then observes that
1009 // the bitrate observed is sinking well below the min-transmit-bitrate threshold
1010 // to verify that the min-transmit bitrate respects incoming REMB.
1012 // Note that the test starts at "high" bitrate and does not ramp up to "higher"
1013 // bitrate since no receiver block or remb is sent in the initial phase.
1014 TEST_F(VideoSendStreamTest, MinTransmitBitrateRespectsRemb) {
1015 static const int kMinTransmitBitrateBps = 400000;
1016 static const int kHighBitrateBps = 150000;
1017 static const int kRembBitrateBps = 80000;
1018 static const int kRembRespectedBitrateBps = 100000;
1019 class BitrateObserver : public test::SendTest, public PacketReceiver {
1022 : SendTest(kDefaultTimeoutMs),
1023 feedback_transport_(ReceiveTransport()),
1024 bitrate_capped_(false) {
1025 RtpRtcp::Configuration config;
1026 feedback_transport_.Enable();
1027 config.outgoing_transport = &feedback_transport_;
1028 rtp_rtcp_.reset(RtpRtcp::CreateRtpRtcp(config));
1029 rtp_rtcp_->SetREMBStatus(true);
1030 rtp_rtcp_->SetRTCPStatus(kRtcpNonCompound);
1033 virtual void OnStreamsCreated(
1034 VideoSendStream* send_stream,
1035 const std::vector<VideoReceiveStream*>& receive_streams) OVERRIDE {
1036 stream_ = send_stream;
1040 virtual DeliveryStatus DeliverPacket(const uint8_t* packet,
1041 size_t length) OVERRIDE {
1042 if (RtpHeaderParser::IsRtcp(packet, length))
1046 if (!parser_->Parse(packet, length, &header))
1047 return DELIVERY_PACKET_ERROR;
1048 assert(stream_ != NULL);
1049 VideoSendStream::Stats stats = stream_->GetStats();
1050 if (!stats.substreams.empty()) {
1051 EXPECT_EQ(1u, stats.substreams.size());
1052 int bitrate_bps = stats.substreams.begin()->second.bitrate_bps;
1055 "min_transmit_bitrate_low_remb",
1057 static_cast<size_t>(bitrate_bps),
1060 if (bitrate_bps > kHighBitrateBps) {
1061 rtp_rtcp_->SetREMBData(kRembBitrateBps, 1, &header.ssrc);
1062 rtp_rtcp_->Process();
1063 bitrate_capped_ = true;
1064 } else if (bitrate_capped_ &&
1065 bitrate_bps < kRembRespectedBitrateBps) {
1066 observation_complete_->Set();
1072 virtual void SetReceivers(
1073 PacketReceiver* send_transport_receiver,
1074 PacketReceiver* receive_transport_receiver) OVERRIDE {
1075 RtpRtcpObserver::SetReceivers(this, send_transport_receiver);
1078 virtual void ModifyConfigs(
1079 VideoSendStream::Config* send_config,
1080 std::vector<VideoReceiveStream::Config>* receive_configs,
1081 std::vector<VideoStream>* video_streams) OVERRIDE {
1082 send_config->rtp.min_transmit_bitrate_bps = kMinTransmitBitrateBps;
1085 virtual void PerformTest() OVERRIDE {
1086 EXPECT_EQ(kEventSignaled, Wait())
1087 << "Timeout while waiting for low bitrate stats after REMB.";
1090 scoped_ptr<RtpRtcp> rtp_rtcp_;
1091 internal::TransportAdapter feedback_transport_;
1092 VideoSendStream* stream_;
1093 bool bitrate_capped_;
1099 TEST_F(VideoSendStreamTest, CapturesTextureAndI420VideoFrames) {
1100 class FrameObserver : public I420FrameCallback {
1102 FrameObserver() : output_frame_event_(EventWrapper::Create()) {}
1104 void FrameCallback(I420VideoFrame* video_frame) OVERRIDE {
1105 // Clone the frame because the caller owns it.
1106 output_frames_.push_back(video_frame->CloneFrame());
1107 output_frame_event_->Set();
1110 void WaitOutputFrame() {
1111 const unsigned long kWaitFrameTimeoutMs = 3000;
1112 EXPECT_EQ(kEventSignaled, output_frame_event_->Wait(kWaitFrameTimeoutMs))
1113 << "Timeout while waiting for output frames.";
1116 const std::vector<I420VideoFrame*>& output_frames() const {
1117 return output_frames_.get();
1121 // Delivered output frames.
1122 ScopedVector<I420VideoFrame> output_frames_;
1124 // Indicate an output frame has arrived.
1125 scoped_ptr<EventWrapper> output_frame_event_;
1128 // Initialize send stream.
1129 test::NullTransport transport;
1130 CreateSenderCall(Call::Config(&transport));
1132 CreateSendConfig(1);
1133 FrameObserver observer;
1134 send_config_.pre_encode_callback = &observer;
1137 // Prepare five input frames. Send I420VideoFrame and TextureVideoFrame
1139 ScopedVector<I420VideoFrame> input_frames;
1140 int width = static_cast<int>(video_streams_[0].width);
1141 int height = static_cast<int>(video_streams_[0].height);
1142 webrtc::RefCountImpl<FakeNativeHandle>* handle1 =
1143 new webrtc::RefCountImpl<FakeNativeHandle>();
1144 webrtc::RefCountImpl<FakeNativeHandle>* handle2 =
1145 new webrtc::RefCountImpl<FakeNativeHandle>();
1146 webrtc::RefCountImpl<FakeNativeHandle>* handle3 =
1147 new webrtc::RefCountImpl<FakeNativeHandle>();
1148 input_frames.push_back(new TextureVideoFrame(handle1, width, height, 1, 1));
1149 input_frames.push_back(new TextureVideoFrame(handle2, width, height, 2, 2));
1150 input_frames.push_back(CreateI420VideoFrame(width, height, 1));
1151 input_frames.push_back(CreateI420VideoFrame(width, height, 2));
1152 input_frames.push_back(new TextureVideoFrame(handle3, width, height, 3, 3));
1154 send_stream_->Start();
1155 for (size_t i = 0; i < input_frames.size(); i++) {
1156 // Make a copy of the input frame because the buffer will be swapped.
1157 scoped_ptr<I420VideoFrame> frame(input_frames[i]->CloneFrame());
1158 send_stream_->Input()->SwapFrame(frame.get());
1159 // Do not send the next frame too fast, so the frame dropper won't drop it.
1160 if (i < input_frames.size() - 1)
1161 SleepMs(1000 / video_streams_[0].max_framerate);
1162 // Wait until the output frame is received before sending the next input
1163 // frame. Or the previous input frame may be replaced without delivering.
1164 observer.WaitOutputFrame();
1166 send_stream_->Stop();
1168 // Test if the input and output frames are the same. render_time_ms and
1169 // timestamp are not compared because capturer sets those values.
1170 ExpectEqualFramesVector(input_frames.get(), observer.output_frames());
1175 void ExpectEqualFrames(const I420VideoFrame& frame1,
1176 const I420VideoFrame& frame2) {
1177 if (frame1.native_handle() != NULL || frame2.native_handle() != NULL)
1178 ExpectEqualTextureFrames(frame1, frame2);
1180 ExpectEqualBufferFrames(frame1, frame2);
1183 void ExpectEqualTextureFrames(const I420VideoFrame& frame1,
1184 const I420VideoFrame& frame2) {
1185 EXPECT_EQ(frame1.native_handle(), frame2.native_handle());
1186 EXPECT_EQ(frame1.width(), frame2.width());
1187 EXPECT_EQ(frame1.height(), frame2.height());
1190 void ExpectEqualBufferFrames(const I420VideoFrame& frame1,
1191 const I420VideoFrame& frame2) {
1192 EXPECT_EQ(frame1.width(), frame2.width());
1193 EXPECT_EQ(frame1.height(), frame2.height());
1194 EXPECT_EQ(frame1.stride(kYPlane), frame2.stride(kYPlane));
1195 EXPECT_EQ(frame1.stride(kUPlane), frame2.stride(kUPlane));
1196 EXPECT_EQ(frame1.stride(kVPlane), frame2.stride(kVPlane));
1197 EXPECT_EQ(frame1.ntp_time_ms(), frame2.ntp_time_ms());
1198 ASSERT_EQ(frame1.allocated_size(kYPlane), frame2.allocated_size(kYPlane));
1200 memcmp(frame1.buffer(kYPlane),
1201 frame2.buffer(kYPlane),
1202 frame1.allocated_size(kYPlane)));
1203 ASSERT_EQ(frame1.allocated_size(kUPlane), frame2.allocated_size(kUPlane));
1205 memcmp(frame1.buffer(kUPlane),
1206 frame2.buffer(kUPlane),
1207 frame1.allocated_size(kUPlane)));
1208 ASSERT_EQ(frame1.allocated_size(kVPlane), frame2.allocated_size(kVPlane));
1210 memcmp(frame1.buffer(kVPlane),
1211 frame2.buffer(kVPlane),
1212 frame1.allocated_size(kVPlane)));
1215 void ExpectEqualFramesVector(const std::vector<I420VideoFrame*>& frames1,
1216 const std::vector<I420VideoFrame*>& frames2) {
1217 EXPECT_EQ(frames1.size(), frames2.size());
1218 for (size_t i = 0; i < std::min(frames1.size(), frames2.size()); ++i)
1219 ExpectEqualFrames(*frames1[i], *frames2[i]);
1222 I420VideoFrame* CreateI420VideoFrame(int width, int height, uint8_t data) {
1223 I420VideoFrame* frame = new I420VideoFrame();
1224 const int kSizeY = width * height * 2;
1225 const int kSizeUV = width * height;
1226 scoped_ptr<uint8_t[]> buffer(new uint8_t[kSizeY]);
1227 memset(buffer.get(), data, kSizeY);
1228 frame->CreateFrame(kSizeY,
1239 frame->set_timestamp(data);
1240 frame->set_ntp_time_ms(data);
1241 frame->set_render_time_ms(data);
1245 TEST_F(VideoSendStreamTest, EncoderIsProperlyInitializedAndDestroyed) {
1246 class EncoderStateObserver : public test::SendTest, public VideoEncoder {
1248 EncoderStateObserver()
1249 : SendTest(kDefaultTimeoutMs),
1250 crit_(CriticalSectionWrapper::CreateCriticalSection()),
1251 initialized_(false),
1252 callback_registered_(false),
1257 CriticalSectionScoped lock(crit_.get());
1261 bool IsReadyForEncode() {
1262 CriticalSectionScoped lock(crit_.get());
1263 return initialized_ && callback_registered_;
1266 size_t num_releases() {
1267 CriticalSectionScoped lock(crit_.get());
1268 return num_releases_;
1272 virtual int32_t InitEncode(const VideoCodec* codecSettings,
1273 int32_t numberOfCores,
1274 uint32_t maxPayloadSize) OVERRIDE {
1275 CriticalSectionScoped lock(crit_.get());
1276 EXPECT_FALSE(initialized_);
1277 initialized_ = true;
1282 virtual int32_t Encode(
1283 const I420VideoFrame& inputImage,
1284 const CodecSpecificInfo* codecSpecificInfo,
1285 const std::vector<VideoFrameType>* frame_types) OVERRIDE {
1286 EXPECT_TRUE(IsReadyForEncode());
1288 observation_complete_->Set();
1292 virtual int32_t RegisterEncodeCompleteCallback(
1293 EncodedImageCallback* callback) OVERRIDE {
1294 CriticalSectionScoped lock(crit_.get());
1295 EXPECT_TRUE(initialized_);
1296 callback_registered_ = true;
1300 virtual int32_t Release() OVERRIDE {
1301 CriticalSectionScoped lock(crit_.get());
1302 EXPECT_TRUE(IsReadyForEncode());
1303 EXPECT_FALSE(released_);
1304 initialized_ = false;
1305 callback_registered_ = false;
1311 virtual int32_t SetChannelParameters(uint32_t packetLoss,
1313 EXPECT_TRUE(IsReadyForEncode());
1317 virtual int32_t SetRates(uint32_t newBitRate, uint32_t frameRate) OVERRIDE {
1318 EXPECT_TRUE(IsReadyForEncode());
1322 virtual void OnStreamsCreated(
1323 VideoSendStream* send_stream,
1324 const std::vector<VideoReceiveStream*>& receive_streams) OVERRIDE {
1325 // Encoder initialization should be done in stream construction before
1327 EXPECT_TRUE(IsReadyForEncode());
1328 stream_ = send_stream;
1331 virtual void ModifyConfigs(
1332 VideoSendStream::Config* send_config,
1333 std::vector<VideoReceiveStream::Config>* receive_configs,
1334 std::vector<VideoStream>* video_streams) OVERRIDE {
1335 send_config->encoder_settings.encoder = this;
1336 video_streams_ = *video_streams;
1339 virtual void PerformTest() OVERRIDE {
1340 EXPECT_EQ(kEventSignaled, Wait())
1341 << "Timed out while waiting for Encode.";
1342 EXPECT_EQ(0u, num_releases());
1343 stream_->ReconfigureVideoEncoder(video_streams_, NULL);
1344 EXPECT_EQ(0u, num_releases());
1346 // Encoder should not be released before destroying the VideoSendStream.
1347 EXPECT_FALSE(IsReleased());
1348 EXPECT_TRUE(IsReadyForEncode());
1350 // Sanity check, make sure we still encode frames with this encoder.
1351 EXPECT_EQ(kEventSignaled, Wait())
1352 << "Timed out while waiting for Encode.";
1355 scoped_ptr<CriticalSectionWrapper> crit_;
1356 VideoSendStream* stream_;
1357 bool initialized_ GUARDED_BY(crit_);
1358 bool callback_registered_ GUARDED_BY(crit_);
1359 size_t num_releases_ GUARDED_BY(crit_);
1360 bool released_ GUARDED_BY(crit_);
1361 std::vector<VideoStream> video_streams_;
1364 RunBaseTest(&test_encoder);
1366 EXPECT_TRUE(test_encoder.IsReleased());
1367 EXPECT_EQ(1u, test_encoder.num_releases());
1370 TEST_F(VideoSendStreamTest, EncoderSetupPropagatesVp8Config) {
1371 class VideoCodecConfigObserver : public test::SendTest,
1372 public test::FakeEncoder {
1374 VideoCodecConfigObserver()
1375 : SendTest(kDefaultTimeoutMs),
1376 FakeEncoder(Clock::GetRealTimeClock()),
1377 num_initializations_(0) {
1378 memset(&vp8_settings_, 0, sizeof(vp8_settings_));
1382 virtual void ModifyConfigs(
1383 VideoSendStream::Config* send_config,
1384 std::vector<VideoReceiveStream::Config>* receive_configs,
1385 std::vector<VideoStream>* video_streams) OVERRIDE {
1386 send_config->encoder_settings.encoder = this;
1387 send_config->encoder_settings.payload_name = "VP8";
1389 video_streams_ = *video_streams;
1392 virtual void OnStreamsCreated(
1393 VideoSendStream* send_stream,
1394 const std::vector<VideoReceiveStream*>& receive_streams) OVERRIDE {
1395 stream_ = send_stream;
1398 virtual int32_t InitEncode(const VideoCodec* config,
1399 int32_t number_of_cores,
1400 uint32_t max_payload_size) OVERRIDE {
1401 EXPECT_EQ(kVideoCodecVP8, config->codecType);
1403 memcmp(&config->codecSpecific.VP8,
1405 sizeof(vp8_settings_)));
1406 ++num_initializations_;
1407 return FakeEncoder::InitEncode(config, number_of_cores, max_payload_size);
1410 virtual void PerformTest() OVERRIDE {
1411 EXPECT_EQ(1u, num_initializations_) << "VideoEncoder not initialized.";
1413 vp8_settings_.denoisingOn = true;
1414 stream_->ReconfigureVideoEncoder(video_streams_, &vp8_settings_);
1415 EXPECT_EQ(2u, num_initializations_)
1416 << "ReconfigureVideoEncoder did not reinitialize the encoder with "
1417 "new encoder settings.";
1421 const I420VideoFrame& input_image,
1422 const CodecSpecificInfo* codec_specific_info,
1423 const std::vector<VideoFrameType>* frame_types) {
1424 // Silently skip the encode, FakeEncoder::Encode doesn't produce VP8.
1428 virtual const void* GetEncoderSettings() OVERRIDE { return &vp8_settings_; }
1430 VideoCodecVP8 vp8_settings_;
1431 size_t num_initializations_;
1432 VideoSendStream* stream_;
1433 std::vector<VideoStream> video_streams_;
1439 TEST_F(VideoSendStreamTest, RtcpSenderReportContainsMediaBytesSent) {
1440 class RtcpByeTest : public test::SendTest {
1442 RtcpByeTest() : SendTest(kDefaultTimeoutMs), media_bytes_sent_(0) {}
1445 virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE {
1447 EXPECT_TRUE(parser_->Parse(packet, length, &header));
1448 media_bytes_sent_ += length - header.headerLength - header.paddingLength;
1452 virtual Action OnSendRtcp(const uint8_t* packet, size_t length) OVERRIDE {
1453 RTCPUtility::RTCPParserV2 parser(packet, length, true);
1454 EXPECT_TRUE(parser.IsValid());
1456 RTCPUtility::RTCPPacketTypes packet_type = parser.Begin();
1457 uint32_t sender_octet_count = 0;
1458 while (packet_type != RTCPUtility::kRtcpNotValidCode) {
1459 if (packet_type == RTCPUtility::kRtcpSrCode) {
1460 sender_octet_count = parser.Packet().SR.SenderOctetCount;
1461 EXPECT_EQ(sender_octet_count, media_bytes_sent_);
1462 if (sender_octet_count > 0)
1463 observation_complete_->Set();
1466 packet_type = parser.Iterate();
1472 virtual void PerformTest() OVERRIDE {
1473 EXPECT_EQ(kEventSignaled, Wait())
1474 << "Timed out while waiting for RTCP sender report.";
1477 size_t media_bytes_sent_;
1483 } // namespace webrtc