blob: 44d442d4c27e71461d9f6ec856b3d4744896f2b6 [file] [log] [blame]
pbos@webrtc.orgce851092013-08-05 12:01:36 +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 */
pbos@webrtc.org8ce445e2013-08-19 16:09:34 +000010#include <assert.h>
11
stefan@webrtc.orge0284102013-11-18 11:45:11 +000012#include <algorithm>
pbos@webrtc.orgce851092013-08-05 12:01:36 +000013#include <map>
stefan@webrtc.orge0284102013-11-18 11:45:11 +000014#include <sstream>
15#include <string>
pbos@webrtc.orgce851092013-08-05 12:01:36 +000016
17#include "testing/gtest/include/gtest/gtest.h"
18
pbos@webrtc.org24e20892013-10-28 16:32:01 +000019#include "webrtc/call.h"
sprang@webrtc.org2e98d452013-11-26 11:41:59 +000020#include "webrtc/frame_callback.h"
pbos@webrtc.orgce851092013-08-05 12:01:36 +000021#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
pbos@webrtc.orge2a7a772014-03-19 08:43:57 +000022#include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h"
pbos@webrtc.orgce851092013-08-05 12:01:36 +000023#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
pbos@webrtc.orgce851092013-08-05 12:01:36 +000024#include "webrtc/system_wrappers/interface/event_wrapper.h"
pbos@webrtc.orgfa996f22013-09-10 09:26:25 +000025#include "webrtc/system_wrappers/interface/scoped_ptr.h"
pbos@webrtc.orgd60137f2013-12-16 18:24:37 +000026#include "webrtc/system_wrappers/interface/sleep.h"
pbos@webrtc.orgc33d37c2013-12-11 16:26:16 +000027#include "webrtc/test/direct_transport.h"
pbos@webrtc.orge2a7a772014-03-19 08:43:57 +000028#include "webrtc/test/encoder_settings.h"
pbos@webrtc.orgc33d37c2013-12-11 16:26:16 +000029#include "webrtc/test/fake_audio_device.h"
30#include "webrtc/test/fake_decoder.h"
31#include "webrtc/test/fake_encoder.h"
32#include "webrtc/test/frame_generator.h"
33#include "webrtc/test/frame_generator_capturer.h"
pbos@webrtc.org75e7da32014-01-10 18:47:32 +000034#include "webrtc/test/null_transport.h"
pbos@webrtc.orgc33d37c2013-12-11 16:26:16 +000035#include "webrtc/test/rtp_rtcp_observer.h"
36#include "webrtc/test/testsupport/fileutils.h"
37#include "webrtc/test/testsupport/perf_test.h"
stefan@webrtc.orge0284102013-11-18 11:45:11 +000038#include "webrtc/video/transport_adapter.h"
pbos@webrtc.orgce851092013-08-05 12:01:36 +000039
40namespace webrtc {
41
pbos@webrtc.org51e01012013-10-17 14:14:42 +000042static unsigned int kDefaultTimeoutMs = 30 * 1000;
43static unsigned int kLongTimeoutMs = 120 * 1000;
pbos@webrtc.org4b50db12013-12-03 10:13:04 +000044static const uint32_t kSendSsrc = 0x654321;
pbos@webrtc.orgc71929d2014-01-24 09:30:53 +000045static const uint32_t kSendRtxSsrc = 0x424242;
pbos@webrtc.org4b50db12013-12-03 10:13:04 +000046static const uint32_t kReceiverLocalSsrc = 0x123456;
stefan@webrtc.org4985c7b2013-11-15 12:32:15 +000047static const uint8_t kSendPayloadType = 125;
pbos@webrtc.orgc71929d2014-01-24 09:30:53 +000048static const uint8_t kSendRtxPayloadType = 126;
pbos@webrtc.orgea15f8d2014-04-08 11:21:45 +000049static const int kRedPayloadType = 118;
50static const int kUlpfecPayloadType = 119;
pbos@webrtc.org51e01012013-10-17 14:14:42 +000051
pbos@webrtc.org362e3e52013-09-27 10:54:10 +000052class CallTest : public ::testing::Test {
pbos@webrtc.orgce851092013-08-05 12:01:36 +000053 public:
pbos@webrtc.org28a11662013-09-19 14:22:12 +000054 CallTest()
pbos@webrtc.org618a0ec2013-09-09 08:26:30 +000055 : send_stream_(NULL),
56 receive_stream_(NULL),
57 fake_encoder_(Clock::GetRealTimeClock()) {}
pbos@webrtc.orgce851092013-08-05 12:01:36 +000058
pbos@webrtc.org46f72882013-12-16 12:24:44 +000059 virtual ~CallTest() {
pbos@webrtc.org8ce445e2013-08-19 16:09:34 +000060 EXPECT_EQ(NULL, send_stream_);
61 EXPECT_EQ(NULL, receive_stream_);
62 }
pbos@webrtc.orgce851092013-08-05 12:01:36 +000063
pbos@webrtc.org8ce445e2013-08-19 16:09:34 +000064 protected:
pbos@webrtc.orgb5d2d162013-10-02 13:36:09 +000065 void CreateCalls(const Call::Config& sender_config,
66 const Call::Config& receiver_config) {
pbos@webrtc.orgbf6d5722013-09-09 15:04:25 +000067 sender_call_.reset(Call::Create(sender_config));
68 receiver_call_.reset(Call::Create(receiver_config));
pbos@webrtc.org8ce445e2013-08-19 16:09:34 +000069 }
pbos@webrtc.orgce851092013-08-05 12:01:36 +000070
pbos@webrtc.org8ce445e2013-08-19 16:09:34 +000071 void CreateTestConfigs() {
pbos@webrtc.org8ce445e2013-08-19 16:09:34 +000072 send_config_ = sender_call_->GetDefaultSendConfig();
73 receive_config_ = receiver_call_->GetDefaultReceiveConfig();
pbos@webrtc.orgce851092013-08-05 12:01:36 +000074
pbos@webrtc.org4b50db12013-12-03 10:13:04 +000075 send_config_.rtp.ssrcs.push_back(kSendSsrc);
pbos@webrtc.orge2a7a772014-03-19 08:43:57 +000076 send_config_.encoder_settings = test::CreateEncoderSettings(
77 &fake_encoder_, "FAKE", kSendPayloadType, 1);
pbos@webrtc.orgce851092013-08-05 12:01:36 +000078
pbos@webrtc.orge2a7a772014-03-19 08:43:57 +000079 assert(receive_config_.codecs.empty());
80 VideoCodec codec =
81 test::CreateDecoderVideoCodec(send_config_.encoder_settings);
82 receive_config_.codecs.push_back(codec);
pbos@webrtc.org618a0ec2013-09-09 08:26:30 +000083 ExternalVideoDecoder decoder;
84 decoder.decoder = &fake_decoder_;
pbos@webrtc.orge2a7a772014-03-19 08:43:57 +000085 decoder.payload_type = send_config_.encoder_settings.payload_type;
pbos@webrtc.org618a0ec2013-09-09 08:26:30 +000086 receive_config_.external_decoders.push_back(decoder);
pbos@webrtc.org4b50db12013-12-03 10:13:04 +000087 receive_config_.rtp.remote_ssrc = send_config_.rtp.ssrcs[0];
88 receive_config_.rtp.local_ssrc = kReceiverLocalSsrc;
pbos@webrtc.org8ce445e2013-08-19 16:09:34 +000089 }
pbos@webrtc.orgce851092013-08-05 12:01:36 +000090
pbos@webrtc.org8ce445e2013-08-19 16:09:34 +000091 void CreateStreams() {
92 assert(send_stream_ == NULL);
93 assert(receive_stream_ == NULL);
pbos@webrtc.orgce851092013-08-05 12:01:36 +000094
pbos@webrtc.org964d78e2013-11-20 10:40:25 +000095 send_stream_ = sender_call_->CreateVideoSendStream(send_config_);
96 receive_stream_ = receiver_call_->CreateVideoReceiveStream(receive_config_);
pbos@webrtc.org8ce445e2013-08-19 16:09:34 +000097 }
pbos@webrtc.orgce851092013-08-05 12:01:36 +000098
pbos@webrtc.org8ce445e2013-08-19 16:09:34 +000099 void CreateFrameGenerator() {
pbos@webrtc.orge2a7a772014-03-19 08:43:57 +0000100 frame_generator_capturer_.reset(test::FrameGeneratorCapturer::Create(
101 send_stream_->Input(),
102 send_config_.encoder_settings.streams[0].width,
103 send_config_.encoder_settings.streams[0].height,
104 30,
105 Clock::GetRealTimeClock()));
pbos@webrtc.org8ce445e2013-08-19 16:09:34 +0000106 }
pbos@webrtc.orgce851092013-08-05 12:01:36 +0000107
pbos@webrtc.org8ce445e2013-08-19 16:09:34 +0000108 void StartSending() {
pbos@webrtc.org7f9f8402013-11-20 11:36:47 +0000109 receive_stream_->StartReceiving();
110 send_stream_->StartSending();
pbos@webrtc.orgc5b5ad12013-10-21 09:02:30 +0000111 if (frame_generator_capturer_.get() != NULL)
112 frame_generator_capturer_->Start();
pbos@webrtc.org8ce445e2013-08-19 16:09:34 +0000113 }
pbos@webrtc.orgce851092013-08-05 12:01:36 +0000114
pbos@webrtc.org8ce445e2013-08-19 16:09:34 +0000115 void StopSending() {
pbos@webrtc.orgc5b5ad12013-10-21 09:02:30 +0000116 if (frame_generator_capturer_.get() != NULL)
117 frame_generator_capturer_->Stop();
pbos@webrtc.org00208582013-09-05 12:38:54 +0000118 if (send_stream_ != NULL)
pbos@webrtc.org7f9f8402013-11-20 11:36:47 +0000119 send_stream_->StopSending();
pbos@webrtc.org00208582013-09-05 12:38:54 +0000120 if (receive_stream_ != NULL)
pbos@webrtc.org7f9f8402013-11-20 11:36:47 +0000121 receive_stream_->StopReceiving();
pbos@webrtc.org8ce445e2013-08-19 16:09:34 +0000122 }
pbos@webrtc.orgce851092013-08-05 12:01:36 +0000123
pbos@webrtc.org8ce445e2013-08-19 16:09:34 +0000124 void DestroyStreams() {
pbos@webrtc.org00208582013-09-05 12:38:54 +0000125 if (send_stream_ != NULL)
pbos@webrtc.org12a93e02013-11-21 13:49:43 +0000126 sender_call_->DestroyVideoSendStream(send_stream_);
pbos@webrtc.org00208582013-09-05 12:38:54 +0000127 if (receive_stream_ != NULL)
pbos@webrtc.org12a93e02013-11-21 13:49:43 +0000128 receiver_call_->DestroyVideoReceiveStream(receive_stream_);
pbos@webrtc.orgbf6d5722013-09-09 15:04:25 +0000129 send_stream_ = NULL;
pbos@webrtc.org8ce445e2013-08-19 16:09:34 +0000130 receive_stream_ = NULL;
131 }
132
pbos@webrtc.orgc71929d2014-01-24 09:30:53 +0000133 void DecodesRetransmittedFrame(bool retransmit_over_rtx);
pbos@webrtc.org8ce445e2013-08-19 16:09:34 +0000134 void ReceivesPliAndRecovers(int rtp_history_ms);
pbos@webrtc.org51e01012013-10-17 14:14:42 +0000135 void RespectsRtcpMode(newapi::RtcpMode rtcp_mode);
asapersson@webrtc.orgb4263e02014-01-20 08:34:49 +0000136 void TestXrReceiverReferenceTimeReport(bool enable_rrtr);
pbos@webrtc.org8ce445e2013-08-19 16:09:34 +0000137
pbos@webrtc.orgbf6d5722013-09-09 15:04:25 +0000138 scoped_ptr<Call> sender_call_;
139 scoped_ptr<Call> receiver_call_;
pbos@webrtc.org8ce445e2013-08-19 16:09:34 +0000140
pbos@webrtc.orgc1797062013-08-23 09:19:30 +0000141 VideoSendStream::Config send_config_;
142 VideoReceiveStream::Config receive_config_;
pbos@webrtc.org8ce445e2013-08-19 16:09:34 +0000143
pbos@webrtc.orgc1797062013-08-23 09:19:30 +0000144 VideoSendStream* send_stream_;
145 VideoReceiveStream* receive_stream_;
pbos@webrtc.org8ce445e2013-08-19 16:09:34 +0000146
147 scoped_ptr<test::FrameGeneratorCapturer> frame_generator_capturer_;
148
pbos@webrtc.org618a0ec2013-09-09 08:26:30 +0000149 test::FakeEncoder fake_encoder_;
150 test::FakeDecoder fake_decoder_;
pbos@webrtc.org8ce445e2013-08-19 16:09:34 +0000151};
152
pbos@webrtc.org8ce445e2013-08-19 16:09:34 +0000153class NackObserver : public test::RtpRtcpObserver {
mflodman@webrtc.org5e252ac2013-12-18 09:44:53 +0000154 static const int kNumberOfNacksToObserve = 2;
155 static const int kLossBurstSize = 2;
156 static const int kPacketsBetweenLossBursts = 9;
pbos@webrtc.orgbf6d5722013-09-09 15:04:25 +0000157
pbos@webrtc.org8ce445e2013-08-19 16:09:34 +0000158 public:
pbos@webrtc.orgce851092013-08-05 12:01:36 +0000159 NackObserver()
pbos@webrtc.org51e01012013-10-17 14:14:42 +0000160 : test::RtpRtcpObserver(kLongTimeoutMs),
pbos@webrtc.orgce851092013-08-05 12:01:36 +0000161 rtp_parser_(RtpHeaderParser::Create()),
pbos@webrtc.orgce851092013-08-05 12:01:36 +0000162 sent_rtp_packets_(0),
mflodman@webrtc.org5e252ac2013-12-18 09:44:53 +0000163 packets_left_to_drop_(0),
pbos@webrtc.org8ce445e2013-08-19 16:09:34 +0000164 nacks_left_(kNumberOfNacksToObserve) {}
pbos@webrtc.orgce851092013-08-05 12:01:36 +0000165
pbos@webrtc.orgce851092013-08-05 12:01:36 +0000166 private:
pbos@webrtc.org8ce445e2013-08-19 16:09:34 +0000167 virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE {
pbos@webrtc.orgce851092013-08-05 12:01:36 +0000168 RTPHeader header;
169 EXPECT_TRUE(rtp_parser_->Parse(packet, static_cast<int>(length), &header));
170
171 // Never drop retransmitted packets.
172 if (dropped_packets_.find(header.sequenceNumber) !=
173 dropped_packets_.end()) {
174 retransmitted_packets_.insert(header.sequenceNumber);
mflodman@webrtc.org5e252ac2013-12-18 09:44:53 +0000175 if (nacks_left_ == 0 &&
176 retransmitted_packets_.size() == dropped_packets_.size()) {
177 observation_complete_->Set();
178 }
pbos@webrtc.org8ce445e2013-08-19 16:09:34 +0000179 return SEND_PACKET;
pbos@webrtc.orgce851092013-08-05 12:01:36 +0000180 }
181
pbos@webrtc.org8ce445e2013-08-19 16:09:34 +0000182 ++sent_rtp_packets_;
mflodman@webrtc.org5e252ac2013-12-18 09:44:53 +0000183
184 // Enough NACKs received, stop dropping packets.
185 if (nacks_left_ == 0)
186 return SEND_PACKET;
187
188 // Check if it's time for a new loss burst.
189 if (sent_rtp_packets_ % kPacketsBetweenLossBursts == 0)
190 packets_left_to_drop_ = kLossBurstSize;
191
192 if (packets_left_to_drop_ > 0) {
193 --packets_left_to_drop_;
194 dropped_packets_.insert(header.sequenceNumber);
195 return DROP_PACKET;
196 }
197
pbos@webrtc.org8ce445e2013-08-19 16:09:34 +0000198 return SEND_PACKET;
pbos@webrtc.orgce851092013-08-05 12:01:36 +0000199 }
200
pbos@webrtc.org8ce445e2013-08-19 16:09:34 +0000201 virtual Action OnReceiveRtcp(const uint8_t* packet, size_t length) OVERRIDE {
202 RTCPUtility::RTCPParserV2 parser(packet, length, true);
203 EXPECT_TRUE(parser.IsValid());
204
pbos@webrtc.org8ce445e2013-08-19 16:09:34 +0000205 RTCPUtility::RTCPPacketTypes packet_type = parser.Begin();
206 while (packet_type != RTCPUtility::kRtcpNotValidCode) {
mflodman@webrtc.org5e252ac2013-12-18 09:44:53 +0000207 if (packet_type == RTCPUtility::kRtcpRtpfbNackCode) {
208 --nacks_left_;
209 break;
210 }
pbos@webrtc.org8ce445e2013-08-19 16:09:34 +0000211 packet_type = parser.Iterate();
212 }
pbos@webrtc.org8ce445e2013-08-19 16:09:34 +0000213 return SEND_PACKET;
214 }
215
216 private:
pbos@webrtc.orgce851092013-08-05 12:01:36 +0000217 scoped_ptr<RtpHeaderParser> rtp_parser_;
218 std::set<uint16_t> dropped_packets_;
219 std::set<uint16_t> retransmitted_packets_;
pbos@webrtc.orgce851092013-08-05 12:01:36 +0000220 uint64_t sent_rtp_packets_;
mflodman@webrtc.org5e252ac2013-12-18 09:44:53 +0000221 int packets_left_to_drop_;
pbos@webrtc.orgce851092013-08-05 12:01:36 +0000222 int nacks_left_;
pbos@webrtc.orgce851092013-08-05 12:01:36 +0000223};
224
pbos@webrtc.org55bc2812014-04-10 14:39:22 +0000225// Test disabled, ongoing work disabled traces causing UsesTraceCallback to
226// fail. Tracked by webrtc:3157.
227TEST_F(CallTest, DISABLED_UsesTraceCallback) {
pbos@webrtc.orgb5d2d162013-10-02 13:36:09 +0000228 const unsigned int kSenderTraceFilter = kTraceDebug;
229 const unsigned int kReceiverTraceFilter = kTraceDefault & (~kTraceDebug);
pbos@webrtc.org63301bd2013-10-21 10:34:43 +0000230 class TraceObserver : public TraceCallback {
pbos@webrtc.orgb5d2d162013-10-02 13:36:09 +0000231 public:
pbos@webrtc.orgd05597a2013-12-05 12:11:47 +0000232 explicit TraceObserver(unsigned int filter)
pbos@webrtc.orgb5d2d162013-10-02 13:36:09 +0000233 : filter_(filter), messages_left_(50), done_(EventWrapper::Create()) {}
234
235 virtual void Print(TraceLevel level,
236 const char* message,
237 int length) OVERRIDE {
238 EXPECT_EQ(0u, level & (~filter_));
239 if (--messages_left_ == 0)
240 done_->Set();
241 }
242
pbos@webrtc.org51e01012013-10-17 14:14:42 +0000243 EventTypeWrapper Wait() { return done_->Wait(kDefaultTimeoutMs); }
pbos@webrtc.orgb5d2d162013-10-02 13:36:09 +0000244
245 private:
246 unsigned int filter_;
247 unsigned int messages_left_;
248 scoped_ptr<EventWrapper> done_;
249 } sender_trace(kSenderTraceFilter), receiver_trace(kReceiverTraceFilter);
250
251 test::DirectTransport send_transport, receive_transport;
252 Call::Config sender_call_config(&send_transport);
253 sender_call_config.trace_callback = &sender_trace;
254 sender_call_config.trace_filter = kSenderTraceFilter;
255 Call::Config receiver_call_config(&receive_transport);
256 receiver_call_config.trace_callback = &receiver_trace;
257 receiver_call_config.trace_filter = kReceiverTraceFilter;
258 CreateCalls(sender_call_config, receiver_call_config);
259 send_transport.SetReceiver(receiver_call_->Receiver());
260 receive_transport.SetReceiver(sender_call_->Receiver());
261
262 CreateTestConfigs();
263
264 CreateStreams();
265 CreateFrameGenerator();
266 StartSending();
267
268 // Wait() waits for a couple of trace callbacks to occur.
269 EXPECT_EQ(kEventSignaled, sender_trace.Wait());
270 EXPECT_EQ(kEventSignaled, receiver_trace.Wait());
271
272 StopSending();
273 send_transport.StopSending();
274 receive_transport.StopSending();
275 DestroyStreams();
276
277 // The TraceCallback instance MUST outlive Calls, destroy Calls explicitly.
278 sender_call_.reset();
279 receiver_call_.reset();
280}
281
pbos@webrtc.org75e7da32014-01-10 18:47:32 +0000282TEST_F(CallTest, ReceiverCanBeStartedTwice) {
283 test::NullTransport transport;
284 CreateCalls(Call::Config(&transport), Call::Config(&transport));
285
286 CreateTestConfigs();
287 CreateStreams();
288
289 receive_stream_->StartReceiving();
290 receive_stream_->StartReceiving();
291
292 DestroyStreams();
293}
294
295TEST_F(CallTest, ReceiverCanBeStoppedTwice) {
296 test::NullTransport transport;
297 CreateCalls(Call::Config(&transport), Call::Config(&transport));
298
299 CreateTestConfigs();
300 CreateStreams();
301
302 receive_stream_->StopReceiving();
303 receive_stream_->StopReceiving();
304
305 DestroyStreams();
306}
307
pbos@webrtc.orgd60137f2013-12-16 18:24:37 +0000308TEST_F(CallTest, RendersSingleDelayedFrame) {
309 static const int kWidth = 320;
310 static const int kHeight = 240;
311 // This constant is chosen to be higher than the timeout in the video_render
312 // module. This makes sure that frames aren't dropped if there are no other
313 // frames in the queue.
314 static const int kDelayRenderCallbackMs = 1000;
315
316 class Renderer : public VideoRenderer {
317 public:
318 Renderer() : event_(EventWrapper::Create()) {}
319
320 virtual void RenderFrame(const I420VideoFrame& video_frame,
321 int /*time_to_render_ms*/) OVERRIDE {
322 event_->Set();
323 }
324
325 EventTypeWrapper Wait() { return event_->Wait(kDefaultTimeoutMs); }
326
327 scoped_ptr<EventWrapper> event_;
328 } renderer;
329
330 class TestFrameCallback : public I420FrameCallback {
331 public:
332 TestFrameCallback() : event_(EventWrapper::Create()) {}
333
334 EventTypeWrapper Wait() { return event_->Wait(kDefaultTimeoutMs); }
335
336 private:
pbos@webrtc.orgc71929d2014-01-24 09:30:53 +0000337 virtual void FrameCallback(I420VideoFrame* frame) OVERRIDE {
pbos@webrtc.orgd60137f2013-12-16 18:24:37 +0000338 SleepMs(kDelayRenderCallbackMs);
339 event_->Set();
340 }
341
342 scoped_ptr<EventWrapper> event_;
343 };
344
345 test::DirectTransport sender_transport, receiver_transport;
346
347 CreateCalls(Call::Config(&sender_transport),
348 Call::Config(&receiver_transport));
349
350 sender_transport.SetReceiver(receiver_call_->Receiver());
351 receiver_transport.SetReceiver(sender_call_->Receiver());
352
353 CreateTestConfigs();
354
355 TestFrameCallback pre_render_callback;
356 receive_config_.pre_render_callback = &pre_render_callback;
357 receive_config_.renderer = &renderer;
358
359 CreateStreams();
360 StartSending();
361
362 // Create frames that are smaller than the send width/height, this is done to
363 // check that the callbacks are done after processing video.
364 scoped_ptr<test::FrameGenerator> frame_generator(
365 test::FrameGenerator::Create(kWidth, kHeight));
366 send_stream_->Input()->SwapFrame(frame_generator->NextFrame());
367 EXPECT_EQ(kEventSignaled, pre_render_callback.Wait())
368 << "Timed out while waiting for pre-render callback.";
369 EXPECT_EQ(kEventSignaled, renderer.Wait())
370 << "Timed out while waiting for the frame to render.";
371
372 StopSending();
373
374 sender_transport.StopSending();
375 receiver_transport.StopSending();
376
377 DestroyStreams();
378}
379
pbos@webrtc.orgc5b5ad12013-10-21 09:02:30 +0000380TEST_F(CallTest, TransmitsFirstFrame) {
381 class Renderer : public VideoRenderer {
382 public:
383 Renderer() : event_(EventWrapper::Create()) {}
384
385 virtual void RenderFrame(const I420VideoFrame& video_frame,
386 int /*time_to_render_ms*/) OVERRIDE {
387 event_->Set();
388 }
389
390 EventTypeWrapper Wait() { return event_->Wait(kDefaultTimeoutMs); }
391
392 scoped_ptr<EventWrapper> event_;
393 } renderer;
394
395 test::DirectTransport sender_transport, receiver_transport;
396
397 CreateCalls(Call::Config(&sender_transport),
398 Call::Config(&receiver_transport));
399
400 sender_transport.SetReceiver(receiver_call_->Receiver());
401 receiver_transport.SetReceiver(sender_call_->Receiver());
402
403 CreateTestConfigs();
404 receive_config_.renderer = &renderer;
405
406 CreateStreams();
407 StartSending();
408
409 scoped_ptr<test::FrameGenerator> frame_generator(test::FrameGenerator::Create(
pbos@webrtc.orge2a7a772014-03-19 08:43:57 +0000410 send_config_.encoder_settings.streams[0].width,
411 send_config_.encoder_settings.streams[0].height));
pbos@webrtc.orgc33d37c2013-12-11 16:26:16 +0000412 send_stream_->Input()->SwapFrame(frame_generator->NextFrame());
pbos@webrtc.orgc5b5ad12013-10-21 09:02:30 +0000413
414 EXPECT_EQ(kEventSignaled, renderer.Wait())
415 << "Timed out while waiting for the frame to render.";
416
417 StopSending();
418
419 sender_transport.StopSending();
420 receiver_transport.StopSending();
421
422 DestroyStreams();
423}
424
pbos@webrtc.org4b50db12013-12-03 10:13:04 +0000425TEST_F(CallTest, ReceiverUsesLocalSsrc) {
426 class SyncRtcpObserver : public test::RtpRtcpObserver {
427 public:
428 SyncRtcpObserver() : test::RtpRtcpObserver(kDefaultTimeoutMs) {}
429
430 virtual Action OnReceiveRtcp(const uint8_t* packet,
431 size_t length) OVERRIDE {
432 RTCPUtility::RTCPParserV2 parser(packet, length, true);
433 EXPECT_TRUE(parser.IsValid());
434 uint32_t ssrc = 0;
435 ssrc |= static_cast<uint32_t>(packet[4]) << 24;
436 ssrc |= static_cast<uint32_t>(packet[5]) << 16;
437 ssrc |= static_cast<uint32_t>(packet[6]) << 8;
438 ssrc |= static_cast<uint32_t>(packet[7]) << 0;
439 EXPECT_EQ(kReceiverLocalSsrc, ssrc);
440 observation_complete_->Set();
441
442 return SEND_PACKET;
443 }
444 } observer;
445
446 CreateCalls(Call::Config(observer.SendTransport()),
447 Call::Config(observer.ReceiveTransport()));
448
449 observer.SetReceivers(receiver_call_->Receiver(), sender_call_->Receiver());
450
451 CreateTestConfigs();
452
453 CreateStreams();
454 CreateFrameGenerator();
455 StartSending();
456
457 EXPECT_EQ(kEventSignaled, observer.Wait())
458 << "Timed out while waiting for a receiver RTCP packet to be sent.";
459
460 StopSending();
461
462 observer.StopSending();
463
464 DestroyStreams();
465}
466
pbos@webrtc.org362e3e52013-09-27 10:54:10 +0000467TEST_F(CallTest, ReceivesAndRetransmitsNack) {
pbos@webrtc.orgce851092013-08-05 12:01:36 +0000468 NackObserver observer;
469
pbos@webrtc.orgb5d2d162013-10-02 13:36:09 +0000470 CreateCalls(Call::Config(observer.SendTransport()),
471 Call::Config(observer.ReceiveTransport()));
pbos@webrtc.orgce851092013-08-05 12:01:36 +0000472
pbos@webrtc.org8ce445e2013-08-19 16:09:34 +0000473 observer.SetReceivers(receiver_call_->Receiver(), sender_call_->Receiver());
pbos@webrtc.orgce851092013-08-05 12:01:36 +0000474
pbos@webrtc.org8ce445e2013-08-19 16:09:34 +0000475 CreateTestConfigs();
476 int rtp_history_ms = 1000;
477 send_config_.rtp.nack.rtp_history_ms = rtp_history_ms;
478 receive_config_.rtp.nack.rtp_history_ms = rtp_history_ms;
pbos@webrtc.orgce851092013-08-05 12:01:36 +0000479
pbos@webrtc.org8ce445e2013-08-19 16:09:34 +0000480 CreateStreams();
481 CreateFrameGenerator();
pbos@webrtc.org8ce445e2013-08-19 16:09:34 +0000482 StartSending();
pbos@webrtc.orgce851092013-08-05 12:01:36 +0000483
pbos@webrtc.org8ce445e2013-08-19 16:09:34 +0000484 // Wait() waits for an event triggered when NACKs have been received, NACKed
485 // packets retransmitted and frames rendered again.
pbos@webrtc.orgce851092013-08-05 12:01:36 +0000486 EXPECT_EQ(kEventSignaled, observer.Wait());
487
pbos@webrtc.org8ce445e2013-08-19 16:09:34 +0000488 StopSending();
pbos@webrtc.orgce851092013-08-05 12:01:36 +0000489
pbos@webrtc.orgfe881f62013-08-12 12:59:04 +0000490 observer.StopSending();
pbos@webrtc.org618a0ec2013-09-09 08:26:30 +0000491
492 DestroyStreams();
pbos@webrtc.orgce851092013-08-05 12:01:36 +0000493}
494
pbos@webrtc.orgea15f8d2014-04-08 11:21:45 +0000495TEST_F(CallTest, CanReceiveFec) {
496 class FecRenderObserver : public test::RtpRtcpObserver, public VideoRenderer {
497 public:
498 FecRenderObserver()
499 : RtpRtcpObserver(kDefaultTimeoutMs),
500 state_(kFirstPacket),
501 protected_sequence_number_(0),
502 protected_frame_timestamp_(0) {}
503
504 private:
505 virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE {
506 RTPHeader header;
507 EXPECT_TRUE(parser_->Parse(packet, static_cast<int>(length), &header));
508
509 EXPECT_EQ(kRedPayloadType, header.payloadType);
510 int encapsulated_payload_type =
511 static_cast<int>(packet[header.headerLength]);
512 if (encapsulated_payload_type != kSendPayloadType)
513 EXPECT_EQ(kUlpfecPayloadType, encapsulated_payload_type);
514
515 switch(state_) {
516 case kFirstPacket:
517 state_ = kDropEveryOtherPacketUntilFec;
518 break;
519 case kDropEveryOtherPacketUntilFec:
520 if (encapsulated_payload_type == kUlpfecPayloadType) {
521 state_ = kDropNextMediaPacket;
522 return SEND_PACKET;
523 }
524 if (header.sequenceNumber % 2 == 0)
525 return DROP_PACKET;
526 break;
527 case kDropNextMediaPacket:
528 if (encapsulated_payload_type == kSendPayloadType) {
529 protected_sequence_number_ = header.sequenceNumber;
530 protected_frame_timestamp_ = header.timestamp;
531 state_ = kProtectedPacketDropped;
532 return DROP_PACKET;
533 }
534 break;
535 case kProtectedPacketDropped:
536 EXPECT_NE(header.sequenceNumber, protected_sequence_number_)
537 << "Protected packet retransmitted. Should not happen with FEC.";
538 break;
539 }
540
541 return SEND_PACKET;
542 }
543
544 virtual void RenderFrame(const I420VideoFrame& video_frame,
545 int time_to_render_ms) OVERRIDE {
546 CriticalSectionScoped crit_(lock_.get());
547 // Rendering frame with timestamp associated with dropped packet -> FEC
548 // protection worked.
549 if (state_ == kProtectedPacketDropped &&
550 video_frame.timestamp() == protected_frame_timestamp_) {
551 observation_complete_->Set();
552 }
553 }
554
555 enum {
556 kFirstPacket,
557 kDropEveryOtherPacketUntilFec,
558 kDropNextMediaPacket,
559 kProtectedPacketDropped,
560 } state_;
561
562 uint32_t protected_sequence_number_;
563 uint32_t protected_frame_timestamp_;
564 } observer;
565
566 CreateCalls(Call::Config(observer.SendTransport()),
567 Call::Config(observer.ReceiveTransport()));
568
569 observer.SetReceivers(receiver_call_->Receiver(), sender_call_->Receiver());
570
571 CreateTestConfigs();
572 // TODO(pbos): Run this test with combined NACK/FEC enabled as well.
573 // int rtp_history_ms = 1000;
574 // receive_config_.rtp.nack.rtp_history_ms = rtp_history_ms;
575 // send_config_.rtp.nack.rtp_history_ms = rtp_history_ms;
576 send_config_.rtp.fec.red_payload_type = kRedPayloadType;
577 send_config_.rtp.fec.ulpfec_payload_type = kUlpfecPayloadType;
578
579 receive_config_.rtp.fec.red_payload_type = kRedPayloadType;
580 receive_config_.rtp.fec.ulpfec_payload_type = kUlpfecPayloadType;
581 receive_config_.renderer = &observer;
582
583 CreateStreams();
584 CreateFrameGenerator();
585 StartSending();
586
587 // Wait() waits for an event triggered when NACKs have been received, NACKed
588 // packets retransmitted and frames rendered again.
589 EXPECT_EQ(kEventSignaled, observer.Wait());
590
591 StopSending();
592
593 observer.StopSending();
594
595 DestroyStreams();
596}
597
pbos@webrtc.orgc71929d2014-01-24 09:30:53 +0000598// This test drops second RTP packet with a marker bit set, makes sure it's
599// retransmitted and renders. Retransmission SSRCs are also checked.
600void CallTest::DecodesRetransmittedFrame(bool retransmit_over_rtx) {
601 static const int kDroppedFrameNumber = 2;
602 class RetransmissionObserver : public test::RtpRtcpObserver,
603 public I420FrameCallback {
604 public:
605 RetransmissionObserver(bool expect_rtx)
606 : RtpRtcpObserver(kDefaultTimeoutMs),
607 retransmission_ssrc_(expect_rtx ? kSendRtxSsrc : kSendSsrc),
608 retransmission_payload_type_(expect_rtx ? kSendRtxPayloadType
609 : kSendPayloadType),
610 marker_bits_observed_(0),
611 retransmitted_timestamp_(0),
612 frame_retransmitted_(false) {}
613
614 private:
615 virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE {
616 RTPHeader header;
617 EXPECT_TRUE(parser_->Parse(packet, static_cast<int>(length), &header));
618
619 if (header.timestamp == retransmitted_timestamp_) {
620 EXPECT_EQ(retransmission_ssrc_, header.ssrc);
621 EXPECT_EQ(retransmission_payload_type_, header.payloadType);
622 frame_retransmitted_ = true;
623 return SEND_PACKET;
624 }
625
626 EXPECT_EQ(kSendSsrc, header.ssrc);
627 EXPECT_EQ(kSendPayloadType, header.payloadType);
628
629 // Found the second frame's final packet, drop this and expect a
630 // retransmission.
631 if (header.markerBit && ++marker_bits_observed_ == kDroppedFrameNumber) {
632 retransmitted_timestamp_ = header.timestamp;
633 return DROP_PACKET;
634 }
635
636 return SEND_PACKET;
637 }
638
639 virtual void FrameCallback(I420VideoFrame* frame) OVERRIDE {
640 CriticalSectionScoped crit_(lock_.get());
641 if (frame->timestamp() == retransmitted_timestamp_) {
642 EXPECT_TRUE(frame_retransmitted_);
643 observation_complete_->Set();
644 }
645 }
646
647 const uint32_t retransmission_ssrc_;
648 const int retransmission_payload_type_;
649 int marker_bits_observed_;
650 uint32_t retransmitted_timestamp_;
651 bool frame_retransmitted_;
652 } observer(retransmit_over_rtx);
653
654 CreateCalls(Call::Config(observer.SendTransport()),
655 Call::Config(observer.ReceiveTransport()));
656
657 observer.SetReceivers(receiver_call_->Receiver(), sender_call_->Receiver());
658
659 CreateTestConfigs();
660 send_config_.rtp.nack.rtp_history_ms =
661 receive_config_.rtp.nack.rtp_history_ms = 1000;
662 if (retransmit_over_rtx) {
663 send_config_.rtp.rtx.ssrcs.push_back(kSendRtxSsrc);
664 send_config_.rtp.rtx.payload_type = kSendRtxPayloadType;
pbos@webrtc.orge2a7a772014-03-19 08:43:57 +0000665 int payload_type = send_config_.encoder_settings.payload_type;
pbos@webrtc.orgc71929d2014-01-24 09:30:53 +0000666 receive_config_.rtp.rtx[payload_type].ssrc = kSendRtxSsrc;
667 receive_config_.rtp.rtx[payload_type].payload_type = kSendRtxPayloadType;
668 }
669 receive_config_.pre_render_callback = &observer;
670
671 CreateStreams();
672 CreateFrameGenerator();
673 StartSending();
674
675 EXPECT_EQ(kEventSignaled, observer.Wait())
676 << "Timed out while waiting for retransmission to render.";
677
678 StopSending();
679 observer.StopSending();
680 DestroyStreams();
681}
682
683TEST_F(CallTest, DecodesRetransmittedFrame) {
684 DecodesRetransmittedFrame(false);
685}
686
687TEST_F(CallTest, DecodesRetransmittedFrameOverRtx) {
688 DecodesRetransmittedFrame(true);
689}
690
pbos@webrtc.org63301bd2013-10-21 10:34:43 +0000691TEST_F(CallTest, UsesFrameCallbacks) {
692 static const int kWidth = 320;
693 static const int kHeight = 240;
694
695 class Renderer : public VideoRenderer {
696 public:
697 Renderer() : event_(EventWrapper::Create()) {}
698
699 virtual void RenderFrame(const I420VideoFrame& video_frame,
700 int /*time_to_render_ms*/) OVERRIDE {
701 EXPECT_EQ(0, *video_frame.buffer(kYPlane))
702 << "Rendered frame should have zero luma which is applied by the "
703 "pre-render callback.";
704 event_->Set();
705 }
706
707 EventTypeWrapper Wait() { return event_->Wait(kDefaultTimeoutMs); }
708 scoped_ptr<EventWrapper> event_;
709 } renderer;
710
711 class TestFrameCallback : public I420FrameCallback {
712 public:
713 TestFrameCallback(int expected_luma_byte, int next_luma_byte)
714 : event_(EventWrapper::Create()),
715 expected_luma_byte_(expected_luma_byte),
716 next_luma_byte_(next_luma_byte) {}
717
718 EventTypeWrapper Wait() { return event_->Wait(kDefaultTimeoutMs); }
719
720 private:
721 virtual void FrameCallback(I420VideoFrame* frame) {
722 EXPECT_EQ(kWidth, frame->width())
723 << "Width not as expected, callback done before resize?";
724 EXPECT_EQ(kHeight, frame->height())
725 << "Height not as expected, callback done before resize?";
726
727 // Previous luma specified, observed luma should be fairly close.
728 if (expected_luma_byte_ != -1) {
729 EXPECT_NEAR(expected_luma_byte_, *frame->buffer(kYPlane), 10);
730 }
731
732 memset(frame->buffer(kYPlane),
733 next_luma_byte_,
734 frame->allocated_size(kYPlane));
735
736 event_->Set();
737 }
738
739 scoped_ptr<EventWrapper> event_;
740 int expected_luma_byte_;
741 int next_luma_byte_;
742 };
743
744 TestFrameCallback pre_encode_callback(-1, 255); // Changes luma to 255.
745 TestFrameCallback pre_render_callback(255, 0); // Changes luma from 255 to 0.
746
747 test::DirectTransport sender_transport, receiver_transport;
748
749 CreateCalls(Call::Config(&sender_transport),
750 Call::Config(&receiver_transport));
751
752 sender_transport.SetReceiver(receiver_call_->Receiver());
753 receiver_transport.SetReceiver(sender_call_->Receiver());
754
755 CreateTestConfigs();
pbos@webrtc.orge2a7a772014-03-19 08:43:57 +0000756 scoped_ptr<VP8Encoder> encoder(VP8Encoder::Create());
757 send_config_.encoder_settings.encoder = encoder.get();
758 send_config_.encoder_settings.payload_name = "VP8";
759 ASSERT_EQ(1u, send_config_.encoder_settings.streams.size())
760 << "Test setup error.";
761 send_config_.encoder_settings.streams[0].width = kWidth;
762 send_config_.encoder_settings.streams[0].height = kHeight;
pbos@webrtc.org63301bd2013-10-21 10:34:43 +0000763 send_config_.pre_encode_callback = &pre_encode_callback;
pbos@webrtc.orge2a7a772014-03-19 08:43:57 +0000764 receive_config_.codecs.clear();
765 VideoCodec codec =
766 test::CreateDecoderVideoCodec(send_config_.encoder_settings);
767 receive_config_.external_decoders.clear();
768 receive_config_.codecs.push_back(codec);
pbos@webrtc.org63301bd2013-10-21 10:34:43 +0000769 receive_config_.pre_render_callback = &pre_render_callback;
770 receive_config_.renderer = &renderer;
771
772 CreateStreams();
773 StartSending();
774
775 // Create frames that are smaller than the send width/height, this is done to
776 // check that the callbacks are done after processing video.
777 scoped_ptr<test::FrameGenerator> frame_generator(
778 test::FrameGenerator::Create(kWidth / 2, kHeight / 2));
pbos@webrtc.orgc33d37c2013-12-11 16:26:16 +0000779 send_stream_->Input()->SwapFrame(frame_generator->NextFrame());
pbos@webrtc.org63301bd2013-10-21 10:34:43 +0000780
781 EXPECT_EQ(kEventSignaled, pre_encode_callback.Wait())
782 << "Timed out while waiting for pre-encode callback.";
783 EXPECT_EQ(kEventSignaled, pre_render_callback.Wait())
784 << "Timed out while waiting for pre-render callback.";
785 EXPECT_EQ(kEventSignaled, renderer.Wait())
786 << "Timed out while waiting for the frame to render.";
787
788 StopSending();
789
790 sender_transport.StopSending();
791 receiver_transport.StopSending();
792
793 DestroyStreams();
794}
795
pbos@webrtc.org28a11662013-09-19 14:22:12 +0000796class PliObserver : public test::RtpRtcpObserver, public VideoRenderer {
pbos@webrtc.org8ce445e2013-08-19 16:09:34 +0000797 static const int kInverseDropProbability = 16;
pbos@webrtc.orgbf6d5722013-09-09 15:04:25 +0000798
pbos@webrtc.org8ce445e2013-08-19 16:09:34 +0000799 public:
pbos@webrtc.org28a11662013-09-19 14:22:12 +0000800 explicit PliObserver(bool nack_enabled)
pbos@webrtc.org51e01012013-10-17 14:14:42 +0000801 : test::RtpRtcpObserver(kLongTimeoutMs),
pbos@webrtc.org8ce445e2013-08-19 16:09:34 +0000802 nack_enabled_(nack_enabled),
mflodman@webrtc.org6c172c52013-12-18 09:45:45 +0000803 highest_dropped_timestamp_(0),
804 frames_to_drop_(0),
pbos@webrtc.org8ce445e2013-08-19 16:09:34 +0000805 received_pli_(false) {}
806
807 virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE {
808 RTPHeader header;
pbos@webrtc.orgc71929d2014-01-24 09:30:53 +0000809 EXPECT_TRUE(parser_->Parse(packet, static_cast<int>(length), &header));
pbos@webrtc.org8ce445e2013-08-19 16:09:34 +0000810
mflodman@webrtc.org6c172c52013-12-18 09:45:45 +0000811 // Drop all retransmitted packets to force a PLI.
812 if (header.timestamp <= highest_dropped_timestamp_)
pbos@webrtc.org8ce445e2013-08-19 16:09:34 +0000813 return DROP_PACKET;
814
mflodman@webrtc.org6c172c52013-12-18 09:45:45 +0000815 if (frames_to_drop_ > 0) {
816 highest_dropped_timestamp_ = header.timestamp;
817 --frames_to_drop_;
pbos@webrtc.org8ce445e2013-08-19 16:09:34 +0000818 return DROP_PACKET;
819 }
820
pbos@webrtc.org8ce445e2013-08-19 16:09:34 +0000821 return SEND_PACKET;
822 }
823
824 virtual Action OnReceiveRtcp(const uint8_t* packet, size_t length) OVERRIDE {
825 RTCPUtility::RTCPParserV2 parser(packet, length, true);
826 EXPECT_TRUE(parser.IsValid());
827
828 for (RTCPUtility::RTCPPacketTypes packet_type = parser.Begin();
829 packet_type != RTCPUtility::kRtcpNotValidCode;
830 packet_type = parser.Iterate()) {
831 if (!nack_enabled_)
832 EXPECT_NE(packet_type, RTCPUtility::kRtcpRtpfbNackCode);
833
834 if (packet_type == RTCPUtility::kRtcpPsfbPliCode) {
835 received_pli_ = true;
836 break;
837 }
838 }
839 return SEND_PACKET;
840 }
841
pbos@webrtc.org28a11662013-09-19 14:22:12 +0000842 virtual void RenderFrame(const I420VideoFrame& video_frame,
843 int time_to_render_ms) OVERRIDE {
844 CriticalSectionScoped crit_(lock_.get());
mflodman@webrtc.org6c172c52013-12-18 09:45:45 +0000845 if (received_pli_ && video_frame.timestamp() > highest_dropped_timestamp_) {
pbos@webrtc.org28a11662013-09-19 14:22:12 +0000846 observation_complete_->Set();
pbos@webrtc.org8ce445e2013-08-19 16:09:34 +0000847 }
mflodman@webrtc.org6c172c52013-12-18 09:45:45 +0000848 if (!received_pli_)
849 frames_to_drop_ = kPacketsToDrop;
pbos@webrtc.org8ce445e2013-08-19 16:09:34 +0000850 }
851
852 private:
mflodman@webrtc.org6c172c52013-12-18 09:45:45 +0000853 static const int kPacketsToDrop = 1;
854
pbos@webrtc.org8ce445e2013-08-19 16:09:34 +0000855 bool nack_enabled_;
mflodman@webrtc.org6c172c52013-12-18 09:45:45 +0000856 uint32_t highest_dropped_timestamp_;
857 int frames_to_drop_;
pbos@webrtc.org8ce445e2013-08-19 16:09:34 +0000858 bool received_pli_;
859};
860
pbos@webrtc.org28a11662013-09-19 14:22:12 +0000861void CallTest::ReceivesPliAndRecovers(int rtp_history_ms) {
pbos@webrtc.org8ce445e2013-08-19 16:09:34 +0000862 PliObserver observer(rtp_history_ms > 0);
863
pbos@webrtc.orgb5d2d162013-10-02 13:36:09 +0000864 CreateCalls(Call::Config(observer.SendTransport()),
865 Call::Config(observer.ReceiveTransport()));
pbos@webrtc.org8ce445e2013-08-19 16:09:34 +0000866
867 observer.SetReceivers(receiver_call_->Receiver(), sender_call_->Receiver());
868
869 CreateTestConfigs();
870 send_config_.rtp.nack.rtp_history_ms = rtp_history_ms;
871 receive_config_.rtp.nack.rtp_history_ms = rtp_history_ms;
pbos@webrtc.org28a11662013-09-19 14:22:12 +0000872 receive_config_.renderer = &observer;
pbos@webrtc.org8ce445e2013-08-19 16:09:34 +0000873
874 CreateStreams();
875 CreateFrameGenerator();
pbos@webrtc.org8ce445e2013-08-19 16:09:34 +0000876 StartSending();
877
878 // Wait() waits for an event triggered when Pli has been received and frames
879 // have been rendered afterwards.
880 EXPECT_EQ(kEventSignaled, observer.Wait());
881
882 StopSending();
883
pbos@webrtc.org8ce445e2013-08-19 16:09:34 +0000884 observer.StopSending();
pbos@webrtc.org618a0ec2013-09-09 08:26:30 +0000885
886 DestroyStreams();
pbos@webrtc.org8ce445e2013-08-19 16:09:34 +0000887}
888
pbos@webrtc.org362e3e52013-09-27 10:54:10 +0000889TEST_F(CallTest, ReceivesPliAndRecoversWithNack) {
pbos@webrtc.org8ce445e2013-08-19 16:09:34 +0000890 ReceivesPliAndRecovers(1000);
891}
892
893// TODO(pbos): Enable this when 2250 is resolved.
pbos@webrtc.org362e3e52013-09-27 10:54:10 +0000894TEST_F(CallTest, DISABLED_ReceivesPliAndRecoversWithoutNack) {
pbos@webrtc.org8ce445e2013-08-19 16:09:34 +0000895 ReceivesPliAndRecovers(0);
896}
897
pbos@webrtc.org362e3e52013-09-27 10:54:10 +0000898TEST_F(CallTest, SurvivesIncomingRtpPacketsToDestroyedReceiveStream) {
pbos@webrtc.org00208582013-09-05 12:38:54 +0000899 class PacketInputObserver : public PacketReceiver {
900 public:
901 explicit PacketInputObserver(PacketReceiver* receiver)
902 : receiver_(receiver), delivered_packet_(EventWrapper::Create()) {}
903
pbos@webrtc.org51e01012013-10-17 14:14:42 +0000904 EventTypeWrapper Wait() {
905 return delivered_packet_->Wait(kDefaultTimeoutMs);
906 }
pbos@webrtc.org00208582013-09-05 12:38:54 +0000907
908 private:
909 virtual bool DeliverPacket(const uint8_t* packet, size_t length) {
910 if (RtpHeaderParser::IsRtcp(packet, static_cast<int>(length))) {
911 return receiver_->DeliverPacket(packet, length);
912 } else {
913 EXPECT_FALSE(receiver_->DeliverPacket(packet, length));
914 delivered_packet_->Set();
915 return false;
916 }
917 }
918
919 PacketReceiver* receiver_;
920 scoped_ptr<EventWrapper> delivered_packet_;
921 };
922
923 test::DirectTransport send_transport, receive_transport;
924
pbos@webrtc.orgb5d2d162013-10-02 13:36:09 +0000925 CreateCalls(Call::Config(&send_transport), Call::Config(&receive_transport));
pbos@webrtc.org00208582013-09-05 12:38:54 +0000926 PacketInputObserver input_observer(receiver_call_->Receiver());
927
928 send_transport.SetReceiver(&input_observer);
929 receive_transport.SetReceiver(sender_call_->Receiver());
930
931 CreateTestConfigs();
932
933 CreateStreams();
934 CreateFrameGenerator();
pbos@webrtc.org00208582013-09-05 12:38:54 +0000935 StartSending();
936
pbos@webrtc.org12a93e02013-11-21 13:49:43 +0000937 receiver_call_->DestroyVideoReceiveStream(receive_stream_);
pbos@webrtc.org00208582013-09-05 12:38:54 +0000938 receive_stream_ = NULL;
939
940 // Wait() waits for a received packet.
941 EXPECT_EQ(kEventSignaled, input_observer.Wait());
942
943 StopSending();
944
945 DestroyStreams();
946
947 send_transport.StopSending();
948 receive_transport.StopSending();
949}
pbos@webrtc.orgc5080a92013-10-01 11:33:24 +0000950
pbos@webrtc.org51e01012013-10-17 14:14:42 +0000951void CallTest::RespectsRtcpMode(newapi::RtcpMode rtcp_mode) {
952 static const int kRtpHistoryMs = 1000;
953 static const int kNumCompoundRtcpPacketsToObserve = 10;
954 class RtcpModeObserver : public test::RtpRtcpObserver {
955 public:
pbos@webrtc.orgd05597a2013-12-05 12:11:47 +0000956 explicit RtcpModeObserver(newapi::RtcpMode rtcp_mode)
pbos@webrtc.org51e01012013-10-17 14:14:42 +0000957 : test::RtpRtcpObserver(kDefaultTimeoutMs),
958 rtcp_mode_(rtcp_mode),
959 sent_rtp_(0),
960 sent_rtcp_(0) {}
961
962 private:
963 virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE {
964 if (++sent_rtp_ % 3 == 0)
965 return DROP_PACKET;
966
967 return SEND_PACKET;
968 }
969
970 virtual Action OnReceiveRtcp(const uint8_t* packet,
971 size_t length) OVERRIDE {
972 ++sent_rtcp_;
973 RTCPUtility::RTCPParserV2 parser(packet, length, true);
974 EXPECT_TRUE(parser.IsValid());
975
976 RTCPUtility::RTCPPacketTypes packet_type = parser.Begin();
977 bool has_report_block = false;
978 while (packet_type != RTCPUtility::kRtcpNotValidCode) {
979 EXPECT_NE(RTCPUtility::kRtcpSrCode, packet_type);
980 if (packet_type == RTCPUtility::kRtcpRrCode) {
981 has_report_block = true;
982 break;
983 }
984 packet_type = parser.Iterate();
985 }
986
987 switch (rtcp_mode_) {
988 case newapi::kRtcpCompound:
989 if (!has_report_block) {
990 ADD_FAILURE() << "Received RTCP packet without receiver report for "
991 "kRtcpCompound.";
992 observation_complete_->Set();
993 }
994
995 if (sent_rtcp_ >= kNumCompoundRtcpPacketsToObserve)
996 observation_complete_->Set();
997
998 break;
999 case newapi::kRtcpReducedSize:
1000 if (!has_report_block)
1001 observation_complete_->Set();
1002 break;
1003 }
1004
1005 return SEND_PACKET;
1006 }
1007
1008 newapi::RtcpMode rtcp_mode_;
1009 int sent_rtp_;
1010 int sent_rtcp_;
1011 } observer(rtcp_mode);
1012
1013 CreateCalls(Call::Config(observer.SendTransport()),
1014 Call::Config(observer.ReceiveTransport()));
1015
1016 observer.SetReceivers(receiver_call_->Receiver(), sender_call_->Receiver());
1017
1018 CreateTestConfigs();
1019 send_config_.rtp.nack.rtp_history_ms = kRtpHistoryMs;
1020 receive_config_.rtp.nack.rtp_history_ms = kRtpHistoryMs;
1021 receive_config_.rtp.rtcp_mode = rtcp_mode;
1022
1023 CreateStreams();
1024 CreateFrameGenerator();
1025 StartSending();
1026
1027 EXPECT_EQ(kEventSignaled, observer.Wait())
1028 << (rtcp_mode == newapi::kRtcpCompound
1029 ? "Timed out before observing enough compound packets."
1030 : "Timed out before receiving a non-compound RTCP packet.");
1031
1032 StopSending();
1033 observer.StopSending();
1034 DestroyStreams();
1035}
1036
1037TEST_F(CallTest, UsesRtcpCompoundMode) {
1038 RespectsRtcpMode(newapi::kRtcpCompound);
1039}
1040
1041TEST_F(CallTest, UsesRtcpReducedSizeMode) {
1042 RespectsRtcpMode(newapi::kRtcpReducedSize);
1043}
1044
pbos@webrtc.orgc5080a92013-10-01 11:33:24 +00001045// Test sets up a Call multiple senders with different resolutions and SSRCs.
1046// Another is set up to receive all three of these with different renderers.
1047// Each renderer verifies that it receives the expected resolution, and as soon
1048// as every renderer has received a frame, the test finishes.
1049TEST_F(CallTest, SendsAndReceivesMultipleStreams) {
1050 static const size_t kNumStreams = 3;
1051
1052 class VideoOutputObserver : public VideoRenderer {
1053 public:
pbos@webrtc.org43835392013-12-06 15:48:17 +00001054 VideoOutputObserver(test::FrameGeneratorCapturer** capturer,
1055 int width,
1056 int height)
1057 : capturer_(capturer),
1058 width_(width),
1059 height_(height),
1060 done_(EventWrapper::Create()) {}
pbos@webrtc.orgc5080a92013-10-01 11:33:24 +00001061
1062 virtual void RenderFrame(const I420VideoFrame& video_frame,
1063 int time_to_render_ms) OVERRIDE {
1064 EXPECT_EQ(width_, video_frame.width());
1065 EXPECT_EQ(height_, video_frame.height());
pbos@webrtc.org43835392013-12-06 15:48:17 +00001066 (*capturer_)->Stop();
pbos@webrtc.orgc5080a92013-10-01 11:33:24 +00001067 done_->Set();
1068 }
1069
pbos@webrtc.orge2a7a772014-03-19 08:43:57 +00001070 EventTypeWrapper Wait() { return done_->Wait(kDefaultTimeoutMs); }
pbos@webrtc.orgc5080a92013-10-01 11:33:24 +00001071
1072 private:
pbos@webrtc.org43835392013-12-06 15:48:17 +00001073 test::FrameGeneratorCapturer** capturer_;
pbos@webrtc.orgc5080a92013-10-01 11:33:24 +00001074 int width_;
1075 int height_;
1076 scoped_ptr<EventWrapper> done_;
1077 };
1078
1079 struct {
1080 uint32_t ssrc;
1081 int width;
1082 int height;
1083 } codec_settings[kNumStreams] = {{1, 640, 480}, {2, 320, 240}, {3, 240, 160}};
1084
1085 test::DirectTransport sender_transport, receiver_transport;
1086 scoped_ptr<Call> sender_call(Call::Create(Call::Config(&sender_transport)));
1087 scoped_ptr<Call> receiver_call(
1088 Call::Create(Call::Config(&receiver_transport)));
1089 sender_transport.SetReceiver(receiver_call->Receiver());
1090 receiver_transport.SetReceiver(sender_call->Receiver());
1091
1092 VideoSendStream* send_streams[kNumStreams];
1093 VideoReceiveStream* receive_streams[kNumStreams];
1094
1095 VideoOutputObserver* observers[kNumStreams];
1096 test::FrameGeneratorCapturer* frame_generators[kNumStreams];
1097
pbos@webrtc.orge2a7a772014-03-19 08:43:57 +00001098 scoped_ptr<VP8Encoder> encoders[kNumStreams];
1099 for (size_t i = 0; i < kNumStreams; ++i)
1100 encoders[i].reset(VP8Encoder::Create());
1101
pbos@webrtc.orgc5080a92013-10-01 11:33:24 +00001102 for (size_t i = 0; i < kNumStreams; ++i) {
1103 uint32_t ssrc = codec_settings[i].ssrc;
1104 int width = codec_settings[i].width;
1105 int height = codec_settings[i].height;
pbos@webrtc.org43835392013-12-06 15:48:17 +00001106 observers[i] = new VideoOutputObserver(&frame_generators[i], width, height);
pbos@webrtc.orgc5080a92013-10-01 11:33:24 +00001107
pbos@webrtc.orge2a7a772014-03-19 08:43:57 +00001108 VideoSendStream::Config send_config = sender_call->GetDefaultSendConfig();
1109 send_config.rtp.ssrcs.push_back(ssrc);
1110 send_config.encoder_settings =
1111 test::CreateEncoderSettings(encoders[i].get(), "VP8", 124, 1);
1112 VideoStream* stream = &send_config.encoder_settings.streams[0];
1113 stream->width = width;
1114 stream->height = height;
1115 stream->max_framerate = 5;
1116 stream->min_bitrate_bps = stream->target_bitrate_bps =
1117 stream->max_bitrate_bps = 100000;
1118 send_streams[i] = sender_call->CreateVideoSendStream(send_config);
1119 send_streams[i]->StartSending();
1120
pbos@webrtc.orgc5080a92013-10-01 11:33:24 +00001121 VideoReceiveStream::Config receive_config =
1122 receiver_call->GetDefaultReceiveConfig();
1123 receive_config.renderer = observers[i];
pbos@webrtc.org4b50db12013-12-03 10:13:04 +00001124 receive_config.rtp.remote_ssrc = ssrc;
1125 receive_config.rtp.local_ssrc = kReceiverLocalSsrc;
pbos@webrtc.orge2a7a772014-03-19 08:43:57 +00001126 VideoCodec codec =
1127 test::CreateDecoderVideoCodec(send_config.encoder_settings);
1128 receive_config.codecs.push_back(codec);
pbos@webrtc.org964d78e2013-11-20 10:40:25 +00001129 receive_streams[i] =
1130 receiver_call->CreateVideoReceiveStream(receive_config);
pbos@webrtc.org7f9f8402013-11-20 11:36:47 +00001131 receive_streams[i]->StartReceiving();
pbos@webrtc.orgc5080a92013-10-01 11:33:24 +00001132
pbos@webrtc.orgc5080a92013-10-01 11:33:24 +00001133 frame_generators[i] = test::FrameGeneratorCapturer::Create(
1134 send_streams[i]->Input(), width, height, 30, Clock::GetRealTimeClock());
1135 frame_generators[i]->Start();
1136 }
1137
1138 for (size_t i = 0; i < kNumStreams; ++i) {
pbos@webrtc.orge2a7a772014-03-19 08:43:57 +00001139 EXPECT_EQ(kEventSignaled, observers[i]->Wait())
1140 << "Timed out while waiting for observer " << i << " to render.";
pbos@webrtc.orgc5080a92013-10-01 11:33:24 +00001141 }
1142
1143 for (size_t i = 0; i < kNumStreams; ++i) {
1144 frame_generators[i]->Stop();
pbos@webrtc.org12a93e02013-11-21 13:49:43 +00001145 sender_call->DestroyVideoSendStream(send_streams[i]);
1146 receiver_call->DestroyVideoReceiveStream(receive_streams[i]);
pbos@webrtc.org471354f2013-12-16 14:55:54 +00001147 delete frame_generators[i];
pbos@webrtc.orgc5080a92013-10-01 11:33:24 +00001148 delete observers[i];
1149 }
1150
1151 sender_transport.StopSending();
1152 receiver_transport.StopSending();
pbos@webrtc.org46f72882013-12-16 12:24:44 +00001153};
stefan@webrtc.orge0284102013-11-18 11:45:11 +00001154
sprang@webrtc.org2e98d452013-11-26 11:41:59 +00001155TEST_F(CallTest, ObserversEncodedFrames) {
1156 class EncodedFrameTestObserver : public EncodedFrameObserver {
1157 public:
pbos@webrtc.orgc71929d2014-01-24 09:30:53 +00001158 EncodedFrameTestObserver()
1159 : length_(0),
1160 frame_type_(kFrameEmpty),
1161 called_(EventWrapper::Create()) {}
sprang@webrtc.org2e98d452013-11-26 11:41:59 +00001162 virtual ~EncodedFrameTestObserver() {}
1163
1164 virtual void EncodedFrameCallback(const EncodedFrame& encoded_frame) {
1165 frame_type_ = encoded_frame.frame_type_;
1166 length_ = encoded_frame.length_;
1167 buffer_.reset(new uint8_t[length_]);
1168 memcpy(buffer_.get(), encoded_frame.data_, length_);
1169 called_->Set();
1170 }
1171
pbos@webrtc.orgc71929d2014-01-24 09:30:53 +00001172 EventTypeWrapper Wait() { return called_->Wait(kDefaultTimeoutMs); }
sprang@webrtc.org2e98d452013-11-26 11:41:59 +00001173
1174 void ExpectEqualFrames(const EncodedFrameTestObserver& observer) {
1175 ASSERT_EQ(length_, observer.length_)
1176 << "Observed frames are of different lengths.";
1177 EXPECT_EQ(frame_type_, observer.frame_type_)
1178 << "Observed frames have different frame types.";
1179 EXPECT_EQ(0, memcmp(buffer_.get(), observer.buffer_.get(), length_))
1180 << "Observed encoded frames have different content.";
1181 }
1182
1183 private:
1184 scoped_ptr<uint8_t[]> buffer_;
1185 size_t length_;
1186 FrameType frame_type_;
1187 scoped_ptr<EventWrapper> called_;
1188 };
1189
1190 EncodedFrameTestObserver post_encode_observer;
1191 EncodedFrameTestObserver pre_decode_observer;
1192
1193 test::DirectTransport sender_transport, receiver_transport;
1194
1195 CreateCalls(Call::Config(&sender_transport),
1196 Call::Config(&receiver_transport));
1197
1198 sender_transport.SetReceiver(receiver_call_->Receiver());
1199 receiver_transport.SetReceiver(sender_call_->Receiver());
1200
1201 CreateTestConfigs();
1202 send_config_.post_encode_callback = &post_encode_observer;
1203 receive_config_.pre_decode_callback = &pre_decode_observer;
1204
1205 CreateStreams();
1206 StartSending();
1207
1208 scoped_ptr<test::FrameGenerator> frame_generator(test::FrameGenerator::Create(
pbos@webrtc.orge2a7a772014-03-19 08:43:57 +00001209 send_config_.encoder_settings.streams[0].width,
1210 send_config_.encoder_settings.streams[0].height));
pbos@webrtc.orgc33d37c2013-12-11 16:26:16 +00001211 send_stream_->Input()->SwapFrame(frame_generator->NextFrame());
sprang@webrtc.org2e98d452013-11-26 11:41:59 +00001212
1213 EXPECT_EQ(kEventSignaled, post_encode_observer.Wait())
1214 << "Timed out while waiting for send-side encoded-frame callback.";
1215
1216 EXPECT_EQ(kEventSignaled, pre_decode_observer.Wait())
1217 << "Timed out while waiting for pre-decode encoded-frame callback.";
1218
1219 post_encode_observer.ExpectEqualFrames(pre_decode_observer);
1220
1221 StopSending();
1222
1223 sender_transport.StopSending();
1224 receiver_transport.StopSending();
1225
1226 DestroyStreams();
1227}
mflodman@webrtc.org7ff40892013-12-13 16:36:28 +00001228
1229TEST_F(CallTest, ReceiveStreamSendsRemb) {
1230 class RembObserver : public test::RtpRtcpObserver {
1231 public:
1232 RembObserver() : test::RtpRtcpObserver(kDefaultTimeoutMs) {}
1233
1234 virtual Action OnReceiveRtcp(const uint8_t* packet,
1235 size_t length) OVERRIDE {
1236 RTCPUtility::RTCPParserV2 parser(packet, length, true);
1237 EXPECT_TRUE(parser.IsValid());
1238
1239 bool received_psfb = false;
1240 bool received_remb = false;
1241 RTCPUtility::RTCPPacketTypes packet_type = parser.Begin();
1242 while (packet_type != RTCPUtility::kRtcpNotValidCode) {
1243 if (packet_type == RTCPUtility::kRtcpPsfbRembCode) {
1244 const RTCPUtility::RTCPPacket& packet = parser.Packet();
1245 EXPECT_EQ(packet.PSFBAPP.SenderSSRC, kReceiverLocalSsrc);
1246 received_psfb = true;
1247 } else if (packet_type == RTCPUtility::kRtcpPsfbRembItemCode) {
1248 const RTCPUtility::RTCPPacket& packet = parser.Packet();
1249 EXPECT_GT(packet.REMBItem.BitRate, 0u);
1250 EXPECT_EQ(packet.REMBItem.NumberOfSSRCs, 1u);
1251 EXPECT_EQ(packet.REMBItem.SSRCs[0], kSendSsrc);
1252 received_remb = true;
1253 }
1254 packet_type = parser.Iterate();
1255 }
1256 if (received_psfb && received_remb)
1257 observation_complete_->Set();
1258 return SEND_PACKET;
1259 }
1260 } observer;
1261
1262 CreateCalls(Call::Config(observer.SendTransport()),
1263 Call::Config(observer.ReceiveTransport()));
1264 observer.SetReceivers(receiver_call_->Receiver(), sender_call_->Receiver());
1265 CreateTestConfigs();
1266 CreateStreams();
1267 CreateFrameGenerator();
1268 StartSending();
1269
1270 EXPECT_EQ(kEventSignaled, observer.Wait())
1271 << "Timed out while waiting for a receiver RTCP REMB packet to be sent.";
1272
1273 StopSending();
1274 observer.StopSending();
1275 DestroyStreams();
1276}
asapersson@webrtc.orgb4263e02014-01-20 08:34:49 +00001277
1278void CallTest::TestXrReceiverReferenceTimeReport(bool enable_rrtr) {
1279 static const int kNumRtcpReportPacketsToObserve = 5;
1280 class RtcpXrObserver : public test::RtpRtcpObserver {
1281 public:
1282 explicit RtcpXrObserver(bool enable_rrtr)
1283 : test::RtpRtcpObserver(kDefaultTimeoutMs),
1284 enable_rrtr_(enable_rrtr),
1285 sent_rtcp_sr_(0),
1286 sent_rtcp_rr_(0),
1287 sent_rtcp_rrtr_(0),
1288 sent_rtcp_dlrr_(0) {}
pbos@webrtc.orgc71929d2014-01-24 09:30:53 +00001289
asapersson@webrtc.orgb4263e02014-01-20 08:34:49 +00001290 private:
1291 // Receive stream should send RR packets (and RRTR packets if enabled).
1292 virtual Action OnReceiveRtcp(const uint8_t* packet,
1293 size_t length) OVERRIDE {
1294 RTCPUtility::RTCPParserV2 parser(packet, length, true);
1295 EXPECT_TRUE(parser.IsValid());
1296
1297 RTCPUtility::RTCPPacketTypes packet_type = parser.Begin();
1298 while (packet_type != RTCPUtility::kRtcpNotValidCode) {
1299 if (packet_type == RTCPUtility::kRtcpRrCode) {
1300 ++sent_rtcp_rr_;
pbos@webrtc.orgc71929d2014-01-24 09:30:53 +00001301 } else if (packet_type ==
1302 RTCPUtility::kRtcpXrReceiverReferenceTimeCode) {
asapersson@webrtc.orgb4263e02014-01-20 08:34:49 +00001303 ++sent_rtcp_rrtr_;
1304 }
1305 EXPECT_NE(packet_type, RTCPUtility::kRtcpSrCode);
1306 EXPECT_NE(packet_type, RTCPUtility::kRtcpXrDlrrReportBlockItemCode);
1307 packet_type = parser.Iterate();
1308 }
1309 return SEND_PACKET;
1310 }
1311 // Send stream should send SR packets (and DLRR packets if enabled).
1312 virtual Action OnSendRtcp(const uint8_t* packet, size_t length) {
1313 RTCPUtility::RTCPParserV2 parser(packet, length, true);
1314 EXPECT_TRUE(parser.IsValid());
1315
1316 RTCPUtility::RTCPPacketTypes packet_type = parser.Begin();
1317 while (packet_type != RTCPUtility::kRtcpNotValidCode) {
1318 if (packet_type == RTCPUtility::kRtcpSrCode) {
1319 ++sent_rtcp_sr_;
1320 } else if (packet_type == RTCPUtility::kRtcpXrDlrrReportBlockItemCode) {
1321 ++sent_rtcp_dlrr_;
1322 }
1323 EXPECT_NE(packet_type, RTCPUtility::kRtcpXrReceiverReferenceTimeCode);
1324 packet_type = parser.Iterate();
1325 }
1326 if (sent_rtcp_sr_ > kNumRtcpReportPacketsToObserve &&
1327 sent_rtcp_rr_ > kNumRtcpReportPacketsToObserve) {
1328 if (enable_rrtr_) {
1329 EXPECT_GT(sent_rtcp_rrtr_, 0);
1330 EXPECT_GT(sent_rtcp_dlrr_, 0);
1331 } else {
1332 EXPECT_EQ(0, sent_rtcp_rrtr_);
1333 EXPECT_EQ(0, sent_rtcp_dlrr_);
1334 }
1335 observation_complete_->Set();
1336 }
1337 return SEND_PACKET;
1338 }
1339 bool enable_rrtr_;
1340 int sent_rtcp_sr_;
1341 int sent_rtcp_rr_;
1342 int sent_rtcp_rrtr_;
1343 int sent_rtcp_dlrr_;
1344 } observer(enable_rrtr);
1345
1346 CreateCalls(Call::Config(observer.SendTransport()),
1347 Call::Config(observer.ReceiveTransport()));
pbos@webrtc.orgc71929d2014-01-24 09:30:53 +00001348 observer.SetReceivers(receiver_call_->Receiver(), sender_call_->Receiver());
asapersson@webrtc.orgb4263e02014-01-20 08:34:49 +00001349
1350 CreateTestConfigs();
1351 receive_config_.rtp.rtcp_mode = newapi::kRtcpReducedSize;
1352 receive_config_.rtp.rtcp_xr.receiver_reference_time_report = enable_rrtr;
1353
1354 CreateStreams();
1355 CreateFrameGenerator();
1356 StartSending();
1357
1358 EXPECT_EQ(kEventSignaled, observer.Wait())
1359 << "Timed out while waiting for RTCP SR/RR packets to be sent.";
1360
1361 StopSending();
1362 observer.StopSending();
1363 DestroyStreams();
1364}
1365
sprang@webrtc.orgc8ab7212014-02-07 12:06:29 +00001366class StatsObserver : public test::RtpRtcpObserver, public I420FrameCallback {
1367 public:
1368 StatsObserver()
1369 : test::RtpRtcpObserver(kLongTimeoutMs),
1370 receive_stream_(NULL),
1371 send_stream_(NULL),
1372 expected_receive_ssrc_(),
1373 expected_send_ssrcs_(),
1374 check_stats_event_(EventWrapper::Create()) {}
1375
1376 void SetExpectedReceiveSsrc(uint32_t ssrc) { expected_receive_ssrc_ = ssrc; }
1377
1378 void SetExpectedSendSsrcs(const std::vector<uint32_t>& ssrcs) {
1379 for (std::vector<uint32_t>::const_iterator it = ssrcs.begin();
1380 it != ssrcs.end();
1381 ++it) {
1382 expected_send_ssrcs_.insert(*it);
1383 }
1384 }
1385
1386 void SetExpectedCName(std::string cname) { expected_cname_ = cname; }
1387
1388 void SetReceiveStream(VideoReceiveStream* stream) {
1389 receive_stream_ = stream;
1390 }
1391
1392 void SetSendStream(VideoSendStream* stream) { send_stream_ = stream; }
1393
1394 void WaitForFilledStats() {
1395 Clock* clock = Clock::GetRealTimeClock();
1396 int64_t now = clock->TimeInMilliseconds();
1397 int64_t stop_time = now + kLongTimeoutMs;
1398 bool receive_ok = false;
1399 bool send_ok = false;
1400
1401 while (now < stop_time) {
1402 if (!receive_ok)
1403 receive_ok = CheckReceiveStats();
1404 if (!send_ok)
1405 send_ok = CheckSendStats();
1406
1407 if (receive_ok && send_ok)
1408 return;
1409
1410 int64_t time_until_timout_ = stop_time - now;
1411 if (time_until_timout_ > 0)
1412 check_stats_event_->Wait(time_until_timout_);
1413 now = clock->TimeInMilliseconds();
1414 }
1415
1416 ADD_FAILURE() << "Timed out waiting for filled stats.";
1417 for (std::map<std::string, bool>::const_iterator it =
1418 receive_stats_filled_.begin();
1419 it != receive_stats_filled_.end();
1420 ++it) {
1421 if (!it->second) {
1422 ADD_FAILURE() << "Missing receive stats: " << it->first;
1423 }
1424 }
1425
1426 for (std::map<std::string, bool>::const_iterator it =
1427 send_stats_filled_.begin();
1428 it != send_stats_filled_.end();
1429 ++it) {
1430 if (!it->second) {
1431 ADD_FAILURE() << "Missing send stats: " << it->first;
1432 }
1433 }
1434 }
1435
1436 private:
1437 virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE {
1438 check_stats_event_->Set();
1439 return SEND_PACKET;
1440 }
1441
1442 virtual Action OnSendRtcp(const uint8_t* packet, size_t length) OVERRIDE {
1443 check_stats_event_->Set();
1444 return SEND_PACKET;
1445 }
1446
1447 virtual Action OnReceiveRtp(const uint8_t* packet, size_t length) OVERRIDE {
1448 check_stats_event_->Set();
1449 return SEND_PACKET;
1450 }
1451
1452 virtual Action OnReceiveRtcp(const uint8_t* packet, size_t length) OVERRIDE {
1453 check_stats_event_->Set();
1454 return SEND_PACKET;
1455 }
1456
1457 virtual void FrameCallback(I420VideoFrame* video_frame) OVERRIDE {
1458 // Ensure that we have at least 5ms send side delay.
1459 int64_t render_time = video_frame->render_time_ms();
1460 if (render_time > 0)
1461 video_frame->set_render_time_ms(render_time - 5);
1462 }
1463
1464 bool CheckReceiveStats() {
1465 assert(receive_stream_ != NULL);
1466 VideoReceiveStream::Stats stats = receive_stream_->GetStats();
1467 EXPECT_EQ(expected_receive_ssrc_, stats.ssrc);
1468
1469 // Make sure all fields have been populated.
1470
1471 receive_stats_filled_["IncomingRate"] |=
1472 stats.network_frame_rate != 0 || stats.bitrate_bps != 0;
1473
1474 receive_stats_filled_["FrameCallback"] |= stats.decode_frame_rate != 0;
1475
1476 receive_stats_filled_["FrameRendered"] |= stats.render_frame_rate != 0;
1477
1478 receive_stats_filled_["StatisticsUpdated"] |=
1479 stats.rtcp_stats.cumulative_lost != 0 ||
1480 stats.rtcp_stats.extended_max_sequence_number != 0 ||
1481 stats.rtcp_stats.fraction_lost != 0 || stats.rtcp_stats.jitter != 0;
1482
1483 receive_stats_filled_["DataCountersUpdated"] |=
1484 stats.rtp_stats.bytes != 0 || stats.rtp_stats.fec_packets != 0 ||
1485 stats.rtp_stats.header_bytes != 0 || stats.rtp_stats.packets != 0 ||
1486 stats.rtp_stats.padding_bytes != 0 ||
1487 stats.rtp_stats.retransmitted_packets != 0;
1488
1489 receive_stats_filled_["CodecStats"] |=
1490 stats.avg_delay_ms != 0 || stats.discarded_packets != 0 ||
1491 stats.key_frames != 0 || stats.delta_frames != 0;
1492
1493 receive_stats_filled_["CName"] |= stats.c_name == expected_cname_;
1494
1495 return AllStatsFilled(receive_stats_filled_);
1496 }
1497
1498 bool CheckSendStats() {
1499 assert(send_stream_ != NULL);
1500 VideoSendStream::Stats stats = send_stream_->GetStats();
1501
1502 send_stats_filled_["NumStreams"] |=
1503 stats.substreams.size() == expected_send_ssrcs_.size();
1504
1505 send_stats_filled_["Delay"] |=
1506 stats.avg_delay_ms != 0 || stats.max_delay_ms != 0;
1507
1508 receive_stats_filled_["CName"] |= stats.c_name == expected_cname_;
1509
1510 for (std::map<uint32_t, StreamStats>::const_iterator it =
1511 stats.substreams.begin();
1512 it != stats.substreams.end();
1513 ++it) {
1514 EXPECT_TRUE(expected_send_ssrcs_.find(it->first) !=
1515 expected_send_ssrcs_.end());
1516
1517 send_stats_filled_[CompoundKey("IncomingRate", it->first)] |=
1518 stats.input_frame_rate != 0;
1519
1520 const StreamStats& stream_stats = it->second;
1521
1522 send_stats_filled_[CompoundKey("StatisticsUpdated", it->first)] |=
1523 stream_stats.rtcp_stats.cumulative_lost != 0 ||
1524 stream_stats.rtcp_stats.extended_max_sequence_number != 0 ||
1525 stream_stats.rtcp_stats.fraction_lost != 0;
1526
1527 send_stats_filled_[CompoundKey("DataCountersUpdated", it->first)] |=
1528 stream_stats.rtp_stats.fec_packets != 0 ||
1529 stream_stats.rtp_stats.padding_bytes != 0 ||
1530 stream_stats.rtp_stats.retransmitted_packets != 0 ||
1531 stream_stats.rtp_stats.packets != 0;
1532
1533 send_stats_filled_[CompoundKey("BitrateStatisticsObserver", it->first)] |=
1534 stream_stats.bitrate_bps != 0;
1535
1536 send_stats_filled_[CompoundKey("FrameCountObserver", it->first)] |=
1537 stream_stats.delta_frames != 0 || stream_stats.key_frames != 0;
1538
1539 send_stats_filled_[CompoundKey("OutgoingRate", it->first)] |=
1540 stats.encode_frame_rate != 0;
1541 }
1542
1543 return AllStatsFilled(send_stats_filled_);
1544 }
1545
1546 std::string CompoundKey(const char* name, uint32_t ssrc) {
1547 std::ostringstream oss;
1548 oss << name << "_" << ssrc;
1549 return oss.str();
1550 }
1551
1552 bool AllStatsFilled(const std::map<std::string, bool>& stats_map) {
1553 for (std::map<std::string, bool>::const_iterator it = stats_map.begin();
1554 it != stats_map.end();
1555 ++it) {
1556 if (!it->second)
1557 return false;
1558 }
1559 return true;
1560 }
1561
1562 VideoReceiveStream* receive_stream_;
1563 std::map<std::string, bool> receive_stats_filled_;
1564
1565 VideoSendStream* send_stream_;
1566 std::map<std::string, bool> send_stats_filled_;
1567
1568 uint32_t expected_receive_ssrc_;
1569 std::set<uint32_t> expected_send_ssrcs_;
1570 std::string expected_cname_;
1571
1572 scoped_ptr<EventWrapper> check_stats_event_;
1573};
1574
1575TEST_F(CallTest, GetStats) {
1576 StatsObserver observer;
1577
1578 CreateCalls(Call::Config(observer.SendTransport()),
1579 Call::Config(observer.ReceiveTransport()));
1580
1581 observer.SetReceivers(receiver_call_->Receiver(), sender_call_->Receiver());
1582
1583 CreateTestConfigs();
1584 send_config_.pre_encode_callback = &observer; // Used to inject delay.
1585 send_config_.rtp.c_name = "SomeCName";
1586
1587 observer.SetExpectedReceiveSsrc(receive_config_.rtp.local_ssrc);
1588 observer.SetExpectedSendSsrcs(send_config_.rtp.ssrcs);
1589 observer.SetExpectedCName(send_config_.rtp.c_name);
1590
1591 CreateStreams();
1592 observer.SetReceiveStream(receive_stream_);
1593 observer.SetSendStream(send_stream_);
1594 CreateFrameGenerator();
1595 StartSending();
1596
1597 observer.WaitForFilledStats();
1598
1599 StopSending();
1600 observer.StopSending();
1601 DestroyStreams();
1602}
1603
asapersson@webrtc.orgb4263e02014-01-20 08:34:49 +00001604TEST_F(CallTest, ReceiverReferenceTimeReportEnabled) {
1605 TestXrReceiverReferenceTimeReport(true);
1606}
1607
1608TEST_F(CallTest, ReceiverReferenceTimeReportDisabled) {
1609 TestXrReceiverReferenceTimeReport(false);
1610}
pbos@webrtc.org3f83f9c2014-03-13 12:52:27 +00001611
pbos@webrtc.orgce851092013-08-05 12:01:36 +00001612} // namespace webrtc