blob: 1753b43538c373d2be73e640af6749bc99291be2 [file] [log] [blame]
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +00001/*
2 * Copyright (c) 2013 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#include "testing/gtest/include/gtest/gtest.h"
11#include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +000012#include "webrtc/modules/rtp_rtcp/source/rtcp_sender.h"
pbos@webrtc.org013d9942013-08-22 09:42:17 +000013#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +000014#include "webrtc/system_wrappers/interface/event_wrapper.h"
15#include "webrtc/system_wrappers/interface/scoped_ptr.h"
pbos@webrtc.org29023282013-09-11 10:14:56 +000016#include "webrtc/system_wrappers/interface/sleep.h"
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +000017#include "webrtc/system_wrappers/interface/thread_wrapper.h"
pbos@webrtc.orgcb5118c2013-09-03 09:10:37 +000018#include "webrtc/video_engine/test/common/fake_encoder.h"
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +000019#include "webrtc/video_engine/test/common/frame_generator.h"
20#include "webrtc/video_engine/test/common/frame_generator_capturer.h"
21#include "webrtc/video_engine/test/common/null_transport.h"
pbos@webrtc.org841c8a42013-09-09 15:04:25 +000022#include "webrtc/video_engine/new_include/call.h"
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +000023#include "webrtc/video_engine/new_include/video_send_stream.h"
24
25namespace webrtc {
26
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +000027class SendTransportObserver : public test::NullTransport {
28 public:
29 explicit SendTransportObserver(unsigned long timeout_ms)
30 : rtp_header_parser_(RtpHeaderParser::Create()),
31 send_test_complete_(EventWrapper::Create()),
32 timeout_ms_(timeout_ms) {}
33
pbos@webrtc.org841c8a42013-09-09 15:04:25 +000034 EventTypeWrapper Wait() { return send_test_complete_->Wait(timeout_ms_); }
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +000035
36 protected:
37 scoped_ptr<RtpHeaderParser> rtp_header_parser_;
38 scoped_ptr<EventWrapper> send_test_complete_;
39
40 private:
41 unsigned long timeout_ms_;
42};
43
pbos@webrtc.org013d9942013-08-22 09:42:17 +000044class VideoSendStreamTest : public ::testing::Test {
pbos@webrtc.orgcb5118c2013-09-03 09:10:37 +000045 public:
46 VideoSendStreamTest() : fake_encoder_(Clock::GetRealTimeClock()) {}
pbos@webrtc.org841c8a42013-09-09 15:04:25 +000047
pbos@webrtc.org013d9942013-08-22 09:42:17 +000048 protected:
49 static const uint32_t kSendSsrc;
pbos@webrtc.org841c8a42013-09-09 15:04:25 +000050 void RunSendTest(Call* call,
pbos@webrtc.org74fa4892013-08-23 09:19:30 +000051 const VideoSendStream::Config& config,
pbos@webrtc.org013d9942013-08-22 09:42:17 +000052 SendTransportObserver* observer) {
pbos@webrtc.org74fa4892013-08-23 09:19:30 +000053 VideoSendStream* send_stream = call->CreateSendStream(config);
pbos@webrtc.org013d9942013-08-22 09:42:17 +000054 scoped_ptr<test::FrameGeneratorCapturer> frame_generator_capturer(
55 test::FrameGeneratorCapturer::Create(
56 send_stream->Input(),
57 test::FrameGenerator::Create(320, 240, Clock::GetRealTimeClock()),
58 30));
59 send_stream->StartSend();
60 frame_generator_capturer->Start();
61
62 EXPECT_EQ(kEventSignaled, observer->Wait());
63
64 frame_generator_capturer->Stop();
65 send_stream->StopSend();
66 call->DestroySendStream(send_stream);
67 }
pbos@webrtc.orgcb5118c2013-09-03 09:10:37 +000068
pbos@webrtc.org841c8a42013-09-09 15:04:25 +000069 VideoSendStream::Config GetSendTestConfig(Call* call) {
pbos@webrtc.orgcb5118c2013-09-03 09:10:37 +000070 VideoSendStream::Config config = call->GetDefaultSendConfig();
71 config.encoder = &fake_encoder_;
72 config.internal_source = false;
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +000073 config.rtp.ssrcs.push_back(kSendSsrc);
pbos@webrtc.org0181b5f2013-09-09 08:26:30 +000074 test::FakeEncoder::SetCodecSettings(&config.codec, 1);
pbos@webrtc.orgcb5118c2013-09-03 09:10:37 +000075 return config;
76 }
77
78 test::FakeEncoder fake_encoder_;
pbos@webrtc.org013d9942013-08-22 09:42:17 +000079};
80
81const uint32_t VideoSendStreamTest::kSendSsrc = 0xC0FFEE;
82
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +000083TEST_F(VideoSendStreamTest, SendsSetSsrc) {
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +000084 class SendSsrcObserver : public SendTransportObserver {
85 public:
86 SendSsrcObserver() : SendTransportObserver(30 * 1000) {}
87
88 virtual bool SendRTP(const uint8_t* packet, size_t length) OVERRIDE {
89 RTPHeader header;
90 EXPECT_TRUE(
91 rtp_header_parser_->Parse(packet, static_cast<int>(length), &header));
92
93 if (header.ssrc == kSendSsrc)
94 send_test_complete_->Set();
95
96 return true;
97 }
98 } observer;
99
pbos@webrtc.org841c8a42013-09-09 15:04:25 +0000100 Call::Config call_config(&observer);
101 scoped_ptr<Call> call(Call::Create(call_config));
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +0000102
pbos@webrtc.orgcb5118c2013-09-03 09:10:37 +0000103 VideoSendStream::Config send_config = GetSendTestConfig(call.get());
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +0000104
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000105 RunSendTest(call.get(), send_config, &observer);
106}
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +0000107
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000108TEST_F(VideoSendStreamTest, SupportsCName) {
109 static std::string kCName = "PjQatC14dGfbVwGPUOA9IH7RlsFDbWl4AhXEiDsBizo=";
110 class CNameObserver : public SendTransportObserver {
111 public:
112 CNameObserver() : SendTransportObserver(30 * 1000) {}
113
114 virtual bool SendRTCP(const uint8_t* packet, size_t length) OVERRIDE {
115 RTCPUtility::RTCPParserV2 parser(packet, length, true);
116 EXPECT_TRUE(parser.IsValid());
117
118 RTCPUtility::RTCPPacketTypes packet_type = parser.Begin();
119 while (packet_type != RTCPUtility::kRtcpNotValidCode) {
120 if (packet_type == RTCPUtility::kRtcpSdesChunkCode) {
121 EXPECT_EQ(parser.Packet().CName.CName, kCName);
122 send_test_complete_->Set();
123 }
124
125 packet_type = parser.Iterate();
126 }
127
128 return true;
129 }
130 } observer;
131
pbos@webrtc.org841c8a42013-09-09 15:04:25 +0000132 Call::Config call_config(&observer);
133 scoped_ptr<Call> call(Call::Create(call_config));
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000134
pbos@webrtc.orgcb5118c2013-09-03 09:10:37 +0000135 VideoSendStream::Config send_config = GetSendTestConfig(call.get());
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000136 send_config.rtp.c_name = kCName;
137
138 RunSendTest(call.get(), send_config, &observer);
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +0000139}
140
pbos@webrtc.org5c678ea2013-09-11 19:00:39 +0000141TEST_F(VideoSendStreamTest, SupportsAbsoluteSendTime) {
142 static const uint8_t kAbsSendTimeExtensionId = 13;
143 class AbsoluteSendTimeObserver : public SendTransportObserver {
144 public:
145 AbsoluteSendTimeObserver() : SendTransportObserver(30 * 1000) {
146 EXPECT_TRUE(rtp_header_parser_->RegisterRtpHeaderExtension(
147 kRtpExtensionAbsoluteSendTime, kAbsSendTimeExtensionId));
148 }
149
150 virtual bool SendRTP(const uint8_t* packet, size_t length) OVERRIDE {
151 RTPHeader header;
152 EXPECT_TRUE(
153 rtp_header_parser_->Parse(packet, static_cast<int>(length), &header));
154
155 if (header.extension.absoluteSendTime > 0)
156 send_test_complete_->Set();
157
158 return true;
159 }
160 } observer;
161
162 Call::Config call_config(&observer);
163 scoped_ptr<Call> call(Call::Create(call_config));
164
165 VideoSendStream::Config send_config = GetSendTestConfig(call.get());
166 send_config.rtp.extensions.push_back(
167 RtpExtension("abs-send-time", kAbsSendTimeExtensionId));
168
169 RunSendTest(call.get(), send_config, &observer);
170}
171
pbos@webrtc.org29023282013-09-11 10:14:56 +0000172TEST_F(VideoSendStreamTest, SupportsTransmissionTimeOffset) {
173 static const uint8_t kTOffsetExtensionId = 13;
174 class DelayedEncoder : public test::FakeEncoder {
175 public:
176 DelayedEncoder(Clock* clock) : test::FakeEncoder(clock) {}
177 virtual int32_t Encode(
178 const I420VideoFrame& input_image,
179 const CodecSpecificInfo* codec_specific_info,
180 const std::vector<VideoFrameType>* frame_types) OVERRIDE {
181 // A delay needs to be introduced to assure that we get a timestamp
182 // offset.
183 SleepMs(5);
184 return FakeEncoder::Encode(input_image, codec_specific_info, frame_types);
185 }
186 } encoder(Clock::GetRealTimeClock());
187
188 class TransmissionTimeOffsetObserver : public SendTransportObserver {
189 public:
190 TransmissionTimeOffsetObserver() : SendTransportObserver(30 * 1000) {
191 EXPECT_TRUE(rtp_header_parser_->RegisterRtpHeaderExtension(
192 kRtpExtensionTransmissionTimeOffset, kTOffsetExtensionId));
193 }
194
195 virtual bool SendRTP(const uint8_t* packet, size_t length) OVERRIDE {
196 RTPHeader header;
197 EXPECT_TRUE(
198 rtp_header_parser_->Parse(packet, static_cast<int>(length), &header));
199
200 EXPECT_GT(header.extension.transmissionTimeOffset, 0);
201 send_test_complete_->Set();
202
203 return true;
204 }
205 } observer;
206
207 Call::Config call_config(&observer);
208 scoped_ptr<Call> call(Call::Create(call_config));
209
210 VideoSendStream::Config send_config = GetSendTestConfig(call.get());
211 send_config.encoder = &encoder;
212 send_config.rtp.extensions.push_back(
213 RtpExtension("toffset", kTOffsetExtensionId));
214
215 RunSendTest(call.get(), send_config, &observer);
216}
217
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000218TEST_F(VideoSendStreamTest, RespondsToNack) {
219 class NackObserver : public SendTransportObserver, webrtc::Transport {
220 public:
221 NackObserver()
222 : SendTransportObserver(30 * 1000),
223 thread_(ThreadWrapper::CreateThread(NackProcess, this)),
224 send_call_receiver_(NULL),
225 send_count_(0),
226 ssrc_(0),
227 nacked_sequence_number_(0) {}
228
229 ~NackObserver() {
230 EXPECT_TRUE(thread_->Stop());
231 }
232
233 void SetReceiver(PacketReceiver* send_call_receiver) {
234 send_call_receiver_ = send_call_receiver;
235 }
236
237 // Sending NACKs must be done from a different "network" thread to prevent
238 // violating locking orders. With this no locks are held prior to inserting
239 // packets back into the sender.
240 static bool NackProcess(void* observer) {
241 return static_cast<NackObserver*>(observer)->SendNack();
242 }
243
244 bool SendNack() {
245 NullReceiveStatistics null_stats;
246 RTCPSender rtcp_sender(0, false, Clock::GetRealTimeClock(), &null_stats);
247 EXPECT_EQ(0, rtcp_sender.RegisterSendTransport(this));
248
249 rtcp_sender.SetRTCPStatus(kRtcpNonCompound);
250 rtcp_sender.SetRemoteSSRC(ssrc_);
251
252 RTCPSender::FeedbackState feedback_state;
253 EXPECT_EQ(0, rtcp_sender.SendRTCP(
254 feedback_state, kRtcpNack, 1, &nacked_sequence_number_));
255 return false;
256 }
257
258 virtual int SendPacket(int channel, const void* data, int len) OVERRIDE {
259 ADD_FAILURE()
260 << "This should never be reached. Only a NACK should be sent.";
261 return -1;
262 }
263
264 virtual int SendRTCPPacket(int channel,
265 const void* data,
266 int len) OVERRIDE {
267 EXPECT_TRUE(send_call_receiver_->DeliverPacket(
268 static_cast<const uint8_t*>(data), static_cast<size_t>(len)));
269 return len;
270 }
271
272 virtual bool SendRTP(const uint8_t* packet, size_t length) OVERRIDE {
273 EXPECT_TRUE(send_call_receiver_ != NULL);
274 RTPHeader header;
275 EXPECT_TRUE(
276 rtp_header_parser_->Parse(packet, static_cast<int>(length), &header));
277
278 // Nack second packet after receiving the third one.
279 if (++send_count_ == 3) {
280 ssrc_ = header.ssrc;
281 nacked_sequence_number_ = header.sequenceNumber - 1;
282 unsigned int id;
283 EXPECT_TRUE(thread_->Start(id));
284 }
285
286 if (header.sequenceNumber == nacked_sequence_number_)
287 send_test_complete_->Set();
288
289 return true;
290 }
291 private:
292 scoped_ptr<ThreadWrapper> thread_;
293 PacketReceiver* send_call_receiver_;
294 int send_count_;
295 uint32_t ssrc_;
296 uint16_t nacked_sequence_number_;
297 } observer;
298
299 Call::Config call_config(&observer);
300 scoped_ptr<Call> call(Call::Create(call_config));
301 observer.SetReceiver(call->Receiver());
302
303 VideoSendStream::Config send_config = GetSendTestConfig(call.get());
304 send_config.rtp.nack.rtp_history_ms = 1000;
305
306 RunSendTest(call.get(), send_config, &observer);
307}
308
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +0000309} // namespace webrtc