Home | History | Annotate | Download | only in source
      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  * This file includes unit tests for the RTPPacketHistory.
     11  */
     12 
     13 #include "testing/gtest/include/gtest/gtest.h"
     14 
     15 #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
     16 #include "webrtc/modules/rtp_rtcp/source/rtp_packet_history.h"
     17 #include "webrtc/system_wrappers/include/clock.h"
     18 #include "webrtc/typedefs.h"
     19 
     20 namespace webrtc {
     21 
     22 class RtpPacketHistoryTest : public ::testing::Test {
     23  protected:
     24   RtpPacketHistoryTest()
     25      : fake_clock_(123456),
     26        hist_(new RTPPacketHistory(&fake_clock_)) {
     27   }
     28   ~RtpPacketHistoryTest() {
     29     delete hist_;
     30   }
     31 
     32   SimulatedClock fake_clock_;
     33   RTPPacketHistory* hist_;
     34   enum {kPayload = 127};
     35   enum {kSsrc = 12345678};
     36   enum {kSeqNum = 88};
     37   enum {kTimestamp = 127};
     38   enum {kMaxPacketLength = 1500};
     39   uint8_t packet_[kMaxPacketLength];
     40   uint8_t packet_out_[kMaxPacketLength];
     41 
     42   void CreateRtpPacket(uint16_t seq_num, uint32_t ssrc, uint8_t payload,
     43       uint32_t timestamp, uint8_t* array, size_t* cur_pos) {
     44     array[(*cur_pos)++] = 0x80;
     45     array[(*cur_pos)++] = payload;
     46     array[(*cur_pos)++] = seq_num >> 8;
     47     array[(*cur_pos)++] = seq_num;
     48     array[(*cur_pos)++] = timestamp >> 24;
     49     array[(*cur_pos)++] = timestamp >> 16;
     50     array[(*cur_pos)++] = timestamp >> 8;
     51     array[(*cur_pos)++] = timestamp;
     52     array[(*cur_pos)++] = ssrc >> 24;
     53     array[(*cur_pos)++] = ssrc >> 16;
     54     array[(*cur_pos)++] = ssrc >> 8;
     55     array[(*cur_pos)++] = ssrc;
     56   }
     57 };
     58 
     59 TEST_F(RtpPacketHistoryTest, SetStoreStatus) {
     60   EXPECT_FALSE(hist_->StorePackets());
     61   hist_->SetStorePacketsStatus(true, 10);
     62   EXPECT_TRUE(hist_->StorePackets());
     63   hist_->SetStorePacketsStatus(false, 0);
     64   EXPECT_FALSE(hist_->StorePackets());
     65 }
     66 
     67 TEST_F(RtpPacketHistoryTest, NoStoreStatus) {
     68   EXPECT_FALSE(hist_->StorePackets());
     69   size_t len = 0;
     70   int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
     71   CreateRtpPacket(kSeqNum, kSsrc, kPayload, kTimestamp, packet_, &len);
     72   EXPECT_EQ(0, hist_->PutRTPPacket(packet_, len, capture_time_ms,
     73                                    kAllowRetransmission));
     74   // Packet should not be stored.
     75   len = kMaxPacketLength;
     76   int64_t time;
     77   EXPECT_FALSE(hist_->GetPacketAndSetSendTime(kSeqNum, 0, false, packet_, &len,
     78                                               &time));
     79 }
     80 
     81 TEST_F(RtpPacketHistoryTest, PutRtpPacket_TooLargePacketLength) {
     82   hist_->SetStorePacketsStatus(true, 10);
     83   int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
     84   EXPECT_EQ(-1, hist_->PutRTPPacket(packet_, kMaxPacketLength + 1,
     85                                     capture_time_ms, kAllowRetransmission));
     86 }
     87 
     88 TEST_F(RtpPacketHistoryTest, GetRtpPacket_NotStored) {
     89   hist_->SetStorePacketsStatus(true, 10);
     90   size_t len = kMaxPacketLength;
     91   int64_t time;
     92   EXPECT_FALSE(hist_->GetPacketAndSetSendTime(0, 0, false, packet_, &len,
     93                                               &time));
     94 }
     95 
     96 TEST_F(RtpPacketHistoryTest, PutRtpPacket) {
     97   hist_->SetStorePacketsStatus(true, 10);
     98   size_t len = 0;
     99   CreateRtpPacket(kSeqNum, kSsrc, kPayload, kTimestamp, packet_, &len);
    100 
    101   EXPECT_FALSE(hist_->HasRTPPacket(kSeqNum));
    102   int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
    103   EXPECT_EQ(0, hist_->PutRTPPacket(packet_, len, capture_time_ms,
    104                                    kAllowRetransmission));
    105   EXPECT_TRUE(hist_->HasRTPPacket(kSeqNum));
    106 }
    107 
    108 TEST_F(RtpPacketHistoryTest, GetRtpPacket) {
    109   hist_->SetStorePacketsStatus(true, 10);
    110   size_t len = 0;
    111   int64_t capture_time_ms = 1;
    112   CreateRtpPacket(kSeqNum, kSsrc, kPayload, kTimestamp, packet_, &len);
    113   EXPECT_EQ(0, hist_->PutRTPPacket(packet_, len, capture_time_ms,
    114                                    kAllowRetransmission));
    115 
    116   size_t len_out = kMaxPacketLength;
    117   int64_t time;
    118   EXPECT_TRUE(hist_->GetPacketAndSetSendTime(kSeqNum, 0, false, packet_out_,
    119                                              &len_out, &time));
    120   EXPECT_EQ(len, len_out);
    121   EXPECT_EQ(capture_time_ms, time);
    122   for (size_t i = 0; i < len; i++)  {
    123     EXPECT_EQ(packet_[i], packet_out_[i]);
    124   }
    125 }
    126 
    127 TEST_F(RtpPacketHistoryTest, NoCaptureTime) {
    128   hist_->SetStorePacketsStatus(true, 10);
    129   size_t len = 0;
    130   fake_clock_.AdvanceTimeMilliseconds(1);
    131   int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
    132   CreateRtpPacket(kSeqNum, kSsrc, kPayload, kTimestamp, packet_, &len);
    133   EXPECT_EQ(0, hist_->PutRTPPacket(packet_, len, -1, kAllowRetransmission));
    134 
    135   size_t len_out = kMaxPacketLength;
    136   int64_t time;
    137   EXPECT_TRUE(hist_->GetPacketAndSetSendTime(kSeqNum, 0, false, packet_out_,
    138                                              &len_out, &time));
    139   EXPECT_EQ(len, len_out);
    140   EXPECT_EQ(capture_time_ms, time);
    141   for (size_t i = 0; i < len; i++)  {
    142     EXPECT_EQ(packet_[i], packet_out_[i]);
    143   }
    144 }
    145 
    146 TEST_F(RtpPacketHistoryTest, DontRetransmit) {
    147   hist_->SetStorePacketsStatus(true, 10);
    148   size_t len = 0;
    149   int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
    150   CreateRtpPacket(kSeqNum, kSsrc, kPayload, kTimestamp, packet_, &len);
    151   EXPECT_EQ(
    152       0, hist_->PutRTPPacket(packet_, len, capture_time_ms, kDontRetransmit));
    153 
    154   size_t len_out = kMaxPacketLength;
    155   int64_t time;
    156   EXPECT_TRUE(hist_->GetPacketAndSetSendTime(kSeqNum, 0, false, packet_out_,
    157                                              &len_out, &time));
    158   EXPECT_EQ(len, len_out);
    159   EXPECT_EQ(capture_time_ms, time);
    160 }
    161 
    162 TEST_F(RtpPacketHistoryTest, MinResendTime) {
    163   static const int64_t kMinRetransmitIntervalMs = 100;
    164 
    165   hist_->SetStorePacketsStatus(true, 10);
    166   size_t len = 0;
    167   int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
    168   CreateRtpPacket(kSeqNum, kSsrc, kPayload, kTimestamp, packet_, &len);
    169   EXPECT_EQ(0, hist_->PutRTPPacket(packet_, len, capture_time_ms,
    170                                    kAllowRetransmission));
    171 
    172   // First transmission: TimeToSendPacket() call from pacer.
    173   int64_t time;
    174   len = kMaxPacketLength;
    175   EXPECT_TRUE(
    176       hist_->GetPacketAndSetSendTime(kSeqNum, 0, false, packet_, &len, &time));
    177 
    178   fake_clock_.AdvanceTimeMilliseconds(kMinRetransmitIntervalMs);
    179   // Time has elapsed.
    180   len = kMaxPacketLength;
    181   EXPECT_TRUE(hist_->GetPacketAndSetSendTime(kSeqNum, kMinRetransmitIntervalMs,
    182                                              true, packet_, &len, &time));
    183   EXPECT_GT(len, 0u);
    184   EXPECT_EQ(capture_time_ms, time);
    185 
    186   fake_clock_.AdvanceTimeMilliseconds(kMinRetransmitIntervalMs - 1);
    187   // Time has not elapsed. Packet should be found, but no bytes copied.
    188   len = kMaxPacketLength;
    189   EXPECT_FALSE(hist_->GetPacketAndSetSendTime(kSeqNum, kMinRetransmitIntervalMs,
    190                                               true, packet_, &len, &time));
    191 }
    192 
    193 TEST_F(RtpPacketHistoryTest, EarlyFirstResend) {
    194   static const int64_t kMinRetransmitIntervalMs = 100;
    195 
    196   hist_->SetStorePacketsStatus(true, 10);
    197   size_t len = 0;
    198   int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
    199   CreateRtpPacket(kSeqNum, kSsrc, kPayload, kTimestamp, packet_, &len);
    200   EXPECT_EQ(0, hist_->PutRTPPacket(packet_, len, capture_time_ms,
    201                                    kAllowRetransmission));
    202 
    203   // First transmission: TimeToSendPacket() call from pacer.
    204   int64_t time;
    205   len = kMaxPacketLength;
    206   EXPECT_TRUE(
    207       hist_->GetPacketAndSetSendTime(kSeqNum, 0, false, packet_, &len, &time));
    208 
    209   fake_clock_.AdvanceTimeMilliseconds(kMinRetransmitIntervalMs - 1);
    210   // Time has not elapsed, but this is the first retransmission request so
    211   // allow anyway.
    212   len = kMaxPacketLength;
    213   EXPECT_TRUE(hist_->GetPacketAndSetSendTime(kSeqNum, kMinRetransmitIntervalMs,
    214                                              true, packet_, &len, &time));
    215   EXPECT_GT(len, 0u);
    216   EXPECT_EQ(capture_time_ms, time);
    217 
    218   fake_clock_.AdvanceTimeMilliseconds(kMinRetransmitIntervalMs - 1);
    219   // Time has not elapsed. Packet should be found, but no bytes copied.
    220   len = kMaxPacketLength;
    221   EXPECT_FALSE(hist_->GetPacketAndSetSendTime(kSeqNum, kMinRetransmitIntervalMs,
    222                                               true, packet_, &len, &time));
    223 }
    224 
    225 TEST_F(RtpPacketHistoryTest, DynamicExpansion) {
    226   hist_->SetStorePacketsStatus(true, 10);
    227   size_t len;
    228   int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
    229   int64_t time;
    230 
    231   // Add 4 packets, and then send them.
    232   for (int i = 0; i < 4; ++i) {
    233     len = 0;
    234     CreateRtpPacket(kSeqNum + i, kSsrc, kPayload, kTimestamp, packet_, &len);
    235     EXPECT_EQ(0, hist_->PutRTPPacket(packet_, len, capture_time_ms,
    236                                      kAllowRetransmission));
    237   }
    238   for (int i = 0; i < 4; ++i) {
    239     len = kMaxPacketLength;
    240     EXPECT_TRUE(hist_->GetPacketAndSetSendTime(kSeqNum + i, 100, false, packet_,
    241                                                &len, &time));
    242   }
    243   capture_time_ms += 33;
    244 
    245   // Add 16 packets, and then send them. History should expand to make this
    246   // work.
    247   for (int i = 4; i < 20; ++i) {
    248     len = 0;
    249     CreateRtpPacket(kSeqNum + i, kSsrc, kPayload, kTimestamp, packet_, &len);
    250     EXPECT_EQ(0, hist_->PutRTPPacket(packet_, len, capture_time_ms,
    251                                      kAllowRetransmission));
    252   }
    253   for (int i = 4; i < 20; ++i) {
    254     len = kMaxPacketLength;
    255     EXPECT_TRUE(hist_->GetPacketAndSetSendTime(kSeqNum + i, 100, false, packet_,
    256                                                &len, &time));
    257   }
    258 
    259   fake_clock_.AdvanceTimeMilliseconds(100);
    260 
    261   // Retransmit last 16 packets.
    262   for (int i = 4; i < 20; ++i) {
    263     len = kMaxPacketLength;
    264     EXPECT_TRUE(hist_->GetPacketAndSetSendTime(kSeqNum + i, 100, false, packet_,
    265                                                &len, &time));
    266   }
    267 }
    268 
    269 TEST_F(RtpPacketHistoryTest, FullExpansion) {
    270   static const int kSendSidePacketHistorySize = 600;
    271   hist_->SetStorePacketsStatus(true, kSendSidePacketHistorySize);
    272   size_t len;
    273   int64_t capture_time_ms = fake_clock_.TimeInMilliseconds();
    274   int64_t time;
    275   for (size_t i = 0; i < kMaxHistoryCapacity + 1; ++i) {
    276     len = 0;
    277     CreateRtpPacket(kSeqNum + i, kSsrc, kPayload, kTimestamp, packet_, &len);
    278     EXPECT_EQ(0, hist_->PutRTPPacket(packet_, len, capture_time_ms,
    279                                      kAllowRetransmission));
    280   }
    281 
    282   fake_clock_.AdvanceTimeMilliseconds(100);
    283 
    284   // Retransmit all packets currently in buffer.
    285   for (size_t i = 1; i < kMaxHistoryCapacity + 1; ++i) {
    286     len = kMaxPacketLength;
    287     EXPECT_TRUE(hist_->GetPacketAndSetSendTime(kSeqNum + i, 100, false, packet_,
    288                                                &len, &time));
    289   }
    290 }
    291 
    292 }  // namespace webrtc
    293