blob: 80ec4ce0754991c7c0ffe3eeaa053edeb435bd95 [file] [log] [blame]
andrew@webrtc.orgb015cbe2012-10-22 18:19:231/*
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
stefan@webrtc.orgcf4441c2012-12-03 14:01:4611#include <stdlib.h>
12
andrew@webrtc.orgb015cbe2012-10-22 18:19:2313#include <algorithm>
kwiberg6e27acd2016-04-27 08:19:5814#include <memory>
andrew@webrtc.orgb015cbe2012-10-22 18:19:2315#include <vector>
andrew@webrtc.orgb015cbe2012-10-22 18:19:2316
kwiberg15b966d2016-09-29 00:42:0117#include "webrtc/test/gtest.h"
Erik Språng00779972016-07-29 10:59:3618#include "webrtc/base/rate_limiter.h"
stefan@webrtc.orgcf4441c2012-12-03 14:01:4619#include "webrtc/common_types.h"
Henrik Kjellander36a14b52015-11-04 07:31:5220#include "webrtc/modules/rtp_rtcp/include/rtp_payload_registry.h"
21#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h"
22#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h"
sprang@webrtc.org1557a0b2015-03-17 16:42:4923#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
pbos@webrtc.orgd3756f72013-07-10 15:40:4224#include "webrtc/modules/rtp_rtcp/source/rtp_receiver_video.h"
stefan@webrtc.orgcf4441c2012-12-03 14:01:4625#include "webrtc/modules/rtp_rtcp/test/testAPI/test_api.h"
andrew@webrtc.orgb015cbe2012-10-22 18:19:2326
pkasting@chromium.orgbe487b42015-02-23 21:28:2227namespace {
28
29const unsigned char kPayloadType = 100;
30
31};
32
stefan@webrtc.orgcf4441c2012-12-03 14:01:4633namespace webrtc {
andrew@webrtc.orgb015cbe2012-10-22 18:19:2334
35class RtpRtcpVideoTest : public ::testing::Test {
36 protected:
stefan@webrtc.orgcf4441c2012-12-03 14:01:4637 RtpRtcpVideoTest()
Peter Boström00a7fa42015-09-17 21:03:5738 : rtp_payload_registry_(RTPPayloadStrategy::CreateStrategy(false)),
stefan@webrtc.orgcf4441c2012-12-03 14:01:4639 test_ssrc_(3456),
40 test_timestamp_(4567),
stefan@webrtc.org1bb21462013-01-21 07:42:1141 test_sequence_number_(2345),
Erik Språng00779972016-07-29 10:59:3642 fake_clock(123456),
43 retransmission_rate_limiter_(&fake_clock, 1000) {}
andrew@webrtc.orgb015cbe2012-10-22 18:19:2344 ~RtpRtcpVideoTest() {}
45
46 virtual void SetUp() {
stefan@webrtc.orgcf4441c2012-12-03 14:01:4647 transport_ = new LoopBackTransport();
wu@webrtc.org7fc75bb2013-08-15 23:38:5448 receiver_ = new TestRtpReceiver();
49 receive_statistics_.reset(ReceiveStatistics::Create(&fake_clock));
andrew@webrtc.orgb015cbe2012-10-22 18:19:2350 RtpRtcp::Configuration configuration;
andrew@webrtc.orgb015cbe2012-10-22 18:19:2351 configuration.audio = false;
52 configuration.clock = &fake_clock;
stefan@webrtc.orgcf4441c2012-12-03 14:01:4653 configuration.outgoing_transport = transport_;
Erik Språng00779972016-07-29 10:59:3654 configuration.retransmission_rate_limiter = &retransmission_rate_limiter_;
andrew@webrtc.orgb015cbe2012-10-22 18:19:2355
stefan@webrtc.orgcf4441c2012-12-03 14:01:4656 video_module_ = RtpRtcp::CreateRtpRtcp(configuration);
wu@webrtc.org7fc75bb2013-08-15 23:38:5457 rtp_receiver_.reset(RtpReceiver::CreateVideoReceiver(
Peter Boström00a7fa42015-09-17 21:03:5758 &fake_clock, receiver_, NULL, &rtp_payload_registry_));
andrew@webrtc.orgb015cbe2012-10-22 18:19:2359
pbosba01e952015-10-02 09:36:5660 video_module_->SetRTCPStatus(RtcpMode::kCompound);
stefan@webrtc.org903e7462014-06-05 08:25:2961 video_module_->SetSSRC(test_ssrc_);
pbos@webrtc.orgf377da92014-12-19 13:49:5562 video_module_->SetStorePacketsStatus(true, 600);
stefan@webrtc.orgcf4441c2012-12-03 14:01:4663 EXPECT_EQ(0, video_module_->SetSendingStatus(true));
andrew@webrtc.orgb015cbe2012-10-22 18:19:2364
wu@webrtc.org7fc75bb2013-08-15 23:38:5465 transport_->SetSendModule(video_module_, &rtp_payload_registry_,
66 rtp_receiver_.get(), receive_statistics_.get());
andrew@webrtc.orgb015cbe2012-10-22 18:19:2367
68 VideoCodec video_codec;
69 memset(&video_codec, 0, sizeof(video_codec));
70 video_codec.plType = 123;
71 memcpy(video_codec.plName, "I420", 5);
72
stefan@webrtc.orgcf4441c2012-12-03 14:01:4673 EXPECT_EQ(0, video_module_->RegisterSendPayload(video_codec));
wu@webrtc.org7fc75bb2013-08-15 23:38:5474 EXPECT_EQ(0, rtp_receiver_->RegisterReceivePayload(video_codec.plName,
75 video_codec.plType,
76 90000,
77 0,
78 video_codec.maxBitrate));
andrew@webrtc.orgb015cbe2012-10-22 18:19:2379
stefan@webrtc.orgcf4441c2012-12-03 14:01:4680 payload_data_length_ = sizeof(video_frame_);
andrew@webrtc.orgb015cbe2012-10-22 18:19:2381
pkasting@chromium.org0ab923a2014-11-20 22:28:1482 for (size_t n = 0; n < payload_data_length_; n++) {
stefan@webrtc.orgcf4441c2012-12-03 14:01:4683 video_frame_[n] = n%10;
andrew@webrtc.orgb015cbe2012-10-22 18:19:2384 }
85 }
86
pkasting@chromium.org0ab923a2014-11-20 22:28:1487 size_t BuildRTPheader(uint8_t* dataBuffer,
88 uint32_t timestamp,
89 uint32_t sequence_number) {
pbos@webrtc.orgb57da652013-04-08 11:08:4190 dataBuffer[0] = static_cast<uint8_t>(0x80); // version 2
91 dataBuffer[1] = static_cast<uint8_t>(kPayloadType);
sprang@webrtc.org1557a0b2015-03-17 16:42:4992 ByteWriter<uint16_t>::WriteBigEndian(dataBuffer + 2, sequence_number);
93 ByteWriter<uint32_t>::WriteBigEndian(dataBuffer + 4, timestamp);
94 ByteWriter<uint32_t>::WriteBigEndian(dataBuffer + 8, 0x1234); // SSRC.
pkasting@chromium.org0ab923a2014-11-20 22:28:1495 size_t rtpHeaderLength = 12;
stefan@webrtc.orgcf4441c2012-12-03 14:01:4696 return rtpHeaderLength;
andrew@webrtc.orgb015cbe2012-10-22 18:19:2397 }
98
pkasting@chromium.org0ab923a2014-11-20 22:28:1499 size_t PaddingPacket(uint8_t* buffer,
100 uint32_t timestamp,
101 uint32_t sequence_number,
102 size_t bytes) {
stefan@webrtc.orgcf4441c2012-12-03 14:01:46103 // Max in the RFC 3550 is 255 bytes, we limit it to be modulus 32 for SRTP.
pkasting@chromium.org0ab923a2014-11-20 22:28:14104 size_t max_length = 224;
stefan@webrtc.orgcf4441c2012-12-03 14:01:46105
pkasting@chromium.org0ab923a2014-11-20 22:28:14106 size_t padding_bytes_in_packet = max_length;
stefan@webrtc.orgcf4441c2012-12-03 14:01:46107 if (bytes < max_length) {
108 padding_bytes_in_packet = (bytes + 16) & 0xffe0; // Keep our modulus 32.
109 }
110 // Correct seq num, timestamp and payload type.
pkasting@chromium.org0ab923a2014-11-20 22:28:14111 size_t header_length = BuildRTPheader(buffer, timestamp, sequence_number);
stefan@webrtc.orgcf4441c2012-12-03 14:01:46112 buffer[0] |= 0x20; // Set padding bit.
pbos@webrtc.orgb57da652013-04-08 11:08:41113 int32_t* data =
114 reinterpret_cast<int32_t*>(&(buffer[header_length]));
stefan@webrtc.orgcf4441c2012-12-03 14:01:46115
116 // Fill data buffer with random data.
pkasting@chromium.org0ab923a2014-11-20 22:28:14117 for (size_t j = 0; j < (padding_bytes_in_packet >> 2); j++) {
stefan@webrtc.orgcf4441c2012-12-03 14:01:46118 data[j] = rand(); // NOLINT
119 }
120 // Set number of padding bytes in the last byte of the packet.
121 buffer[header_length + padding_bytes_in_packet - 1] =
122 padding_bytes_in_packet;
123 return padding_bytes_in_packet + header_length;
124 }
125
126 virtual void TearDown() {
127 delete video_module_;
128 delete transport_;
129 delete receiver_;
130 }
131
132 int test_id_;
kwiberg6e27acd2016-04-27 08:19:58133 std::unique_ptr<ReceiveStatistics> receive_statistics_;
wu@webrtc.org7fc75bb2013-08-15 23:38:54134 RTPPayloadRegistry rtp_payload_registry_;
kwiberg6e27acd2016-04-27 08:19:58135 std::unique_ptr<RtpReceiver> rtp_receiver_;
stefan@webrtc.orgcf4441c2012-12-03 14:01:46136 RtpRtcp* video_module_;
137 LoopBackTransport* transport_;
wu@webrtc.org7fc75bb2013-08-15 23:38:54138 TestRtpReceiver* receiver_;
pbos@webrtc.orgb57da652013-04-08 11:08:41139 uint32_t test_ssrc_;
140 uint32_t test_timestamp_;
141 uint16_t test_sequence_number_;
142 uint8_t video_frame_[65000];
pkasting@chromium.org0ab923a2014-11-20 22:28:14143 size_t payload_data_length_;
stefan@webrtc.org1bb21462013-01-21 07:42:11144 SimulatedClock fake_clock;
Erik Språng00779972016-07-29 10:59:36145 RateLimiter retransmission_rate_limiter_;
andrew@webrtc.orgb015cbe2012-10-22 18:19:23146};
147
148TEST_F(RtpRtcpVideoTest, BasicVideo) {
pbos@webrtc.orgb57da652013-04-08 11:08:41149 uint32_t timestamp = 3000;
Sergey Ulanov83a148b2016-08-03 00:46:41150 EXPECT_TRUE(video_module_->SendOutgoingData(
151 kVideoFrameDelta, 123, timestamp, timestamp / 90, video_frame_,
152 payload_data_length_, nullptr, nullptr, nullptr));
andrew@webrtc.orgb015cbe2012-10-22 18:19:23153}
154
stefan@webrtc.orgcf4441c2012-12-03 14:01:46155TEST_F(RtpRtcpVideoTest, PaddingOnlyFrames) {
pkasting@chromium.org0ab923a2014-11-20 22:28:14156 const size_t kPadSize = 255;
stefan@webrtc.orgcf4441c2012-12-03 14:01:46157 uint8_t padding_packet[kPadSize];
158 uint32_t seq_num = 0;
159 uint32_t timestamp = 3000;
160 VideoCodec codec;
161 codec.codecType = kVideoCodecVP8;
162 codec.plType = kPayloadType;
163 strncpy(codec.plName, "VP8", 4);
wu@webrtc.org7fc75bb2013-08-15 23:38:54164 EXPECT_EQ(0, rtp_receiver_->RegisterReceivePayload(codec.plName,
165 codec.plType,
166 90000,
167 0,
168 codec.maxBitrate));
stefan@webrtc.orgcf4441c2012-12-03 14:01:46169 for (int frame_idx = 0; frame_idx < 10; ++frame_idx) {
170 for (int packet_idx = 0; packet_idx < 5; ++packet_idx) {
pkasting@chromium.org0ab923a2014-11-20 22:28:14171 size_t packet_size = PaddingPacket(padding_packet, timestamp, seq_num,
172 kPadSize);
stefan@webrtc.orgcf4441c2012-12-03 14:01:46173 ++seq_num;
stefan@webrtc.org6696fba2013-05-29 12:12:51174 RTPHeader header;
kwiberg6e27acd2016-04-27 08:19:58175 std::unique_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create());
stefan@webrtc.org6696fba2013-05-29 12:12:51176 EXPECT_TRUE(parser->Parse(padding_packet, packet_size, &header));
wu@webrtc.org7fc75bb2013-08-15 23:38:54177 PayloadUnion payload_specific;
178 EXPECT_TRUE(rtp_payload_registry_.GetPayloadSpecifics(header.payloadType,
pkasting@chromium.orgbe487b42015-02-23 21:28:22179 &payload_specific));
stefan@webrtc.orgdb74c612013-09-06 13:40:11180 const uint8_t* payload = padding_packet + header.headerLength;
pkasting@chromium.org0ab923a2014-11-20 22:28:14181 const size_t payload_length = packet_size - header.headerLength;
stefan@webrtc.orgdb74c612013-09-06 13:40:11182 EXPECT_TRUE(rtp_receiver_->IncomingRtpPacket(header, payload,
183 payload_length,
wu@webrtc.org7fc75bb2013-08-15 23:38:54184 payload_specific, true));
pkasting@chromium.org0ab923a2014-11-20 22:28:14185 EXPECT_EQ(0u, receiver_->payload_size());
stefan@webrtc.orgdb74c612013-09-06 13:40:11186 EXPECT_EQ(payload_length, receiver_->rtp_header().header.paddingLength);
stefan@webrtc.orgcf4441c2012-12-03 14:01:46187 }
188 timestamp += 3000;
stefan@webrtc.org1bb21462013-01-21 07:42:11189 fake_clock.AdvanceTimeMilliseconds(33);
stefan@webrtc.orgcf4441c2012-12-03 14:01:46190 }
191}
192
193} // namespace webrtc