• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
RtpRtcpVideoTest()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) {}
~RtpRtcpVideoTest()41   ~RtpRtcpVideoTest() {}
42 
SetUp()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 
BuildRTPheader(uint8_t * dataBuffer,uint32_t timestamp,uint32_t sequence_number)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 
PaddingPacket(uint8_t * buffer,uint32_t timestamp,uint32_t sequence_number,size_t bytes)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 
TearDown()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 
TEST_F(RtpRtcpVideoTest,BasicVideo)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 
TEST_F(RtpRtcpVideoTest,PaddingOnlyFrames)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