blob: 3b5012d78e79efa4edde07c43e7e6300415f20cf [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"
22#include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h"
23#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
24#include "webrtc/system_wrappers/interface/event_wrapper.h"
25#include "webrtc/system_wrappers/interface/scoped_ptr.h"
26#include "webrtc/system_wrappers/interface/sleep.h"
27#include "webrtc/test/call_test.h"
28#include "webrtc/test/direct_transport.h"
29#include "webrtc/test/encoder_settings.h"
30#include "webrtc/test/fake_audio_device.h"
31#include "webrtc/test/fake_decoder.h"
32#include "webrtc/test/fake_encoder.h"
33#include "webrtc/test/frame_generator.h"
34#include "webrtc/test/frame_generator_capturer.h"
35#include "webrtc/test/null_transport.h"
36#include "webrtc/test/rtp_rtcp_observer.h"
37#include "webrtc/test/testsupport/fileutils.h"
38#include "webrtc/test/testsupport/perf_test.h"
39#include "webrtc/video/transport_adapter.h"
40
41namespace webrtc {
42
43static const int kRedPayloadType = 118;
44static const int kUlpfecPayloadType = 119;
45
46class EndToEndTest : public test::CallTest {
47 public:
48 EndToEndTest() {}
49
50 virtual ~EndToEndTest() {
51 EXPECT_EQ(NULL, send_stream_);
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +000052 EXPECT_TRUE(receive_streams_.empty());
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000053 }
54
55 protected:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000056 void DecodesRetransmittedFrame(bool retransmit_over_rtx);
57 void ReceivesPliAndRecovers(int rtp_history_ms);
58 void RespectsRtcpMode(newapi::RtcpMode rtcp_mode);
59 void TestXrReceiverReferenceTimeReport(bool enable_rrtr);
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +000060 void TestSendsSetSsrcs(size_t num_ssrcs, bool send_single_ssrc_first);
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +000061 void TestRtpStatePreservation(bool use_rtx);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000062};
63
64TEST_F(EndToEndTest, ReceiverCanBeStartedTwice) {
65 test::NullTransport transport;
66 CreateCalls(Call::Config(&transport), Call::Config(&transport));
67
68 CreateSendConfig(1);
69 CreateMatchingReceiveConfigs();
70
71 CreateStreams();
72
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +000073 receive_streams_[0]->Start();
74 receive_streams_[0]->Start();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000075
76 DestroyStreams();
77}
78
79TEST_F(EndToEndTest, ReceiverCanBeStoppedTwice) {
80 test::NullTransport transport;
81 CreateCalls(Call::Config(&transport), Call::Config(&transport));
82
83 CreateSendConfig(1);
84 CreateMatchingReceiveConfigs();
85
86 CreateStreams();
87
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +000088 receive_streams_[0]->Stop();
89 receive_streams_[0]->Stop();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000090
91 DestroyStreams();
92}
93
94TEST_F(EndToEndTest, RendersSingleDelayedFrame) {
95 static const int kWidth = 320;
96 static const int kHeight = 240;
97 // This constant is chosen to be higher than the timeout in the video_render
98 // module. This makes sure that frames aren't dropped if there are no other
99 // frames in the queue.
100 static const int kDelayRenderCallbackMs = 1000;
101
102 class Renderer : public VideoRenderer {
103 public:
104 Renderer() : event_(EventWrapper::Create()) {}
105
106 virtual void RenderFrame(const I420VideoFrame& video_frame,
107 int /*time_to_render_ms*/) OVERRIDE {
108 event_->Set();
109 }
110
111 EventTypeWrapper Wait() { return event_->Wait(kDefaultTimeoutMs); }
112
113 scoped_ptr<EventWrapper> event_;
114 } renderer;
115
116 class TestFrameCallback : public I420FrameCallback {
117 public:
118 TestFrameCallback() : event_(EventWrapper::Create()) {}
119
120 EventTypeWrapper Wait() { return event_->Wait(kDefaultTimeoutMs); }
121
122 private:
123 virtual void FrameCallback(I420VideoFrame* frame) OVERRIDE {
124 SleepMs(kDelayRenderCallbackMs);
125 event_->Set();
126 }
127
128 scoped_ptr<EventWrapper> event_;
129 };
130
131 test::DirectTransport sender_transport, receiver_transport;
132
133 CreateCalls(Call::Config(&sender_transport),
134 Call::Config(&receiver_transport));
135
136 sender_transport.SetReceiver(receiver_call_->Receiver());
137 receiver_transport.SetReceiver(sender_call_->Receiver());
138
139 CreateSendConfig(1);
140 CreateMatchingReceiveConfigs();
141
142 TestFrameCallback pre_render_callback;
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000143 receive_configs_[0].pre_render_callback = &pre_render_callback;
144 receive_configs_[0].renderer = &renderer;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000145
146 CreateStreams();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000147 Start();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000148
149 // Create frames that are smaller than the send width/height, this is done to
150 // check that the callbacks are done after processing video.
151 scoped_ptr<test::FrameGenerator> frame_generator(
152 test::FrameGenerator::Create(kWidth, kHeight));
153 send_stream_->Input()->SwapFrame(frame_generator->NextFrame());
154 EXPECT_EQ(kEventSignaled, pre_render_callback.Wait())
155 << "Timed out while waiting for pre-render callback.";
156 EXPECT_EQ(kEventSignaled, renderer.Wait())
157 << "Timed out while waiting for the frame to render.";
158
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000159 Stop();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000160
161 sender_transport.StopSending();
162 receiver_transport.StopSending();
163
164 DestroyStreams();
165}
166
167TEST_F(EndToEndTest, TransmitsFirstFrame) {
168 class Renderer : public VideoRenderer {
169 public:
170 Renderer() : event_(EventWrapper::Create()) {}
171
172 virtual void RenderFrame(const I420VideoFrame& video_frame,
173 int /*time_to_render_ms*/) OVERRIDE {
174 event_->Set();
175 }
176
177 EventTypeWrapper Wait() { return event_->Wait(kDefaultTimeoutMs); }
178
179 scoped_ptr<EventWrapper> event_;
180 } renderer;
181
182 test::DirectTransport sender_transport, receiver_transport;
183
184 CreateCalls(Call::Config(&sender_transport),
185 Call::Config(&receiver_transport));
186
187 sender_transport.SetReceiver(receiver_call_->Receiver());
188 receiver_transport.SetReceiver(sender_call_->Receiver());
189
190 CreateSendConfig(1);
191 CreateMatchingReceiveConfigs();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000192 receive_configs_[0].renderer = &renderer;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000193
194 CreateStreams();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000195 Start();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000196
197 scoped_ptr<test::FrameGenerator> frame_generator(test::FrameGenerator::Create(
198 video_streams_[0].width, video_streams_[0].height));
199 send_stream_->Input()->SwapFrame(frame_generator->NextFrame());
200
201 EXPECT_EQ(kEventSignaled, renderer.Wait())
202 << "Timed out while waiting for the frame to render.";
203
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000204 Stop();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000205
206 sender_transport.StopSending();
207 receiver_transport.StopSending();
208
209 DestroyStreams();
210}
211
212TEST_F(EndToEndTest, ReceiverUsesLocalSsrc) {
213 class SyncRtcpObserver : public test::EndToEndTest {
214 public:
215 SyncRtcpObserver() : EndToEndTest(kDefaultTimeoutMs) {}
216
217 virtual Action OnReceiveRtcp(const uint8_t* packet,
218 size_t length) OVERRIDE {
219 RTCPUtility::RTCPParserV2 parser(packet, length, true);
220 EXPECT_TRUE(parser.IsValid());
221 uint32_t ssrc = 0;
222 ssrc |= static_cast<uint32_t>(packet[4]) << 24;
223 ssrc |= static_cast<uint32_t>(packet[5]) << 16;
224 ssrc |= static_cast<uint32_t>(packet[6]) << 8;
225 ssrc |= static_cast<uint32_t>(packet[7]) << 0;
226 EXPECT_EQ(kReceiverLocalSsrc, ssrc);
227 observation_complete_->Set();
228
229 return SEND_PACKET;
230 }
231
232 virtual void PerformTest() OVERRIDE {
233 EXPECT_EQ(kEventSignaled, Wait())
234 << "Timed out while waiting for a receiver RTCP packet to be sent.";
235 }
236 } test;
237
238 RunBaseTest(&test);
239}
240
241TEST_F(EndToEndTest, ReceivesAndRetransmitsNack) {
242 static const int kNumberOfNacksToObserve = 2;
243 static const int kLossBurstSize = 2;
244 static const int kPacketsBetweenLossBursts = 9;
245 class NackObserver : public test::EndToEndTest {
246 public:
247 NackObserver()
248 : EndToEndTest(kLongTimeoutMs),
249 rtp_parser_(RtpHeaderParser::Create()),
250 sent_rtp_packets_(0),
251 packets_left_to_drop_(0),
252 nacks_left_(kNumberOfNacksToObserve) {}
253
254 private:
255 virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE {
256 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000257 EXPECT_TRUE(rtp_parser_->Parse(packet, length, &header));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000258
259 // Never drop retransmitted packets.
260 if (dropped_packets_.find(header.sequenceNumber) !=
261 dropped_packets_.end()) {
262 retransmitted_packets_.insert(header.sequenceNumber);
263 if (nacks_left_ == 0 &&
264 retransmitted_packets_.size() == dropped_packets_.size()) {
265 observation_complete_->Set();
266 }
267 return SEND_PACKET;
268 }
269
270 ++sent_rtp_packets_;
271
272 // Enough NACKs received, stop dropping packets.
273 if (nacks_left_ == 0)
274 return SEND_PACKET;
275
276 // Check if it's time for a new loss burst.
277 if (sent_rtp_packets_ % kPacketsBetweenLossBursts == 0)
278 packets_left_to_drop_ = kLossBurstSize;
279
280 if (packets_left_to_drop_ > 0) {
281 --packets_left_to_drop_;
282 dropped_packets_.insert(header.sequenceNumber);
283 return DROP_PACKET;
284 }
285
286 return SEND_PACKET;
287 }
288
289 virtual Action OnReceiveRtcp(const uint8_t* packet,
290 size_t length) OVERRIDE {
291 RTCPUtility::RTCPParserV2 parser(packet, length, true);
292 EXPECT_TRUE(parser.IsValid());
293
294 RTCPUtility::RTCPPacketTypes packet_type = parser.Begin();
295 while (packet_type != RTCPUtility::kRtcpNotValidCode) {
296 if (packet_type == RTCPUtility::kRtcpRtpfbNackCode) {
297 --nacks_left_;
298 break;
299 }
300 packet_type = parser.Iterate();
301 }
302 return SEND_PACKET;
303 }
304
305 virtual void ModifyConfigs(
306 VideoSendStream::Config* send_config,
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000307 std::vector<VideoReceiveStream::Config>* receive_configs,
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000308 std::vector<VideoStream>* video_streams) OVERRIDE {
309 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000310 (*receive_configs)[0].rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000311 }
312
313 virtual void PerformTest() OVERRIDE {
314 EXPECT_EQ(kEventSignaled, Wait())
315 << "Timed out waiting for packets to be NACKed, retransmitted and "
316 "rendered.";
317 }
318
319 scoped_ptr<RtpHeaderParser> rtp_parser_;
320 std::set<uint16_t> dropped_packets_;
321 std::set<uint16_t> retransmitted_packets_;
322 uint64_t sent_rtp_packets_;
323 int packets_left_to_drop_;
324 int nacks_left_;
325 } test;
326
327 RunBaseTest(&test);
328}
329
330// TODO(pbos): Flaky, webrtc:3269
331TEST_F(EndToEndTest, DISABLED_CanReceiveFec) {
332 class FecRenderObserver : public test::EndToEndTest, public VideoRenderer {
333 public:
334 FecRenderObserver()
335 : EndToEndTest(kDefaultTimeoutMs),
336 state_(kFirstPacket),
337 protected_sequence_number_(0),
338 protected_frame_timestamp_(0) {}
339
340 private:
341 virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE
342 EXCLUSIVE_LOCKS_REQUIRED(crit_) {
343 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000344 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000345
346 EXPECT_EQ(kRedPayloadType, header.payloadType);
347 int encapsulated_payload_type =
348 static_cast<int>(packet[header.headerLength]);
349 if (encapsulated_payload_type != kFakeSendPayloadType)
350 EXPECT_EQ(kUlpfecPayloadType, encapsulated_payload_type);
351
352 switch (state_) {
353 case kFirstPacket:
354 state_ = kDropEveryOtherPacketUntilFec;
355 break;
356 case kDropEveryOtherPacketUntilFec:
357 if (encapsulated_payload_type == kUlpfecPayloadType) {
358 state_ = kDropNextMediaPacket;
359 return SEND_PACKET;
360 }
361 if (header.sequenceNumber % 2 == 0)
362 return DROP_PACKET;
363 break;
364 case kDropNextMediaPacket:
365 if (encapsulated_payload_type == kFakeSendPayloadType) {
366 protected_sequence_number_ = header.sequenceNumber;
367 protected_frame_timestamp_ = header.timestamp;
368 state_ = kProtectedPacketDropped;
369 return DROP_PACKET;
370 }
371 break;
372 case kProtectedPacketDropped:
373 EXPECT_NE(header.sequenceNumber, protected_sequence_number_)
374 << "Protected packet retransmitted. Should not happen with FEC.";
375 break;
376 }
377
378 return SEND_PACKET;
379 }
380
381 virtual void RenderFrame(const I420VideoFrame& video_frame,
382 int time_to_render_ms) OVERRIDE {
383 CriticalSectionScoped lock(crit_.get());
384 // Rendering frame with timestamp associated with dropped packet -> FEC
385 // protection worked.
386 if (state_ == kProtectedPacketDropped &&
387 video_frame.timestamp() == protected_frame_timestamp_) {
388 observation_complete_->Set();
389 }
390 }
391
392 enum {
393 kFirstPacket,
394 kDropEveryOtherPacketUntilFec,
395 kDropNextMediaPacket,
396 kProtectedPacketDropped,
397 } state_;
398
399 virtual void ModifyConfigs(
400 VideoSendStream::Config* send_config,
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000401 std::vector<VideoReceiveStream::Config>* receive_configs,
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000402 std::vector<VideoStream>* video_streams) OVERRIDE {
403 // TODO(pbos): Run this test with combined NACK/FEC enabled as well.
404 // int rtp_history_ms = 1000;
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000405 // (*receive_configs)[0].rtp.nack.rtp_history_ms = rtp_history_ms;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000406 // send_config->rtp.nack.rtp_history_ms = rtp_history_ms;
407 send_config->rtp.fec.red_payload_type = kRedPayloadType;
408 send_config->rtp.fec.ulpfec_payload_type = kUlpfecPayloadType;
409
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000410 (*receive_configs)[0].rtp.fec.red_payload_type = kRedPayloadType;
411 (*receive_configs)[0].rtp.fec.ulpfec_payload_type = kUlpfecPayloadType;
412 (*receive_configs)[0].renderer = this;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000413 }
414
415 virtual void PerformTest() OVERRIDE {
416 EXPECT_EQ(kEventSignaled, Wait())
417 << "Timed out while waiting for retransmitted NACKed frames to be "
418 "rendered again.";
419 }
420
421 uint32_t protected_sequence_number_ GUARDED_BY(crit_);
422 uint32_t protected_frame_timestamp_ GUARDED_BY(crit_);
423 } test;
424
425 RunBaseTest(&test);
426}
427
428// This test drops second RTP packet with a marker bit set, makes sure it's
429// retransmitted and renders. Retransmission SSRCs are also checked.
430void EndToEndTest::DecodesRetransmittedFrame(bool retransmit_over_rtx) {
431 static const int kDroppedFrameNumber = 2;
432 class RetransmissionObserver : public test::EndToEndTest,
433 public I420FrameCallback {
434 public:
435 explicit RetransmissionObserver(bool expect_rtx)
436 : EndToEndTest(kDefaultTimeoutMs),
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +0000437 retransmission_ssrc_(expect_rtx ? kSendRtxSsrcs[0] : kSendSsrcs[0]),
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000438 retransmission_payload_type_(expect_rtx ? kSendRtxPayloadType
439 : kFakeSendPayloadType),
440 marker_bits_observed_(0),
441 retransmitted_timestamp_(0),
442 frame_retransmitted_(false) {}
443
444 private:
445 virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE {
446 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000447 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000448
449 if (header.timestamp == retransmitted_timestamp_) {
450 EXPECT_EQ(retransmission_ssrc_, header.ssrc);
451 EXPECT_EQ(retransmission_payload_type_, header.payloadType);
452 frame_retransmitted_ = true;
453 return SEND_PACKET;
454 }
455
456 EXPECT_EQ(kSendSsrcs[0], header.ssrc);
457 EXPECT_EQ(kFakeSendPayloadType, header.payloadType);
458
459 // Found the second frame's final packet, drop this and expect a
460 // retransmission.
461 if (header.markerBit && ++marker_bits_observed_ == kDroppedFrameNumber) {
462 retransmitted_timestamp_ = header.timestamp;
463 return DROP_PACKET;
464 }
465
466 return SEND_PACKET;
467 }
468
469 virtual void FrameCallback(I420VideoFrame* frame) OVERRIDE {
470 CriticalSectionScoped lock(crit_.get());
471 if (frame->timestamp() == retransmitted_timestamp_) {
472 EXPECT_TRUE(frame_retransmitted_);
473 observation_complete_->Set();
474 }
475 }
476
477 virtual void ModifyConfigs(
478 VideoSendStream::Config* send_config,
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000479 std::vector<VideoReceiveStream::Config>* receive_configs,
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000480 std::vector<VideoStream>* video_streams) OVERRIDE {
481 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000482 (*receive_configs)[0].pre_render_callback = this;
483 (*receive_configs)[0].rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +0000484 if (retransmission_ssrc_ == kSendRtxSsrcs[0]) {
485 send_config->rtp.rtx.ssrcs.push_back(kSendRtxSsrcs[0]);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000486 send_config->rtp.rtx.payload_type = kSendRtxPayloadType;
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +0000487 (*receive_configs)[0].rtp.rtx[kSendRtxPayloadType].ssrc =
488 kSendRtxSsrcs[0];
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000489 (*receive_configs)[0].rtp.rtx[kSendRtxPayloadType].payload_type =
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000490 kSendRtxPayloadType;
491 }
492 }
493
494 virtual void PerformTest() OVERRIDE {
495 EXPECT_EQ(kEventSignaled, Wait())
496 << "Timed out while waiting for retransmission to render.";
497 }
498
499 const uint32_t retransmission_ssrc_;
500 const int retransmission_payload_type_;
501 int marker_bits_observed_;
502 uint32_t retransmitted_timestamp_;
503 bool frame_retransmitted_;
504 } test(retransmit_over_rtx);
505
506 RunBaseTest(&test);
507}
508
509TEST_F(EndToEndTest, DecodesRetransmittedFrame) {
510 DecodesRetransmittedFrame(false);
511}
512
513TEST_F(EndToEndTest, DecodesRetransmittedFrameOverRtx) {
514 DecodesRetransmittedFrame(true);
515}
516
517TEST_F(EndToEndTest, UsesFrameCallbacks) {
518 static const int kWidth = 320;
519 static const int kHeight = 240;
520
521 class Renderer : public VideoRenderer {
522 public:
523 Renderer() : event_(EventWrapper::Create()) {}
524
525 virtual void RenderFrame(const I420VideoFrame& video_frame,
526 int /*time_to_render_ms*/) OVERRIDE {
527 EXPECT_EQ(0, *video_frame.buffer(kYPlane))
528 << "Rendered frame should have zero luma which is applied by the "
529 "pre-render callback.";
530 event_->Set();
531 }
532
533 EventTypeWrapper Wait() { return event_->Wait(kDefaultTimeoutMs); }
534 scoped_ptr<EventWrapper> event_;
535 } renderer;
536
537 class TestFrameCallback : public I420FrameCallback {
538 public:
539 TestFrameCallback(int expected_luma_byte, int next_luma_byte)
540 : event_(EventWrapper::Create()),
541 expected_luma_byte_(expected_luma_byte),
542 next_luma_byte_(next_luma_byte) {}
543
544 EventTypeWrapper Wait() { return event_->Wait(kDefaultTimeoutMs); }
545
546 private:
547 virtual void FrameCallback(I420VideoFrame* frame) {
548 EXPECT_EQ(kWidth, frame->width())
549 << "Width not as expected, callback done before resize?";
550 EXPECT_EQ(kHeight, frame->height())
551 << "Height not as expected, callback done before resize?";
552
553 // Previous luma specified, observed luma should be fairly close.
554 if (expected_luma_byte_ != -1) {
555 EXPECT_NEAR(expected_luma_byte_, *frame->buffer(kYPlane), 10);
556 }
557
558 memset(frame->buffer(kYPlane),
559 next_luma_byte_,
560 frame->allocated_size(kYPlane));
561
562 event_->Set();
563 }
564
565 scoped_ptr<EventWrapper> event_;
566 int expected_luma_byte_;
567 int next_luma_byte_;
568 };
569
570 TestFrameCallback pre_encode_callback(-1, 255); // Changes luma to 255.
571 TestFrameCallback pre_render_callback(255, 0); // Changes luma from 255 to 0.
572
573 test::DirectTransport sender_transport, receiver_transport;
574
575 CreateCalls(Call::Config(&sender_transport),
576 Call::Config(&receiver_transport));
577
578 sender_transport.SetReceiver(receiver_call_->Receiver());
579 receiver_transport.SetReceiver(sender_call_->Receiver());
580
581 CreateSendConfig(1);
582 scoped_ptr<VP8Encoder> encoder(VP8Encoder::Create());
583 send_config_.encoder_settings.encoder = encoder.get();
584 send_config_.encoder_settings.payload_name = "VP8";
585 ASSERT_EQ(1u, video_streams_.size()) << "Test setup error.";
586 video_streams_[0].width = kWidth;
587 video_streams_[0].height = kHeight;
588 send_config_.pre_encode_callback = &pre_encode_callback;
589
590 CreateMatchingReceiveConfigs();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000591 receive_configs_[0].pre_render_callback = &pre_render_callback;
592 receive_configs_[0].renderer = &renderer;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000593
594 CreateStreams();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000595 Start();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000596
597 // Create frames that are smaller than the send width/height, this is done to
598 // check that the callbacks are done after processing video.
599 scoped_ptr<test::FrameGenerator> frame_generator(
600 test::FrameGenerator::Create(kWidth / 2, kHeight / 2));
601 send_stream_->Input()->SwapFrame(frame_generator->NextFrame());
602
603 EXPECT_EQ(kEventSignaled, pre_encode_callback.Wait())
604 << "Timed out while waiting for pre-encode callback.";
605 EXPECT_EQ(kEventSignaled, pre_render_callback.Wait())
606 << "Timed out while waiting for pre-render callback.";
607 EXPECT_EQ(kEventSignaled, renderer.Wait())
608 << "Timed out while waiting for the frame to render.";
609
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000610 Stop();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000611
612 sender_transport.StopSending();
613 receiver_transport.StopSending();
614
615 DestroyStreams();
616}
617
618void EndToEndTest::ReceivesPliAndRecovers(int rtp_history_ms) {
619 static const int kPacketsToDrop = 1;
620
621 class PliObserver : public test::EndToEndTest, public VideoRenderer {
622 public:
623 explicit PliObserver(int rtp_history_ms)
624 : EndToEndTest(kLongTimeoutMs),
625 rtp_history_ms_(rtp_history_ms),
626 nack_enabled_(rtp_history_ms > 0),
627 highest_dropped_timestamp_(0),
628 frames_to_drop_(0),
629 received_pli_(false) {}
630
631 private:
632 virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE {
633 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000634 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000635
636 // Drop all retransmitted packets to force a PLI.
637 if (header.timestamp <= highest_dropped_timestamp_)
638 return DROP_PACKET;
639
640 if (frames_to_drop_ > 0) {
641 highest_dropped_timestamp_ = header.timestamp;
642 --frames_to_drop_;
643 return DROP_PACKET;
644 }
645
646 return SEND_PACKET;
647 }
648
649 virtual Action OnReceiveRtcp(const uint8_t* packet,
650 size_t length) OVERRIDE {
651 RTCPUtility::RTCPParserV2 parser(packet, length, true);
652 EXPECT_TRUE(parser.IsValid());
653
654 for (RTCPUtility::RTCPPacketTypes packet_type = parser.Begin();
655 packet_type != RTCPUtility::kRtcpNotValidCode;
656 packet_type = parser.Iterate()) {
657 if (!nack_enabled_)
658 EXPECT_NE(packet_type, RTCPUtility::kRtcpRtpfbNackCode);
659
660 if (packet_type == RTCPUtility::kRtcpPsfbPliCode) {
661 received_pli_ = true;
662 break;
663 }
664 }
665 return SEND_PACKET;
666 }
667
668 virtual void RenderFrame(const I420VideoFrame& video_frame,
669 int time_to_render_ms) OVERRIDE {
670 CriticalSectionScoped lock(crit_.get());
671 if (received_pli_ &&
672 video_frame.timestamp() > highest_dropped_timestamp_) {
673 observation_complete_->Set();
674 }
675 if (!received_pli_)
676 frames_to_drop_ = kPacketsToDrop;
677 }
678
679 virtual void ModifyConfigs(
680 VideoSendStream::Config* send_config,
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000681 std::vector<VideoReceiveStream::Config>* receive_configs,
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000682 std::vector<VideoStream>* video_streams) OVERRIDE {
683 send_config->rtp.nack.rtp_history_ms = rtp_history_ms_;
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000684 (*receive_configs)[0].rtp.nack.rtp_history_ms = rtp_history_ms_;
685 (*receive_configs)[0].renderer = this;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000686 }
687
688 virtual void PerformTest() OVERRIDE {
689 EXPECT_EQ(kEventSignaled, Wait()) << "Timed out waiting for PLI to be "
690 "received and a frame to be "
691 "rendered afterwards.";
692 }
693
694 int rtp_history_ms_;
695 bool nack_enabled_;
696 uint32_t highest_dropped_timestamp_;
697 int frames_to_drop_;
698 bool received_pli_;
699 } test(rtp_history_ms);
700
701 RunBaseTest(&test);
702}
703
704TEST_F(EndToEndTest, ReceivesPliAndRecoversWithNack) {
705 ReceivesPliAndRecovers(1000);
706}
707
708// TODO(pbos): Enable this when 2250 is resolved.
709TEST_F(EndToEndTest, DISABLED_ReceivesPliAndRecoversWithoutNack) {
710 ReceivesPliAndRecovers(0);
711}
712
713TEST_F(EndToEndTest, UnknownRtpPacketGivesUnknownSsrcReturnCode) {
714 class PacketInputObserver : public PacketReceiver {
715 public:
716 explicit PacketInputObserver(PacketReceiver* receiver)
717 : receiver_(receiver), delivered_packet_(EventWrapper::Create()) {}
718
719 EventTypeWrapper Wait() {
720 return delivered_packet_->Wait(kDefaultTimeoutMs);
721 }
722
723 private:
724 virtual DeliveryStatus DeliverPacket(const uint8_t* packet,
725 size_t length) OVERRIDE {
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000726 if (RtpHeaderParser::IsRtcp(packet, length)) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000727 return receiver_->DeliverPacket(packet, length);
728 } else {
729 DeliveryStatus delivery_status =
730 receiver_->DeliverPacket(packet, length);
731 EXPECT_EQ(DELIVERY_UNKNOWN_SSRC, delivery_status);
732 delivered_packet_->Set();
733 return delivery_status;
734 }
735 }
736
737 PacketReceiver* receiver_;
738 scoped_ptr<EventWrapper> delivered_packet_;
739 };
740
741 test::DirectTransport send_transport, receive_transport;
742
743 CreateCalls(Call::Config(&send_transport), Call::Config(&receive_transport));
744 PacketInputObserver input_observer(receiver_call_->Receiver());
745
746 send_transport.SetReceiver(&input_observer);
747 receive_transport.SetReceiver(sender_call_->Receiver());
748
749 CreateSendConfig(1);
750 CreateMatchingReceiveConfigs();
751
752 CreateStreams();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000753 CreateFrameGeneratorCapturer();
754 Start();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000755
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000756 receiver_call_->DestroyVideoReceiveStream(receive_streams_[0]);
757 receive_streams_.clear();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000758
759 // Wait() waits for a received packet.
760 EXPECT_EQ(kEventSignaled, input_observer.Wait());
761
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000762 Stop();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000763
764 DestroyStreams();
765
766 send_transport.StopSending();
767 receive_transport.StopSending();
768}
769
770void EndToEndTest::RespectsRtcpMode(newapi::RtcpMode rtcp_mode) {
771 static const int kNumCompoundRtcpPacketsToObserve = 10;
772 class RtcpModeObserver : public test::EndToEndTest {
773 public:
774 explicit RtcpModeObserver(newapi::RtcpMode rtcp_mode)
775 : EndToEndTest(kDefaultTimeoutMs),
776 rtcp_mode_(rtcp_mode),
777 sent_rtp_(0),
778 sent_rtcp_(0) {}
779
780 private:
781 virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE {
782 if (++sent_rtp_ % 3 == 0)
783 return DROP_PACKET;
784
785 return SEND_PACKET;
786 }
787
788 virtual Action OnReceiveRtcp(const uint8_t* packet,
789 size_t length) OVERRIDE {
790 ++sent_rtcp_;
791 RTCPUtility::RTCPParserV2 parser(packet, length, true);
792 EXPECT_TRUE(parser.IsValid());
793
794 RTCPUtility::RTCPPacketTypes packet_type = parser.Begin();
795 bool has_report_block = false;
796 while (packet_type != RTCPUtility::kRtcpNotValidCode) {
797 EXPECT_NE(RTCPUtility::kRtcpSrCode, packet_type);
798 if (packet_type == RTCPUtility::kRtcpRrCode) {
799 has_report_block = true;
800 break;
801 }
802 packet_type = parser.Iterate();
803 }
804
805 switch (rtcp_mode_) {
806 case newapi::kRtcpCompound:
807 if (!has_report_block) {
808 ADD_FAILURE() << "Received RTCP packet without receiver report for "
809 "kRtcpCompound.";
810 observation_complete_->Set();
811 }
812
813 if (sent_rtcp_ >= kNumCompoundRtcpPacketsToObserve)
814 observation_complete_->Set();
815
816 break;
817 case newapi::kRtcpReducedSize:
818 if (!has_report_block)
819 observation_complete_->Set();
820 break;
821 }
822
823 return SEND_PACKET;
824 }
825
826 virtual void ModifyConfigs(
827 VideoSendStream::Config* send_config,
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000828 std::vector<VideoReceiveStream::Config>* receive_configs,
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000829 std::vector<VideoStream>* video_streams) OVERRIDE {
830 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000831 (*receive_configs)[0].rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
832 (*receive_configs)[0].rtp.rtcp_mode = rtcp_mode_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000833 }
834
835 virtual void PerformTest() OVERRIDE {
836 EXPECT_EQ(kEventSignaled, Wait())
837 << (rtcp_mode_ == newapi::kRtcpCompound
838 ? "Timed out before observing enough compound packets."
839 : "Timed out before receiving a non-compound RTCP packet.");
840 }
841
842 newapi::RtcpMode rtcp_mode_;
843 int sent_rtp_;
844 int sent_rtcp_;
845 } test(rtcp_mode);
846
847 RunBaseTest(&test);
848}
849
850TEST_F(EndToEndTest, UsesRtcpCompoundMode) {
851 RespectsRtcpMode(newapi::kRtcpCompound);
852}
853
854TEST_F(EndToEndTest, UsesRtcpReducedSizeMode) {
855 RespectsRtcpMode(newapi::kRtcpReducedSize);
856}
857
858// Test sets up a Call multiple senders with different resolutions and SSRCs.
859// Another is set up to receive all three of these with different renderers.
860// Each renderer verifies that it receives the expected resolution, and as soon
861// as every renderer has received a frame, the test finishes.
862TEST_F(EndToEndTest, SendsAndReceivesMultipleStreams) {
863 static const size_t kNumStreams = 3;
864
865 class VideoOutputObserver : public VideoRenderer {
866 public:
867 VideoOutputObserver(test::FrameGeneratorCapturer** capturer,
868 int width,
869 int height)
870 : capturer_(capturer),
871 width_(width),
872 height_(height),
873 done_(EventWrapper::Create()) {}
874
875 virtual void RenderFrame(const I420VideoFrame& video_frame,
876 int time_to_render_ms) OVERRIDE {
877 EXPECT_EQ(width_, video_frame.width());
878 EXPECT_EQ(height_, video_frame.height());
879 (*capturer_)->Stop();
880 done_->Set();
881 }
882
883 EventTypeWrapper Wait() { return done_->Wait(kDefaultTimeoutMs); }
884
885 private:
886 test::FrameGeneratorCapturer** capturer_;
887 int width_;
888 int height_;
889 scoped_ptr<EventWrapper> done_;
890 };
891
892 struct {
893 uint32_t ssrc;
894 int width;
895 int height;
896 } codec_settings[kNumStreams] = {{1, 640, 480}, {2, 320, 240}, {3, 240, 160}};
897
898 test::DirectTransport sender_transport, receiver_transport;
899 scoped_ptr<Call> sender_call(Call::Create(Call::Config(&sender_transport)));
900 scoped_ptr<Call> receiver_call(
901 Call::Create(Call::Config(&receiver_transport)));
902 sender_transport.SetReceiver(receiver_call->Receiver());
903 receiver_transport.SetReceiver(sender_call->Receiver());
904
905 VideoSendStream* send_streams[kNumStreams];
906 VideoReceiveStream* receive_streams[kNumStreams];
907
908 VideoOutputObserver* observers[kNumStreams];
909 test::FrameGeneratorCapturer* frame_generators[kNumStreams];
910
911 scoped_ptr<VP8Encoder> encoders[kNumStreams];
912 for (size_t i = 0; i < kNumStreams; ++i)
913 encoders[i].reset(VP8Encoder::Create());
914
915 for (size_t i = 0; i < kNumStreams; ++i) {
916 uint32_t ssrc = codec_settings[i].ssrc;
917 int width = codec_settings[i].width;
918 int height = codec_settings[i].height;
919 observers[i] = new VideoOutputObserver(&frame_generators[i], width, height);
920
pbos@webrtc.orgbd249bc2014-07-07 04:45:15 +0000921 VideoSendStream::Config send_config;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000922 send_config.rtp.ssrcs.push_back(ssrc);
923 send_config.encoder_settings.encoder = encoders[i].get();
924 send_config.encoder_settings.payload_name = "VP8";
925 send_config.encoder_settings.payload_type = 124;
926 std::vector<VideoStream> video_streams = test::CreateVideoStreams(1);
927 VideoStream* stream = &video_streams[0];
928 stream->width = width;
929 stream->height = height;
930 stream->max_framerate = 5;
931 stream->min_bitrate_bps = stream->target_bitrate_bps =
932 stream->max_bitrate_bps = 100000;
933 send_streams[i] =
934 sender_call->CreateVideoSendStream(send_config, video_streams, NULL);
935 send_streams[i]->Start();
936
pbos@webrtc.orgbd249bc2014-07-07 04:45:15 +0000937 VideoReceiveStream::Config receive_config;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000938 receive_config.renderer = observers[i];
939 receive_config.rtp.remote_ssrc = ssrc;
940 receive_config.rtp.local_ssrc = kReceiverLocalSsrc;
941 VideoCodec codec =
942 test::CreateDecoderVideoCodec(send_config.encoder_settings);
943 receive_config.codecs.push_back(codec);
944 receive_streams[i] =
945 receiver_call->CreateVideoReceiveStream(receive_config);
946 receive_streams[i]->Start();
947
948 frame_generators[i] = test::FrameGeneratorCapturer::Create(
949 send_streams[i]->Input(), width, height, 30, Clock::GetRealTimeClock());
950 frame_generators[i]->Start();
951 }
952
953 for (size_t i = 0; i < kNumStreams; ++i) {
954 EXPECT_EQ(kEventSignaled, observers[i]->Wait())
955 << "Timed out while waiting for observer " << i << " to render.";
956 }
957
958 for (size_t i = 0; i < kNumStreams; ++i) {
959 frame_generators[i]->Stop();
960 sender_call->DestroyVideoSendStream(send_streams[i]);
961 receiver_call->DestroyVideoReceiveStream(receive_streams[i]);
962 delete frame_generators[i];
963 delete observers[i];
964 }
965
966 sender_transport.StopSending();
967 receiver_transport.StopSending();
968}
969
970TEST_F(EndToEndTest, ObserversEncodedFrames) {
971 class EncodedFrameTestObserver : public EncodedFrameObserver {
972 public:
973 EncodedFrameTestObserver()
974 : length_(0),
975 frame_type_(kFrameEmpty),
976 called_(EventWrapper::Create()) {}
977 virtual ~EncodedFrameTestObserver() {}
978
979 virtual void EncodedFrameCallback(const EncodedFrame& encoded_frame) {
980 frame_type_ = encoded_frame.frame_type_;
981 length_ = encoded_frame.length_;
982 buffer_.reset(new uint8_t[length_]);
983 memcpy(buffer_.get(), encoded_frame.data_, length_);
984 called_->Set();
985 }
986
987 EventTypeWrapper Wait() { return called_->Wait(kDefaultTimeoutMs); }
988
989 void ExpectEqualFrames(const EncodedFrameTestObserver& observer) {
990 ASSERT_EQ(length_, observer.length_)
991 << "Observed frames are of different lengths.";
992 EXPECT_EQ(frame_type_, observer.frame_type_)
993 << "Observed frames have different frame types.";
994 EXPECT_EQ(0, memcmp(buffer_.get(), observer.buffer_.get(), length_))
995 << "Observed encoded frames have different content.";
996 }
997
998 private:
999 scoped_ptr<uint8_t[]> buffer_;
1000 size_t length_;
1001 FrameType frame_type_;
1002 scoped_ptr<EventWrapper> called_;
1003 };
1004
1005 EncodedFrameTestObserver post_encode_observer;
1006 EncodedFrameTestObserver pre_decode_observer;
1007
1008 test::DirectTransport sender_transport, receiver_transport;
1009
1010 CreateCalls(Call::Config(&sender_transport),
1011 Call::Config(&receiver_transport));
1012
1013 sender_transport.SetReceiver(receiver_call_->Receiver());
1014 receiver_transport.SetReceiver(sender_call_->Receiver());
1015
1016 CreateSendConfig(1);
1017 CreateMatchingReceiveConfigs();
1018 send_config_.post_encode_callback = &post_encode_observer;
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001019 receive_configs_[0].pre_decode_callback = &pre_decode_observer;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001020
1021 CreateStreams();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001022 Start();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001023
1024 scoped_ptr<test::FrameGenerator> frame_generator(test::FrameGenerator::Create(
1025 video_streams_[0].width, video_streams_[0].height));
1026 send_stream_->Input()->SwapFrame(frame_generator->NextFrame());
1027
1028 EXPECT_EQ(kEventSignaled, post_encode_observer.Wait())
1029 << "Timed out while waiting for send-side encoded-frame callback.";
1030
1031 EXPECT_EQ(kEventSignaled, pre_decode_observer.Wait())
1032 << "Timed out while waiting for pre-decode encoded-frame callback.";
1033
1034 post_encode_observer.ExpectEqualFrames(pre_decode_observer);
1035
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001036 Stop();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001037
1038 sender_transport.StopSending();
1039 receiver_transport.StopSending();
1040
1041 DestroyStreams();
1042}
1043
1044TEST_F(EndToEndTest, ReceiveStreamSendsRemb) {
1045 class RembObserver : public test::EndToEndTest {
1046 public:
1047 RembObserver() : EndToEndTest(kDefaultTimeoutMs) {}
1048
1049 virtual Action OnReceiveRtcp(const uint8_t* packet,
1050 size_t length) OVERRIDE {
1051 RTCPUtility::RTCPParserV2 parser(packet, length, true);
1052 EXPECT_TRUE(parser.IsValid());
1053
1054 bool received_psfb = false;
1055 bool received_remb = false;
1056 RTCPUtility::RTCPPacketTypes packet_type = parser.Begin();
1057 while (packet_type != RTCPUtility::kRtcpNotValidCode) {
1058 if (packet_type == RTCPUtility::kRtcpPsfbRembCode) {
1059 const RTCPUtility::RTCPPacket& packet = parser.Packet();
1060 EXPECT_EQ(packet.PSFBAPP.SenderSSRC, kReceiverLocalSsrc);
1061 received_psfb = true;
1062 } else if (packet_type == RTCPUtility::kRtcpPsfbRembItemCode) {
1063 const RTCPUtility::RTCPPacket& packet = parser.Packet();
1064 EXPECT_GT(packet.REMBItem.BitRate, 0u);
1065 EXPECT_EQ(packet.REMBItem.NumberOfSSRCs, 1u);
1066 EXPECT_EQ(packet.REMBItem.SSRCs[0], kSendSsrcs[0]);
1067 received_remb = true;
1068 }
1069 packet_type = parser.Iterate();
1070 }
1071 if (received_psfb && received_remb)
1072 observation_complete_->Set();
1073 return SEND_PACKET;
1074 }
1075 virtual void PerformTest() OVERRIDE {
1076 EXPECT_EQ(kEventSignaled, Wait()) << "Timed out while waiting for a "
1077 "receiver RTCP REMB packet to be "
1078 "sent.";
1079 }
1080 } test;
1081
1082 RunBaseTest(&test);
1083}
1084
1085void EndToEndTest::TestXrReceiverReferenceTimeReport(bool enable_rrtr) {
1086 static const int kNumRtcpReportPacketsToObserve = 5;
1087 class RtcpXrObserver : public test::EndToEndTest {
1088 public:
1089 explicit RtcpXrObserver(bool enable_rrtr)
1090 : EndToEndTest(kDefaultTimeoutMs),
1091 enable_rrtr_(enable_rrtr),
1092 sent_rtcp_sr_(0),
1093 sent_rtcp_rr_(0),
1094 sent_rtcp_rrtr_(0),
1095 sent_rtcp_dlrr_(0) {}
1096
1097 private:
1098 // Receive stream should send RR packets (and RRTR packets if enabled).
1099 virtual Action OnReceiveRtcp(const uint8_t* packet,
1100 size_t length) OVERRIDE {
1101 RTCPUtility::RTCPParserV2 parser(packet, length, true);
1102 EXPECT_TRUE(parser.IsValid());
1103
1104 RTCPUtility::RTCPPacketTypes packet_type = parser.Begin();
1105 while (packet_type != RTCPUtility::kRtcpNotValidCode) {
1106 if (packet_type == RTCPUtility::kRtcpRrCode) {
1107 ++sent_rtcp_rr_;
1108 } else if (packet_type ==
1109 RTCPUtility::kRtcpXrReceiverReferenceTimeCode) {
1110 ++sent_rtcp_rrtr_;
1111 }
1112 EXPECT_NE(packet_type, RTCPUtility::kRtcpSrCode);
1113 EXPECT_NE(packet_type, RTCPUtility::kRtcpXrDlrrReportBlockItemCode);
1114 packet_type = parser.Iterate();
1115 }
1116 return SEND_PACKET;
1117 }
1118 // Send stream should send SR packets (and DLRR packets if enabled).
1119 virtual Action OnSendRtcp(const uint8_t* packet, size_t length) {
1120 RTCPUtility::RTCPParserV2 parser(packet, length, true);
1121 EXPECT_TRUE(parser.IsValid());
1122
1123 RTCPUtility::RTCPPacketTypes packet_type = parser.Begin();
1124 while (packet_type != RTCPUtility::kRtcpNotValidCode) {
1125 if (packet_type == RTCPUtility::kRtcpSrCode) {
1126 ++sent_rtcp_sr_;
1127 } else if (packet_type == RTCPUtility::kRtcpXrDlrrReportBlockItemCode) {
1128 ++sent_rtcp_dlrr_;
1129 }
1130 EXPECT_NE(packet_type, RTCPUtility::kRtcpXrReceiverReferenceTimeCode);
1131 packet_type = parser.Iterate();
1132 }
1133 if (sent_rtcp_sr_ > kNumRtcpReportPacketsToObserve &&
1134 sent_rtcp_rr_ > kNumRtcpReportPacketsToObserve) {
1135 if (enable_rrtr_) {
1136 EXPECT_GT(sent_rtcp_rrtr_, 0);
1137 EXPECT_GT(sent_rtcp_dlrr_, 0);
1138 } else {
1139 EXPECT_EQ(0, sent_rtcp_rrtr_);
1140 EXPECT_EQ(0, sent_rtcp_dlrr_);
1141 }
1142 observation_complete_->Set();
1143 }
1144 return SEND_PACKET;
1145 }
1146
1147 virtual void ModifyConfigs(
1148 VideoSendStream::Config* send_config,
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001149 std::vector<VideoReceiveStream::Config>* receive_configs,
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001150 std::vector<VideoStream>* video_streams) OVERRIDE {
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001151 (*receive_configs)[0].rtp.rtcp_mode = newapi::kRtcpReducedSize;
1152 (*receive_configs)[0].rtp.rtcp_xr.receiver_reference_time_report =
1153 enable_rrtr_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001154 }
1155
1156 virtual void PerformTest() OVERRIDE {
1157 EXPECT_EQ(kEventSignaled, Wait())
1158 << "Timed out while waiting for RTCP SR/RR packets to be sent.";
1159 }
1160
1161 bool enable_rrtr_;
1162 int sent_rtcp_sr_;
1163 int sent_rtcp_rr_;
1164 int sent_rtcp_rrtr_;
1165 int sent_rtcp_dlrr_;
1166 } test(enable_rrtr);
1167
1168 RunBaseTest(&test);
1169}
1170
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001171void EndToEndTest::TestSendsSetSsrcs(size_t num_ssrcs,
1172 bool send_single_ssrc_first) {
1173 class SendsSetSsrcs : public test::EndToEndTest {
1174 public:
1175 SendsSetSsrcs(const uint32_t* ssrcs,
1176 size_t num_ssrcs,
1177 bool send_single_ssrc_first)
1178 : EndToEndTest(kDefaultTimeoutMs),
1179 num_ssrcs_(num_ssrcs),
1180 send_single_ssrc_first_(send_single_ssrc_first),
1181 ssrcs_to_observe_(num_ssrcs),
1182 expect_single_ssrc_(send_single_ssrc_first) {
1183 for (size_t i = 0; i < num_ssrcs; ++i)
1184 valid_ssrcs_[ssrcs[i]] = true;
1185 }
1186
1187 private:
1188 virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE {
1189 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001190 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001191
1192 EXPECT_TRUE(valid_ssrcs_[header.ssrc])
1193 << "Received unknown SSRC: " << header.ssrc;
1194
1195 if (!valid_ssrcs_[header.ssrc])
1196 observation_complete_->Set();
1197
1198 if (!is_observed_[header.ssrc]) {
1199 is_observed_[header.ssrc] = true;
1200 --ssrcs_to_observe_;
1201 if (expect_single_ssrc_) {
1202 expect_single_ssrc_ = false;
1203 observation_complete_->Set();
1204 }
1205 }
1206
1207 if (ssrcs_to_observe_ == 0)
1208 observation_complete_->Set();
1209
1210 return SEND_PACKET;
1211 }
1212
1213 virtual size_t GetNumStreams() const OVERRIDE { return num_ssrcs_; }
1214
1215 virtual void ModifyConfigs(
1216 VideoSendStream::Config* send_config,
1217 std::vector<VideoReceiveStream::Config>* receive_configs,
1218 std::vector<VideoStream>* video_streams) OVERRIDE {
1219 if (num_ssrcs_ > 1) {
1220 // Set low simulcast bitrates to not have to wait for bandwidth ramp-up.
1221 for (size_t i = 0; i < video_streams->size(); ++i) {
1222 (*video_streams)[i].min_bitrate_bps = 10000;
1223 (*video_streams)[i].target_bitrate_bps = 15000;
1224 (*video_streams)[i].max_bitrate_bps = 20000;
1225 }
1226 }
1227
1228 all_streams_ = *video_streams;
1229 if (send_single_ssrc_first_)
1230 video_streams->resize(1);
1231 }
1232
1233 virtual void OnStreamsCreated(
1234 VideoSendStream* send_stream,
1235 const std::vector<VideoReceiveStream*>& receive_streams) OVERRIDE {
1236 send_stream_ = send_stream;
1237 }
1238
1239 virtual void PerformTest() OVERRIDE {
1240 EXPECT_EQ(kEventSignaled, Wait())
1241 << "Timed out while waiting for "
1242 << (send_single_ssrc_first_ ? "first SSRC." : "SSRCs.");
1243
1244 if (send_single_ssrc_first_) {
1245 // Set full simulcast and continue with the rest of the SSRCs.
1246 send_stream_->ReconfigureVideoEncoder(all_streams_, NULL);
1247 EXPECT_EQ(kEventSignaled, Wait())
1248 << "Timed out while waiting on additional SSRCs.";
1249 }
1250 }
1251
1252 private:
1253 std::map<uint32_t, bool> valid_ssrcs_;
1254 std::map<uint32_t, bool> is_observed_;
1255
1256 const size_t num_ssrcs_;
1257 const bool send_single_ssrc_first_;
1258
1259 size_t ssrcs_to_observe_;
1260 bool expect_single_ssrc_;
1261
1262 VideoSendStream* send_stream_;
1263 std::vector<VideoStream> all_streams_;
1264 } test(kSendSsrcs, num_ssrcs, send_single_ssrc_first);
1265
1266 RunBaseTest(&test);
1267}
1268
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001269TEST_F(EndToEndTest, GetStats) {
1270 class StatsObserver : public test::EndToEndTest, public I420FrameCallback {
1271 public:
1272 StatsObserver()
1273 : EndToEndTest(kLongTimeoutMs),
1274 receive_stream_(NULL),
1275 send_stream_(NULL),
1276 expected_receive_ssrc_(),
1277 expected_send_ssrcs_(),
1278 check_stats_event_(EventWrapper::Create()) {}
1279
1280 private:
1281 virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE {
1282 check_stats_event_->Set();
1283 return SEND_PACKET;
1284 }
1285
1286 virtual Action OnSendRtcp(const uint8_t* packet, size_t length) OVERRIDE {
1287 check_stats_event_->Set();
1288 return SEND_PACKET;
1289 }
1290
1291 virtual Action OnReceiveRtp(const uint8_t* packet, size_t length) OVERRIDE {
1292 check_stats_event_->Set();
1293 return SEND_PACKET;
1294 }
1295
1296 virtual Action OnReceiveRtcp(const uint8_t* packet,
1297 size_t length) OVERRIDE {
1298 check_stats_event_->Set();
1299 return SEND_PACKET;
1300 }
1301
1302 virtual void FrameCallback(I420VideoFrame* video_frame) OVERRIDE {
1303 // Ensure that we have at least 5ms send side delay.
1304 int64_t render_time = video_frame->render_time_ms();
1305 if (render_time > 0)
1306 video_frame->set_render_time_ms(render_time - 5);
1307 }
1308
1309 bool CheckReceiveStats() {
1310 assert(receive_stream_ != NULL);
1311 VideoReceiveStream::Stats stats = receive_stream_->GetStats();
1312 EXPECT_EQ(expected_receive_ssrc_, stats.ssrc);
1313
1314 // Make sure all fields have been populated.
1315
1316 receive_stats_filled_["IncomingRate"] |=
1317 stats.network_frame_rate != 0 || stats.bitrate_bps != 0;
1318
1319 receive_stats_filled_["FrameCallback"] |= stats.decode_frame_rate != 0;
1320
1321 receive_stats_filled_["FrameRendered"] |= stats.render_frame_rate != 0;
1322
1323 receive_stats_filled_["StatisticsUpdated"] |=
1324 stats.rtcp_stats.cumulative_lost != 0 ||
1325 stats.rtcp_stats.extended_max_sequence_number != 0 ||
1326 stats.rtcp_stats.fraction_lost != 0 || stats.rtcp_stats.jitter != 0;
1327
1328 receive_stats_filled_["DataCountersUpdated"] |=
1329 stats.rtp_stats.bytes != 0 || stats.rtp_stats.fec_packets != 0 ||
1330 stats.rtp_stats.header_bytes != 0 || stats.rtp_stats.packets != 0 ||
1331 stats.rtp_stats.padding_bytes != 0 ||
1332 stats.rtp_stats.retransmitted_packets != 0;
1333
1334 receive_stats_filled_["CodecStats"] |=
1335 stats.avg_delay_ms != 0 || stats.discarded_packets != 0 ||
1336 stats.key_frames != 0 || stats.delta_frames != 0;
1337
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001338 return AllStatsFilled(receive_stats_filled_);
1339 }
1340
1341 bool CheckSendStats() {
1342 assert(send_stream_ != NULL);
1343 VideoSendStream::Stats stats = send_stream_->GetStats();
1344
1345 send_stats_filled_["NumStreams"] |=
1346 stats.substreams.size() == expected_send_ssrcs_.size();
1347
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001348 for (std::map<uint32_t, StreamStats>::const_iterator it =
1349 stats.substreams.begin();
1350 it != stats.substreams.end();
1351 ++it) {
1352 EXPECT_TRUE(expected_send_ssrcs_.find(it->first) !=
1353 expected_send_ssrcs_.end());
1354
1355 send_stats_filled_[CompoundKey("IncomingRate", it->first)] |=
1356 stats.input_frame_rate != 0;
1357
1358 const StreamStats& stream_stats = it->second;
1359
1360 send_stats_filled_[CompoundKey("StatisticsUpdated", it->first)] |=
1361 stream_stats.rtcp_stats.cumulative_lost != 0 ||
1362 stream_stats.rtcp_stats.extended_max_sequence_number != 0 ||
1363 stream_stats.rtcp_stats.fraction_lost != 0;
1364
1365 send_stats_filled_[CompoundKey("DataCountersUpdated", it->first)] |=
1366 stream_stats.rtp_stats.fec_packets != 0 ||
1367 stream_stats.rtp_stats.padding_bytes != 0 ||
1368 stream_stats.rtp_stats.retransmitted_packets != 0 ||
1369 stream_stats.rtp_stats.packets != 0;
1370
1371 send_stats_filled_[CompoundKey("BitrateStatisticsObserver",
1372 it->first)] |=
1373 stream_stats.bitrate_bps != 0;
1374
1375 send_stats_filled_[CompoundKey("FrameCountObserver", it->first)] |=
1376 stream_stats.delta_frames != 0 || stream_stats.key_frames != 0;
1377
1378 send_stats_filled_[CompoundKey("OutgoingRate", it->first)] |=
1379 stats.encode_frame_rate != 0;
stefan@webrtc.org168f23f2014-07-11 13:44:02 +00001380
1381 send_stats_filled_[CompoundKey("Delay", it->first)] |=
1382 stream_stats.avg_delay_ms != 0 || stream_stats.max_delay_ms != 0;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001383 }
1384
1385 return AllStatsFilled(send_stats_filled_);
1386 }
1387
1388 std::string CompoundKey(const char* name, uint32_t ssrc) {
1389 std::ostringstream oss;
1390 oss << name << "_" << ssrc;
1391 return oss.str();
1392 }
1393
1394 bool AllStatsFilled(const std::map<std::string, bool>& stats_map) {
1395 for (std::map<std::string, bool>::const_iterator it = stats_map.begin();
1396 it != stats_map.end();
1397 ++it) {
1398 if (!it->second)
1399 return false;
1400 }
1401 return true;
1402 }
1403
1404 virtual void ModifyConfigs(
1405 VideoSendStream::Config* send_config,
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001406 std::vector<VideoReceiveStream::Config>* receive_configs,
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001407 std::vector<VideoStream>* video_streams) OVERRIDE {
1408 send_config->pre_encode_callback = this; // Used to inject delay.
1409 send_config->rtp.c_name = "SomeCName";
1410
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001411 expected_receive_ssrc_ = (*receive_configs)[0].rtp.local_ssrc;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001412 const std::vector<uint32_t>& ssrcs = send_config->rtp.ssrcs;
1413 for (size_t i = 0; i < ssrcs.size(); ++i)
1414 expected_send_ssrcs_.insert(ssrcs[i]);
1415
1416 expected_cname_ = send_config->rtp.c_name;
1417 }
1418
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001419 virtual void OnStreamsCreated(
1420 VideoSendStream* send_stream,
1421 const std::vector<VideoReceiveStream*>& receive_streams) OVERRIDE {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001422 send_stream_ = send_stream;
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001423 receive_stream_ = receive_streams[0];
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001424 }
1425
1426 virtual void PerformTest() OVERRIDE {
1427 Clock* clock = Clock::GetRealTimeClock();
1428 int64_t now = clock->TimeInMilliseconds();
1429 int64_t stop_time = now + test::CallTest::kLongTimeoutMs;
1430 bool receive_ok = false;
1431 bool send_ok = false;
1432
1433 while (now < stop_time) {
1434 if (!receive_ok)
1435 receive_ok = CheckReceiveStats();
1436 if (!send_ok)
1437 send_ok = CheckSendStats();
1438
1439 if (receive_ok && send_ok)
1440 return;
1441
1442 int64_t time_until_timout_ = stop_time - now;
1443 if (time_until_timout_ > 0)
1444 check_stats_event_->Wait(time_until_timout_);
1445 now = clock->TimeInMilliseconds();
1446 }
1447
1448 ADD_FAILURE() << "Timed out waiting for filled stats.";
1449 for (std::map<std::string, bool>::const_iterator it =
1450 receive_stats_filled_.begin();
1451 it != receive_stats_filled_.end();
1452 ++it) {
1453 if (!it->second) {
1454 ADD_FAILURE() << "Missing receive stats: " << it->first;
1455 }
1456 }
1457
1458 for (std::map<std::string, bool>::const_iterator it =
1459 send_stats_filled_.begin();
1460 it != send_stats_filled_.end();
1461 ++it) {
1462 if (!it->second) {
1463 ADD_FAILURE() << "Missing send stats: " << it->first;
1464 }
1465 }
1466 }
1467
1468 VideoReceiveStream* receive_stream_;
1469 std::map<std::string, bool> receive_stats_filled_;
1470
1471 VideoSendStream* send_stream_;
1472 std::map<std::string, bool> send_stats_filled_;
1473
1474 uint32_t expected_receive_ssrc_;
1475 std::set<uint32_t> expected_send_ssrcs_;
1476 std::string expected_cname_;
1477
1478 scoped_ptr<EventWrapper> check_stats_event_;
1479 } test;
1480
1481 RunBaseTest(&test);
1482}
1483
1484TEST_F(EndToEndTest, ReceiverReferenceTimeReportEnabled) {
1485 TestXrReceiverReferenceTimeReport(true);
1486}
1487
1488TEST_F(EndToEndTest, ReceiverReferenceTimeReportDisabled) {
1489 TestXrReceiverReferenceTimeReport(false);
1490}
1491
1492TEST_F(EndToEndTest, TestReceivedRtpPacketStats) {
1493 static const size_t kNumRtpPacketsToSend = 5;
1494 class ReceivedRtpStatsObserver : public test::EndToEndTest {
1495 public:
1496 ReceivedRtpStatsObserver()
1497 : EndToEndTest(kDefaultTimeoutMs),
1498 receive_stream_(NULL),
1499 sent_rtp_(0) {}
1500
1501 private:
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001502 virtual void OnStreamsCreated(
1503 VideoSendStream* send_stream,
1504 const std::vector<VideoReceiveStream*>& receive_streams) OVERRIDE {
1505 receive_stream_ = receive_streams[0];
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001506 }
1507
1508 virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE {
1509 if (sent_rtp_ >= kNumRtpPacketsToSend) {
1510 VideoReceiveStream::Stats stats = receive_stream_->GetStats();
1511 if (kNumRtpPacketsToSend == stats.rtp_stats.packets) {
1512 observation_complete_->Set();
1513 }
1514 return DROP_PACKET;
1515 }
1516 ++sent_rtp_;
1517 return SEND_PACKET;
1518 }
1519
1520 virtual void PerformTest() OVERRIDE {
1521 EXPECT_EQ(kEventSignaled, Wait())
1522 << "Timed out while verifying number of received RTP packets.";
1523 }
1524
1525 VideoReceiveStream* receive_stream_;
1526 uint32_t sent_rtp_;
1527 } test;
1528
1529 RunBaseTest(&test);
1530}
1531
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001532TEST_F(EndToEndTest, SendsSetSsrc) { TestSendsSetSsrcs(1, false); }
1533
1534TEST_F(EndToEndTest, SendsSetSimulcastSsrcs) {
1535 TestSendsSetSsrcs(kNumSsrcs, false);
1536}
1537
1538TEST_F(EndToEndTest, CanSwitchToUseAllSsrcs) {
1539 TestSendsSetSsrcs(kNumSsrcs, true);
1540}
1541
mflodman@webrtc.orgf9460682014-07-24 16:41:25 +00001542TEST_F(EndToEndTest, DISABLED_RedundantPayloadsTransmittedOnAllSsrcs) {
pbos@webrtc.org20c1f562014-07-04 10:58:12 +00001543 class ObserveRedundantPayloads: public test::EndToEndTest {
1544 public:
1545 ObserveRedundantPayloads()
1546 : EndToEndTest(kDefaultTimeoutMs), ssrcs_to_observe_(kNumSsrcs) {
1547 for(size_t i = 0; i < kNumSsrcs; ++i) {
1548 registered_rtx_ssrc_[kSendRtxSsrcs[i]] = true;
1549 }
1550 }
1551
1552 private:
1553 virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE {
1554 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001555 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.org20c1f562014-07-04 10:58:12 +00001556
1557 if (!registered_rtx_ssrc_[header.ssrc])
1558 return SEND_PACKET;
1559
1560 EXPECT_LE(static_cast<size_t>(header.headerLength + header.paddingLength),
1561 length);
1562 const bool packet_is_redundant_payload =
1563 static_cast<size_t>(header.headerLength + header.paddingLength) <
1564 length;
1565
1566 if (!packet_is_redundant_payload)
1567 return SEND_PACKET;
1568
1569 if (!observed_redundant_retransmission_[header.ssrc]) {
1570 observed_redundant_retransmission_[header.ssrc] = true;
1571 if (--ssrcs_to_observe_ == 0)
1572 observation_complete_->Set();
1573 }
1574
1575 return SEND_PACKET;
1576 }
1577
1578 virtual size_t GetNumStreams() const OVERRIDE { return kNumSsrcs; }
1579
1580 virtual void ModifyConfigs(
1581 VideoSendStream::Config* send_config,
1582 std::vector<VideoReceiveStream::Config>* receive_configs,
1583 std::vector<VideoStream>* video_streams) OVERRIDE {
1584 // Set low simulcast bitrates to not have to wait for bandwidth ramp-up.
1585 for (size_t i = 0; i < video_streams->size(); ++i) {
1586 (*video_streams)[i].min_bitrate_bps = 10000;
1587 (*video_streams)[i].target_bitrate_bps = 15000;
1588 (*video_streams)[i].max_bitrate_bps = 20000;
1589 }
1590 // Significantly higher than max bitrates for all video streams -> forcing
1591 // padding to trigger redundant padding on all RTX SSRCs.
1592 send_config->rtp.min_transmit_bitrate_bps = 100000;
1593
1594 send_config->rtp.rtx.payload_type = kSendRtxPayloadType;
1595 send_config->rtp.rtx.pad_with_redundant_payloads = true;
1596
1597 for (size_t i = 0; i < kNumSsrcs; ++i)
1598 send_config->rtp.rtx.ssrcs.push_back(kSendRtxSsrcs[i]);
1599 }
1600
1601 virtual void PerformTest() OVERRIDE {
1602 EXPECT_EQ(kEventSignaled, Wait())
1603 << "Timed out while waiting for redundant payloads on all SSRCs.";
1604 }
1605
1606 private:
1607 size_t ssrcs_to_observe_;
1608 std::map<uint32_t, bool> observed_redundant_retransmission_;
1609 std::map<uint32_t, bool> registered_rtx_ssrc_;
1610 } test;
1611
1612 RunBaseTest(&test);
1613}
1614
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +00001615void EndToEndTest::TestRtpStatePreservation(bool use_rtx) {
1616 static const uint32_t kMaxSequenceNumberGap = 100;
1617 static const uint64_t kMaxTimestampGap = kDefaultTimeoutMs * 90;
1618 class RtpSequenceObserver : public test::RtpRtcpObserver {
1619 public:
1620 RtpSequenceObserver(bool use_rtx)
1621 : test::RtpRtcpObserver(kDefaultTimeoutMs),
1622 crit_(CriticalSectionWrapper::CreateCriticalSection()),
1623 ssrcs_to_observe_(kNumSsrcs) {
1624 for (size_t i = 0; i < kNumSsrcs; ++i) {
1625 configured_ssrcs_[kSendSsrcs[i]] = true;
1626 if (use_rtx)
1627 configured_ssrcs_[kSendRtxSsrcs[i]] = true;
1628 }
1629 }
1630
1631 void ResetExpectedSsrcs(size_t num_expected_ssrcs) {
1632 CriticalSectionScoped lock(crit_.get());
1633 ssrc_observed_.clear();
1634 ssrcs_to_observe_ = num_expected_ssrcs;
1635 }
1636
1637 private:
1638 virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE {
1639 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001640 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +00001641 const uint32_t ssrc = header.ssrc;
1642 const uint16_t sequence_number = header.sequenceNumber;
1643 const uint32_t timestamp = header.timestamp;
1644 const bool only_padding =
1645 static_cast<size_t>(header.headerLength + header.paddingLength) ==
1646 length;
1647
1648 EXPECT_TRUE(configured_ssrcs_[ssrc])
1649 << "Received SSRC that wasn't configured: " << ssrc;
1650
1651 std::map<uint32_t, uint16_t>::iterator it =
1652 last_observed_sequence_number_.find(header.ssrc);
1653 if (it == last_observed_sequence_number_.end()) {
1654 last_observed_sequence_number_[ssrc] = sequence_number;
1655 last_observed_timestamp_[ssrc] = timestamp;
1656 } else {
1657 // Verify sequence numbers are reasonably close.
1658 uint32_t extended_sequence_number = sequence_number;
1659 // Check for roll-over.
1660 if (sequence_number < last_observed_sequence_number_[ssrc])
1661 extended_sequence_number += 0xFFFFu + 1;
1662 EXPECT_LE(
1663 extended_sequence_number - last_observed_sequence_number_[ssrc],
1664 kMaxSequenceNumberGap)
1665 << "Gap in sequence numbers ("
1666 << last_observed_sequence_number_[ssrc] << " -> " << sequence_number
1667 << ") too large for SSRC: " << ssrc << ".";
1668 last_observed_sequence_number_[ssrc] = sequence_number;
1669
1670 // TODO(pbos): Remove this check if we ever have monotonically
1671 // increasing timestamps. Right now padding packets add a delta which
1672 // can cause reordering between padding packets and regular packets,
1673 // hence we drop padding-only packets to not flake.
1674 if (only_padding) {
1675 // Verify that timestamps are reasonably close.
1676 uint64_t extended_timestamp = timestamp;
1677 // Check for roll-over.
1678 if (timestamp < last_observed_timestamp_[ssrc])
1679 extended_timestamp += static_cast<uint64_t>(0xFFFFFFFFu) + 1;
1680 EXPECT_LE(extended_timestamp - last_observed_timestamp_[ssrc],
1681 kMaxTimestampGap)
1682 << "Gap in timestamps (" << last_observed_timestamp_[ssrc]
1683 << " -> " << timestamp << ") too large for SSRC: " << ssrc << ".";
1684 }
1685 last_observed_timestamp_[ssrc] = timestamp;
1686 }
1687
1688 CriticalSectionScoped lock(crit_.get());
1689 // Wait for media packets on all ssrcs.
1690 if (!ssrc_observed_[ssrc] && !only_padding) {
1691 ssrc_observed_[ssrc] = true;
1692 if (--ssrcs_to_observe_ == 0)
1693 observation_complete_->Set();
1694 }
1695
1696 return SEND_PACKET;
1697 }
1698
1699 std::map<uint32_t, uint16_t> last_observed_sequence_number_;
1700 std::map<uint32_t, uint32_t> last_observed_timestamp_;
1701 std::map<uint32_t, bool> configured_ssrcs_;
1702
1703 scoped_ptr<CriticalSectionWrapper> crit_;
1704 size_t ssrcs_to_observe_ GUARDED_BY(crit_);
1705 std::map<uint32_t, bool> ssrc_observed_ GUARDED_BY(crit_);
1706 } observer(use_rtx);
1707
1708 CreateCalls(Call::Config(observer.SendTransport()),
1709 Call::Config(observer.ReceiveTransport()));
1710 observer.SetReceivers(sender_call_->Receiver(), NULL);
1711
1712 CreateSendConfig(kNumSsrcs);
1713
1714 if (use_rtx) {
1715 for (size_t i = 0; i < kNumSsrcs; ++i) {
1716 send_config_.rtp.rtx.ssrcs.push_back(kSendRtxSsrcs[i]);
1717 }
1718 send_config_.rtp.rtx.payload_type = kSendRtxPayloadType;
1719 }
1720
1721 // Lower bitrates so that all streams send initially.
1722 for (size_t i = 0; i < video_streams_.size(); ++i) {
1723 video_streams_[i].min_bitrate_bps = 10000;
1724 video_streams_[i].target_bitrate_bps = 15000;
1725 video_streams_[i].max_bitrate_bps = 20000;
1726 }
1727
1728 CreateMatchingReceiveConfigs();
1729
1730 CreateStreams();
1731 CreateFrameGeneratorCapturer();
1732
1733 Start();
1734 EXPECT_EQ(kEventSignaled, observer.Wait())
1735 << "Timed out waiting for all SSRCs to send packets.";
1736
1737 // Test stream resetting more than once to make sure that the state doesn't
1738 // get set once (this could be due to using std::map::insert for instance).
1739 for (size_t i = 0; i < 3; ++i) {
1740 frame_generator_capturer_->Stop();
1741 sender_call_->DestroyVideoSendStream(send_stream_);
1742
1743 // Re-create VideoSendStream with only one stream.
1744 std::vector<VideoStream> one_stream = video_streams_;
1745 one_stream.resize(1);
1746 send_stream_ =
1747 sender_call_->CreateVideoSendStream(send_config_, one_stream, NULL);
1748 send_stream_->Start();
1749 CreateFrameGeneratorCapturer();
1750 frame_generator_capturer_->Start();
1751
1752 observer.ResetExpectedSsrcs(1);
1753 EXPECT_EQ(kEventSignaled, observer.Wait())
1754 << "Timed out waiting for single RTP packet.";
1755
1756 // Reconfigure back to use all streams.
1757 send_stream_->ReconfigureVideoEncoder(video_streams_, NULL);
1758 observer.ResetExpectedSsrcs(kNumSsrcs);
1759 EXPECT_EQ(kEventSignaled, observer.Wait())
1760 << "Timed out waiting for all SSRCs to send packets.";
1761
1762 // Reconfigure down to one stream.
1763 send_stream_->ReconfigureVideoEncoder(one_stream, NULL);
1764 observer.ResetExpectedSsrcs(1);
1765 EXPECT_EQ(kEventSignaled, observer.Wait())
1766 << "Timed out waiting for single RTP packet.";
1767
1768 // Reconfigure back to use all streams.
1769 send_stream_->ReconfigureVideoEncoder(video_streams_, NULL);
1770 observer.ResetExpectedSsrcs(kNumSsrcs);
1771 EXPECT_EQ(kEventSignaled, observer.Wait())
1772 << "Timed out waiting for all SSRCs to send packets.";
1773 }
1774
1775 observer.StopSending();
1776
1777 Stop();
1778 DestroyStreams();
1779}
1780
1781TEST_F(EndToEndTest, RestartingSendStreamPreservesRtpState) {
1782 TestRtpStatePreservation(false);
1783}
1784
1785TEST_F(EndToEndTest, RestartingSendStreamPreservesRtpStatesWithRtx) {
1786 TestRtpStatePreservation(true);
1787}
1788
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001789} // namespace webrtc