Home | History | Annotate | Download | only in rtcp
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include <stdint.h>
      6 
      7 #include "base/test/simple_test_tick_clock.h"
      8 #include "media/cast/cast_defines.h"
      9 #include "media/cast/net/cast_transport_config.h"
     10 #include "media/cast/net/pacing/paced_sender.h"
     11 #include "media/cast/net/rtcp/rtcp.h"
     12 #include "media/cast/test/skewed_tick_clock.h"
     13 #include "testing/gmock/include/gmock/gmock.h"
     14 
     15 namespace media {
     16 namespace cast {
     17 
     18 using testing::_;
     19 
     20 static const uint32 kSenderSsrc = 0x10203;
     21 static const uint32 kReceiverSsrc = 0x40506;
     22 static const int kInitialReceiverClockOffsetSeconds = -5;
     23 
     24 class FakeRtcpTransport : public PacedPacketSender {
     25  public:
     26   explicit FakeRtcpTransport(base::SimpleTestTickClock* clock)
     27       : clock_(clock),
     28         packet_delay_(base::TimeDelta::FromMilliseconds(42)) {}
     29 
     30   void set_rtcp_destination(Rtcp* rtcp) { rtcp_ = rtcp; }
     31 
     32   base::TimeDelta packet_delay() const { return packet_delay_; }
     33   void set_packet_delay(base::TimeDelta delay) { packet_delay_ = delay; }
     34 
     35   virtual bool SendRtcpPacket(uint32 ssrc, PacketRef packet) OVERRIDE {
     36     clock_->Advance(packet_delay_);
     37     rtcp_->IncomingRtcpPacket(&packet->data[0], packet->data.size());
     38     return true;
     39   }
     40 
     41   virtual bool SendPackets(const SendPacketVector& packets) OVERRIDE {
     42     return false;
     43   }
     44 
     45   virtual bool ResendPackets(
     46       const SendPacketVector& packets, const DedupInfo& dedup_info) OVERRIDE {
     47     return false;
     48   }
     49 
     50   virtual void CancelSendingPacket(const PacketKey& packet_key) OVERRIDE {
     51   }
     52 
     53  private:
     54   base::SimpleTestTickClock* const clock_;
     55   base::TimeDelta packet_delay_;
     56   Rtcp* rtcp_;
     57 
     58   DISALLOW_COPY_AND_ASSIGN(FakeRtcpTransport);
     59 };
     60 
     61 class FakeReceiverStats : public RtpReceiverStatistics {
     62  public:
     63   FakeReceiverStats() {}
     64   virtual ~FakeReceiverStats() {}
     65 
     66   virtual void GetStatistics(uint8* fraction_lost,
     67                              uint32* cumulative_lost,
     68                              uint32* extended_high_sequence_number,
     69                              uint32* jitter) OVERRIDE {
     70     *fraction_lost = 0;
     71     *cumulative_lost = 0;
     72     *extended_high_sequence_number = 0;
     73     *jitter = 0;
     74   }
     75 
     76  private:
     77   DISALLOW_COPY_AND_ASSIGN(FakeReceiverStats);
     78 };
     79 
     80 class MockFrameSender {
     81  public:
     82   MockFrameSender() {}
     83   virtual ~MockFrameSender() {}
     84 
     85   MOCK_METHOD1(OnReceivedCastFeedback,
     86                void(const RtcpCastMessage& cast_message));
     87   MOCK_METHOD1(OnMeasuredRoundTripTime, void(base::TimeDelta rtt));
     88 
     89  private:
     90   DISALLOW_COPY_AND_ASSIGN(MockFrameSender);
     91 };
     92 
     93 class RtcpTest : public ::testing::Test {
     94  protected:
     95   RtcpTest()
     96       : sender_clock_(new base::SimpleTestTickClock()),
     97         receiver_clock_(new test::SkewedTickClock(sender_clock_.get())),
     98         sender_to_receiver_(sender_clock_.get()),
     99         receiver_to_sender_(sender_clock_.get()),
    100         rtcp_for_sender_(base::Bind(&MockFrameSender::OnReceivedCastFeedback,
    101                                     base::Unretained(&mock_frame_sender_)),
    102                          base::Bind(&MockFrameSender::OnMeasuredRoundTripTime,
    103                                     base::Unretained(&mock_frame_sender_)),
    104                          RtcpLogMessageCallback(),
    105                          sender_clock_.get(),
    106                          &sender_to_receiver_,
    107                          kSenderSsrc,
    108                          kReceiverSsrc),
    109         rtcp_for_receiver_(RtcpCastMessageCallback(),
    110                            RtcpRttCallback(),
    111                            RtcpLogMessageCallback(),
    112                            receiver_clock_.get(),
    113                            &receiver_to_sender_,
    114                            kReceiverSsrc,
    115                            kSenderSsrc) {
    116     sender_clock_->Advance(base::TimeTicks::Now() - base::TimeTicks());
    117     receiver_clock_->SetSkew(
    118         1.0,  // No skew.
    119         base::TimeDelta::FromSeconds(kInitialReceiverClockOffsetSeconds));
    120 
    121     sender_to_receiver_.set_rtcp_destination(&rtcp_for_receiver_);
    122     receiver_to_sender_.set_rtcp_destination(&rtcp_for_sender_);
    123   }
    124 
    125   virtual ~RtcpTest() {}
    126 
    127   scoped_ptr<base::SimpleTestTickClock> sender_clock_;
    128   scoped_ptr<test::SkewedTickClock> receiver_clock_;
    129   FakeRtcpTransport sender_to_receiver_;
    130   FakeRtcpTransport receiver_to_sender_;
    131   MockFrameSender mock_frame_sender_;
    132   Rtcp rtcp_for_sender_;
    133   Rtcp rtcp_for_receiver_;
    134   FakeReceiverStats stats_;
    135 
    136   DISALLOW_COPY_AND_ASSIGN(RtcpTest);
    137 };
    138 
    139 TEST_F(RtcpTest, LipSyncGleanedFromSenderReport) {
    140   // Initially, expect no lip-sync info receiver-side without having first
    141   // received a RTCP packet.
    142   base::TimeTicks reference_time;
    143   uint32 rtp_timestamp;
    144   ASSERT_FALSE(rtcp_for_receiver_.GetLatestLipSyncTimes(&rtp_timestamp,
    145                                                         &reference_time));
    146 
    147   // Send a Sender Report to the receiver.
    148   const base::TimeTicks reference_time_sent = sender_clock_->NowTicks();
    149   const uint32 rtp_timestamp_sent = 0xbee5;
    150   rtcp_for_sender_.SendRtcpFromRtpSender(
    151       reference_time_sent, rtp_timestamp_sent, 1, 1);
    152 
    153   // Now the receiver should have lip-sync info.  Confirm that the lip-sync
    154   // reference time is the same as that sent.
    155   EXPECT_TRUE(rtcp_for_receiver_.GetLatestLipSyncTimes(&rtp_timestamp,
    156                                                        &reference_time));
    157   const base::TimeTicks rolled_back_time =
    158       (reference_time -
    159        // Roll-back relative clock offset:
    160        base::TimeDelta::FromSeconds(kInitialReceiverClockOffsetSeconds) -
    161        // Roll-back packet transmission time (because RTT is not yet known):
    162        sender_to_receiver_.packet_delay());
    163   EXPECT_NEAR(0, (reference_time_sent - rolled_back_time).InMicroseconds(), 5);
    164   EXPECT_EQ(rtp_timestamp_sent, rtp_timestamp);
    165 }
    166 
    167 // TODO(miu): There were a few tests here that didn't actually test anything
    168 // except that the code wouldn't crash and a callback method was invoked.  We
    169 // need to fill-in more testing of RTCP now that much of the refactoring work
    170 // has been completed.
    171 
    172 TEST_F(RtcpTest, RoundTripTimesDeterminedFromReportPingPong) {
    173   const int iterations = 12;
    174   EXPECT_CALL(mock_frame_sender_, OnMeasuredRoundTripTime(_))
    175       .Times(iterations);
    176 
    177   // Initially, neither side knows the round trip time.
    178   ASSERT_EQ(base::TimeDelta(), rtcp_for_sender_.current_round_trip_time());
    179   ASSERT_EQ(base::TimeDelta(), rtcp_for_receiver_.current_round_trip_time());
    180 
    181   // Do a number of ping-pongs, checking how the round trip times are measured
    182   // by the sender and receiver.
    183   base::TimeDelta expected_rtt_according_to_sender;
    184   base::TimeDelta expected_rtt_according_to_receiver;
    185   for (int i = 0; i < iterations; ++i) {
    186     const base::TimeDelta one_way_trip_time =
    187         base::TimeDelta::FromMilliseconds(1 << i);
    188     sender_to_receiver_.set_packet_delay(one_way_trip_time);
    189     receiver_to_sender_.set_packet_delay(one_way_trip_time);
    190 
    191     // Sender --> Receiver
    192     base::TimeTicks reference_time_sent = sender_clock_->NowTicks();
    193     uint32 rtp_timestamp_sent = 0xbee5 + i;
    194     rtcp_for_sender_.SendRtcpFromRtpSender(
    195         reference_time_sent, rtp_timestamp_sent, 1, 1);
    196     EXPECT_EQ(expected_rtt_according_to_sender,
    197               rtcp_for_sender_.current_round_trip_time());
    198 #ifdef SENDER_PROVIDES_REPORT_BLOCK
    199     EXPECT_EQ(expected_rtt_according_to_receiver,
    200               rtcp_for_receiver_.current_round_trip_time());
    201 #endif
    202 
    203     // Receiver --> Sender
    204     rtcp_for_receiver_.SendRtcpFromRtpReceiver(
    205         NULL, base::TimeDelta(), NULL, &stats_);
    206     expected_rtt_according_to_sender = one_way_trip_time * 2;
    207     EXPECT_EQ(expected_rtt_according_to_sender,
    208               rtcp_for_sender_.current_round_trip_time());
    209 #ifdef SENDER_PROVIDES_REPORT_BLOCK
    210     EXPECT_EQ(expected_rtt_according_to_receiver,
    211               rtcp_for_receiver_.current_round_trip_time();
    212 #endif
    213 
    214     // In the next iteration of this loop, after the receiver gets the sender
    215     // report, it will be measuring a round trip time consisting of two
    216     // different one-way trip times.
    217     expected_rtt_according_to_receiver =
    218         (one_way_trip_time + one_way_trip_time * 2) / 2;
    219   }
    220 }
    221 
    222 // TODO(miu): Find a better home for this test.
    223 TEST(MisplacedCastTest, NtpAndTime) {
    224   const int64 kSecondsbetweenYear1900and2010 = INT64_C(40176 * 24 * 60 * 60);
    225   const int64 kSecondsbetweenYear1900and2030 = INT64_C(47481 * 24 * 60 * 60);
    226 
    227   uint32 ntp_seconds_1 = 0;
    228   uint32 ntp_fraction_1 = 0;
    229   base::TimeTicks input_time = base::TimeTicks::Now();
    230   ConvertTimeTicksToNtp(input_time, &ntp_seconds_1, &ntp_fraction_1);
    231 
    232   // Verify absolute value.
    233   EXPECT_GT(ntp_seconds_1, kSecondsbetweenYear1900and2010);
    234   EXPECT_LT(ntp_seconds_1, kSecondsbetweenYear1900and2030);
    235 
    236   base::TimeTicks out_1 = ConvertNtpToTimeTicks(ntp_seconds_1, ntp_fraction_1);
    237   EXPECT_EQ(input_time, out_1);  // Verify inverse.
    238 
    239   base::TimeDelta time_delta = base::TimeDelta::FromMilliseconds(1000);
    240   input_time += time_delta;
    241 
    242   uint32 ntp_seconds_2 = 0;
    243   uint32 ntp_fraction_2 = 0;
    244 
    245   ConvertTimeTicksToNtp(input_time, &ntp_seconds_2, &ntp_fraction_2);
    246   base::TimeTicks out_2 = ConvertNtpToTimeTicks(ntp_seconds_2, ntp_fraction_2);
    247   EXPECT_EQ(input_time, out_2);  // Verify inverse.
    248 
    249   // Verify delta.
    250   EXPECT_EQ((out_2 - out_1), time_delta);
    251   EXPECT_EQ((ntp_seconds_2 - ntp_seconds_1), UINT32_C(1));
    252   EXPECT_NEAR(ntp_fraction_2, ntp_fraction_1, 1);
    253 
    254   time_delta = base::TimeDelta::FromMilliseconds(500);
    255   input_time += time_delta;
    256 
    257   uint32 ntp_seconds_3 = 0;
    258   uint32 ntp_fraction_3 = 0;
    259 
    260   ConvertTimeTicksToNtp(input_time, &ntp_seconds_3, &ntp_fraction_3);
    261   base::TimeTicks out_3 = ConvertNtpToTimeTicks(ntp_seconds_3, ntp_fraction_3);
    262   EXPECT_EQ(input_time, out_3);  // Verify inverse.
    263 
    264   // Verify delta.
    265   EXPECT_EQ((out_3 - out_2), time_delta);
    266   EXPECT_NEAR((ntp_fraction_3 - ntp_fraction_2), 0xffffffff / 2, 1);
    267 }
    268 
    269 }  // namespace cast
    270 }  // namespace media
    271