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