blob: 3dd499c54dd077625a42e9b62c22bff43ebe4be5 [file] [log] [blame]
pbos@webrtc.org994d0b72014-06-27 08:47:52 +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 <assert.h>
11
12#include <algorithm>
13#include <map>
14#include <sstream>
15#include <string>
16
17#include "testing/gtest/include/gtest/gtest.h"
18
19#include "webrtc/call.h"
20#include "webrtc/frame_callback.h"
21#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
marpan@webrtc.org5b883172014-11-01 06:10:48 +000022#include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h"
23#include "webrtc/modules/video_coding/codecs/vp9/include/vp9.h"
24#include "webrtc/modules/video_coding/main/interface/video_coding_defines.h"
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000025#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
26#include "webrtc/system_wrappers/interface/event_wrapper.h"
27#include "webrtc/system_wrappers/interface/scoped_ptr.h"
28#include "webrtc/system_wrappers/interface/sleep.h"
29#include "webrtc/test/call_test.h"
30#include "webrtc/test/direct_transport.h"
31#include "webrtc/test/encoder_settings.h"
32#include "webrtc/test/fake_audio_device.h"
33#include "webrtc/test/fake_decoder.h"
34#include "webrtc/test/fake_encoder.h"
35#include "webrtc/test/frame_generator.h"
36#include "webrtc/test/frame_generator_capturer.h"
37#include "webrtc/test/null_transport.h"
asapersson@webrtc.org37c05592015-01-28 13:58:27 +000038#include "webrtc/test/rtcp_packet_parser.h"
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000039#include "webrtc/test/rtp_rtcp_observer.h"
40#include "webrtc/test/testsupport/fileutils.h"
andresp@webrtc.orgab071da2014-09-18 08:58:15 +000041#include "webrtc/test/testsupport/gtest_disable.h"
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000042#include "webrtc/test/testsupport/perf_test.h"
43#include "webrtc/video/transport_adapter.h"
pbos@webrtc.orgab990ae2014-09-17 09:02:25 +000044#include "webrtc/video_encoder.h"
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000045
46namespace webrtc {
47
pbos@webrtc.org26c0c412014-09-03 16:17:12 +000048static const unsigned long kSilenceTimeoutMs = 2000;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000049
50class EndToEndTest : public test::CallTest {
51 public:
52 EndToEndTest() {}
53
54 virtual ~EndToEndTest() {
55 EXPECT_EQ(NULL, send_stream_);
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +000056 EXPECT_TRUE(receive_streams_.empty());
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000057 }
58
59 protected:
pbos@webrtc.org26c0c412014-09-03 16:17:12 +000060 class UnusedTransport : public newapi::Transport {
61 private:
pbos@webrtc.org0d852d52015-02-09 15:14:36 +000062 virtual bool SendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org26c0c412014-09-03 16:17:12 +000063 ADD_FAILURE() << "Unexpected RTP sent.";
64 return false;
65 }
66
pbos@webrtc.org0d852d52015-02-09 15:14:36 +000067 virtual bool SendRtcp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org26c0c412014-09-03 16:17:12 +000068 ADD_FAILURE() << "Unexpected RTCP sent.";
69 return false;
70 }
71 };
72
andrew@webrtc.org8f27fcc2015-01-09 20:22:46 +000073 void DecodesRetransmittedFrame(bool retransmit_over_rtx);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000074 void ReceivesPliAndRecovers(int rtp_history_ms);
75 void RespectsRtcpMode(newapi::RtcpMode rtcp_mode);
76 void TestXrReceiverReferenceTimeReport(bool enable_rrtr);
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +000077 void TestSendsSetSsrcs(size_t num_ssrcs, bool send_single_ssrc_first);
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +000078 void TestRtpStatePreservation(bool use_rtx);
asapersson@webrtc.org37c05592015-01-28 13:58:27 +000079 void TestReceivedFecPacketsNotNacked(const FakeNetworkPipe::Config& config);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000080};
81
82TEST_F(EndToEndTest, ReceiverCanBeStartedTwice) {
83 test::NullTransport transport;
84 CreateCalls(Call::Config(&transport), Call::Config(&transport));
85
86 CreateSendConfig(1);
87 CreateMatchingReceiveConfigs();
88
89 CreateStreams();
90
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +000091 receive_streams_[0]->Start();
92 receive_streams_[0]->Start();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000093
94 DestroyStreams();
95}
96
97TEST_F(EndToEndTest, ReceiverCanBeStoppedTwice) {
98 test::NullTransport transport;
99 CreateCalls(Call::Config(&transport), Call::Config(&transport));
100
101 CreateSendConfig(1);
102 CreateMatchingReceiveConfigs();
103
104 CreateStreams();
105
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000106 receive_streams_[0]->Stop();
107 receive_streams_[0]->Stop();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000108
109 DestroyStreams();
110}
111
112TEST_F(EndToEndTest, RendersSingleDelayedFrame) {
113 static const int kWidth = 320;
114 static const int kHeight = 240;
115 // This constant is chosen to be higher than the timeout in the video_render
116 // module. This makes sure that frames aren't dropped if there are no other
117 // frames in the queue.
118 static const int kDelayRenderCallbackMs = 1000;
119
120 class Renderer : public VideoRenderer {
121 public:
122 Renderer() : event_(EventWrapper::Create()) {}
123
124 virtual void RenderFrame(const I420VideoFrame& video_frame,
pbos@webrtc.org0d852d52015-02-09 15:14:36 +0000125 int /*time_to_render_ms*/) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000126 event_->Set();
127 }
128
pbos@webrtc.org0d852d52015-02-09 15:14:36 +0000129 virtual bool IsTextureSupported() const override { return false; }
130
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000131 EventTypeWrapper Wait() { return event_->Wait(kDefaultTimeoutMs); }
132
133 scoped_ptr<EventWrapper> event_;
134 } renderer;
135
136 class TestFrameCallback : public I420FrameCallback {
137 public:
138 TestFrameCallback() : event_(EventWrapper::Create()) {}
139
140 EventTypeWrapper Wait() { return event_->Wait(kDefaultTimeoutMs); }
141
142 private:
pbos@webrtc.org0d852d52015-02-09 15:14:36 +0000143 virtual void FrameCallback(I420VideoFrame* frame) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000144 SleepMs(kDelayRenderCallbackMs);
145 event_->Set();
146 }
147
148 scoped_ptr<EventWrapper> event_;
149 };
150
151 test::DirectTransport sender_transport, receiver_transport;
152
153 CreateCalls(Call::Config(&sender_transport),
154 Call::Config(&receiver_transport));
155
156 sender_transport.SetReceiver(receiver_call_->Receiver());
157 receiver_transport.SetReceiver(sender_call_->Receiver());
158
159 CreateSendConfig(1);
160 CreateMatchingReceiveConfigs();
161
162 TestFrameCallback pre_render_callback;
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000163 receive_configs_[0].pre_render_callback = &pre_render_callback;
164 receive_configs_[0].renderer = &renderer;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000165
166 CreateStreams();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000167 Start();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000168
169 // Create frames that are smaller than the send width/height, this is done to
170 // check that the callbacks are done after processing video.
171 scoped_ptr<test::FrameGenerator> frame_generator(
172 test::FrameGenerator::Create(kWidth, kHeight));
173 send_stream_->Input()->SwapFrame(frame_generator->NextFrame());
174 EXPECT_EQ(kEventSignaled, pre_render_callback.Wait())
175 << "Timed out while waiting for pre-render callback.";
176 EXPECT_EQ(kEventSignaled, renderer.Wait())
177 << "Timed out while waiting for the frame to render.";
178
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000179 Stop();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000180
181 sender_transport.StopSending();
182 receiver_transport.StopSending();
183
184 DestroyStreams();
185}
186
187TEST_F(EndToEndTest, TransmitsFirstFrame) {
188 class Renderer : public VideoRenderer {
189 public:
190 Renderer() : event_(EventWrapper::Create()) {}
191
192 virtual void RenderFrame(const I420VideoFrame& video_frame,
pbos@webrtc.org0d852d52015-02-09 15:14:36 +0000193 int /*time_to_render_ms*/) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000194 event_->Set();
195 }
pbos@webrtc.org0d852d52015-02-09 15:14:36 +0000196 virtual bool IsTextureSupported() const override { return false; }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000197
198 EventTypeWrapper Wait() { return event_->Wait(kDefaultTimeoutMs); }
199
200 scoped_ptr<EventWrapper> event_;
201 } renderer;
202
203 test::DirectTransport sender_transport, receiver_transport;
204
205 CreateCalls(Call::Config(&sender_transport),
206 Call::Config(&receiver_transport));
207
208 sender_transport.SetReceiver(receiver_call_->Receiver());
209 receiver_transport.SetReceiver(sender_call_->Receiver());
210
211 CreateSendConfig(1);
212 CreateMatchingReceiveConfigs();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000213 receive_configs_[0].renderer = &renderer;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000214
215 CreateStreams();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000216 Start();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000217
218 scoped_ptr<test::FrameGenerator> frame_generator(test::FrameGenerator::Create(
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +0000219 encoder_config_.streams[0].width, encoder_config_.streams[0].height));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000220 send_stream_->Input()->SwapFrame(frame_generator->NextFrame());
221
222 EXPECT_EQ(kEventSignaled, renderer.Wait())
223 << "Timed out while waiting for the frame to render.";
224
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000225 Stop();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000226
227 sender_transport.StopSending();
228 receiver_transport.StopSending();
229
230 DestroyStreams();
231}
232
marpan@webrtc.org5f1e2e42014-11-06 02:02:28 +0000233TEST_F(EndToEndTest, SendsAndReceivesVP9) {
marpan@webrtc.org5b883172014-11-01 06:10:48 +0000234 class VP9Observer : public test::EndToEndTest, public VideoRenderer {
235 public:
236 VP9Observer()
237 : EndToEndTest(2 * kDefaultTimeoutMs),
238 encoder_(VideoEncoder::Create(VideoEncoder::kVp9)),
239 decoder_(VP9Decoder::Create()),
240 frame_counter_(0) {}
241
pbos@webrtc.org0d852d52015-02-09 15:14:36 +0000242 virtual void PerformTest() override {
marpan@webrtc.org5b883172014-11-01 06:10:48 +0000243 EXPECT_EQ(kEventSignaled, Wait())
244 << "Timed out while waiting for enough frames to be decoded.";
245 }
246
247 virtual void ModifyConfigs(
248 VideoSendStream::Config* send_config,
249 std::vector<VideoReceiveStream::Config>* receive_configs,
pbos@webrtc.org0d852d52015-02-09 15:14:36 +0000250 VideoEncoderConfig* encoder_config) override {
marpan@webrtc.org5b883172014-11-01 06:10:48 +0000251 send_config->encoder_settings.encoder = encoder_.get();
252 send_config->encoder_settings.payload_name = "VP9";
253 send_config->encoder_settings.payload_type = VCM_VP9_PAYLOAD_TYPE;
254 encoder_config->streams[0].min_bitrate_bps = 50000;
255 encoder_config->streams[0].target_bitrate_bps =
256 encoder_config->streams[0].max_bitrate_bps = 2000000;
257
258 (*receive_configs)[0].renderer = this;
259 (*receive_configs)[0].decoders.resize(1);
260 (*receive_configs)[0].decoders[0].payload_type =
261 send_config->encoder_settings.payload_type;
262 (*receive_configs)[0].decoders[0].payload_name =
263 send_config->encoder_settings.payload_name;
264 (*receive_configs)[0].decoders[0].decoder = decoder_.get();
265 }
266
267 virtual void RenderFrame(const I420VideoFrame& video_frame,
pbos@webrtc.org0d852d52015-02-09 15:14:36 +0000268 int time_to_render_ms) override {
marpan@webrtc.org5b883172014-11-01 06:10:48 +0000269 const int kRequiredFrames = 500;
270 if (++frame_counter_ == kRequiredFrames)
271 observation_complete_->Set();
272 }
273
pbos@webrtc.org0d852d52015-02-09 15:14:36 +0000274 virtual bool IsTextureSupported() const override { return false; }
275
marpan@webrtc.org5b883172014-11-01 06:10:48 +0000276 private:
277 scoped_ptr<webrtc::VideoEncoder> encoder_;
278 scoped_ptr<webrtc::VideoDecoder> decoder_;
279 int frame_counter_;
280 } test;
281
282 RunBaseTest(&test);
283}
284
stefan@webrtc.org79c33592014-08-06 09:24:53 +0000285TEST_F(EndToEndTest, SendsAndReceivesH264) {
286 class H264Observer : public test::EndToEndTest, public VideoRenderer {
287 public:
288 H264Observer()
289 : EndToEndTest(2 * kDefaultTimeoutMs),
290 fake_encoder_(Clock::GetRealTimeClock()),
291 frame_counter_(0) {}
292
pbos@webrtc.org0d852d52015-02-09 15:14:36 +0000293 virtual void PerformTest() override {
stefan@webrtc.org79c33592014-08-06 09:24:53 +0000294 EXPECT_EQ(kEventSignaled, Wait())
295 << "Timed out while waiting for enough frames to be decoded.";
296 }
297
298 virtual void ModifyConfigs(
299 VideoSendStream::Config* send_config,
300 std::vector<VideoReceiveStream::Config>* receive_configs,
pbos@webrtc.org0d852d52015-02-09 15:14:36 +0000301 VideoEncoderConfig* encoder_config) override {
stefan@webrtc.org79c33592014-08-06 09:24:53 +0000302 send_config->encoder_settings.encoder = &fake_encoder_;
303 send_config->encoder_settings.payload_name = "H264";
304 send_config->encoder_settings.payload_type = kFakeSendPayloadType;
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +0000305 encoder_config->streams[0].min_bitrate_bps = 50000;
306 encoder_config->streams[0].target_bitrate_bps =
307 encoder_config->streams[0].max_bitrate_bps = 2000000;
stefan@webrtc.org79c33592014-08-06 09:24:53 +0000308
309 (*receive_configs)[0].renderer = this;
pbos@webrtc.org776e6f22014-10-29 15:28:39 +0000310 (*receive_configs)[0].decoders.resize(1);
311 (*receive_configs)[0].decoders[0].payload_type =
stefan@webrtc.org79c33592014-08-06 09:24:53 +0000312 send_config->encoder_settings.payload_type;
pbos@webrtc.org776e6f22014-10-29 15:28:39 +0000313 (*receive_configs)[0].decoders[0].payload_name =
314 send_config->encoder_settings.payload_name;
315 (*receive_configs)[0].decoders[0].decoder = &fake_decoder_;
stefan@webrtc.org79c33592014-08-06 09:24:53 +0000316 }
317
318 virtual void RenderFrame(const I420VideoFrame& video_frame,
pbos@webrtc.org0d852d52015-02-09 15:14:36 +0000319 int time_to_render_ms) override {
stefan@webrtc.org79c33592014-08-06 09:24:53 +0000320 const int kRequiredFrames = 500;
321 if (++frame_counter_ == kRequiredFrames)
322 observation_complete_->Set();
323 }
324
pbos@webrtc.org0d852d52015-02-09 15:14:36 +0000325 virtual bool IsTextureSupported() const override { return false; }
326
stefan@webrtc.org79c33592014-08-06 09:24:53 +0000327 private:
328 test::FakeH264Decoder fake_decoder_;
329 test::FakeH264Encoder fake_encoder_;
330 int frame_counter_;
331 } test;
332
333 RunBaseTest(&test);
334}
335
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000336TEST_F(EndToEndTest, ReceiverUsesLocalSsrc) {
337 class SyncRtcpObserver : public test::EndToEndTest {
338 public:
339 SyncRtcpObserver() : EndToEndTest(kDefaultTimeoutMs) {}
340
341 virtual Action OnReceiveRtcp(const uint8_t* packet,
pbos@webrtc.org0d852d52015-02-09 15:14:36 +0000342 size_t length) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000343 RTCPUtility::RTCPParserV2 parser(packet, length, true);
344 EXPECT_TRUE(parser.IsValid());
345 uint32_t ssrc = 0;
346 ssrc |= static_cast<uint32_t>(packet[4]) << 24;
347 ssrc |= static_cast<uint32_t>(packet[5]) << 16;
348 ssrc |= static_cast<uint32_t>(packet[6]) << 8;
349 ssrc |= static_cast<uint32_t>(packet[7]) << 0;
350 EXPECT_EQ(kReceiverLocalSsrc, ssrc);
351 observation_complete_->Set();
352
353 return SEND_PACKET;
354 }
355
pbos@webrtc.org0d852d52015-02-09 15:14:36 +0000356 virtual void PerformTest() override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000357 EXPECT_EQ(kEventSignaled, Wait())
358 << "Timed out while waiting for a receiver RTCP packet to be sent.";
359 }
360 } test;
361
362 RunBaseTest(&test);
363}
364
365TEST_F(EndToEndTest, ReceivesAndRetransmitsNack) {
366 static const int kNumberOfNacksToObserve = 2;
367 static const int kLossBurstSize = 2;
368 static const int kPacketsBetweenLossBursts = 9;
369 class NackObserver : public test::EndToEndTest {
370 public:
371 NackObserver()
372 : EndToEndTest(kLongTimeoutMs),
373 rtp_parser_(RtpHeaderParser::Create()),
374 sent_rtp_packets_(0),
375 packets_left_to_drop_(0),
376 nacks_left_(kNumberOfNacksToObserve) {}
377
378 private:
pbos@webrtc.org0d852d52015-02-09 15:14:36 +0000379 virtual Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000380 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000381 EXPECT_TRUE(rtp_parser_->Parse(packet, length, &header));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000382
383 // Never drop retransmitted packets.
384 if (dropped_packets_.find(header.sequenceNumber) !=
385 dropped_packets_.end()) {
386 retransmitted_packets_.insert(header.sequenceNumber);
387 if (nacks_left_ == 0 &&
388 retransmitted_packets_.size() == dropped_packets_.size()) {
389 observation_complete_->Set();
390 }
391 return SEND_PACKET;
392 }
393
394 ++sent_rtp_packets_;
395
396 // Enough NACKs received, stop dropping packets.
397 if (nacks_left_ == 0)
398 return SEND_PACKET;
399
400 // Check if it's time for a new loss burst.
401 if (sent_rtp_packets_ % kPacketsBetweenLossBursts == 0)
402 packets_left_to_drop_ = kLossBurstSize;
403
404 if (packets_left_to_drop_ > 0) {
405 --packets_left_to_drop_;
406 dropped_packets_.insert(header.sequenceNumber);
407 return DROP_PACKET;
408 }
409
410 return SEND_PACKET;
411 }
412
413 virtual Action OnReceiveRtcp(const uint8_t* packet,
pbos@webrtc.org0d852d52015-02-09 15:14:36 +0000414 size_t length) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000415 RTCPUtility::RTCPParserV2 parser(packet, length, true);
416 EXPECT_TRUE(parser.IsValid());
417
418 RTCPUtility::RTCPPacketTypes packet_type = parser.Begin();
419 while (packet_type != RTCPUtility::kRtcpNotValidCode) {
420 if (packet_type == RTCPUtility::kRtcpRtpfbNackCode) {
421 --nacks_left_;
422 break;
423 }
424 packet_type = parser.Iterate();
425 }
426 return SEND_PACKET;
427 }
428
429 virtual void ModifyConfigs(
430 VideoSendStream::Config* send_config,
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000431 std::vector<VideoReceiveStream::Config>* receive_configs,
pbos@webrtc.org0d852d52015-02-09 15:14:36 +0000432 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000433 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000434 (*receive_configs)[0].rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000435 }
436
pbos@webrtc.org0d852d52015-02-09 15:14:36 +0000437 virtual void PerformTest() override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000438 EXPECT_EQ(kEventSignaled, Wait())
439 << "Timed out waiting for packets to be NACKed, retransmitted and "
440 "rendered.";
441 }
442
443 scoped_ptr<RtpHeaderParser> rtp_parser_;
444 std::set<uint16_t> dropped_packets_;
445 std::set<uint16_t> retransmitted_packets_;
446 uint64_t sent_rtp_packets_;
447 int packets_left_to_drop_;
448 int nacks_left_;
449 } test;
450
451 RunBaseTest(&test);
452}
453
pbos@webrtc.orga9c2d452014-11-13 14:40:15 +0000454TEST_F(EndToEndTest, CanReceiveFec) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000455 class FecRenderObserver : public test::EndToEndTest, public VideoRenderer {
456 public:
457 FecRenderObserver()
pbos@webrtc.orga9c2d452014-11-13 14:40:15 +0000458 : EndToEndTest(kDefaultTimeoutMs), state_(kFirstPacket) {}
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000459
460 private:
pbos@webrtc.org0d852d52015-02-09 15:14:36 +0000461 virtual Action OnSendRtp(const uint8_t* packet, size_t length) override
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000462 EXCLUSIVE_LOCKS_REQUIRED(crit_) {
463 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000464 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000465
466 EXPECT_EQ(kRedPayloadType, header.payloadType);
467 int encapsulated_payload_type =
468 static_cast<int>(packet[header.headerLength]);
469 if (encapsulated_payload_type != kFakeSendPayloadType)
470 EXPECT_EQ(kUlpfecPayloadType, encapsulated_payload_type);
471
pbos@webrtc.orga9c2d452014-11-13 14:40:15 +0000472 if (protected_sequence_numbers_.count(header.sequenceNumber) != 0) {
473 // Retransmitted packet, should not count.
474 protected_sequence_numbers_.erase(header.sequenceNumber);
475 EXPECT_GT(protected_timestamps_.count(header.timestamp), 0u);
476 protected_timestamps_.erase(header.timestamp);
477 return SEND_PACKET;
478 }
479
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000480 switch (state_) {
481 case kFirstPacket:
482 state_ = kDropEveryOtherPacketUntilFec;
483 break;
484 case kDropEveryOtherPacketUntilFec:
485 if (encapsulated_payload_type == kUlpfecPayloadType) {
486 state_ = kDropNextMediaPacket;
487 return SEND_PACKET;
488 }
489 if (header.sequenceNumber % 2 == 0)
490 return DROP_PACKET;
491 break;
492 case kDropNextMediaPacket:
493 if (encapsulated_payload_type == kFakeSendPayloadType) {
pbos@webrtc.orga9c2d452014-11-13 14:40:15 +0000494 protected_sequence_numbers_.insert(header.sequenceNumber);
495 protected_timestamps_.insert(header.timestamp);
496 state_ = kDropEveryOtherPacketUntilFec;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000497 return DROP_PACKET;
498 }
499 break;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000500 }
501
502 return SEND_PACKET;
503 }
504
505 virtual void RenderFrame(const I420VideoFrame& video_frame,
pbos@webrtc.org0d852d52015-02-09 15:14:36 +0000506 int time_to_render_ms) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000507 CriticalSectionScoped lock(crit_.get());
pbos@webrtc.orga9c2d452014-11-13 14:40:15 +0000508 // Rendering frame with timestamp of packet that was dropped -> FEC
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000509 // protection worked.
pbos@webrtc.orga9c2d452014-11-13 14:40:15 +0000510 if (protected_timestamps_.count(video_frame.timestamp()) != 0)
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000511 observation_complete_->Set();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000512 }
513
pbos@webrtc.org0d852d52015-02-09 15:14:36 +0000514 virtual bool IsTextureSupported() const override { return false; }
515
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000516 enum {
517 kFirstPacket,
518 kDropEveryOtherPacketUntilFec,
519 kDropNextMediaPacket,
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000520 } state_;
521
522 virtual void ModifyConfigs(
523 VideoSendStream::Config* send_config,
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000524 std::vector<VideoReceiveStream::Config>* receive_configs,
pbos@webrtc.org0d852d52015-02-09 15:14:36 +0000525 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000526 // TODO(pbos): Run this test with combined NACK/FEC enabled as well.
527 // int rtp_history_ms = 1000;
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000528 // (*receive_configs)[0].rtp.nack.rtp_history_ms = rtp_history_ms;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000529 // send_config->rtp.nack.rtp_history_ms = rtp_history_ms;
530 send_config->rtp.fec.red_payload_type = kRedPayloadType;
531 send_config->rtp.fec.ulpfec_payload_type = kUlpfecPayloadType;
532
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000533 (*receive_configs)[0].rtp.fec.red_payload_type = kRedPayloadType;
534 (*receive_configs)[0].rtp.fec.ulpfec_payload_type = kUlpfecPayloadType;
535 (*receive_configs)[0].renderer = this;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000536 }
537
pbos@webrtc.org0d852d52015-02-09 15:14:36 +0000538 virtual void PerformTest() override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000539 EXPECT_EQ(kEventSignaled, Wait())
pbos@webrtc.orga9c2d452014-11-13 14:40:15 +0000540 << "Timed out waiting for dropped frames frames to be rendered.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000541 }
542
pbos@webrtc.orga9c2d452014-11-13 14:40:15 +0000543 std::set<uint32_t> protected_sequence_numbers_ GUARDED_BY(crit_);
544 std::set<uint32_t> protected_timestamps_ GUARDED_BY(crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000545 } test;
546
547 RunBaseTest(&test);
548}
549
asapersson@webrtc.org37c05592015-01-28 13:58:27 +0000550TEST_F(EndToEndTest, ReceivedFecPacketsNotNacked) {
551 // At low RTT (< kLowRttNackMs) -> NACK only, no FEC.
552 // Configure some network delay.
553 const int kNetworkDelayMs = 50;
554 FakeNetworkPipe::Config config;
555 config.queue_delay_ms = kNetworkDelayMs;
556 TestReceivedFecPacketsNotNacked(config);
557}
558
559void EndToEndTest::TestReceivedFecPacketsNotNacked(
560 const FakeNetworkPipe::Config& config) {
561 class FecNackObserver : public test::EndToEndTest {
562 public:
563 explicit FecNackObserver(const FakeNetworkPipe::Config& config)
564 : EndToEndTest(kDefaultTimeoutMs, config),
565 state_(kDropEveryOtherPacketUntilFec),
566 fec_sequence_number_(0),
567 has_last_sequence_number_(false),
568 last_sequence_number_(0) {}
569
570 private:
pbos@webrtc.org0d852d52015-02-09 15:14:36 +0000571 virtual Action OnSendRtp(const uint8_t* packet, size_t length) override {
asapersson@webrtc.org37c05592015-01-28 13:58:27 +0000572 RTPHeader header;
573 EXPECT_TRUE(parser_->Parse(packet, length, &header));
574 EXPECT_EQ(kRedPayloadType, header.payloadType);
575
576 int encapsulated_payload_type =
577 static_cast<int>(packet[header.headerLength]);
578 if (encapsulated_payload_type != kFakeSendPayloadType)
579 EXPECT_EQ(kUlpfecPayloadType, encapsulated_payload_type);
580
581 if (has_last_sequence_number_ &&
582 !IsNewerSequenceNumber(header.sequenceNumber,
583 last_sequence_number_)) {
584 // Drop retransmitted packets.
585 return DROP_PACKET;
586 }
587 last_sequence_number_ = header.sequenceNumber;
588 has_last_sequence_number_ = true;
589
590 bool fec_packet = encapsulated_payload_type == kUlpfecPayloadType;
591 switch (state_) {
592 case kDropEveryOtherPacketUntilFec:
593 if (fec_packet) {
594 state_ = kDropAllMediaPacketsUntilFec;
595 } else if (header.sequenceNumber % 2 == 0) {
596 return DROP_PACKET;
597 }
598 break;
599 case kDropAllMediaPacketsUntilFec:
600 if (!fec_packet)
601 return DROP_PACKET;
602 fec_sequence_number_ = header.sequenceNumber;
603 state_ = kVerifyFecPacketNotInNackList;
604 break;
605 case kVerifyFecPacketNotInNackList:
606 // Continue to drop packets. Make sure no frame can be decoded.
607 if (fec_packet || header.sequenceNumber % 2 == 0)
608 return DROP_PACKET;
609 break;
610 }
611 return SEND_PACKET;
612 }
613
pbos@webrtc.org0d852d52015-02-09 15:14:36 +0000614 virtual Action OnReceiveRtcp(const uint8_t* packet,
615 size_t length) override {
asapersson@webrtc.org37c05592015-01-28 13:58:27 +0000616 if (state_ == kVerifyFecPacketNotInNackList) {
617 test::RtcpPacketParser rtcp_parser;
618 rtcp_parser.Parse(packet, length);
619 std::vector<uint16_t> nacks = rtcp_parser.nack_item()->last_nack_list();
620 if (!nacks.empty() &&
621 IsNewerSequenceNumber(nacks.back(), fec_sequence_number_)) {
622 EXPECT_TRUE(std::find(
623 nacks.begin(), nacks.end(), fec_sequence_number_) == nacks.end());
624 observation_complete_->Set();
625 }
626 }
627 return SEND_PACKET;
628 }
629
630 virtual void ModifyConfigs(
631 VideoSendStream::Config* send_config,
632 std::vector<VideoReceiveStream::Config>* receive_configs,
pbos@webrtc.org0d852d52015-02-09 15:14:36 +0000633 VideoEncoderConfig* encoder_config) override {
asapersson@webrtc.org37c05592015-01-28 13:58:27 +0000634 // Configure hybrid NACK/FEC.
635 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
636 send_config->rtp.fec.red_payload_type = kRedPayloadType;
637 send_config->rtp.fec.ulpfec_payload_type = kUlpfecPayloadType;
638 (*receive_configs)[0].rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
639 (*receive_configs)[0].rtp.fec.red_payload_type = kRedPayloadType;
640 (*receive_configs)[0].rtp.fec.ulpfec_payload_type = kUlpfecPayloadType;
641 }
642
pbos@webrtc.org0d852d52015-02-09 15:14:36 +0000643 virtual void PerformTest() override {
asapersson@webrtc.org37c05592015-01-28 13:58:27 +0000644 EXPECT_EQ(kEventSignaled, Wait())
645 << "Timed out while waiting for FEC packets to be received.";
646 }
647
648 enum {
649 kDropEveryOtherPacketUntilFec,
650 kDropAllMediaPacketsUntilFec,
651 kVerifyFecPacketNotInNackList,
652 } state_;
653
654 uint16_t fec_sequence_number_;
655 bool has_last_sequence_number_;
656 uint16_t last_sequence_number_;
657 } test(config);
658
659 RunBaseTest(&test);
660}
661
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000662// This test drops second RTP packet with a marker bit set, makes sure it's
663// retransmitted and renders. Retransmission SSRCs are also checked.
andrew@webrtc.org8f27fcc2015-01-09 20:22:46 +0000664void EndToEndTest::DecodesRetransmittedFrame(bool retransmit_over_rtx) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000665 static const int kDroppedFrameNumber = 2;
666 class RetransmissionObserver : public test::EndToEndTest,
667 public I420FrameCallback {
668 public:
andrew@webrtc.org8f27fcc2015-01-09 20:22:46 +0000669 explicit RetransmissionObserver(bool expect_rtx)
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000670 : EndToEndTest(kDefaultTimeoutMs),
andrew@webrtc.org8f27fcc2015-01-09 20:22:46 +0000671 retransmission_ssrc_(expect_rtx ? kSendRtxSsrcs[0] : kSendSsrcs[0]),
672 retransmission_payload_type_(expect_rtx ? kSendRtxPayloadType
673 : kFakeSendPayloadType),
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000674 marker_bits_observed_(0),
675 retransmitted_timestamp_(0),
676 frame_retransmitted_(false) {}
677
678 private:
pbos@webrtc.org0d852d52015-02-09 15:14:36 +0000679 virtual Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000680 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000681 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000682
683 if (header.timestamp == retransmitted_timestamp_) {
684 EXPECT_EQ(retransmission_ssrc_, header.ssrc);
685 EXPECT_EQ(retransmission_payload_type_, header.payloadType);
686 frame_retransmitted_ = true;
687 return SEND_PACKET;
688 }
689
690 EXPECT_EQ(kSendSsrcs[0], header.ssrc);
andrew@webrtc.org8f27fcc2015-01-09 20:22:46 +0000691 EXPECT_EQ(kFakeSendPayloadType, header.payloadType);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000692
693 // Found the second frame's final packet, drop this and expect a
694 // retransmission.
695 if (header.markerBit && ++marker_bits_observed_ == kDroppedFrameNumber) {
696 retransmitted_timestamp_ = header.timestamp;
697 return DROP_PACKET;
698 }
699
700 return SEND_PACKET;
701 }
702
pbos@webrtc.org0d852d52015-02-09 15:14:36 +0000703 virtual void FrameCallback(I420VideoFrame* frame) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000704 CriticalSectionScoped lock(crit_.get());
705 if (frame->timestamp() == retransmitted_timestamp_) {
706 EXPECT_TRUE(frame_retransmitted_);
707 observation_complete_->Set();
708 }
709 }
710
711 virtual void ModifyConfigs(
712 VideoSendStream::Config* send_config,
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000713 std::vector<VideoReceiveStream::Config>* receive_configs,
pbos@webrtc.org0d852d52015-02-09 15:14:36 +0000714 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000715 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000716 (*receive_configs)[0].pre_render_callback = this;
717 (*receive_configs)[0].rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +0000718 if (retransmission_ssrc_ == kSendRtxSsrcs[0]) {
719 send_config->rtp.rtx.ssrcs.push_back(kSendRtxSsrcs[0]);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000720 send_config->rtp.rtx.payload_type = kSendRtxPayloadType;
andrew@webrtc.org8f27fcc2015-01-09 20:22:46 +0000721 (*receive_configs)[0].rtp.rtx[kSendRtxPayloadType].ssrc =
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +0000722 kSendRtxSsrcs[0];
andrew@webrtc.org8f27fcc2015-01-09 20:22:46 +0000723 (*receive_configs)[0].rtp.rtx[kSendRtxPayloadType].payload_type =
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000724 kSendRtxPayloadType;
725 }
726 }
727
pbos@webrtc.org0d852d52015-02-09 15:14:36 +0000728 virtual void PerformTest() override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000729 EXPECT_EQ(kEventSignaled, Wait())
730 << "Timed out while waiting for retransmission to render.";
731 }
732
733 const uint32_t retransmission_ssrc_;
734 const int retransmission_payload_type_;
735 int marker_bits_observed_;
736 uint32_t retransmitted_timestamp_;
737 bool frame_retransmitted_;
andrew@webrtc.org8f27fcc2015-01-09 20:22:46 +0000738 } test(retransmit_over_rtx);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000739
740 RunBaseTest(&test);
741}
742
743TEST_F(EndToEndTest, DecodesRetransmittedFrame) {
andrew@webrtc.org8f27fcc2015-01-09 20:22:46 +0000744 DecodesRetransmittedFrame(false);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000745}
746
747TEST_F(EndToEndTest, DecodesRetransmittedFrameOverRtx) {
andrew@webrtc.org8f27fcc2015-01-09 20:22:46 +0000748 DecodesRetransmittedFrame(true);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000749}
750
andresp@webrtc.org02686112014-09-19 08:24:19 +0000751TEST_F(EndToEndTest, UsesFrameCallbacks) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000752 static const int kWidth = 320;
753 static const int kHeight = 240;
754
755 class Renderer : public VideoRenderer {
756 public:
757 Renderer() : event_(EventWrapper::Create()) {}
758
759 virtual void RenderFrame(const I420VideoFrame& video_frame,
pbos@webrtc.org0d852d52015-02-09 15:14:36 +0000760 int /*time_to_render_ms*/) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000761 EXPECT_EQ(0, *video_frame.buffer(kYPlane))
762 << "Rendered frame should have zero luma which is applied by the "
763 "pre-render callback.";
764 event_->Set();
765 }
766
pbos@webrtc.org0d852d52015-02-09 15:14:36 +0000767 virtual bool IsTextureSupported() const override { return false; }
768
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000769 EventTypeWrapper Wait() { return event_->Wait(kDefaultTimeoutMs); }
770 scoped_ptr<EventWrapper> event_;
771 } renderer;
772
773 class TestFrameCallback : public I420FrameCallback {
774 public:
775 TestFrameCallback(int expected_luma_byte, int next_luma_byte)
776 : event_(EventWrapper::Create()),
777 expected_luma_byte_(expected_luma_byte),
778 next_luma_byte_(next_luma_byte) {}
779
780 EventTypeWrapper Wait() { return event_->Wait(kDefaultTimeoutMs); }
781
782 private:
783 virtual void FrameCallback(I420VideoFrame* frame) {
784 EXPECT_EQ(kWidth, frame->width())
785 << "Width not as expected, callback done before resize?";
786 EXPECT_EQ(kHeight, frame->height())
787 << "Height not as expected, callback done before resize?";
788
789 // Previous luma specified, observed luma should be fairly close.
790 if (expected_luma_byte_ != -1) {
791 EXPECT_NEAR(expected_luma_byte_, *frame->buffer(kYPlane), 10);
792 }
793
794 memset(frame->buffer(kYPlane),
795 next_luma_byte_,
796 frame->allocated_size(kYPlane));
797
798 event_->Set();
799 }
800
801 scoped_ptr<EventWrapper> event_;
802 int expected_luma_byte_;
803 int next_luma_byte_;
804 };
805
806 TestFrameCallback pre_encode_callback(-1, 255); // Changes luma to 255.
807 TestFrameCallback pre_render_callback(255, 0); // Changes luma from 255 to 0.
808
809 test::DirectTransport sender_transport, receiver_transport;
810
811 CreateCalls(Call::Config(&sender_transport),
812 Call::Config(&receiver_transport));
813
814 sender_transport.SetReceiver(receiver_call_->Receiver());
815 receiver_transport.SetReceiver(sender_call_->Receiver());
816
817 CreateSendConfig(1);
pbos@webrtc.orgab990ae2014-09-17 09:02:25 +0000818 scoped_ptr<VideoEncoder> encoder(
819 VideoEncoder::Create(VideoEncoder::kVp8));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000820 send_config_.encoder_settings.encoder = encoder.get();
821 send_config_.encoder_settings.payload_name = "VP8";
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +0000822 ASSERT_EQ(1u, encoder_config_.streams.size()) << "Test setup error.";
823 encoder_config_.streams[0].width = kWidth;
824 encoder_config_.streams[0].height = kHeight;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000825 send_config_.pre_encode_callback = &pre_encode_callback;
826
827 CreateMatchingReceiveConfigs();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000828 receive_configs_[0].pre_render_callback = &pre_render_callback;
829 receive_configs_[0].renderer = &renderer;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000830
831 CreateStreams();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000832 Start();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000833
834 // Create frames that are smaller than the send width/height, this is done to
835 // check that the callbacks are done after processing video.
836 scoped_ptr<test::FrameGenerator> frame_generator(
837 test::FrameGenerator::Create(kWidth / 2, kHeight / 2));
838 send_stream_->Input()->SwapFrame(frame_generator->NextFrame());
839
840 EXPECT_EQ(kEventSignaled, pre_encode_callback.Wait())
841 << "Timed out while waiting for pre-encode callback.";
842 EXPECT_EQ(kEventSignaled, pre_render_callback.Wait())
843 << "Timed out while waiting for pre-render callback.";
844 EXPECT_EQ(kEventSignaled, renderer.Wait())
845 << "Timed out while waiting for the frame to render.";
846
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000847 Stop();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000848
849 sender_transport.StopSending();
850 receiver_transport.StopSending();
851
852 DestroyStreams();
853}
854
855void EndToEndTest::ReceivesPliAndRecovers(int rtp_history_ms) {
856 static const int kPacketsToDrop = 1;
857
858 class PliObserver : public test::EndToEndTest, public VideoRenderer {
859 public:
860 explicit PliObserver(int rtp_history_ms)
861 : EndToEndTest(kLongTimeoutMs),
862 rtp_history_ms_(rtp_history_ms),
863 nack_enabled_(rtp_history_ms > 0),
864 highest_dropped_timestamp_(0),
865 frames_to_drop_(0),
866 received_pli_(false) {}
867
868 private:
pbos@webrtc.org0d852d52015-02-09 15:14:36 +0000869 virtual Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000870 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000871 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000872
873 // Drop all retransmitted packets to force a PLI.
874 if (header.timestamp <= highest_dropped_timestamp_)
875 return DROP_PACKET;
876
877 if (frames_to_drop_ > 0) {
878 highest_dropped_timestamp_ = header.timestamp;
879 --frames_to_drop_;
880 return DROP_PACKET;
881 }
882
883 return SEND_PACKET;
884 }
885
886 virtual Action OnReceiveRtcp(const uint8_t* packet,
pbos@webrtc.org0d852d52015-02-09 15:14:36 +0000887 size_t length) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000888 RTCPUtility::RTCPParserV2 parser(packet, length, true);
889 EXPECT_TRUE(parser.IsValid());
890
891 for (RTCPUtility::RTCPPacketTypes packet_type = parser.Begin();
892 packet_type != RTCPUtility::kRtcpNotValidCode;
893 packet_type = parser.Iterate()) {
894 if (!nack_enabled_)
895 EXPECT_NE(packet_type, RTCPUtility::kRtcpRtpfbNackCode);
896
897 if (packet_type == RTCPUtility::kRtcpPsfbPliCode) {
898 received_pli_ = true;
899 break;
900 }
901 }
902 return SEND_PACKET;
903 }
904
905 virtual void RenderFrame(const I420VideoFrame& video_frame,
pbos@webrtc.org0d852d52015-02-09 15:14:36 +0000906 int time_to_render_ms) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000907 CriticalSectionScoped lock(crit_.get());
908 if (received_pli_ &&
909 video_frame.timestamp() > highest_dropped_timestamp_) {
910 observation_complete_->Set();
911 }
912 if (!received_pli_)
913 frames_to_drop_ = kPacketsToDrop;
914 }
915
pbos@webrtc.org0d852d52015-02-09 15:14:36 +0000916 virtual bool IsTextureSupported() const override { return false; }
917
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000918 virtual void ModifyConfigs(
919 VideoSendStream::Config* send_config,
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000920 std::vector<VideoReceiveStream::Config>* receive_configs,
pbos@webrtc.org0d852d52015-02-09 15:14:36 +0000921 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000922 send_config->rtp.nack.rtp_history_ms = rtp_history_ms_;
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000923 (*receive_configs)[0].rtp.nack.rtp_history_ms = rtp_history_ms_;
924 (*receive_configs)[0].renderer = this;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000925 }
926
pbos@webrtc.org0d852d52015-02-09 15:14:36 +0000927 virtual void PerformTest() override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000928 EXPECT_EQ(kEventSignaled, Wait()) << "Timed out waiting for PLI to be "
929 "received and a frame to be "
930 "rendered afterwards.";
931 }
932
933 int rtp_history_ms_;
934 bool nack_enabled_;
935 uint32_t highest_dropped_timestamp_;
936 int frames_to_drop_;
937 bool received_pli_;
938 } test(rtp_history_ms);
939
940 RunBaseTest(&test);
941}
942
943TEST_F(EndToEndTest, ReceivesPliAndRecoversWithNack) {
944 ReceivesPliAndRecovers(1000);
945}
946
947// TODO(pbos): Enable this when 2250 is resolved.
948TEST_F(EndToEndTest, DISABLED_ReceivesPliAndRecoversWithoutNack) {
949 ReceivesPliAndRecovers(0);
950}
951
952TEST_F(EndToEndTest, UnknownRtpPacketGivesUnknownSsrcReturnCode) {
953 class PacketInputObserver : public PacketReceiver {
954 public:
955 explicit PacketInputObserver(PacketReceiver* receiver)
956 : receiver_(receiver), delivered_packet_(EventWrapper::Create()) {}
957
958 EventTypeWrapper Wait() {
959 return delivered_packet_->Wait(kDefaultTimeoutMs);
960 }
961
962 private:
963 virtual DeliveryStatus DeliverPacket(const uint8_t* packet,
pbos@webrtc.org0d852d52015-02-09 15:14:36 +0000964 size_t length) override {
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000965 if (RtpHeaderParser::IsRtcp(packet, length)) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000966 return receiver_->DeliverPacket(packet, length);
967 } else {
968 DeliveryStatus delivery_status =
969 receiver_->DeliverPacket(packet, length);
970 EXPECT_EQ(DELIVERY_UNKNOWN_SSRC, delivery_status);
971 delivered_packet_->Set();
972 return delivery_status;
973 }
974 }
975
976 PacketReceiver* receiver_;
977 scoped_ptr<EventWrapper> delivered_packet_;
978 };
979
980 test::DirectTransport send_transport, receive_transport;
981
982 CreateCalls(Call::Config(&send_transport), Call::Config(&receive_transport));
983 PacketInputObserver input_observer(receiver_call_->Receiver());
984
985 send_transport.SetReceiver(&input_observer);
986 receive_transport.SetReceiver(sender_call_->Receiver());
987
988 CreateSendConfig(1);
989 CreateMatchingReceiveConfigs();
990
991 CreateStreams();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000992 CreateFrameGeneratorCapturer();
993 Start();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000994
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000995 receiver_call_->DestroyVideoReceiveStream(receive_streams_[0]);
996 receive_streams_.clear();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000997
998 // Wait() waits for a received packet.
999 EXPECT_EQ(kEventSignaled, input_observer.Wait());
1000
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001001 Stop();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001002
1003 DestroyStreams();
1004
1005 send_transport.StopSending();
1006 receive_transport.StopSending();
1007}
1008
1009void EndToEndTest::RespectsRtcpMode(newapi::RtcpMode rtcp_mode) {
1010 static const int kNumCompoundRtcpPacketsToObserve = 10;
1011 class RtcpModeObserver : public test::EndToEndTest {
1012 public:
1013 explicit RtcpModeObserver(newapi::RtcpMode rtcp_mode)
1014 : EndToEndTest(kDefaultTimeoutMs),
1015 rtcp_mode_(rtcp_mode),
1016 sent_rtp_(0),
1017 sent_rtcp_(0) {}
1018
1019 private:
pbos@webrtc.org0d852d52015-02-09 15:14:36 +00001020 virtual Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001021 if (++sent_rtp_ % 3 == 0)
1022 return DROP_PACKET;
1023
1024 return SEND_PACKET;
1025 }
1026
1027 virtual Action OnReceiveRtcp(const uint8_t* packet,
pbos@webrtc.org0d852d52015-02-09 15:14:36 +00001028 size_t length) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001029 ++sent_rtcp_;
1030 RTCPUtility::RTCPParserV2 parser(packet, length, true);
1031 EXPECT_TRUE(parser.IsValid());
1032
1033 RTCPUtility::RTCPPacketTypes packet_type = parser.Begin();
1034 bool has_report_block = false;
1035 while (packet_type != RTCPUtility::kRtcpNotValidCode) {
1036 EXPECT_NE(RTCPUtility::kRtcpSrCode, packet_type);
1037 if (packet_type == RTCPUtility::kRtcpRrCode) {
1038 has_report_block = true;
1039 break;
1040 }
1041 packet_type = parser.Iterate();
1042 }
1043
1044 switch (rtcp_mode_) {
1045 case newapi::kRtcpCompound:
1046 if (!has_report_block) {
1047 ADD_FAILURE() << "Received RTCP packet without receiver report for "
1048 "kRtcpCompound.";
1049 observation_complete_->Set();
1050 }
1051
1052 if (sent_rtcp_ >= kNumCompoundRtcpPacketsToObserve)
1053 observation_complete_->Set();
1054
1055 break;
1056 case newapi::kRtcpReducedSize:
1057 if (!has_report_block)
1058 observation_complete_->Set();
1059 break;
1060 }
1061
1062 return SEND_PACKET;
1063 }
1064
1065 virtual void ModifyConfigs(
1066 VideoSendStream::Config* send_config,
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001067 std::vector<VideoReceiveStream::Config>* receive_configs,
pbos@webrtc.org0d852d52015-02-09 15:14:36 +00001068 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001069 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001070 (*receive_configs)[0].rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
1071 (*receive_configs)[0].rtp.rtcp_mode = rtcp_mode_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001072 }
1073
pbos@webrtc.org0d852d52015-02-09 15:14:36 +00001074 virtual void PerformTest() override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001075 EXPECT_EQ(kEventSignaled, Wait())
1076 << (rtcp_mode_ == newapi::kRtcpCompound
1077 ? "Timed out before observing enough compound packets."
1078 : "Timed out before receiving a non-compound RTCP packet.");
1079 }
1080
1081 newapi::RtcpMode rtcp_mode_;
1082 int sent_rtp_;
1083 int sent_rtcp_;
1084 } test(rtcp_mode);
1085
1086 RunBaseTest(&test);
1087}
1088
1089TEST_F(EndToEndTest, UsesRtcpCompoundMode) {
1090 RespectsRtcpMode(newapi::kRtcpCompound);
1091}
1092
1093TEST_F(EndToEndTest, UsesRtcpReducedSizeMode) {
1094 RespectsRtcpMode(newapi::kRtcpReducedSize);
1095}
1096
1097// Test sets up a Call multiple senders with different resolutions and SSRCs.
1098// Another is set up to receive all three of these with different renderers.
1099// Each renderer verifies that it receives the expected resolution, and as soon
1100// as every renderer has received a frame, the test finishes.
andresp@webrtc.org02686112014-09-19 08:24:19 +00001101TEST_F(EndToEndTest, SendsAndReceivesMultipleStreams) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001102 static const size_t kNumStreams = 3;
1103
1104 class VideoOutputObserver : public VideoRenderer {
1105 public:
1106 VideoOutputObserver(test::FrameGeneratorCapturer** capturer,
1107 int width,
1108 int height)
1109 : capturer_(capturer),
1110 width_(width),
1111 height_(height),
1112 done_(EventWrapper::Create()) {}
1113
1114 virtual void RenderFrame(const I420VideoFrame& video_frame,
pbos@webrtc.org0d852d52015-02-09 15:14:36 +00001115 int time_to_render_ms) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001116 EXPECT_EQ(width_, video_frame.width());
1117 EXPECT_EQ(height_, video_frame.height());
1118 (*capturer_)->Stop();
1119 done_->Set();
1120 }
1121
pbos@webrtc.org0d852d52015-02-09 15:14:36 +00001122 virtual bool IsTextureSupported() const override { return false; }
1123
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001124 EventTypeWrapper Wait() { return done_->Wait(kDefaultTimeoutMs); }
1125
1126 private:
1127 test::FrameGeneratorCapturer** capturer_;
1128 int width_;
1129 int height_;
1130 scoped_ptr<EventWrapper> done_;
1131 };
1132
1133 struct {
1134 uint32_t ssrc;
1135 int width;
1136 int height;
1137 } codec_settings[kNumStreams] = {{1, 640, 480}, {2, 320, 240}, {3, 240, 160}};
1138
1139 test::DirectTransport sender_transport, receiver_transport;
1140 scoped_ptr<Call> sender_call(Call::Create(Call::Config(&sender_transport)));
1141 scoped_ptr<Call> receiver_call(
1142 Call::Create(Call::Config(&receiver_transport)));
1143 sender_transport.SetReceiver(receiver_call->Receiver());
1144 receiver_transport.SetReceiver(sender_call->Receiver());
1145
1146 VideoSendStream* send_streams[kNumStreams];
1147 VideoReceiveStream* receive_streams[kNumStreams];
1148
1149 VideoOutputObserver* observers[kNumStreams];
1150 test::FrameGeneratorCapturer* frame_generators[kNumStreams];
1151
pbos@webrtc.orgab990ae2014-09-17 09:02:25 +00001152 scoped_ptr<VideoEncoder> encoders[kNumStreams];
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001153 for (size_t i = 0; i < kNumStreams; ++i)
pbos@webrtc.orgab990ae2014-09-17 09:02:25 +00001154 encoders[i].reset(VideoEncoder::Create(VideoEncoder::kVp8));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001155
pbos@webrtc.org776e6f22014-10-29 15:28:39 +00001156 ScopedVector<VideoDecoder> allocated_decoders;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001157 for (size_t i = 0; i < kNumStreams; ++i) {
1158 uint32_t ssrc = codec_settings[i].ssrc;
1159 int width = codec_settings[i].width;
1160 int height = codec_settings[i].height;
1161 observers[i] = new VideoOutputObserver(&frame_generators[i], width, height);
1162
pbos@webrtc.orgbd249bc2014-07-07 04:45:15 +00001163 VideoSendStream::Config send_config;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001164 send_config.rtp.ssrcs.push_back(ssrc);
1165 send_config.encoder_settings.encoder = encoders[i].get();
1166 send_config.encoder_settings.payload_name = "VP8";
1167 send_config.encoder_settings.payload_type = 124;
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00001168 VideoEncoderConfig encoder_config;
1169 encoder_config.streams = test::CreateVideoStreams(1);
1170 VideoStream* stream = &encoder_config.streams[0];
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001171 stream->width = width;
1172 stream->height = height;
1173 stream->max_framerate = 5;
1174 stream->min_bitrate_bps = stream->target_bitrate_bps =
1175 stream->max_bitrate_bps = 100000;
1176 send_streams[i] =
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00001177 sender_call->CreateVideoSendStream(send_config, encoder_config);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001178 send_streams[i]->Start();
1179
pbos@webrtc.orgbd249bc2014-07-07 04:45:15 +00001180 VideoReceiveStream::Config receive_config;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001181 receive_config.renderer = observers[i];
1182 receive_config.rtp.remote_ssrc = ssrc;
1183 receive_config.rtp.local_ssrc = kReceiverLocalSsrc;
pbos@webrtc.org776e6f22014-10-29 15:28:39 +00001184 VideoReceiveStream::Decoder decoder =
1185 test::CreateMatchingDecoder(send_config.encoder_settings);
1186 allocated_decoders.push_back(decoder.decoder);
1187 receive_config.decoders.push_back(decoder);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001188 receive_streams[i] =
1189 receiver_call->CreateVideoReceiveStream(receive_config);
1190 receive_streams[i]->Start();
1191
1192 frame_generators[i] = test::FrameGeneratorCapturer::Create(
1193 send_streams[i]->Input(), width, height, 30, Clock::GetRealTimeClock());
1194 frame_generators[i]->Start();
1195 }
1196
1197 for (size_t i = 0; i < kNumStreams; ++i) {
1198 EXPECT_EQ(kEventSignaled, observers[i]->Wait())
1199 << "Timed out while waiting for observer " << i << " to render.";
1200 }
1201
1202 for (size_t i = 0; i < kNumStreams; ++i) {
1203 frame_generators[i]->Stop();
1204 sender_call->DestroyVideoSendStream(send_streams[i]);
1205 receiver_call->DestroyVideoReceiveStream(receive_streams[i]);
1206 delete frame_generators[i];
1207 delete observers[i];
1208 }
1209
1210 sender_transport.StopSending();
1211 receiver_transport.StopSending();
1212}
1213
1214TEST_F(EndToEndTest, ObserversEncodedFrames) {
1215 class EncodedFrameTestObserver : public EncodedFrameObserver {
1216 public:
1217 EncodedFrameTestObserver()
1218 : length_(0),
1219 frame_type_(kFrameEmpty),
1220 called_(EventWrapper::Create()) {}
1221 virtual ~EncodedFrameTestObserver() {}
1222
1223 virtual void EncodedFrameCallback(const EncodedFrame& encoded_frame) {
1224 frame_type_ = encoded_frame.frame_type_;
1225 length_ = encoded_frame.length_;
1226 buffer_.reset(new uint8_t[length_]);
1227 memcpy(buffer_.get(), encoded_frame.data_, length_);
1228 called_->Set();
1229 }
1230
1231 EventTypeWrapper Wait() { return called_->Wait(kDefaultTimeoutMs); }
1232
1233 void ExpectEqualFrames(const EncodedFrameTestObserver& observer) {
1234 ASSERT_EQ(length_, observer.length_)
1235 << "Observed frames are of different lengths.";
1236 EXPECT_EQ(frame_type_, observer.frame_type_)
1237 << "Observed frames have different frame types.";
1238 EXPECT_EQ(0, memcmp(buffer_.get(), observer.buffer_.get(), length_))
1239 << "Observed encoded frames have different content.";
1240 }
1241
1242 private:
1243 scoped_ptr<uint8_t[]> buffer_;
1244 size_t length_;
1245 FrameType frame_type_;
1246 scoped_ptr<EventWrapper> called_;
1247 };
1248
1249 EncodedFrameTestObserver post_encode_observer;
1250 EncodedFrameTestObserver pre_decode_observer;
1251
1252 test::DirectTransport sender_transport, receiver_transport;
1253
1254 CreateCalls(Call::Config(&sender_transport),
1255 Call::Config(&receiver_transport));
1256
1257 sender_transport.SetReceiver(receiver_call_->Receiver());
1258 receiver_transport.SetReceiver(sender_call_->Receiver());
1259
1260 CreateSendConfig(1);
1261 CreateMatchingReceiveConfigs();
1262 send_config_.post_encode_callback = &post_encode_observer;
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001263 receive_configs_[0].pre_decode_callback = &pre_decode_observer;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001264
1265 CreateStreams();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001266 Start();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001267
1268 scoped_ptr<test::FrameGenerator> frame_generator(test::FrameGenerator::Create(
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00001269 encoder_config_.streams[0].width, encoder_config_.streams[0].height));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001270 send_stream_->Input()->SwapFrame(frame_generator->NextFrame());
1271
1272 EXPECT_EQ(kEventSignaled, post_encode_observer.Wait())
1273 << "Timed out while waiting for send-side encoded-frame callback.";
1274
1275 EXPECT_EQ(kEventSignaled, pre_decode_observer.Wait())
1276 << "Timed out while waiting for pre-decode encoded-frame callback.";
1277
1278 post_encode_observer.ExpectEqualFrames(pre_decode_observer);
1279
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001280 Stop();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001281
1282 sender_transport.StopSending();
1283 receiver_transport.StopSending();
1284
1285 DestroyStreams();
1286}
1287
1288TEST_F(EndToEndTest, ReceiveStreamSendsRemb) {
1289 class RembObserver : public test::EndToEndTest {
1290 public:
1291 RembObserver() : EndToEndTest(kDefaultTimeoutMs) {}
1292
1293 virtual Action OnReceiveRtcp(const uint8_t* packet,
pbos@webrtc.org0d852d52015-02-09 15:14:36 +00001294 size_t length) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001295 RTCPUtility::RTCPParserV2 parser(packet, length, true);
1296 EXPECT_TRUE(parser.IsValid());
1297
1298 bool received_psfb = false;
1299 bool received_remb = false;
1300 RTCPUtility::RTCPPacketTypes packet_type = parser.Begin();
1301 while (packet_type != RTCPUtility::kRtcpNotValidCode) {
1302 if (packet_type == RTCPUtility::kRtcpPsfbRembCode) {
1303 const RTCPUtility::RTCPPacket& packet = parser.Packet();
1304 EXPECT_EQ(packet.PSFBAPP.SenderSSRC, kReceiverLocalSsrc);
1305 received_psfb = true;
1306 } else if (packet_type == RTCPUtility::kRtcpPsfbRembItemCode) {
1307 const RTCPUtility::RTCPPacket& packet = parser.Packet();
1308 EXPECT_GT(packet.REMBItem.BitRate, 0u);
1309 EXPECT_EQ(packet.REMBItem.NumberOfSSRCs, 1u);
1310 EXPECT_EQ(packet.REMBItem.SSRCs[0], kSendSsrcs[0]);
1311 received_remb = true;
1312 }
1313 packet_type = parser.Iterate();
1314 }
1315 if (received_psfb && received_remb)
1316 observation_complete_->Set();
1317 return SEND_PACKET;
1318 }
pbos@webrtc.org0d852d52015-02-09 15:14:36 +00001319 virtual void PerformTest() override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001320 EXPECT_EQ(kEventSignaled, Wait()) << "Timed out while waiting for a "
1321 "receiver RTCP REMB packet to be "
1322 "sent.";
1323 }
1324 } test;
1325
1326 RunBaseTest(&test);
1327}
1328
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001329TEST_F(EndToEndTest, VerifyBandwidthStats) {
1330 class RtcpObserver : public test::EndToEndTest, public PacketReceiver {
1331 public:
1332 RtcpObserver()
1333 : EndToEndTest(kDefaultTimeoutMs),
1334 sender_call_(NULL),
1335 receiver_call_(NULL),
1336 has_seen_pacer_delay_(false) {}
1337
1338 virtual DeliveryStatus DeliverPacket(const uint8_t* packet,
pbos@webrtc.org0d852d52015-02-09 15:14:36 +00001339 size_t length) override {
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001340 Call::Stats sender_stats = sender_call_->GetStats();
1341 Call::Stats receiver_stats = receiver_call_->GetStats();
1342 if (!has_seen_pacer_delay_)
1343 has_seen_pacer_delay_ = sender_stats.pacer_delay_ms > 0;
1344 if (sender_stats.send_bandwidth_bps > 0 &&
pbos@webrtc.org2b19f062014-12-11 13:26:09 +00001345 receiver_stats.recv_bandwidth_bps > 0 && has_seen_pacer_delay_) {
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001346 observation_complete_->Set();
pbos@webrtc.org2b19f062014-12-11 13:26:09 +00001347 }
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001348 return receiver_call_->Receiver()->DeliverPacket(packet, length);
1349 }
1350
1351 virtual void OnCallsCreated(Call* sender_call,
pbos@webrtc.org0d852d52015-02-09 15:14:36 +00001352 Call* receiver_call) override {
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001353 sender_call_ = sender_call;
1354 receiver_call_ = receiver_call;
1355 }
1356
pbos@webrtc.org0d852d52015-02-09 15:14:36 +00001357 virtual void PerformTest() override {
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001358 EXPECT_EQ(kEventSignaled, Wait()) << "Timed out while waiting for "
1359 "non-zero bandwidth stats.";
1360 }
1361
1362 virtual void SetReceivers(
1363 PacketReceiver* send_transport_receiver,
pbos@webrtc.org0d852d52015-02-09 15:14:36 +00001364 PacketReceiver* receive_transport_receiver) override {
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001365 test::RtpRtcpObserver::SetReceivers(this, receive_transport_receiver);
1366 }
1367
1368 private:
1369 Call* sender_call_;
1370 Call* receiver_call_;
1371 bool has_seen_pacer_delay_;
1372 } test;
1373
1374 RunBaseTest(&test);
1375}
1376
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001377void EndToEndTest::TestXrReceiverReferenceTimeReport(bool enable_rrtr) {
1378 static const int kNumRtcpReportPacketsToObserve = 5;
1379 class RtcpXrObserver : public test::EndToEndTest {
1380 public:
1381 explicit RtcpXrObserver(bool enable_rrtr)
1382 : EndToEndTest(kDefaultTimeoutMs),
1383 enable_rrtr_(enable_rrtr),
1384 sent_rtcp_sr_(0),
1385 sent_rtcp_rr_(0),
1386 sent_rtcp_rrtr_(0),
1387 sent_rtcp_dlrr_(0) {}
1388
1389 private:
1390 // Receive stream should send RR packets (and RRTR packets if enabled).
1391 virtual Action OnReceiveRtcp(const uint8_t* packet,
pbos@webrtc.org0d852d52015-02-09 15:14:36 +00001392 size_t length) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001393 RTCPUtility::RTCPParserV2 parser(packet, length, true);
1394 EXPECT_TRUE(parser.IsValid());
1395
1396 RTCPUtility::RTCPPacketTypes packet_type = parser.Begin();
1397 while (packet_type != RTCPUtility::kRtcpNotValidCode) {
1398 if (packet_type == RTCPUtility::kRtcpRrCode) {
1399 ++sent_rtcp_rr_;
1400 } else if (packet_type ==
1401 RTCPUtility::kRtcpXrReceiverReferenceTimeCode) {
1402 ++sent_rtcp_rrtr_;
1403 }
1404 EXPECT_NE(packet_type, RTCPUtility::kRtcpSrCode);
1405 EXPECT_NE(packet_type, RTCPUtility::kRtcpXrDlrrReportBlockItemCode);
1406 packet_type = parser.Iterate();
1407 }
1408 return SEND_PACKET;
1409 }
1410 // Send stream should send SR packets (and DLRR packets if enabled).
1411 virtual Action OnSendRtcp(const uint8_t* packet, size_t length) {
1412 RTCPUtility::RTCPParserV2 parser(packet, length, true);
1413 EXPECT_TRUE(parser.IsValid());
1414
1415 RTCPUtility::RTCPPacketTypes packet_type = parser.Begin();
1416 while (packet_type != RTCPUtility::kRtcpNotValidCode) {
1417 if (packet_type == RTCPUtility::kRtcpSrCode) {
1418 ++sent_rtcp_sr_;
1419 } else if (packet_type == RTCPUtility::kRtcpXrDlrrReportBlockItemCode) {
1420 ++sent_rtcp_dlrr_;
1421 }
1422 EXPECT_NE(packet_type, RTCPUtility::kRtcpXrReceiverReferenceTimeCode);
1423 packet_type = parser.Iterate();
1424 }
1425 if (sent_rtcp_sr_ > kNumRtcpReportPacketsToObserve &&
1426 sent_rtcp_rr_ > kNumRtcpReportPacketsToObserve) {
1427 if (enable_rrtr_) {
1428 EXPECT_GT(sent_rtcp_rrtr_, 0);
1429 EXPECT_GT(sent_rtcp_dlrr_, 0);
1430 } else {
1431 EXPECT_EQ(0, sent_rtcp_rrtr_);
1432 EXPECT_EQ(0, sent_rtcp_dlrr_);
1433 }
1434 observation_complete_->Set();
1435 }
1436 return SEND_PACKET;
1437 }
1438
1439 virtual void ModifyConfigs(
1440 VideoSendStream::Config* send_config,
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001441 std::vector<VideoReceiveStream::Config>* receive_configs,
pbos@webrtc.org0d852d52015-02-09 15:14:36 +00001442 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001443 (*receive_configs)[0].rtp.rtcp_mode = newapi::kRtcpReducedSize;
1444 (*receive_configs)[0].rtp.rtcp_xr.receiver_reference_time_report =
1445 enable_rrtr_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001446 }
1447
pbos@webrtc.org0d852d52015-02-09 15:14:36 +00001448 virtual void PerformTest() override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001449 EXPECT_EQ(kEventSignaled, Wait())
1450 << "Timed out while waiting for RTCP SR/RR packets to be sent.";
1451 }
1452
1453 bool enable_rrtr_;
1454 int sent_rtcp_sr_;
1455 int sent_rtcp_rr_;
1456 int sent_rtcp_rrtr_;
1457 int sent_rtcp_dlrr_;
1458 } test(enable_rrtr);
1459
1460 RunBaseTest(&test);
1461}
1462
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001463void EndToEndTest::TestSendsSetSsrcs(size_t num_ssrcs,
1464 bool send_single_ssrc_first) {
1465 class SendsSetSsrcs : public test::EndToEndTest {
1466 public:
1467 SendsSetSsrcs(const uint32_t* ssrcs,
1468 size_t num_ssrcs,
1469 bool send_single_ssrc_first)
1470 : EndToEndTest(kDefaultTimeoutMs),
1471 num_ssrcs_(num_ssrcs),
1472 send_single_ssrc_first_(send_single_ssrc_first),
1473 ssrcs_to_observe_(num_ssrcs),
1474 expect_single_ssrc_(send_single_ssrc_first) {
1475 for (size_t i = 0; i < num_ssrcs; ++i)
1476 valid_ssrcs_[ssrcs[i]] = true;
1477 }
1478
1479 private:
pbos@webrtc.org0d852d52015-02-09 15:14:36 +00001480 virtual Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001481 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001482 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001483
1484 EXPECT_TRUE(valid_ssrcs_[header.ssrc])
1485 << "Received unknown SSRC: " << header.ssrc;
1486
1487 if (!valid_ssrcs_[header.ssrc])
1488 observation_complete_->Set();
1489
1490 if (!is_observed_[header.ssrc]) {
1491 is_observed_[header.ssrc] = true;
1492 --ssrcs_to_observe_;
1493 if (expect_single_ssrc_) {
1494 expect_single_ssrc_ = false;
1495 observation_complete_->Set();
1496 }
1497 }
1498
1499 if (ssrcs_to_observe_ == 0)
1500 observation_complete_->Set();
1501
1502 return SEND_PACKET;
1503 }
1504
pbos@webrtc.org0d852d52015-02-09 15:14:36 +00001505 virtual size_t GetNumStreams() const override { return num_ssrcs_; }
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001506
1507 virtual void ModifyConfigs(
1508 VideoSendStream::Config* send_config,
1509 std::vector<VideoReceiveStream::Config>* receive_configs,
pbos@webrtc.org0d852d52015-02-09 15:14:36 +00001510 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001511 if (num_ssrcs_ > 1) {
1512 // Set low simulcast bitrates to not have to wait for bandwidth ramp-up.
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00001513 for (size_t i = 0; i < encoder_config->streams.size(); ++i) {
1514 encoder_config->streams[i].min_bitrate_bps = 10000;
1515 encoder_config->streams[i].target_bitrate_bps = 15000;
1516 encoder_config->streams[i].max_bitrate_bps = 20000;
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001517 }
1518 }
1519
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00001520 encoder_config_all_streams_ = *encoder_config;
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001521 if (send_single_ssrc_first_)
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00001522 encoder_config->streams.resize(1);
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001523 }
1524
1525 virtual void OnStreamsCreated(
1526 VideoSendStream* send_stream,
pbos@webrtc.org0d852d52015-02-09 15:14:36 +00001527 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001528 send_stream_ = send_stream;
1529 }
1530
pbos@webrtc.org0d852d52015-02-09 15:14:36 +00001531 virtual void PerformTest() override {
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001532 EXPECT_EQ(kEventSignaled, Wait())
1533 << "Timed out while waiting for "
1534 << (send_single_ssrc_first_ ? "first SSRC." : "SSRCs.");
1535
1536 if (send_single_ssrc_first_) {
1537 // Set full simulcast and continue with the rest of the SSRCs.
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00001538 send_stream_->ReconfigureVideoEncoder(encoder_config_all_streams_);
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001539 EXPECT_EQ(kEventSignaled, Wait())
1540 << "Timed out while waiting on additional SSRCs.";
1541 }
1542 }
1543
1544 private:
1545 std::map<uint32_t, bool> valid_ssrcs_;
1546 std::map<uint32_t, bool> is_observed_;
1547
1548 const size_t num_ssrcs_;
1549 const bool send_single_ssrc_first_;
1550
1551 size_t ssrcs_to_observe_;
1552 bool expect_single_ssrc_;
1553
1554 VideoSendStream* send_stream_;
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00001555 VideoEncoderConfig encoder_config_all_streams_;
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001556 } test(kSendSsrcs, num_ssrcs, send_single_ssrc_first);
1557
1558 RunBaseTest(&test);
1559}
1560
pbos@webrtc.orgba253472014-11-25 09:39:04 +00001561TEST_F(EndToEndTest, GetStats) {
1562 static const int kStartBitrateBps = 3000000;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001563 class StatsObserver : public test::EndToEndTest, public I420FrameCallback {
1564 public:
1565 StatsObserver()
1566 : EndToEndTest(kLongTimeoutMs),
1567 receive_stream_(NULL),
1568 send_stream_(NULL),
1569 expected_receive_ssrc_(),
1570 expected_send_ssrcs_(),
1571 check_stats_event_(EventWrapper::Create()) {}
1572
1573 private:
pbos@webrtc.org0d852d52015-02-09 15:14:36 +00001574 virtual Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001575 check_stats_event_->Set();
1576 return SEND_PACKET;
1577 }
1578
pbos@webrtc.org0d852d52015-02-09 15:14:36 +00001579 virtual Action OnSendRtcp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001580 check_stats_event_->Set();
1581 return SEND_PACKET;
1582 }
1583
pbos@webrtc.org0d852d52015-02-09 15:14:36 +00001584 virtual Action OnReceiveRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001585 check_stats_event_->Set();
1586 return SEND_PACKET;
1587 }
1588
1589 virtual Action OnReceiveRtcp(const uint8_t* packet,
pbos@webrtc.org0d852d52015-02-09 15:14:36 +00001590 size_t length) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001591 check_stats_event_->Set();
1592 return SEND_PACKET;
1593 }
1594
pbos@webrtc.org0d852d52015-02-09 15:14:36 +00001595 virtual void FrameCallback(I420VideoFrame* video_frame) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001596 // Ensure that we have at least 5ms send side delay.
1597 int64_t render_time = video_frame->render_time_ms();
1598 if (render_time > 0)
1599 video_frame->set_render_time_ms(render_time - 5);
1600 }
1601
1602 bool CheckReceiveStats() {
1603 assert(receive_stream_ != NULL);
1604 VideoReceiveStream::Stats stats = receive_stream_->GetStats();
1605 EXPECT_EQ(expected_receive_ssrc_, stats.ssrc);
1606
1607 // Make sure all fields have been populated.
1608
1609 receive_stats_filled_["IncomingRate"] |=
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001610 stats.network_frame_rate != 0 || stats.total_bitrate_bps != 0;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001611
1612 receive_stats_filled_["FrameCallback"] |= stats.decode_frame_rate != 0;
1613
1614 receive_stats_filled_["FrameRendered"] |= stats.render_frame_rate != 0;
1615
1616 receive_stats_filled_["StatisticsUpdated"] |=
1617 stats.rtcp_stats.cumulative_lost != 0 ||
1618 stats.rtcp_stats.extended_max_sequence_number != 0 ||
1619 stats.rtcp_stats.fraction_lost != 0 || stats.rtcp_stats.jitter != 0;
1620
1621 receive_stats_filled_["DataCountersUpdated"] |=
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +00001622 stats.rtp_stats.transmitted.payload_bytes != 0 ||
1623 stats.rtp_stats.fec.packets != 0 ||
1624 stats.rtp_stats.transmitted.header_bytes != 0 ||
1625 stats.rtp_stats.transmitted.packets != 0 ||
1626 stats.rtp_stats.transmitted.padding_bytes != 0 ||
1627 stats.rtp_stats.retransmitted.packets != 0;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001628
1629 receive_stats_filled_["CodecStats"] |=
pbos@webrtc.orgce4e9a32014-12-18 13:50:16 +00001630 stats.avg_delay_ms != 0 || stats.discarded_packets != 0;
1631
1632 receive_stats_filled_["FrameCounts"] |=
1633 stats.frame_counts.key_frames != 0 ||
1634 stats.frame_counts.delta_frames != 0;
1635
1636 receive_stats_filled_["CName"] |= stats.c_name != "";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001637
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001638 return AllStatsFilled(receive_stats_filled_);
1639 }
1640
1641 bool CheckSendStats() {
1642 assert(send_stream_ != NULL);
1643 VideoSendStream::Stats stats = send_stream_->GetStats();
1644
1645 send_stats_filled_["NumStreams"] |=
1646 stats.substreams.size() == expected_send_ssrcs_.size();
1647
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001648 for (std::map<uint32_t, SsrcStats>::const_iterator it =
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001649 stats.substreams.begin();
1650 it != stats.substreams.end();
1651 ++it) {
1652 EXPECT_TRUE(expected_send_ssrcs_.find(it->first) !=
1653 expected_send_ssrcs_.end());
1654
1655 send_stats_filled_[CompoundKey("IncomingRate", it->first)] |=
1656 stats.input_frame_rate != 0;
1657
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001658 const SsrcStats& stream_stats = it->second;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001659
1660 send_stats_filled_[CompoundKey("StatisticsUpdated", it->first)] |=
1661 stream_stats.rtcp_stats.cumulative_lost != 0 ||
1662 stream_stats.rtcp_stats.extended_max_sequence_number != 0 ||
1663 stream_stats.rtcp_stats.fraction_lost != 0;
1664
1665 send_stats_filled_[CompoundKey("DataCountersUpdated", it->first)] |=
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +00001666 stream_stats.rtp_stats.fec.packets != 0 ||
1667 stream_stats.rtp_stats.transmitted.padding_bytes != 0 ||
1668 stream_stats.rtp_stats.retransmitted.packets != 0 ||
1669 stream_stats.rtp_stats.transmitted.packets != 0;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001670
1671 send_stats_filled_[CompoundKey("BitrateStatisticsObserver",
1672 it->first)] |=
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001673 stream_stats.total_bitrate_bps != 0;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001674
1675 send_stats_filled_[CompoundKey("FrameCountObserver", it->first)] |=
pbos@webrtc.orgce4e9a32014-12-18 13:50:16 +00001676 stream_stats.frame_counts.delta_frames != 0 ||
1677 stream_stats.frame_counts.key_frames != 0;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001678
1679 send_stats_filled_[CompoundKey("OutgoingRate", it->first)] |=
1680 stats.encode_frame_rate != 0;
stefan@webrtc.org168f23f2014-07-11 13:44:02 +00001681
1682 send_stats_filled_[CompoundKey("Delay", it->first)] |=
1683 stream_stats.avg_delay_ms != 0 || stream_stats.max_delay_ms != 0;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001684 }
1685
1686 return AllStatsFilled(send_stats_filled_);
1687 }
1688
1689 std::string CompoundKey(const char* name, uint32_t ssrc) {
1690 std::ostringstream oss;
1691 oss << name << "_" << ssrc;
1692 return oss.str();
1693 }
1694
1695 bool AllStatsFilled(const std::map<std::string, bool>& stats_map) {
1696 for (std::map<std::string, bool>::const_iterator it = stats_map.begin();
1697 it != stats_map.end();
1698 ++it) {
1699 if (!it->second)
1700 return false;
1701 }
1702 return true;
1703 }
1704
pbos@webrtc.org0d852d52015-02-09 15:14:36 +00001705 Call::Config GetSenderCallConfig() override {
pbos@webrtc.orgba253472014-11-25 09:39:04 +00001706 Call::Config config = EndToEndTest::GetSenderCallConfig();
pbos@webrtc.org00873182014-11-25 14:03:34 +00001707 config.stream_bitrates.start_bitrate_bps = kStartBitrateBps;
pbos@webrtc.orgba253472014-11-25 09:39:04 +00001708 return config;
1709 }
1710
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001711 virtual void ModifyConfigs(
1712 VideoSendStream::Config* send_config,
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001713 std::vector<VideoReceiveStream::Config>* receive_configs,
pbos@webrtc.org0d852d52015-02-09 15:14:36 +00001714 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001715 send_config->pre_encode_callback = this; // Used to inject delay.
1716 send_config->rtp.c_name = "SomeCName";
1717
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001718 expected_receive_ssrc_ = (*receive_configs)[0].rtp.local_ssrc;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001719 const std::vector<uint32_t>& ssrcs = send_config->rtp.ssrcs;
1720 for (size_t i = 0; i < ssrcs.size(); ++i)
1721 expected_send_ssrcs_.insert(ssrcs[i]);
1722
1723 expected_cname_ = send_config->rtp.c_name;
1724 }
1725
pbos@webrtc.org0d852d52015-02-09 15:14:36 +00001726 virtual size_t GetNumStreams() const override { return kNumSsrcs; }
pbos@webrtc.orgece38902014-11-14 11:52:04 +00001727
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001728 virtual void OnStreamsCreated(
1729 VideoSendStream* send_stream,
pbos@webrtc.org0d852d52015-02-09 15:14:36 +00001730 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001731 send_stream_ = send_stream;
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001732 receive_stream_ = receive_streams[0];
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001733 }
1734
pbos@webrtc.org0d852d52015-02-09 15:14:36 +00001735 virtual void PerformTest() override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001736 Clock* clock = Clock::GetRealTimeClock();
1737 int64_t now = clock->TimeInMilliseconds();
1738 int64_t stop_time = now + test::CallTest::kLongTimeoutMs;
1739 bool receive_ok = false;
1740 bool send_ok = false;
1741
1742 while (now < stop_time) {
1743 if (!receive_ok)
1744 receive_ok = CheckReceiveStats();
1745 if (!send_ok)
1746 send_ok = CheckSendStats();
1747
1748 if (receive_ok && send_ok)
1749 return;
1750
1751 int64_t time_until_timout_ = stop_time - now;
1752 if (time_until_timout_ > 0)
1753 check_stats_event_->Wait(time_until_timout_);
1754 now = clock->TimeInMilliseconds();
1755 }
1756
1757 ADD_FAILURE() << "Timed out waiting for filled stats.";
1758 for (std::map<std::string, bool>::const_iterator it =
1759 receive_stats_filled_.begin();
1760 it != receive_stats_filled_.end();
1761 ++it) {
1762 if (!it->second) {
1763 ADD_FAILURE() << "Missing receive stats: " << it->first;
1764 }
1765 }
1766
1767 for (std::map<std::string, bool>::const_iterator it =
1768 send_stats_filled_.begin();
1769 it != send_stats_filled_.end();
1770 ++it) {
1771 if (!it->second) {
1772 ADD_FAILURE() << "Missing send stats: " << it->first;
1773 }
1774 }
1775 }
1776
1777 VideoReceiveStream* receive_stream_;
1778 std::map<std::string, bool> receive_stats_filled_;
1779
1780 VideoSendStream* send_stream_;
1781 std::map<std::string, bool> send_stats_filled_;
1782
1783 uint32_t expected_receive_ssrc_;
1784 std::set<uint32_t> expected_send_ssrcs_;
1785 std::string expected_cname_;
1786
1787 scoped_ptr<EventWrapper> check_stats_event_;
1788 } test;
1789
1790 RunBaseTest(&test);
1791}
1792
1793TEST_F(EndToEndTest, ReceiverReferenceTimeReportEnabled) {
1794 TestXrReceiverReferenceTimeReport(true);
1795}
1796
1797TEST_F(EndToEndTest, ReceiverReferenceTimeReportDisabled) {
1798 TestXrReceiverReferenceTimeReport(false);
1799}
1800
1801TEST_F(EndToEndTest, TestReceivedRtpPacketStats) {
1802 static const size_t kNumRtpPacketsToSend = 5;
1803 class ReceivedRtpStatsObserver : public test::EndToEndTest {
1804 public:
1805 ReceivedRtpStatsObserver()
1806 : EndToEndTest(kDefaultTimeoutMs),
1807 receive_stream_(NULL),
1808 sent_rtp_(0) {}
1809
1810 private:
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001811 virtual void OnStreamsCreated(
1812 VideoSendStream* send_stream,
pbos@webrtc.org0d852d52015-02-09 15:14:36 +00001813 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001814 receive_stream_ = receive_streams[0];
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001815 }
1816
pbos@webrtc.org0d852d52015-02-09 15:14:36 +00001817 virtual Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001818 if (sent_rtp_ >= kNumRtpPacketsToSend) {
1819 VideoReceiveStream::Stats stats = receive_stream_->GetStats();
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +00001820 if (kNumRtpPacketsToSend == stats.rtp_stats.transmitted.packets) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001821 observation_complete_->Set();
1822 }
1823 return DROP_PACKET;
1824 }
1825 ++sent_rtp_;
1826 return SEND_PACKET;
1827 }
1828
pbos@webrtc.org0d852d52015-02-09 15:14:36 +00001829 virtual void PerformTest() override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001830 EXPECT_EQ(kEventSignaled, Wait())
1831 << "Timed out while verifying number of received RTP packets.";
1832 }
1833
1834 VideoReceiveStream* receive_stream_;
1835 uint32_t sent_rtp_;
1836 } test;
1837
1838 RunBaseTest(&test);
1839}
1840
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001841TEST_F(EndToEndTest, SendsSetSsrc) { TestSendsSetSsrcs(1, false); }
1842
1843TEST_F(EndToEndTest, SendsSetSimulcastSsrcs) {
1844 TestSendsSetSsrcs(kNumSsrcs, false);
1845}
1846
1847TEST_F(EndToEndTest, CanSwitchToUseAllSsrcs) {
1848 TestSendsSetSsrcs(kNumSsrcs, true);
1849}
1850
mflodman@webrtc.orgf9460682014-07-24 16:41:25 +00001851TEST_F(EndToEndTest, DISABLED_RedundantPayloadsTransmittedOnAllSsrcs) {
pbos@webrtc.org20c1f562014-07-04 10:58:12 +00001852 class ObserveRedundantPayloads: public test::EndToEndTest {
1853 public:
1854 ObserveRedundantPayloads()
1855 : EndToEndTest(kDefaultTimeoutMs), ssrcs_to_observe_(kNumSsrcs) {
pbos@webrtc.orgdde16f12014-08-05 23:35:43 +00001856 for (size_t i = 0; i < kNumSsrcs; ++i) {
pbos@webrtc.org20c1f562014-07-04 10:58:12 +00001857 registered_rtx_ssrc_[kSendRtxSsrcs[i]] = true;
1858 }
1859 }
1860
1861 private:
pbos@webrtc.org0d852d52015-02-09 15:14:36 +00001862 virtual Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org20c1f562014-07-04 10:58:12 +00001863 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001864 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.org20c1f562014-07-04 10:58:12 +00001865
1866 if (!registered_rtx_ssrc_[header.ssrc])
1867 return SEND_PACKET;
1868
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001869 EXPECT_LE(header.headerLength + header.paddingLength, length);
pbos@webrtc.org20c1f562014-07-04 10:58:12 +00001870 const bool packet_is_redundant_payload =
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001871 header.headerLength + header.paddingLength < length;
pbos@webrtc.org20c1f562014-07-04 10:58:12 +00001872
1873 if (!packet_is_redundant_payload)
1874 return SEND_PACKET;
1875
1876 if (!observed_redundant_retransmission_[header.ssrc]) {
1877 observed_redundant_retransmission_[header.ssrc] = true;
1878 if (--ssrcs_to_observe_ == 0)
1879 observation_complete_->Set();
1880 }
1881
1882 return SEND_PACKET;
1883 }
1884
pbos@webrtc.org0d852d52015-02-09 15:14:36 +00001885 virtual size_t GetNumStreams() const override { return kNumSsrcs; }
pbos@webrtc.org20c1f562014-07-04 10:58:12 +00001886
1887 virtual void ModifyConfigs(
1888 VideoSendStream::Config* send_config,
1889 std::vector<VideoReceiveStream::Config>* receive_configs,
pbos@webrtc.org0d852d52015-02-09 15:14:36 +00001890 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org20c1f562014-07-04 10:58:12 +00001891 // Set low simulcast bitrates to not have to wait for bandwidth ramp-up.
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00001892 for (size_t i = 0; i < encoder_config->streams.size(); ++i) {
1893 encoder_config->streams[i].min_bitrate_bps = 10000;
1894 encoder_config->streams[i].target_bitrate_bps = 15000;
1895 encoder_config->streams[i].max_bitrate_bps = 20000;
pbos@webrtc.org20c1f562014-07-04 10:58:12 +00001896 }
pbos@webrtc.org20c1f562014-07-04 10:58:12 +00001897
1898 send_config->rtp.rtx.payload_type = kSendRtxPayloadType;
pbos@webrtc.org20c1f562014-07-04 10:58:12 +00001899
1900 for (size_t i = 0; i < kNumSsrcs; ++i)
1901 send_config->rtp.rtx.ssrcs.push_back(kSendRtxSsrcs[i]);
pbos@webrtc.orgad3b5a52014-10-24 09:23:21 +00001902
1903 // Significantly higher than max bitrates for all video streams -> forcing
1904 // padding to trigger redundant padding on all RTX SSRCs.
1905 encoder_config->min_transmit_bitrate_bps = 100000;
pbos@webrtc.org20c1f562014-07-04 10:58:12 +00001906 }
1907
pbos@webrtc.org0d852d52015-02-09 15:14:36 +00001908 virtual void PerformTest() override {
pbos@webrtc.org20c1f562014-07-04 10:58:12 +00001909 EXPECT_EQ(kEventSignaled, Wait())
1910 << "Timed out while waiting for redundant payloads on all SSRCs.";
1911 }
1912
1913 private:
1914 size_t ssrcs_to_observe_;
1915 std::map<uint32_t, bool> observed_redundant_retransmission_;
1916 std::map<uint32_t, bool> registered_rtx_ssrc_;
1917 } test;
1918
1919 RunBaseTest(&test);
1920}
1921
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +00001922void EndToEndTest::TestRtpStatePreservation(bool use_rtx) {
1923 static const uint32_t kMaxSequenceNumberGap = 100;
1924 static const uint64_t kMaxTimestampGap = kDefaultTimeoutMs * 90;
1925 class RtpSequenceObserver : public test::RtpRtcpObserver {
1926 public:
pbos@webrtc.orgdde16f12014-08-05 23:35:43 +00001927 explicit RtpSequenceObserver(bool use_rtx)
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +00001928 : test::RtpRtcpObserver(kDefaultTimeoutMs),
1929 crit_(CriticalSectionWrapper::CreateCriticalSection()),
1930 ssrcs_to_observe_(kNumSsrcs) {
1931 for (size_t i = 0; i < kNumSsrcs; ++i) {
1932 configured_ssrcs_[kSendSsrcs[i]] = true;
1933 if (use_rtx)
1934 configured_ssrcs_[kSendRtxSsrcs[i]] = true;
1935 }
1936 }
1937
1938 void ResetExpectedSsrcs(size_t num_expected_ssrcs) {
1939 CriticalSectionScoped lock(crit_.get());
1940 ssrc_observed_.clear();
1941 ssrcs_to_observe_ = num_expected_ssrcs;
1942 }
1943
1944 private:
pbos@webrtc.org0d852d52015-02-09 15:14:36 +00001945 virtual Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +00001946 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001947 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +00001948 const uint32_t ssrc = header.ssrc;
1949 const uint16_t sequence_number = header.sequenceNumber;
1950 const uint32_t timestamp = header.timestamp;
1951 const bool only_padding =
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00001952 header.headerLength + header.paddingLength == length;
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +00001953
1954 EXPECT_TRUE(configured_ssrcs_[ssrc])
1955 << "Received SSRC that wasn't configured: " << ssrc;
1956
1957 std::map<uint32_t, uint16_t>::iterator it =
1958 last_observed_sequence_number_.find(header.ssrc);
1959 if (it == last_observed_sequence_number_.end()) {
1960 last_observed_sequence_number_[ssrc] = sequence_number;
1961 last_observed_timestamp_[ssrc] = timestamp;
1962 } else {
1963 // Verify sequence numbers are reasonably close.
1964 uint32_t extended_sequence_number = sequence_number;
1965 // Check for roll-over.
1966 if (sequence_number < last_observed_sequence_number_[ssrc])
1967 extended_sequence_number += 0xFFFFu + 1;
1968 EXPECT_LE(
1969 extended_sequence_number - last_observed_sequence_number_[ssrc],
1970 kMaxSequenceNumberGap)
1971 << "Gap in sequence numbers ("
1972 << last_observed_sequence_number_[ssrc] << " -> " << sequence_number
1973 << ") too large for SSRC: " << ssrc << ".";
1974 last_observed_sequence_number_[ssrc] = sequence_number;
1975
1976 // TODO(pbos): Remove this check if we ever have monotonically
1977 // increasing timestamps. Right now padding packets add a delta which
1978 // can cause reordering between padding packets and regular packets,
1979 // hence we drop padding-only packets to not flake.
1980 if (only_padding) {
1981 // Verify that timestamps are reasonably close.
1982 uint64_t extended_timestamp = timestamp;
1983 // Check for roll-over.
1984 if (timestamp < last_observed_timestamp_[ssrc])
1985 extended_timestamp += static_cast<uint64_t>(0xFFFFFFFFu) + 1;
1986 EXPECT_LE(extended_timestamp - last_observed_timestamp_[ssrc],
1987 kMaxTimestampGap)
1988 << "Gap in timestamps (" << last_observed_timestamp_[ssrc]
1989 << " -> " << timestamp << ") too large for SSRC: " << ssrc << ".";
1990 }
1991 last_observed_timestamp_[ssrc] = timestamp;
1992 }
1993
1994 CriticalSectionScoped lock(crit_.get());
1995 // Wait for media packets on all ssrcs.
1996 if (!ssrc_observed_[ssrc] && !only_padding) {
1997 ssrc_observed_[ssrc] = true;
1998 if (--ssrcs_to_observe_ == 0)
1999 observation_complete_->Set();
2000 }
2001
2002 return SEND_PACKET;
2003 }
2004
2005 std::map<uint32_t, uint16_t> last_observed_sequence_number_;
2006 std::map<uint32_t, uint32_t> last_observed_timestamp_;
2007 std::map<uint32_t, bool> configured_ssrcs_;
2008
2009 scoped_ptr<CriticalSectionWrapper> crit_;
2010 size_t ssrcs_to_observe_ GUARDED_BY(crit_);
2011 std::map<uint32_t, bool> ssrc_observed_ GUARDED_BY(crit_);
2012 } observer(use_rtx);
2013
2014 CreateCalls(Call::Config(observer.SendTransport()),
2015 Call::Config(observer.ReceiveTransport()));
2016 observer.SetReceivers(sender_call_->Receiver(), NULL);
2017
2018 CreateSendConfig(kNumSsrcs);
2019
2020 if (use_rtx) {
2021 for (size_t i = 0; i < kNumSsrcs; ++i) {
2022 send_config_.rtp.rtx.ssrcs.push_back(kSendRtxSsrcs[i]);
2023 }
2024 send_config_.rtp.rtx.payload_type = kSendRtxPayloadType;
2025 }
2026
2027 // Lower bitrates so that all streams send initially.
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002028 for (size_t i = 0; i < encoder_config_.streams.size(); ++i) {
2029 encoder_config_.streams[i].min_bitrate_bps = 10000;
2030 encoder_config_.streams[i].target_bitrate_bps = 15000;
2031 encoder_config_.streams[i].max_bitrate_bps = 20000;
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +00002032 }
2033
pbos@webrtc.org32452b22014-10-22 12:15:24 +00002034 // Use the same total bitrates when sending a single stream to avoid lowering
2035 // the bitrate estimate and requiring a subsequent rampup.
2036 VideoEncoderConfig one_stream = encoder_config_;
2037 one_stream.streams.resize(1);
2038 for (size_t i = 1; i < encoder_config_.streams.size(); ++i) {
2039 one_stream.streams.front().min_bitrate_bps +=
2040 encoder_config_.streams[i].min_bitrate_bps;
2041 one_stream.streams.front().target_bitrate_bps +=
2042 encoder_config_.streams[i].target_bitrate_bps;
2043 one_stream.streams.front().max_bitrate_bps +=
2044 encoder_config_.streams[i].max_bitrate_bps;
2045 }
2046
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +00002047 CreateMatchingReceiveConfigs();
2048
2049 CreateStreams();
2050 CreateFrameGeneratorCapturer();
2051
2052 Start();
2053 EXPECT_EQ(kEventSignaled, observer.Wait())
2054 << "Timed out waiting for all SSRCs to send packets.";
2055
2056 // Test stream resetting more than once to make sure that the state doesn't
2057 // get set once (this could be due to using std::map::insert for instance).
2058 for (size_t i = 0; i < 3; ++i) {
2059 frame_generator_capturer_->Stop();
2060 sender_call_->DestroyVideoSendStream(send_stream_);
2061
2062 // Re-create VideoSendStream with only one stream.
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +00002063 send_stream_ =
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002064 sender_call_->CreateVideoSendStream(send_config_, one_stream);
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +00002065 send_stream_->Start();
2066 CreateFrameGeneratorCapturer();
2067 frame_generator_capturer_->Start();
2068
2069 observer.ResetExpectedSsrcs(1);
2070 EXPECT_EQ(kEventSignaled, observer.Wait())
2071 << "Timed out waiting for single RTP packet.";
2072
2073 // Reconfigure back to use all streams.
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002074 send_stream_->ReconfigureVideoEncoder(encoder_config_);
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +00002075 observer.ResetExpectedSsrcs(kNumSsrcs);
2076 EXPECT_EQ(kEventSignaled, observer.Wait())
2077 << "Timed out waiting for all SSRCs to send packets.";
2078
2079 // Reconfigure down to one stream.
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002080 send_stream_->ReconfigureVideoEncoder(one_stream);
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +00002081 observer.ResetExpectedSsrcs(1);
2082 EXPECT_EQ(kEventSignaled, observer.Wait())
2083 << "Timed out waiting for single RTP packet.";
2084
2085 // Reconfigure back to use all streams.
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002086 send_stream_->ReconfigureVideoEncoder(encoder_config_);
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +00002087 observer.ResetExpectedSsrcs(kNumSsrcs);
2088 EXPECT_EQ(kEventSignaled, observer.Wait())
2089 << "Timed out waiting for all SSRCs to send packets.";
2090 }
2091
2092 observer.StopSending();
2093
2094 Stop();
2095 DestroyStreams();
2096}
2097
aluebs@webrtc.orgb623c5c2014-08-26 14:22:51 +00002098TEST_F(EndToEndTest, DISABLED_RestartingSendStreamPreservesRtpState) {
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +00002099 TestRtpStatePreservation(false);
2100}
2101
2102TEST_F(EndToEndTest, RestartingSendStreamPreservesRtpStatesWithRtx) {
2103 TestRtpStatePreservation(true);
2104}
2105
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00002106TEST_F(EndToEndTest, RespectsNetworkState) {
2107 // TODO(pbos): Remove accepted downtime packets etc. when signaling network
2108 // down blocks until no more packets will be sent.
2109
2110 // Pacer will send from its packet list and then send required padding before
2111 // checking paused_ again. This should be enough for one round of pacing,
2112 // otherwise increase.
2113 static const int kNumAcceptedDowntimeRtp = 5;
2114 // A single RTCP may be in the pipeline.
2115 static const int kNumAcceptedDowntimeRtcp = 1;
2116 class NetworkStateTest : public test::EndToEndTest, public test::FakeEncoder {
2117 public:
2118 NetworkStateTest()
2119 : EndToEndTest(kDefaultTimeoutMs),
2120 FakeEncoder(Clock::GetRealTimeClock()),
2121 test_crit_(CriticalSectionWrapper::CreateCriticalSection()),
2122 encoded_frames_(EventWrapper::Create()),
2123 sender_packets_(EventWrapper::Create()),
2124 receiver_packets_(EventWrapper::Create()),
2125 sender_state_(Call::kNetworkUp),
2126 down_sender_rtp_(0),
2127 down_sender_rtcp_(0),
2128 receiver_state_(Call::kNetworkUp),
2129 down_receiver_rtcp_(0),
2130 down_frames_(0) {}
2131
pbos@webrtc.org0d852d52015-02-09 15:14:36 +00002132 virtual Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00002133 CriticalSectionScoped lock(test_crit_.get());
2134 if (sender_state_ == Call::kNetworkDown) {
2135 ++down_sender_rtp_;
2136 EXPECT_LE(down_sender_rtp_, kNumAcceptedDowntimeRtp)
2137 << "RTP sent during sender-side downtime.";
2138 if (down_sender_rtp_> kNumAcceptedDowntimeRtp)
2139 sender_packets_->Set();
2140 } else {
2141 sender_packets_->Set();
2142 }
2143 return SEND_PACKET;
2144 }
2145
pbos@webrtc.org0d852d52015-02-09 15:14:36 +00002146 virtual Action OnSendRtcp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00002147 CriticalSectionScoped lock(test_crit_.get());
2148 if (sender_state_ == Call::kNetworkDown) {
2149 ++down_sender_rtcp_;
2150 EXPECT_LE(down_sender_rtcp_, kNumAcceptedDowntimeRtcp)
2151 << "RTCP sent during sender-side downtime.";
2152 if (down_sender_rtcp_ > kNumAcceptedDowntimeRtcp)
2153 sender_packets_->Set();
2154 } else {
2155 sender_packets_->Set();
2156 }
2157 return SEND_PACKET;
2158 }
2159
pbos@webrtc.org0d852d52015-02-09 15:14:36 +00002160 virtual Action OnReceiveRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00002161 ADD_FAILURE() << "Unexpected receiver RTP, should not be sending.";
2162 return SEND_PACKET;
2163 }
2164
2165 virtual Action OnReceiveRtcp(const uint8_t* packet,
pbos@webrtc.org0d852d52015-02-09 15:14:36 +00002166 size_t length) override {
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00002167 CriticalSectionScoped lock(test_crit_.get());
2168 if (receiver_state_ == Call::kNetworkDown) {
2169 ++down_receiver_rtcp_;
2170 EXPECT_LE(down_receiver_rtcp_, kNumAcceptedDowntimeRtcp)
2171 << "RTCP sent during receiver-side downtime.";
2172 if (down_receiver_rtcp_ > kNumAcceptedDowntimeRtcp)
2173 receiver_packets_->Set();
2174 } else {
2175 receiver_packets_->Set();
2176 }
2177 return SEND_PACKET;
2178 }
2179
2180 virtual void OnCallsCreated(Call* sender_call,
pbos@webrtc.org0d852d52015-02-09 15:14:36 +00002181 Call* receiver_call) override {
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00002182 sender_call_ = sender_call;
2183 receiver_call_ = receiver_call;
2184 }
2185
2186 virtual void ModifyConfigs(
2187 VideoSendStream::Config* send_config,
2188 std::vector<VideoReceiveStream::Config>* receive_configs,
pbos@webrtc.org0d852d52015-02-09 15:14:36 +00002189 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00002190 send_config->encoder_settings.encoder = this;
2191 }
2192
pbos@webrtc.org0d852d52015-02-09 15:14:36 +00002193 virtual void PerformTest() override {
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00002194 EXPECT_EQ(kEventSignaled, encoded_frames_->Wait(kDefaultTimeoutMs))
2195 << "No frames received by the encoder.";
2196 EXPECT_EQ(kEventSignaled, sender_packets_->Wait(kDefaultTimeoutMs))
2197 << "Timed out waiting for send-side packets.";
2198 EXPECT_EQ(kEventSignaled, receiver_packets_->Wait(kDefaultTimeoutMs))
2199 << "Timed out waiting for receiver-side packets.";
2200
2201 // Sender-side network down.
2202 sender_call_->SignalNetworkState(Call::kNetworkDown);
2203 {
2204 CriticalSectionScoped lock(test_crit_.get());
2205 sender_packets_->Reset(); // Earlier packets should not count.
2206 sender_state_ = Call::kNetworkDown;
2207 }
2208 EXPECT_EQ(kEventTimeout, sender_packets_->Wait(kSilenceTimeoutMs))
2209 << "Packets sent during sender-network downtime.";
2210 EXPECT_EQ(kEventSignaled, receiver_packets_->Wait(kDefaultTimeoutMs))
2211 << "Timed out waiting for receiver-side packets.";
2212 // Receiver-side network down.
2213 receiver_call_->SignalNetworkState(Call::kNetworkDown);
2214 {
2215 CriticalSectionScoped lock(test_crit_.get());
2216 receiver_packets_->Reset(); // Earlier packets should not count.
2217 receiver_state_ = Call::kNetworkDown;
2218 }
2219 EXPECT_EQ(kEventTimeout, receiver_packets_->Wait(kSilenceTimeoutMs))
2220 << "Packets sent during receiver-network downtime.";
2221
2222 // Network back up again for both.
2223 {
2224 CriticalSectionScoped lock(test_crit_.get());
2225 sender_packets_->Reset(); // Earlier packets should not count.
2226 receiver_packets_->Reset(); // Earlier packets should not count.
2227 sender_state_ = receiver_state_ = Call::kNetworkUp;
2228 }
2229 sender_call_->SignalNetworkState(Call::kNetworkUp);
2230 receiver_call_->SignalNetworkState(Call::kNetworkUp);
2231 EXPECT_EQ(kEventSignaled, sender_packets_->Wait(kDefaultTimeoutMs))
2232 << "Timed out waiting for send-side packets.";
2233 EXPECT_EQ(kEventSignaled, receiver_packets_->Wait(kDefaultTimeoutMs))
2234 << "Timed out waiting for receiver-side packets.";
2235 }
2236
pbos@webrtc.org0d852d52015-02-09 15:14:36 +00002237 virtual int32_t Encode(
2238 const I420VideoFrame& input_image,
2239 const CodecSpecificInfo* codec_specific_info,
2240 const std::vector<VideoFrameType>* frame_types) override {
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00002241 {
2242 CriticalSectionScoped lock(test_crit_.get());
2243 if (sender_state_ == Call::kNetworkDown) {
2244 ++down_frames_;
2245 EXPECT_LE(down_frames_, 1)
2246 << "Encoding more than one frame while network is down.";
2247 if (down_frames_ > 1)
2248 encoded_frames_->Set();
2249 } else {
2250 encoded_frames_->Set();
2251 }
2252 }
2253 return test::FakeEncoder::Encode(
2254 input_image, codec_specific_info, frame_types);
2255 }
2256
2257 private:
2258 const scoped_ptr<CriticalSectionWrapper> test_crit_;
2259 scoped_ptr<EventWrapper> encoded_frames_;
2260 scoped_ptr<EventWrapper> sender_packets_;
2261 scoped_ptr<EventWrapper> receiver_packets_;
2262 Call* sender_call_;
2263 Call* receiver_call_;
2264 Call::NetworkState sender_state_ GUARDED_BY(test_crit_);
2265 int down_sender_rtp_ GUARDED_BY(test_crit_);
2266 int down_sender_rtcp_ GUARDED_BY(test_crit_);
2267 Call::NetworkState receiver_state_ GUARDED_BY(test_crit_);
2268 int down_receiver_rtcp_ GUARDED_BY(test_crit_);
2269 int down_frames_ GUARDED_BY(test_crit_);
2270 } test;
2271
2272 RunBaseTest(&test);
2273}
2274
pbos@webrtc.org2b19f062014-12-11 13:26:09 +00002275TEST_F(EndToEndTest, CallReportsRttForSender) {
2276 static const int kSendDelayMs = 30;
2277 static const int kReceiveDelayMs = 70;
2278
2279 FakeNetworkPipe::Config config;
2280 config.queue_delay_ms = kSendDelayMs;
2281 test::DirectTransport sender_transport(config);
2282 config.queue_delay_ms = kReceiveDelayMs;
2283 test::DirectTransport receiver_transport(config);
2284
2285 CreateCalls(Call::Config(&sender_transport),
2286 Call::Config(&receiver_transport));
2287
2288 sender_transport.SetReceiver(receiver_call_->Receiver());
2289 receiver_transport.SetReceiver(sender_call_->Receiver());
2290
2291 CreateSendConfig(1);
2292 CreateMatchingReceiveConfigs();
2293
2294 CreateStreams();
2295 CreateFrameGeneratorCapturer();
2296 Start();
2297
2298 int64_t start_time_ms = clock_->TimeInMilliseconds();
2299 while (true) {
2300 Call::Stats stats = sender_call_->GetStats();
2301 ASSERT_GE(start_time_ms + kDefaultTimeoutMs,
2302 clock_->TimeInMilliseconds())
2303 << "No RTT stats before timeout!";
2304 if (stats.rtt_ms != -1) {
2305 EXPECT_GE(stats.rtt_ms, kSendDelayMs + kReceiveDelayMs);
2306 break;
2307 }
2308 SleepMs(10);
2309 }
2310
2311 Stop();
2312 DestroyStreams();
2313}
2314
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00002315TEST_F(EndToEndTest, NewSendStreamsRespectNetworkDown) {
2316 class UnusedEncoder : public test::FakeEncoder {
2317 public:
2318 UnusedEncoder() : FakeEncoder(Clock::GetRealTimeClock()) {}
pbos@webrtc.org0d852d52015-02-09 15:14:36 +00002319 virtual int32_t Encode(
2320 const I420VideoFrame& input_image,
2321 const CodecSpecificInfo* codec_specific_info,
2322 const std::vector<VideoFrameType>* frame_types) override {
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00002323 ADD_FAILURE() << "Unexpected frame encode.";
2324 return test::FakeEncoder::Encode(
2325 input_image, codec_specific_info, frame_types);
2326 }
2327 };
2328
2329 UnusedTransport transport;
2330 CreateSenderCall(Call::Config(&transport));
2331 sender_call_->SignalNetworkState(Call::kNetworkDown);
2332
2333 CreateSendConfig(1);
2334 UnusedEncoder unused_encoder;
2335 send_config_.encoder_settings.encoder = &unused_encoder;
2336 CreateStreams();
2337 CreateFrameGeneratorCapturer();
2338
2339 Start();
2340 SleepMs(kSilenceTimeoutMs);
2341 Stop();
2342
2343 DestroyStreams();
2344}
2345
2346TEST_F(EndToEndTest, NewReceiveStreamsRespectNetworkDown) {
2347 test::DirectTransport sender_transport;
2348 CreateSenderCall(Call::Config(&sender_transport));
2349 UnusedTransport transport;
2350 CreateReceiverCall(Call::Config(&transport));
2351 sender_transport.SetReceiver(receiver_call_->Receiver());
2352
2353 receiver_call_->SignalNetworkState(Call::kNetworkDown);
2354
2355 CreateSendConfig(1);
2356 CreateMatchingReceiveConfigs();
2357 CreateStreams();
2358 CreateFrameGeneratorCapturer();
2359
2360 Start();
2361 SleepMs(kSilenceTimeoutMs);
2362 Stop();
2363
2364 sender_transport.StopSending();
2365
2366 DestroyStreams();
2367}
pbos@webrtc.org09cc6862014-11-04 13:48:15 +00002368
2369// TODO(pbos): Remove this regression test when VideoEngine is no longer used as
2370// a backend. This is to test that we hand channels back properly.
2371TEST_F(EndToEndTest, CanCreateAndDestroyManyVideoStreams) {
2372 test::NullTransport transport;
2373 scoped_ptr<Call> call(Call::Create(Call::Config(&transport)));
2374 test::FakeDecoder fake_decoder;
2375 test::FakeEncoder fake_encoder(Clock::GetRealTimeClock());
2376 for (size_t i = 0; i < 100; ++i) {
2377 VideoSendStream::Config send_config;
2378 send_config.encoder_settings.encoder = &fake_encoder;
2379 send_config.encoder_settings.payload_name = "FAKE";
2380 send_config.encoder_settings.payload_type = 123;
2381
2382 VideoEncoderConfig encoder_config;
2383 encoder_config.streams = test::CreateVideoStreams(1);
2384 send_config.rtp.ssrcs.push_back(1);
2385 VideoSendStream* send_stream =
2386 call->CreateVideoSendStream(send_config, encoder_config);
2387 call->DestroyVideoSendStream(send_stream);
2388
2389 VideoReceiveStream::Config receive_config;
2390 receive_config.rtp.remote_ssrc = 1;
2391 receive_config.rtp.local_ssrc = kReceiverLocalSsrc;
2392 VideoReceiveStream::Decoder decoder;
2393 decoder.decoder = &fake_decoder;
2394 decoder.payload_type = 123;
2395 decoder.payload_name = "FAKE";
2396 receive_config.decoders.push_back(decoder);
2397 VideoReceiveStream* receive_stream =
2398 call->CreateVideoReceiveStream(receive_config);
2399 call->DestroyVideoReceiveStream(receive_stream);
2400 }
2401}
andrew@webrtc.org8f27fcc2015-01-09 20:22:46 +00002402
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002403} // namespace webrtc