blob: 8117e75c5eeb5be30b64676198b8e9691ec6f3ff [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.orgdf531a22013-09-10 14:56:33 +000016#include "webrtc/system_wrappers/interface/thread_wrapper.h"
pbos@webrtc.orgcb5118c2013-09-03 09:10:37 +000017#include "webrtc/video_engine/test/common/fake_encoder.h"
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +000018#include "webrtc/video_engine/test/common/frame_generator.h"
19#include "webrtc/video_engine/test/common/frame_generator_capturer.h"
20#include "webrtc/video_engine/test/common/null_transport.h"
pbos@webrtc.org841c8a42013-09-09 15:04:25 +000021#include "webrtc/video_engine/new_include/call.h"
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +000022#include "webrtc/video_engine/new_include/video_send_stream.h"
23
24namespace webrtc {
25
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +000026class SendTransportObserver : public test::NullTransport {
27 public:
28 explicit SendTransportObserver(unsigned long timeout_ms)
29 : rtp_header_parser_(RtpHeaderParser::Create()),
30 send_test_complete_(EventWrapper::Create()),
31 timeout_ms_(timeout_ms) {}
32
pbos@webrtc.org841c8a42013-09-09 15:04:25 +000033 EventTypeWrapper Wait() { return send_test_complete_->Wait(timeout_ms_); }
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +000034
35 protected:
36 scoped_ptr<RtpHeaderParser> rtp_header_parser_;
37 scoped_ptr<EventWrapper> send_test_complete_;
38
39 private:
40 unsigned long timeout_ms_;
41};
42
pbos@webrtc.org013d9942013-08-22 09:42:17 +000043class VideoSendStreamTest : public ::testing::Test {
pbos@webrtc.orgcb5118c2013-09-03 09:10:37 +000044 public:
45 VideoSendStreamTest() : fake_encoder_(Clock::GetRealTimeClock()) {}
pbos@webrtc.org841c8a42013-09-09 15:04:25 +000046
pbos@webrtc.org013d9942013-08-22 09:42:17 +000047 protected:
48 static const uint32_t kSendSsrc;
pbos@webrtc.org841c8a42013-09-09 15:04:25 +000049 void RunSendTest(Call* call,
pbos@webrtc.org74fa4892013-08-23 09:19:30 +000050 const VideoSendStream::Config& config,
pbos@webrtc.org013d9942013-08-22 09:42:17 +000051 SendTransportObserver* observer) {
pbos@webrtc.org74fa4892013-08-23 09:19:30 +000052 VideoSendStream* send_stream = call->CreateSendStream(config);
pbos@webrtc.org013d9942013-08-22 09:42:17 +000053 scoped_ptr<test::FrameGeneratorCapturer> frame_generator_capturer(
54 test::FrameGeneratorCapturer::Create(
55 send_stream->Input(),
56 test::FrameGenerator::Create(320, 240, Clock::GetRealTimeClock()),
57 30));
58 send_stream->StartSend();
59 frame_generator_capturer->Start();
60
61 EXPECT_EQ(kEventSignaled, observer->Wait());
62
63 frame_generator_capturer->Stop();
64 send_stream->StopSend();
65 call->DestroySendStream(send_stream);
66 }
pbos@webrtc.orgcb5118c2013-09-03 09:10:37 +000067
pbos@webrtc.org841c8a42013-09-09 15:04:25 +000068 VideoSendStream::Config GetSendTestConfig(Call* call) {
pbos@webrtc.orgcb5118c2013-09-03 09:10:37 +000069 VideoSendStream::Config config = call->GetDefaultSendConfig();
70 config.encoder = &fake_encoder_;
71 config.internal_source = false;
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +000072 config.rtp.ssrcs.push_back(kSendSsrc);
pbos@webrtc.org0181b5f2013-09-09 08:26:30 +000073 test::FakeEncoder::SetCodecSettings(&config.codec, 1);
pbos@webrtc.orgcb5118c2013-09-03 09:10:37 +000074 return config;
75 }
76
77 test::FakeEncoder fake_encoder_;
pbos@webrtc.org013d9942013-08-22 09:42:17 +000078};
79
80const uint32_t VideoSendStreamTest::kSendSsrc = 0xC0FFEE;
81
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +000082TEST_F(VideoSendStreamTest, SendsSetSsrc) {
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +000083 class SendSsrcObserver : public SendTransportObserver {
84 public:
85 SendSsrcObserver() : SendTransportObserver(30 * 1000) {}
86
87 virtual bool SendRTP(const uint8_t* packet, size_t length) OVERRIDE {
88 RTPHeader header;
89 EXPECT_TRUE(
90 rtp_header_parser_->Parse(packet, static_cast<int>(length), &header));
91
92 if (header.ssrc == kSendSsrc)
93 send_test_complete_->Set();
94
95 return true;
96 }
97 } observer;
98
pbos@webrtc.org841c8a42013-09-09 15:04:25 +000099 Call::Config call_config(&observer);
100 scoped_ptr<Call> call(Call::Create(call_config));
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +0000101
pbos@webrtc.orgcb5118c2013-09-03 09:10:37 +0000102 VideoSendStream::Config send_config = GetSendTestConfig(call.get());
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +0000103
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000104 RunSendTest(call.get(), send_config, &observer);
105}
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +0000106
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000107TEST_F(VideoSendStreamTest, SupportsCName) {
108 static std::string kCName = "PjQatC14dGfbVwGPUOA9IH7RlsFDbWl4AhXEiDsBizo=";
109 class CNameObserver : public SendTransportObserver {
110 public:
111 CNameObserver() : SendTransportObserver(30 * 1000) {}
112
113 virtual bool SendRTCP(const uint8_t* packet, size_t length) OVERRIDE {
114 RTCPUtility::RTCPParserV2 parser(packet, length, true);
115 EXPECT_TRUE(parser.IsValid());
116
117 RTCPUtility::RTCPPacketTypes packet_type = parser.Begin();
118 while (packet_type != RTCPUtility::kRtcpNotValidCode) {
119 if (packet_type == RTCPUtility::kRtcpSdesChunkCode) {
120 EXPECT_EQ(parser.Packet().CName.CName, kCName);
121 send_test_complete_->Set();
122 }
123
124 packet_type = parser.Iterate();
125 }
126
127 return true;
128 }
129 } observer;
130
pbos@webrtc.org841c8a42013-09-09 15:04:25 +0000131 Call::Config call_config(&observer);
132 scoped_ptr<Call> call(Call::Create(call_config));
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000133
pbos@webrtc.orgcb5118c2013-09-03 09:10:37 +0000134 VideoSendStream::Config send_config = GetSendTestConfig(call.get());
pbos@webrtc.org013d9942013-08-22 09:42:17 +0000135 send_config.rtp.c_name = kCName;
136
137 RunSendTest(call.get(), send_config, &observer);
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +0000138}
139
pbos@webrtc.orgdf531a22013-09-10 14:56:33 +0000140TEST_F(VideoSendStreamTest, RespondsToNack) {
141 class NackObserver : public SendTransportObserver, webrtc::Transport {
142 public:
143 NackObserver()
144 : SendTransportObserver(30 * 1000),
145 thread_(ThreadWrapper::CreateThread(NackProcess, this)),
146 send_call_receiver_(NULL),
147 send_count_(0),
148 ssrc_(0),
149 nacked_sequence_number_(0) {}
150
151 ~NackObserver() {
152 EXPECT_TRUE(thread_->Stop());
153 }
154
155 void SetReceiver(PacketReceiver* send_call_receiver) {
156 send_call_receiver_ = send_call_receiver;
157 }
158
159 // Sending NACKs must be done from a different "network" thread to prevent
160 // violating locking orders. With this no locks are held prior to inserting
161 // packets back into the sender.
162 static bool NackProcess(void* observer) {
163 return static_cast<NackObserver*>(observer)->SendNack();
164 }
165
166 bool SendNack() {
167 NullReceiveStatistics null_stats;
168 RTCPSender rtcp_sender(0, false, Clock::GetRealTimeClock(), &null_stats);
169 EXPECT_EQ(0, rtcp_sender.RegisterSendTransport(this));
170
171 rtcp_sender.SetRTCPStatus(kRtcpNonCompound);
172 rtcp_sender.SetRemoteSSRC(ssrc_);
173
174 RTCPSender::FeedbackState feedback_state;
175 EXPECT_EQ(0, rtcp_sender.SendRTCP(
176 feedback_state, kRtcpNack, 1, &nacked_sequence_number_));
177 return false;
178 }
179
180 virtual int SendPacket(int channel, const void* data, int len) OVERRIDE {
181 ADD_FAILURE()
182 << "This should never be reached. Only a NACK should be sent.";
183 return -1;
184 }
185
186 virtual int SendRTCPPacket(int channel,
187 const void* data,
188 int len) OVERRIDE {
189 EXPECT_TRUE(send_call_receiver_->DeliverPacket(
190 static_cast<const uint8_t*>(data), static_cast<size_t>(len)));
191 return len;
192 }
193
194 virtual bool SendRTP(const uint8_t* packet, size_t length) OVERRIDE {
195 EXPECT_TRUE(send_call_receiver_ != NULL);
196 RTPHeader header;
197 EXPECT_TRUE(
198 rtp_header_parser_->Parse(packet, static_cast<int>(length), &header));
199
200 // Nack second packet after receiving the third one.
201 if (++send_count_ == 3) {
202 ssrc_ = header.ssrc;
203 nacked_sequence_number_ = header.sequenceNumber - 1;
204 unsigned int id;
205 EXPECT_TRUE(thread_->Start(id));
206 }
207
208 if (header.sequenceNumber == nacked_sequence_number_)
209 send_test_complete_->Set();
210
211 return true;
212 }
213 private:
214 scoped_ptr<ThreadWrapper> thread_;
215 PacketReceiver* send_call_receiver_;
216 int send_count_;
217 uint32_t ssrc_;
218 uint16_t nacked_sequence_number_;
219 } observer;
220
221 Call::Config call_config(&observer);
222 scoped_ptr<Call> call(Call::Create(call_config));
223 observer.SetReceiver(call->Receiver());
224
225 VideoSendStream::Config send_config = GetSendTestConfig(call.get());
226 send_config.rtp.nack.rtp_history_ms = 1000;
227
228 RunSendTest(call.get(), send_config, &observer);
229}
230
pbos@webrtc.org119a1cc2013-08-20 13:14:07 +0000231} // namespace webrtc