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