rtp_sender_unittest.cc revision 8911ce46a4c76c09b8c58828532836c9cd95549d
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_format_video_generic.h"
19#include "webrtc/modules/rtp_rtcp/source/rtp_header_extension.h"
20#include "webrtc/modules/rtp_rtcp/source/rtp_sender.h"
21#include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
22#include "webrtc/system_wrappers/interface/scoped_ptr.h"
23#include "webrtc/typedefs.h"
24
25namespace webrtc {
26
27namespace {
28const int kId = 1;
29const int kTypeLength = TRANSMISSION_TIME_OFFSET_LENGTH_IN_BYTES;
30const int kPayload = 100;
31const uint32_t kTimestamp = 10;
32const uint16_t kSeqNum = 33;
33const int kTimeOffset = 22222;
34const int kMaxPacketLength = 1500;
35}  // namespace
36
37class LoopbackTransportTest : public webrtc::Transport {
38 public:
39  LoopbackTransportTest()
40    : packets_sent_(0),
41      last_sent_packet_len_(0) {
42  }
43  virtual int SendPacket(int channel, const void *data, int len) {
44    packets_sent_++;
45    memcpy(last_sent_packet_, data, len);
46    last_sent_packet_len_ = len;
47    return len;
48  }
49  virtual int SendRTCPPacket(int channel, const void *data, int len) {
50    return -1;
51  }
52  int packets_sent_;
53  int last_sent_packet_len_;
54  uint8_t last_sent_packet_[kMaxPacketLength];
55};
56
57class RtpSenderTest : public ::testing::Test {
58 protected:
59  RtpSenderTest()
60    : fake_clock_(123456),
61      rtp_sender_(new RTPSender(0, false, &fake_clock_, &transport_, NULL,
62                                NULL)),
63      kMarkerBit(true),
64      kType(kRtpExtensionTransmissionTimeOffset) {
65    rtp_sender_->SetSequenceNumber(kSeqNum);
66  }
67  SimulatedClock fake_clock_;
68  scoped_ptr<RTPSender> rtp_sender_;
69  LoopbackTransportTest transport_;
70  const bool kMarkerBit;
71  RTPExtensionType kType;
72  uint8_t packet_[kMaxPacketLength];
73
74  void VerifyRTPHeaderCommon(const WebRtcRTPHeader& rtp_header) {
75    EXPECT_EQ(kMarkerBit, rtp_header.header.markerBit);
76    EXPECT_EQ(kPayload, rtp_header.header.payloadType);
77    EXPECT_EQ(kSeqNum, rtp_header.header.sequenceNumber);
78    EXPECT_EQ(kTimestamp, rtp_header.header.timestamp);
79    EXPECT_EQ(rtp_sender_->SSRC(), rtp_header.header.ssrc);
80    EXPECT_EQ(0, rtp_header.header.numCSRCs);
81    EXPECT_EQ(0, rtp_header.header.paddingLength);
82  }
83};
84
85TEST_F(RtpSenderTest, RegisterRtpHeaderExtension) {
86  EXPECT_EQ(0, rtp_sender_->RtpHeaderExtensionTotalLength());
87  EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(kType, kId));
88  EXPECT_EQ(RTP_ONE_BYTE_HEADER_LENGTH_IN_BYTES + kTypeLength,
89            rtp_sender_->RtpHeaderExtensionTotalLength());
90  EXPECT_EQ(0, rtp_sender_->DeregisterRtpHeaderExtension(kType));
91  EXPECT_EQ(0, rtp_sender_->RtpHeaderExtensionTotalLength());
92}
93
94TEST_F(RtpSenderTest, BuildRTPPacket) {
95  WebRtc_Word32 length = rtp_sender_->BuildRTPheader(packet_,
96                                                     kPayload,
97                                                     kMarkerBit,
98                                                     kTimestamp);
99  EXPECT_EQ(12, length);
100
101  // Verify
102  webrtc::ModuleRTPUtility::RTPHeaderParser rtp_parser(packet_, length);
103  webrtc::WebRtcRTPHeader rtp_header;
104
105  RtpHeaderExtensionMap map;
106  map.Register(kType, kId);
107  const bool valid_rtp_header = rtp_parser.Parse(rtp_header, &map);
108
109  ASSERT_TRUE(valid_rtp_header);
110  ASSERT_FALSE(rtp_parser.RTCP());
111  VerifyRTPHeaderCommon(rtp_header);
112  EXPECT_EQ(length, rtp_header.header.headerLength);
113  EXPECT_EQ(0, rtp_header.extension.transmissionTimeOffset);
114}
115
116TEST_F(RtpSenderTest, BuildRTPPacketWithTransmissionOffsetExtension) {
117  EXPECT_EQ(0, rtp_sender_->SetTransmissionTimeOffset(kTimeOffset));
118  EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(kType, kId));
119
120  WebRtc_Word32 length = rtp_sender_->BuildRTPheader(packet_,
121                                                     kPayload,
122                                                     kMarkerBit,
123                                                     kTimestamp);
124  EXPECT_EQ(12 + rtp_sender_->RtpHeaderExtensionTotalLength(), length);
125
126  // Verify
127  webrtc::ModuleRTPUtility::RTPHeaderParser rtp_parser(packet_, length);
128  webrtc::WebRtcRTPHeader rtp_header;
129
130  RtpHeaderExtensionMap map;
131  map.Register(kType, kId);
132  const bool valid_rtp_header = rtp_parser.Parse(rtp_header, &map);
133
134  ASSERT_TRUE(valid_rtp_header);
135  ASSERT_FALSE(rtp_parser.RTCP());
136  VerifyRTPHeaderCommon(rtp_header);
137  EXPECT_EQ(length, rtp_header.header.headerLength);
138  EXPECT_EQ(kTimeOffset, rtp_header.extension.transmissionTimeOffset);
139
140  // Parse without map extension
141  webrtc::WebRtcRTPHeader rtp_header2;
142  const bool valid_rtp_header2 = rtp_parser.Parse(rtp_header2, NULL);
143
144  ASSERT_TRUE(valid_rtp_header2);
145  VerifyRTPHeaderCommon(rtp_header2);
146  EXPECT_EQ(length, rtp_header2.header.headerLength);
147  EXPECT_EQ(0, rtp_header2.extension.transmissionTimeOffset);
148}
149
150TEST_F(RtpSenderTest, BuildRTPPacketWithNegativeTransmissionOffsetExtension) {
151  const int kNegTimeOffset = -500;
152  EXPECT_EQ(0, rtp_sender_->SetTransmissionTimeOffset(kNegTimeOffset));
153  EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(kType, kId));
154
155  WebRtc_Word32 length = rtp_sender_->BuildRTPheader(packet_,
156                                                     kPayload,
157                                                     kMarkerBit,
158                                                     kTimestamp);
159  EXPECT_EQ(12 + rtp_sender_->RtpHeaderExtensionTotalLength(), length);
160
161  // Verify
162  webrtc::ModuleRTPUtility::RTPHeaderParser rtp_parser(packet_, length);
163  webrtc::WebRtcRTPHeader rtp_header;
164
165  RtpHeaderExtensionMap map;
166  map.Register(kType, kId);
167  const bool valid_rtp_header = rtp_parser.Parse(rtp_header, &map);
168
169  ASSERT_TRUE(valid_rtp_header);
170  ASSERT_FALSE(rtp_parser.RTCP());
171  VerifyRTPHeaderCommon(rtp_header);
172  EXPECT_EQ(length, rtp_header.header.headerLength);
173  EXPECT_EQ(kNegTimeOffset, rtp_header.extension.transmissionTimeOffset);
174}
175
176TEST_F(RtpSenderTest, NoTrafficSmoothing) {
177  WebRtc_Word32 rtp_length = rtp_sender_->BuildRTPheader(packet_,
178                                                         kPayload,
179                                                         kMarkerBit,
180                                                         kTimestamp);
181
182  // Packet should be sent immediately.
183  EXPECT_EQ(0, rtp_sender_->SendToNetwork(packet_,
184                                          0,
185                                          rtp_length,
186                                          kTimestamp / 90,
187                                          kAllowRetransmission));
188  EXPECT_EQ(1, transport_.packets_sent_);
189  EXPECT_EQ(rtp_length, transport_.last_sent_packet_len_);
190}
191
192TEST_F(RtpSenderTest, DISABLED_TrafficSmoothing) {
193  // TODO(pwestin) we need to send in a pacer object.
194  rtp_sender_->SetStorePacketsStatus(true, 10);
195  EXPECT_EQ(0, rtp_sender_->RegisterRtpHeaderExtension(kType, kId));
196  rtp_sender_->SetTargetSendBitrate(300000);
197  WebRtc_Word32 rtp_length = rtp_sender_->BuildRTPheader(packet_,
198                                                         kPayload,
199                                                         kMarkerBit,
200                                                         kTimestamp);
201  // Packet should be stored in a send bucket.
202  EXPECT_EQ(0, rtp_sender_->SendToNetwork(packet_,
203                                          0,
204                                          rtp_length,
205                                          fake_clock_.TimeInMilliseconds(),
206                                          kAllowRetransmission));
207  EXPECT_EQ(0, transport_.packets_sent_);
208  const int kStoredTimeInMs = 100;
209  fake_clock_.AdvanceTimeMilliseconds(kStoredTimeInMs);
210  // Process send bucket. Packet should now be sent.
211  EXPECT_EQ(1, transport_.packets_sent_);
212  EXPECT_EQ(rtp_length, transport_.last_sent_packet_len_);
213  // Parse sent packet.
214  webrtc::ModuleRTPUtility::RTPHeaderParser rtp_parser(
215      transport_.last_sent_packet_, rtp_length);
216  webrtc::WebRtcRTPHeader rtp_header;
217  RtpHeaderExtensionMap map;
218  map.Register(kType, kId);
219  const bool valid_rtp_header = rtp_parser.Parse(rtp_header, &map);
220  ASSERT_TRUE(valid_rtp_header);
221  // Verify transmission time offset.
222  EXPECT_EQ(kStoredTimeInMs * 90, rtp_header.extension.transmissionTimeOffset);
223}
224
225TEST_F(RtpSenderTest, SendGenericVideo) {
226  char payload_name[RTP_PAYLOAD_NAME_SIZE] = "GENERIC";
227  const uint8_t payload_type = 127;
228  ASSERT_EQ(0, rtp_sender_->RegisterPayload(payload_name, payload_type, 90000,
229                                            0, 1500));
230  uint8_t payload[] = {47, 11, 32, 93, 89};
231
232  // Send keyframe
233  ASSERT_EQ(0, rtp_sender_->SendOutgoingData(kVideoFrameKey, payload_type, 1234,
234                                             4321, payload, sizeof(payload),
235                                             NULL));
236
237  ModuleRTPUtility::RTPHeaderParser rtp_parser(transport_.last_sent_packet_,
238      transport_.last_sent_packet_len_);
239  webrtc::WebRtcRTPHeader rtp_header;
240  ASSERT_TRUE(rtp_parser.Parse(rtp_header));
241
242  const uint8_t* payload_data = ModuleRTPUtility::GetPayloadData(&rtp_header,
243      transport_.last_sent_packet_);
244  uint8_t generic_header = *payload_data++;
245
246  ASSERT_EQ(sizeof(payload) + sizeof(generic_header),
247            ModuleRTPUtility::GetPayloadDataLength(&rtp_header,
248            transport_.last_sent_packet_len_));
249
250  EXPECT_TRUE(generic_header & RtpFormatVideoGeneric::kKeyFrameBit);
251  EXPECT_TRUE(generic_header & RtpFormatVideoGeneric::kFirstPacketBit);
252
253  EXPECT_EQ(0, memcmp(payload, payload_data, sizeof(payload)));
254
255  // Send delta frame
256  payload[0] = 13;
257  payload[1] = 42;
258  payload[4] = 13;
259
260  ASSERT_EQ(0, rtp_sender_->SendOutgoingData(kVideoFrameDelta, payload_type,
261                                             1234, 4321, payload,
262                                             sizeof(payload), NULL));
263
264  ModuleRTPUtility::RTPHeaderParser rtp_parser2(transport_.last_sent_packet_,
265      transport_.last_sent_packet_len_);
266  ASSERT_TRUE(rtp_parser.Parse(rtp_header));
267
268  payload_data = ModuleRTPUtility::GetPayloadData(&rtp_header,
269      transport_.last_sent_packet_);
270  generic_header = *payload_data++;
271
272  EXPECT_FALSE(generic_header & RtpFormatVideoGeneric::kKeyFrameBit);
273  EXPECT_TRUE(generic_header & RtpFormatVideoGeneric::kFirstPacketBit);
274
275  ASSERT_EQ(sizeof(payload) + sizeof(generic_header),
276            ModuleRTPUtility::GetPayloadDataLength(&rtp_header,
277      transport_.last_sent_packet_len_));
278
279  EXPECT_EQ(0, memcmp(payload, payload_data, sizeof(payload)));
280}
281
282}  // namespace webrtc
283
284