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 ModuleRTPUtility::AssignUWord16ToBuffer(dataBuffer + 2, 87 sequence_number); 88 ModuleRTPUtility::AssignUWord32ToBuffer(dataBuffer + 4, timestamp); 89 ModuleRTPUtility::AssignUWord32ToBuffer(dataBuffer + 8, 90 0x1234); // SSRC. 91 int32_t rtpHeaderLength = 12; 92 return rtpHeaderLength; 93 } 94 95 int PaddingPacket(uint8_t* buffer, 96 uint32_t timestamp, 97 uint32_t sequence_number, 98 int32_t bytes) { 99 // Max in the RFC 3550 is 255 bytes, we limit it to be modulus 32 for SRTP. 100 int max_length = 224; 101 102 int padding_bytes_in_packet = max_length; 103 if (bytes < max_length) { 104 padding_bytes_in_packet = (bytes + 16) & 0xffe0; // Keep our modulus 32. 105 } 106 // Correct seq num, timestamp and payload type. 107 int header_length = BuildRTPheader(buffer, timestamp, 108 sequence_number); 109 buffer[0] |= 0x20; // Set padding bit. 110 int32_t* data = 111 reinterpret_cast<int32_t*>(&(buffer[header_length])); 112 113 // Fill data buffer with random data. 114 for (int j = 0; j < (padding_bytes_in_packet >> 2); j++) { 115 data[j] = rand(); // NOLINT 116 } 117 // Set number of padding bytes in the last byte of the packet. 118 buffer[header_length + padding_bytes_in_packet - 1] = 119 padding_bytes_in_packet; 120 return padding_bytes_in_packet + header_length; 121 } 122 123 virtual void TearDown() { 124 delete video_module_; 125 delete transport_; 126 delete receiver_; 127 } 128 129 int test_id_; 130 scoped_ptr<ReceiveStatistics> receive_statistics_; 131 RTPPayloadRegistry rtp_payload_registry_; 132 scoped_ptr<RtpReceiver> rtp_receiver_; 133 RtpRtcp* video_module_; 134 LoopBackTransport* transport_; 135 TestRtpReceiver* receiver_; 136 uint32_t test_ssrc_; 137 uint32_t test_timestamp_; 138 uint16_t test_sequence_number_; 139 uint8_t video_frame_[65000]; 140 int payload_data_length_; 141 SimulatedClock fake_clock; 142 enum { kPayloadType = 100 }; 143 }; 144 145 TEST_F(RtpRtcpVideoTest, BasicVideo) { 146 uint32_t timestamp = 3000; 147 EXPECT_EQ(0, video_module_->SendOutgoingData(kVideoFrameDelta, 123, 148 timestamp, 149 timestamp / 90, 150 video_frame_, 151 payload_data_length_)); 152 } 153 154 TEST_F(RtpRtcpVideoTest, PaddingOnlyFrames) { 155 const int kPadSize = 255; 156 uint8_t padding_packet[kPadSize]; 157 uint32_t seq_num = 0; 158 uint32_t timestamp = 3000; 159 VideoCodec codec; 160 codec.codecType = kVideoCodecVP8; 161 codec.plType = kPayloadType; 162 strncpy(codec.plName, "VP8", 4); 163 EXPECT_EQ(0, rtp_receiver_->RegisterReceivePayload(codec.plName, 164 codec.plType, 165 90000, 166 0, 167 codec.maxBitrate)); 168 for (int frame_idx = 0; frame_idx < 10; ++frame_idx) { 169 for (int packet_idx = 0; packet_idx < 5; ++packet_idx) { 170 int packet_size = PaddingPacket(padding_packet, timestamp, seq_num, 171 kPadSize); 172 ++seq_num; 173 RTPHeader header; 174 scoped_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create()); 175 EXPECT_TRUE(parser->Parse(padding_packet, packet_size, &header)); 176 PayloadUnion payload_specific; 177 EXPECT_TRUE(rtp_payload_registry_.GetPayloadSpecifics(header.payloadType, 178 &payload_specific)); 179 const uint8_t* payload = padding_packet + header.headerLength; 180 const int payload_length = packet_size - header.headerLength; 181 EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(header, payload, 182 payload_length, 183 payload_specific, true)); 184 EXPECT_EQ(0, receiver_->payload_size()); 185 EXPECT_EQ(payload_length, receiver_->rtp_header().header.paddingLength); 186 } 187 timestamp += 3000; 188 fake_clock.AdvanceTimeMilliseconds(33); 189 } 190 } 191 192 } // namespace webrtc 193