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