• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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