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 #include <stdlib.h> 12 13 #include <algorithm> 14 #include <vector> 15 16 #include "testing/gtest/include/gtest/gtest.h" 17 #include "webrtc/common_types.h" 18 #include "webrtc/modules/rtp_rtcp/interface/rtp_payload_registry.h" 19 #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h" 20 #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp_defines.h" 21 #include "webrtc/modules/rtp_rtcp/source/rtp_receiver_video.h" 22 #include "webrtc/modules/rtp_rtcp/source/rtp_utility.h" 23 #include "webrtc/modules/rtp_rtcp/test/testAPI/test_api.h" 24 25 namespace webrtc { 26 27 class RtpRtcpVideoTest : public ::testing::Test { 28 protected: 29 RtpRtcpVideoTest() 30 : test_id_(123), 31 rtp_payload_registry_(RTPPayloadStrategy::CreateStrategy(false)), 32 test_ssrc_(3456), 33 test_timestamp_(4567), 34 test_sequence_number_(2345), 35 fake_clock(123456) { 36 } 37 ~RtpRtcpVideoTest() {} 38 39 virtual void SetUp() { 40 transport_ = new LoopBackTransport(); 41 receiver_ = new TestRtpReceiver(); 42 receive_statistics_.reset(ReceiveStatistics::Create(&fake_clock)); 43 RtpRtcp::Configuration configuration; 44 configuration.id = test_id_; 45 configuration.audio = false; 46 configuration.clock = &fake_clock; 47 configuration.outgoing_transport = transport_; 48 49 video_module_ = RtpRtcp::CreateRtpRtcp(configuration); 50 rtp_receiver_.reset(RtpReceiver::CreateVideoReceiver( 51 test_id_, &fake_clock, receiver_, NULL, &rtp_payload_registry_)); 52 53 EXPECT_EQ(0, video_module_->SetRTCPStatus(kRtcpCompound)); 54 video_module_->SetSSRC(test_ssrc_); 55 rtp_receiver_->SetNACKStatus(kNackRtcp); 56 EXPECT_EQ(0, video_module_->SetStorePacketsStatus(true, 600)); 57 EXPECT_EQ(0, video_module_->SetSendingStatus(true)); 58 59 transport_->SetSendModule(video_module_, &rtp_payload_registry_, 60 rtp_receiver_.get(), receive_statistics_.get()); 61 62 VideoCodec video_codec; 63 memset(&video_codec, 0, sizeof(video_codec)); 64 video_codec.plType = 123; 65 memcpy(video_codec.plName, "I420", 5); 66 67 EXPECT_EQ(0, video_module_->RegisterSendPayload(video_codec)); 68 EXPECT_EQ(0, rtp_receiver_->RegisterReceivePayload(video_codec.plName, 69 video_codec.plType, 70 90000, 71 0, 72 video_codec.maxBitrate)); 73 74 payload_data_length_ = sizeof(video_frame_); 75 76 for (int n = 0; n < payload_data_length_; n++) { 77 video_frame_[n] = n%10; 78 } 79 } 80 81 int32_t BuildRTPheader(uint8_t* dataBuffer, 82 uint32_t timestamp, 83 uint32_t sequence_number) { 84 dataBuffer[0] = static_cast<uint8_t>(0x80); // version 2 85 dataBuffer[1] = static_cast<uint8_t>(kPayloadType); 86 RtpUtility::AssignUWord16ToBuffer(dataBuffer + 2, sequence_number); 87 RtpUtility::AssignUWord32ToBuffer(dataBuffer + 4, timestamp); 88 RtpUtility::AssignUWord32ToBuffer(dataBuffer + 8, 0x1234); // SSRC. 89 int32_t rtpHeaderLength = 12; 90 return rtpHeaderLength; 91 } 92 93 int PaddingPacket(uint8_t* buffer, 94 uint32_t timestamp, 95 uint32_t sequence_number, 96 int32_t bytes) { 97 // Max in the RFC 3550 is 255 bytes, we limit it to be modulus 32 for SRTP. 98 int max_length = 224; 99 100 int padding_bytes_in_packet = max_length; 101 if (bytes < max_length) { 102 padding_bytes_in_packet = (bytes + 16) & 0xffe0; // Keep our modulus 32. 103 } 104 // Correct seq num, timestamp and payload type. 105 int header_length = BuildRTPheader(buffer, timestamp, 106 sequence_number); 107 buffer[0] |= 0x20; // Set padding bit. 108 int32_t* data = 109 reinterpret_cast<int32_t*>(&(buffer[header_length])); 110 111 // Fill data buffer with random data. 112 for (int j = 0; j < (padding_bytes_in_packet >> 2); j++) { 113 data[j] = rand(); // NOLINT 114 } 115 // Set number of padding bytes in the last byte of the packet. 116 buffer[header_length + padding_bytes_in_packet - 1] = 117 padding_bytes_in_packet; 118 return padding_bytes_in_packet + header_length; 119 } 120 121 virtual void TearDown() { 122 delete video_module_; 123 delete transport_; 124 delete receiver_; 125 } 126 127 int test_id_; 128 scoped_ptr<ReceiveStatistics> receive_statistics_; 129 RTPPayloadRegistry rtp_payload_registry_; 130 scoped_ptr<RtpReceiver> rtp_receiver_; 131 RtpRtcp* video_module_; 132 LoopBackTransport* transport_; 133 TestRtpReceiver* receiver_; 134 uint32_t test_ssrc_; 135 uint32_t test_timestamp_; 136 uint16_t test_sequence_number_; 137 uint8_t video_frame_[65000]; 138 int payload_data_length_; 139 SimulatedClock fake_clock; 140 enum { kPayloadType = 100 }; 141 }; 142 143 TEST_F(RtpRtcpVideoTest, BasicVideo) { 144 uint32_t timestamp = 3000; 145 EXPECT_EQ(0, video_module_->SendOutgoingData(kVideoFrameDelta, 123, 146 timestamp, 147 timestamp / 90, 148 video_frame_, 149 payload_data_length_)); 150 } 151 152 TEST_F(RtpRtcpVideoTest, PaddingOnlyFrames) { 153 const int kPadSize = 255; 154 uint8_t padding_packet[kPadSize]; 155 uint32_t seq_num = 0; 156 uint32_t timestamp = 3000; 157 VideoCodec codec; 158 codec.codecType = kVideoCodecVP8; 159 codec.plType = kPayloadType; 160 strncpy(codec.plName, "VP8", 4); 161 EXPECT_EQ(0, rtp_receiver_->RegisterReceivePayload(codec.plName, 162 codec.plType, 163 90000, 164 0, 165 codec.maxBitrate)); 166 for (int frame_idx = 0; frame_idx < 10; ++frame_idx) { 167 for (int packet_idx = 0; packet_idx < 5; ++packet_idx) { 168 int packet_size = PaddingPacket(padding_packet, timestamp, seq_num, 169 kPadSize); 170 ++seq_num; 171 RTPHeader header; 172 scoped_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create()); 173 EXPECT_TRUE(parser->Parse(padding_packet, packet_size, &header)); 174 PayloadUnion payload_specific; 175 EXPECT_TRUE(rtp_payload_registry_.GetPayloadSpecifics(header.payloadType, 176 &payload_specific)); 177 const uint8_t* payload = padding_packet + header.headerLength; 178 const int payload_length = packet_size - header.headerLength; 179 EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(header, payload, 180 payload_length, 181 payload_specific, true)); 182 EXPECT_EQ(0, receiver_->payload_size()); 183 EXPECT_EQ(payload_length, receiver_->rtp_header().header.paddingLength); 184 } 185 timestamp += 3000; 186 fake_clock.AdvanceTimeMilliseconds(33); 187 } 188 } 189 190 } // namespace webrtc 191