rtp_sender_unittest.cc revision 20ed36dada62ad56ec01263fc0eef0ed198f6476
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/*
12 * This file includes unit tests for the RTPSender.
13 */
14
15#include <gtest/gtest.h>
16
17#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h"
18#include "webrtc/modules/rtp_rtcp/source/rtp_header_extension.h"
19#include "webrtc/modules/rtp_rtcp/source/rtp_sender.h"
20#include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
21#include "webrtc/system_wrappers/interface/scoped_ptr.h"
22#include "webrtc/typedefs.h"
23
24namespace webrtc {
25
26namespace {
27const int kId = 1;
28const int kTypeLength = TRANSMISSION_TIME_OFFSET_LENGTH_IN_BYTES;
29const int kPayload = 100;
30const uint32_t kTimestamp = 10;
31const uint16_t kSeqNum = 33;
32const int kTimeOffset = 22222;
33const int kMaxPacketLength = 1500;
34}  // namespace
35
36class FakeClockTest : public Clock {
37 public:
38  FakeClockTest() {
39    time_in_ms_ = 123456;
40  }
41  // Return a timestamp in milliseconds relative to some arbitrary
42  // source; the source is fixed for this clock.
43  virtual WebRtc_Word64 TimeInMilliseconds() {
44    return time_in_ms_;
45  }
46
47  virtual WebRtc_Word64 TimeInMicroseconds() {
48    return time_in_ms_ * 1000;
49  }
50
51  // Retrieve an NTP absolute timestamp.
52  virtual void CurrentNtp(WebRtc_UWord32& secs, WebRtc_UWord32& frac) {
53    secs = time_in_ms_ / 1000;
54    frac = (time_in_ms_ % 1000) * 4294967;
55  }
56  void IncrementTime(WebRtc_UWord32 time_increment_ms) {
57    time_in_ms_ += time_increment_ms;
58  }
59 private:
60  WebRtc_Word64 time_in_ms_;
61};
62
63class LoopbackTransportTest : public webrtc::Transport {
64 public:
65  LoopbackTransportTest()
66    : packets_sent_(0),
67      last_sent_packet_len_(0) {
68  }
69  virtual int SendPacket(int channel, const void *data, int len) {
70    packets_sent_++;
71    memcpy(last_sent_packet_, data, len);
72    last_sent_packet_len_ = len;
73    return len;
74  }
75  virtual int SendRTCPPacket(int channel, const void *data, int len) {
76    return -1;
77  }
78  int packets_sent_;
79  int last_sent_packet_len_;
80  uint8_t last_sent_packet_[kMaxPacketLength];
81};
82
83class RtpSenderTest : public ::testing::Test {
84 protected:
85  RtpSenderTest()
86    : fake_clock_(),
87      rtp_sender_(new RTPSender(0, false, &fake_clock_, &transport_, NULL,
88                                NULL)),
89      kMarkerBit(true),
90      kType(kRtpExtensionTransmissionTimeOffset) {
91    rtp_sender_->SetSequenceNumber(kSeqNum);
92  }
93  FakeClockTest fake_clock_;
94  scoped_ptr<RTPSender> rtp_sender_;
95  LoopbackTransportTest transport_;
96  const bool kMarkerBit;
97  RTPExtensionType kType;
98  uint8_t packet_[kMaxPacketLength];
99
100  void VerifyRTPHeaderCommon(const WebRtcRTPHeader& rtp_header) {
101    EXPECT_EQ(kMarkerBit, rtp_header.header.markerBit);
102    EXPECT_EQ(kPayload, rtp_header.header.payloadType);
103    EXPECT_EQ(kSeqNum, rtp_header.header.sequenceNumber);
104    EXPECT_EQ(kTimestamp, rtp_header.header.timestamp);
105    EXPECT_EQ(rtp_sender_->SSRC(), rtp_header.header.ssrc);
106    EXPECT_EQ(0, rtp_header.header.numCSRCs);
107    EXPECT_EQ(0, rtp_header.header.paddingLength);
108  }
109};
110
111TEST_F(RtpSenderTest, RegisterRtpHeaderExtension) {
112  EXPECT_EQ(0, rtp_sender_->RtpHeaderExtensionTotalLength());
113  EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(kType, kId));
114  EXPECT_EQ(RTP_ONE_BYTE_HEADER_LENGTH_IN_BYTES + kTypeLength,
115            rtp_sender_->RtpHeaderExtensionTotalLength());
116  EXPECT_EQ(0, rtp_sender_->DeregisterRtpHeaderExtension(kType));
117  EXPECT_EQ(0, rtp_sender_->RtpHeaderExtensionTotalLength());
118}
119
120TEST_F(RtpSenderTest, BuildRTPPacket) {
121  WebRtc_Word32 length = rtp_sender_->BuildRTPheader(packet_,
122                                                     kPayload,
123                                                     kMarkerBit,
124                                                     kTimestamp);
125  EXPECT_EQ(12, length);
126
127  // Verify
128  webrtc::ModuleRTPUtility::RTPHeaderParser rtp_parser(packet_, length);
129  webrtc::WebRtcRTPHeader rtp_header;
130
131  RtpHeaderExtensionMap map;
132  map.Register(kType, kId);
133  const bool valid_rtp_header = rtp_parser.Parse(rtp_header, &map);
134
135  ASSERT_TRUE(valid_rtp_header);
136  ASSERT_FALSE(rtp_parser.RTCP());
137  VerifyRTPHeaderCommon(rtp_header);
138  EXPECT_EQ(length, rtp_header.header.headerLength);
139  EXPECT_EQ(0, rtp_header.extension.transmissionTimeOffset);
140}
141
142TEST_F(RtpSenderTest, BuildRTPPacketWithTransmissionOffsetExtension) {
143  EXPECT_EQ(0, rtp_sender_->SetTransmissionTimeOffset(kTimeOffset));
144  EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(kType, kId));
145
146  WebRtc_Word32 length = rtp_sender_->BuildRTPheader(packet_,
147                                                     kPayload,
148                                                     kMarkerBit,
149                                                     kTimestamp);
150  EXPECT_EQ(12 + rtp_sender_->RtpHeaderExtensionTotalLength(), length);
151
152  // Verify
153  webrtc::ModuleRTPUtility::RTPHeaderParser rtp_parser(packet_, length);
154  webrtc::WebRtcRTPHeader rtp_header;
155
156  RtpHeaderExtensionMap map;
157  map.Register(kType, kId);
158  const bool valid_rtp_header = rtp_parser.Parse(rtp_header, &map);
159
160  ASSERT_TRUE(valid_rtp_header);
161  ASSERT_FALSE(rtp_parser.RTCP());
162  VerifyRTPHeaderCommon(rtp_header);
163  EXPECT_EQ(length, rtp_header.header.headerLength);
164  EXPECT_EQ(kTimeOffset, rtp_header.extension.transmissionTimeOffset);
165
166  // Parse without map extension
167  webrtc::WebRtcRTPHeader rtp_header2;
168  const bool valid_rtp_header2 = rtp_parser.Parse(rtp_header2, NULL);
169
170  ASSERT_TRUE(valid_rtp_header2);
171  VerifyRTPHeaderCommon(rtp_header2);
172  EXPECT_EQ(length, rtp_header2.header.headerLength);
173  EXPECT_EQ(0, rtp_header2.extension.transmissionTimeOffset);
174}
175
176TEST_F(RtpSenderTest, BuildRTPPacketWithNegativeTransmissionOffsetExtension) {
177  const int kNegTimeOffset = -500;
178  EXPECT_EQ(0, rtp_sender_->SetTransmissionTimeOffset(kNegTimeOffset));
179  EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(kType, kId));
180
181  WebRtc_Word32 length = rtp_sender_->BuildRTPheader(packet_,
182                                                     kPayload,
183                                                     kMarkerBit,
184                                                     kTimestamp);
185  EXPECT_EQ(12 + rtp_sender_->RtpHeaderExtensionTotalLength(), length);
186
187  // Verify
188  webrtc::ModuleRTPUtility::RTPHeaderParser rtp_parser(packet_, length);
189  webrtc::WebRtcRTPHeader rtp_header;
190
191  RtpHeaderExtensionMap map;
192  map.Register(kType, kId);
193  const bool valid_rtp_header = rtp_parser.Parse(rtp_header, &map);
194
195  ASSERT_TRUE(valid_rtp_header);
196  ASSERT_FALSE(rtp_parser.RTCP());
197  VerifyRTPHeaderCommon(rtp_header);
198  EXPECT_EQ(length, rtp_header.header.headerLength);
199  EXPECT_EQ(kNegTimeOffset, rtp_header.extension.transmissionTimeOffset);
200}
201
202TEST_F(RtpSenderTest, NoTrafficSmoothing) {
203  WebRtc_Word32 rtp_length = rtp_sender_->BuildRTPheader(packet_,
204                                                         kPayload,
205                                                         kMarkerBit,
206                                                         kTimestamp);
207
208  // Packet should be sent immediately.
209  EXPECT_EQ(0, rtp_sender_->SendToNetwork(packet_,
210                                          0,
211                                          rtp_length,
212                                          kTimestamp / 90,
213                                          kAllowRetransmission));
214  EXPECT_EQ(1, transport_.packets_sent_);
215  EXPECT_EQ(rtp_length, transport_.last_sent_packet_len_);
216}
217
218TEST_F(RtpSenderTest, DISABLED_TrafficSmoothing) {
219  // TODO(pwestin) we need to send in a pacer object.
220  rtp_sender_->SetStorePacketsStatus(true, 10);
221  EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(kType, kId));
222  rtp_sender_->SetTargetSendBitrate(300000);
223  WebRtc_Word32 rtp_length = rtp_sender_->BuildRTPheader(packet_,
224                                                         kPayload,
225                                                         kMarkerBit,
226                                                         kTimestamp);
227  // Packet should be stored in a send bucket.
228  EXPECT_EQ(0, rtp_sender_->SendToNetwork(packet_,
229                                          0,
230                                          rtp_length,
231                                          fake_clock_.TimeInMilliseconds(),
232                                          kAllowRetransmission));
233  EXPECT_EQ(0, transport_.packets_sent_);
234  const int kStoredTimeInMs = 100;
235  fake_clock_.IncrementTime(kStoredTimeInMs);
236  // Process send bucket. Packet should now be sent.
237  EXPECT_EQ(1, transport_.packets_sent_);
238  EXPECT_EQ(rtp_length, transport_.last_sent_packet_len_);
239  // Parse sent packet.
240  webrtc::ModuleRTPUtility::RTPHeaderParser rtp_parser(
241      transport_.last_sent_packet_, rtp_length);
242  webrtc::WebRtcRTPHeader rtp_header;
243  RtpHeaderExtensionMap map;
244  map.Register(kType, kId);
245  const bool valid_rtp_header = rtp_parser.Parse(rtp_header, &map);
246  ASSERT_TRUE(valid_rtp_header);
247  // Verify transmission time offset.
248  EXPECT_EQ(kStoredTimeInMs * 90, rtp_header.extension.transmissionTimeOffset);
249}
250}  // namespace webrtc
251