Home | History | Annotate | Download | only in standard
      1 /*
      2  *  Copyright (c) 2012 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 
     11 #include "webrtc/system_wrappers/interface/atomic32.h"
     12 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
     13 #include "webrtc/system_wrappers/interface/event_wrapper.h"
     14 #include "webrtc/test/testsupport/fileutils.h"
     15 #include "webrtc/voice_engine/test/auto_test/fixtures/after_streaming_fixture.h"
     16 #include "webrtc/voice_engine/test/auto_test/voe_standard_test.h"
     17 
     18 class TestRtpObserver : public webrtc::VoERTPObserver {
     19  public:
     20   TestRtpObserver()
     21       : crit_(voetest::CriticalSectionWrapper::CreateCriticalSection()),
     22         changed_ssrc_event_(voetest::EventWrapper::Create()) {}
     23   virtual ~TestRtpObserver() {}
     24   virtual void OnIncomingCSRCChanged(int channel,
     25                                      unsigned int CSRC,
     26                                      bool added) {}
     27   virtual void OnIncomingSSRCChanged(int channel,
     28                                      unsigned int SSRC);
     29   void WaitForChangedSsrc() {
     30     // 10 seconds should be enough.
     31     EXPECT_EQ(voetest::kEventSignaled, changed_ssrc_event_->Wait(10*1000));
     32     changed_ssrc_event_->Reset();
     33   }
     34   void SetIncomingSsrc(unsigned int ssrc) {
     35     voetest::CriticalSectionScoped lock(crit_.get());
     36     incoming_ssrc_ = ssrc;
     37   }
     38  public:
     39   voetest::scoped_ptr<voetest::CriticalSectionWrapper> crit_;
     40   unsigned int incoming_ssrc_;
     41   voetest::scoped_ptr<voetest::EventWrapper> changed_ssrc_event_;
     42 };
     43 
     44 void TestRtpObserver::OnIncomingSSRCChanged(int channel,
     45                                             unsigned int SSRC) {
     46   char msg[128];
     47   sprintf(msg, "\n=> OnIncomingSSRCChanged(channel=%d, SSRC=%u)\n", channel,
     48           SSRC);
     49   TEST_LOG("%s", msg);
     50 
     51   {
     52     voetest::CriticalSectionScoped lock(crit_.get());
     53     if (incoming_ssrc_ == SSRC)
     54       changed_ssrc_event_->Set();
     55   }
     56 }
     57 
     58 class RtcpAppHandler : public webrtc::VoERTCPObserver {
     59  public:
     60   RtcpAppHandler() : length_in_bytes_(0), sub_type_(0), name_(0) {}
     61   void OnApplicationDataReceived(int channel,
     62                                  unsigned char sub_type,
     63                                  unsigned int name,
     64                                  const unsigned char* data,
     65                                  unsigned short length_in_bytes);
     66   void Reset();
     67   ~RtcpAppHandler() {}
     68   unsigned short length_in_bytes_;
     69   unsigned char data_[256];
     70   unsigned char sub_type_;
     71   unsigned int name_;
     72 };
     73 
     74 
     75 static const char* const RTCP_CNAME = "Whatever";
     76 
     77 class RtpRtcpTest : public AfterStreamingFixture {
     78  protected:
     79   void SetUp() {
     80     // We need a second channel for this test, so set it up.
     81     second_channel_ = voe_base_->CreateChannel();
     82     EXPECT_GE(second_channel_, 0);
     83 
     84     transport_ = new LoopBackTransport(voe_network_);
     85     EXPECT_EQ(0, voe_network_->RegisterExternalTransport(second_channel_,
     86                                                          *transport_));
     87 
     88     EXPECT_EQ(0, voe_base_->StartReceive(second_channel_));
     89     EXPECT_EQ(0, voe_base_->StartPlayout(second_channel_));
     90     EXPECT_EQ(0, voe_rtp_rtcp_->SetLocalSSRC(second_channel_, 5678));
     91     EXPECT_EQ(0, voe_base_->StartSend(second_channel_));
     92 
     93     // We'll set up the RTCP CNAME and SSRC to something arbitrary here.
     94     voe_rtp_rtcp_->SetRTCP_CNAME(channel_, RTCP_CNAME);
     95   }
     96 
     97   void TearDown() {
     98     EXPECT_EQ(0, voe_network_->DeRegisterExternalTransport(second_channel_));
     99     voe_base_->DeleteChannel(second_channel_);
    100     delete transport_;
    101   }
    102 
    103   int second_channel_;
    104   LoopBackTransport* transport_;
    105 };
    106 
    107 void RtcpAppHandler::OnApplicationDataReceived(
    108     const int /*channel*/, unsigned char sub_type,
    109     unsigned int name, const unsigned char* data,
    110     unsigned short length_in_bytes) {
    111   length_in_bytes_ = length_in_bytes;
    112   memcpy(data_, &data[0], length_in_bytes);
    113   sub_type_ = sub_type;
    114   name_ = name;
    115 }
    116 
    117 void RtcpAppHandler::Reset() {
    118   length_in_bytes_ = 0;
    119   memset(data_, 0, sizeof(data_));
    120   sub_type_ = 0;
    121   name_ = 0;
    122 }
    123 
    124 TEST_F(RtpRtcpTest, RemoteRtcpCnameHasPropagatedToRemoteSide) {
    125   if (!FLAGS_include_timing_dependent_tests) {
    126     TEST_LOG("Skipping test - running in slow execution environment...\n");
    127     return;
    128   }
    129 
    130   // We need to sleep a bit here for the name to propagate. For instance,
    131   // 200 milliseconds is not enough, so we'll go with one second here.
    132   Sleep(1000);
    133 
    134   char char_buffer[256];
    135   voe_rtp_rtcp_->GetRemoteRTCP_CNAME(channel_, char_buffer);
    136   EXPECT_STREQ(RTCP_CNAME, char_buffer);
    137 }
    138 
    139 // Flakily hangs on Linux. code.google.com/p/webrtc/issues/detail?id=2178.
    140 TEST_F(RtpRtcpTest, DISABLED_ON_LINUX(SSRCPropagatesCorrectly)) {
    141   unsigned int local_ssrc = 1234;
    142   EXPECT_EQ(0, voe_base_->StopSend(channel_));
    143   EXPECT_EQ(0, voe_rtp_rtcp_->SetLocalSSRC(channel_, local_ssrc));
    144   EXPECT_EQ(0, voe_base_->StartSend(channel_));
    145 
    146   Sleep(1000);
    147 
    148   unsigned int ssrc;
    149   EXPECT_EQ(0, voe_rtp_rtcp_->GetLocalSSRC(channel_, ssrc));
    150   EXPECT_EQ(local_ssrc, ssrc);
    151 
    152   EXPECT_EQ(0, voe_rtp_rtcp_->GetRemoteSSRC(channel_, ssrc));
    153   EXPECT_EQ(local_ssrc, ssrc);
    154 }
    155 
    156 // TODO(xians, phoglund): Re-enable when issue 372 is resolved.
    157 TEST_F(RtpRtcpTest, DISABLED_CanCreateRtpDumpFilesWithoutError) {
    158   // Create two RTP dump files (3 seconds long). You can verify these after
    159   // the test using rtpplay or NetEqRTPplay if you like.
    160   std::string output_path = webrtc::test::OutputPath();
    161   std::string incoming_filename = output_path + "dump_in_3sec.rtp";
    162   std::string outgoing_filename = output_path + "dump_out_3sec.rtp";
    163 
    164   EXPECT_EQ(0, voe_rtp_rtcp_->StartRTPDump(
    165       channel_, incoming_filename.c_str(), webrtc::kRtpIncoming));
    166   EXPECT_EQ(0, voe_rtp_rtcp_->StartRTPDump(
    167       channel_, outgoing_filename.c_str(), webrtc::kRtpOutgoing));
    168 
    169   Sleep(3000);
    170 
    171   EXPECT_EQ(0, voe_rtp_rtcp_->StopRTPDump(channel_, webrtc::kRtpIncoming));
    172   EXPECT_EQ(0, voe_rtp_rtcp_->StopRTPDump(channel_, webrtc::kRtpOutgoing));
    173 }
    174 
    175