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