blob: 5bcf11576420ad9452392a36a43eba98455d086b [file] [log] [blame]
pbos@webrtc.orgbbb07e62013-08-05 12:01:36 +00001/*
2 * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
pbos@webrtc.orge7f056e2013-08-19 16:09:34 +000010#include <assert.h>
11
stefan@webrtc.orgb082ade2013-11-18 11:45:11 +000012#include <algorithm>
pbos@webrtc.orgbbb07e62013-08-05 12:01:36 +000013#include <map>
stefan@webrtc.orgb082ade2013-11-18 11:45:11 +000014#include <sstream>
15#include <string>
pbos@webrtc.orgbbb07e62013-08-05 12:01:36 +000016
17#include "testing/gtest/include/gtest/gtest.h"
18
pbos@webrtc.org16e03b72013-10-28 16:32:01 +000019#include "webrtc/call.h"
sprang@webrtc.org40709352013-11-26 11:41:59 +000020#include "webrtc/frame_callback.h"
pbos@webrtc.orgbbb07e62013-08-05 12:01:36 +000021#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
pbos@webrtc.orgf577ae92014-03-19 08:43:57 +000022#include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h"
pbos@webrtc.orgbbb07e62013-08-05 12:01:36 +000023#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
pbos@webrtc.orgbbb07e62013-08-05 12:01:36 +000024#include "webrtc/system_wrappers/interface/event_wrapper.h"
pbos@webrtc.org744fbc72013-09-10 09:26:25 +000025#include "webrtc/system_wrappers/interface/scoped_ptr.h"
pbos@webrtc.orgeb7b7bc2013-12-16 18:24:37 +000026#include "webrtc/system_wrappers/interface/sleep.h"
pbos@webrtc.org724947b2013-12-11 16:26:16 +000027#include "webrtc/test/direct_transport.h"
pbos@webrtc.orgf577ae92014-03-19 08:43:57 +000028#include "webrtc/test/encoder_settings.h"
pbos@webrtc.org724947b2013-12-11 16:26:16 +000029#include "webrtc/test/fake_audio_device.h"
30#include "webrtc/test/fake_decoder.h"
31#include "webrtc/test/fake_encoder.h"
32#include "webrtc/test/frame_generator.h"
33#include "webrtc/test/frame_generator_capturer.h"
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +000034#include "webrtc/test/null_transport.h"
pbos@webrtc.org724947b2013-12-11 16:26:16 +000035#include "webrtc/test/rtp_rtcp_observer.h"
36#include "webrtc/test/testsupport/fileutils.h"
37#include "webrtc/test/testsupport/perf_test.h"
stefan@webrtc.orgb082ade2013-11-18 11:45:11 +000038#include "webrtc/video/transport_adapter.h"
pbos@webrtc.orgbbb07e62013-08-05 12:01:36 +000039
40namespace webrtc {
41
pbos@webrtc.orgc11148b2013-10-17 14:14:42 +000042static unsigned int kDefaultTimeoutMs = 30 * 1000;
43static unsigned int kLongTimeoutMs = 120 * 1000;
pbos@webrtc.orgb613b5a2013-12-03 10:13:04 +000044static const uint32_t kSendSsrc = 0x654321;
pbos@webrtc.orgc279a5d2014-01-24 09:30:53 +000045static const uint32_t kSendRtxSsrc = 0x424242;
pbos@webrtc.orgb613b5a2013-12-03 10:13:04 +000046static const uint32_t kReceiverLocalSsrc = 0x123456;
stefan@webrtc.org69969e22013-11-15 12:32:15 +000047static const uint8_t kSendPayloadType = 125;
pbos@webrtc.orgc279a5d2014-01-24 09:30:53 +000048static const uint8_t kSendRtxPayloadType = 126;
pbos@webrtc.org2a034982014-04-08 11:21:45 +000049static const int kRedPayloadType = 118;
50static const int kUlpfecPayloadType = 119;
pbos@webrtc.orgc11148b2013-10-17 14:14:42 +000051
pbos@webrtc.org2e246b42013-09-27 10:54:10 +000052class CallTest : public ::testing::Test {
pbos@webrtc.orgbbb07e62013-08-05 12:01:36 +000053 public:
pbos@webrtc.org6917e192013-09-19 14:22:12 +000054 CallTest()
pbos@webrtc.org0181b5f2013-09-09 08:26:30 +000055 : send_stream_(NULL),
56 receive_stream_(NULL),
57 fake_encoder_(Clock::GetRealTimeClock()) {}
pbos@webrtc.orgbbb07e62013-08-05 12:01:36 +000058
pbos@webrtc.org5ab75672013-12-16 12:24:44 +000059 virtual ~CallTest() {
pbos@webrtc.orge7f056e2013-08-19 16:09:34 +000060 EXPECT_EQ(NULL, send_stream_);
61 EXPECT_EQ(NULL, receive_stream_);
62 }
pbos@webrtc.orgbbb07e62013-08-05 12:01:36 +000063
pbos@webrtc.orge7f056e2013-08-19 16:09:34 +000064 protected:
pbos@webrtc.orgde74b642013-10-02 13:36:09 +000065 void CreateCalls(const Call::Config& sender_config,
66 const Call::Config& receiver_config) {
pbos@webrtc.org841c8a42013-09-09 15:04:25 +000067 sender_call_.reset(Call::Create(sender_config));
68 receiver_call_.reset(Call::Create(receiver_config));
pbos@webrtc.orge7f056e2013-08-19 16:09:34 +000069 }
pbos@webrtc.orgbbb07e62013-08-05 12:01:36 +000070
pbos@webrtc.orge7f056e2013-08-19 16:09:34 +000071 void CreateTestConfigs() {
pbos@webrtc.orge7f056e2013-08-19 16:09:34 +000072 send_config_ = sender_call_->GetDefaultSendConfig();
73 receive_config_ = receiver_call_->GetDefaultReceiveConfig();
pbos@webrtc.orgbbb07e62013-08-05 12:01:36 +000074
pbos@webrtc.orgb613b5a2013-12-03 10:13:04 +000075 send_config_.rtp.ssrcs.push_back(kSendSsrc);
pbos@webrtc.org6ae48c62014-06-06 10:49:19 +000076 send_config_.encoder_settings.encoder = &fake_encoder_;
77 send_config_.encoder_settings.payload_name = "FAKE";
78 send_config_.encoder_settings.payload_type = kSendPayloadType;
79 video_streams_ = test::CreateVideoStreams(1);
pbos@webrtc.orgbbb07e62013-08-05 12:01:36 +000080
pbos@webrtc.orgf577ae92014-03-19 08:43:57 +000081 assert(receive_config_.codecs.empty());
82 VideoCodec codec =
83 test::CreateDecoderVideoCodec(send_config_.encoder_settings);
84 receive_config_.codecs.push_back(codec);
pbos@webrtc.org0181b5f2013-09-09 08:26:30 +000085 ExternalVideoDecoder decoder;
86 decoder.decoder = &fake_decoder_;
pbos@webrtc.orgf577ae92014-03-19 08:43:57 +000087 decoder.payload_type = send_config_.encoder_settings.payload_type;
pbos@webrtc.org0181b5f2013-09-09 08:26:30 +000088 receive_config_.external_decoders.push_back(decoder);
pbos@webrtc.orgb613b5a2013-12-03 10:13:04 +000089 receive_config_.rtp.remote_ssrc = send_config_.rtp.ssrcs[0];
90 receive_config_.rtp.local_ssrc = kReceiverLocalSsrc;
pbos@webrtc.orge7f056e2013-08-19 16:09:34 +000091 }
pbos@webrtc.orgbbb07e62013-08-05 12:01:36 +000092
pbos@webrtc.orge7f056e2013-08-19 16:09:34 +000093 void CreateStreams() {
94 assert(send_stream_ == NULL);
95 assert(receive_stream_ == NULL);
pbos@webrtc.orgbbb07e62013-08-05 12:01:36 +000096
pbos@webrtc.org6ae48c62014-06-06 10:49:19 +000097 send_stream_ =
98 sender_call_->CreateVideoSendStream(send_config_, video_streams_, NULL);
pbos@webrtc.org5a636552013-11-20 10:40:25 +000099 receive_stream_ = receiver_call_->CreateVideoReceiveStream(receive_config_);
pbos@webrtc.orge7f056e2013-08-19 16:09:34 +0000100 }
pbos@webrtc.orgbbb07e62013-08-05 12:01:36 +0000101
pbos@webrtc.orge7f056e2013-08-19 16:09:34 +0000102 void CreateFrameGenerator() {
pbos@webrtc.org6ae48c62014-06-06 10:49:19 +0000103 frame_generator_capturer_.reset(
104 test::FrameGeneratorCapturer::Create(send_stream_->Input(),
105 video_streams_[0].width,
106 video_streams_[0].height,
107 30,
108 Clock::GetRealTimeClock()));
pbos@webrtc.orge7f056e2013-08-19 16:09:34 +0000109 }
pbos@webrtc.orgbbb07e62013-08-05 12:01:36 +0000110
pbos@webrtc.orge7f056e2013-08-19 16:09:34 +0000111 void StartSending() {
pbos@webrtc.orga5c8d2c2014-04-24 11:13:21 +0000112 receive_stream_->Start();
113 send_stream_->Start();
pbos@webrtc.orge0536292013-10-21 09:02:30 +0000114 if (frame_generator_capturer_.get() != NULL)
115 frame_generator_capturer_->Start();
pbos@webrtc.orge7f056e2013-08-19 16:09:34 +0000116 }
pbos@webrtc.orgbbb07e62013-08-05 12:01:36 +0000117
pbos@webrtc.orge7f056e2013-08-19 16:09:34 +0000118 void StopSending() {
pbos@webrtc.orge0536292013-10-21 09:02:30 +0000119 if (frame_generator_capturer_.get() != NULL)
120 frame_generator_capturer_->Stop();
pbos@webrtc.org95e51f52013-09-05 12:38:54 +0000121 if (send_stream_ != NULL)
pbos@webrtc.orga5c8d2c2014-04-24 11:13:21 +0000122 send_stream_->Stop();
pbos@webrtc.org95e51f52013-09-05 12:38:54 +0000123 if (receive_stream_ != NULL)
pbos@webrtc.orga5c8d2c2014-04-24 11:13:21 +0000124 receive_stream_->Stop();
pbos@webrtc.orge7f056e2013-08-19 16:09:34 +0000125 }
pbos@webrtc.orgbbb07e62013-08-05 12:01:36 +0000126
pbos@webrtc.orge7f056e2013-08-19 16:09:34 +0000127 void DestroyStreams() {
pbos@webrtc.org95e51f52013-09-05 12:38:54 +0000128 if (send_stream_ != NULL)
pbos@webrtc.org2c46f8d2013-11-21 13:49:43 +0000129 sender_call_->DestroyVideoSendStream(send_stream_);
pbos@webrtc.org95e51f52013-09-05 12:38:54 +0000130 if (receive_stream_ != NULL)
pbos@webrtc.org2c46f8d2013-11-21 13:49:43 +0000131 receiver_call_->DestroyVideoReceiveStream(receive_stream_);
pbos@webrtc.org841c8a42013-09-09 15:04:25 +0000132 send_stream_ = NULL;
pbos@webrtc.orge7f056e2013-08-19 16:09:34 +0000133 receive_stream_ = NULL;
134 }
135
pbos@webrtc.orgc279a5d2014-01-24 09:30:53 +0000136 void DecodesRetransmittedFrame(bool retransmit_over_rtx);
pbos@webrtc.orge7f056e2013-08-19 16:09:34 +0000137 void ReceivesPliAndRecovers(int rtp_history_ms);
pbos@webrtc.orgc11148b2013-10-17 14:14:42 +0000138 void RespectsRtcpMode(newapi::RtcpMode rtcp_mode);
asapersson@webrtc.orgefaeda02014-01-20 08:34:49 +0000139 void TestXrReceiverReferenceTimeReport(bool enable_rrtr);
pbos@webrtc.orge7f056e2013-08-19 16:09:34 +0000140
pbos@webrtc.org841c8a42013-09-09 15:04:25 +0000141 scoped_ptr<Call> sender_call_;
142 scoped_ptr<Call> receiver_call_;
pbos@webrtc.orge7f056e2013-08-19 16:09:34 +0000143
pbos@webrtc.org74fa4892013-08-23 09:19:30 +0000144 VideoSendStream::Config send_config_;
pbos@webrtc.org6ae48c62014-06-06 10:49:19 +0000145 std::vector<VideoStream> video_streams_;
pbos@webrtc.org74fa4892013-08-23 09:19:30 +0000146 VideoReceiveStream::Config receive_config_;
pbos@webrtc.orge7f056e2013-08-19 16:09:34 +0000147
pbos@webrtc.org74fa4892013-08-23 09:19:30 +0000148 VideoSendStream* send_stream_;
149 VideoReceiveStream* receive_stream_;
pbos@webrtc.orge7f056e2013-08-19 16:09:34 +0000150
151 scoped_ptr<test::FrameGeneratorCapturer> frame_generator_capturer_;
152
pbos@webrtc.org0181b5f2013-09-09 08:26:30 +0000153 test::FakeEncoder fake_encoder_;
154 test::FakeDecoder fake_decoder_;
pbos@webrtc.orge7f056e2013-08-19 16:09:34 +0000155};
156
pbos@webrtc.orge7f056e2013-08-19 16:09:34 +0000157class NackObserver : public test::RtpRtcpObserver {
mflodman@webrtc.org1fa41be2013-12-18 09:44:53 +0000158 static const int kNumberOfNacksToObserve = 2;
159 static const int kLossBurstSize = 2;
160 static const int kPacketsBetweenLossBursts = 9;
pbos@webrtc.org841c8a42013-09-09 15:04:25 +0000161
pbos@webrtc.orge7f056e2013-08-19 16:09:34 +0000162 public:
pbos@webrtc.orgbbb07e62013-08-05 12:01:36 +0000163 NackObserver()
pbos@webrtc.orgc11148b2013-10-17 14:14:42 +0000164 : test::RtpRtcpObserver(kLongTimeoutMs),
pbos@webrtc.orgbbb07e62013-08-05 12:01:36 +0000165 rtp_parser_(RtpHeaderParser::Create()),
pbos@webrtc.orgbbb07e62013-08-05 12:01:36 +0000166 sent_rtp_packets_(0),
mflodman@webrtc.org1fa41be2013-12-18 09:44:53 +0000167 packets_left_to_drop_(0),
pbos@webrtc.orge7f056e2013-08-19 16:09:34 +0000168 nacks_left_(kNumberOfNacksToObserve) {}
pbos@webrtc.orgbbb07e62013-08-05 12:01:36 +0000169
pbos@webrtc.orgbbb07e62013-08-05 12:01:36 +0000170 private:
pbos@webrtc.orge7f056e2013-08-19 16:09:34 +0000171 virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE {
pbos@webrtc.orgbbb07e62013-08-05 12:01:36 +0000172 RTPHeader header;
173 EXPECT_TRUE(rtp_parser_->Parse(packet, static_cast<int>(length), &header));
174
175 // Never drop retransmitted packets.
176 if (dropped_packets_.find(header.sequenceNumber) !=
177 dropped_packets_.end()) {
178 retransmitted_packets_.insert(header.sequenceNumber);
mflodman@webrtc.org1fa41be2013-12-18 09:44:53 +0000179 if (nacks_left_ == 0 &&
180 retransmitted_packets_.size() == dropped_packets_.size()) {
181 observation_complete_->Set();
182 }
pbos@webrtc.orge7f056e2013-08-19 16:09:34 +0000183 return SEND_PACKET;
pbos@webrtc.orgbbb07e62013-08-05 12:01:36 +0000184 }
185
pbos@webrtc.orge7f056e2013-08-19 16:09:34 +0000186 ++sent_rtp_packets_;
mflodman@webrtc.org1fa41be2013-12-18 09:44:53 +0000187
188 // Enough NACKs received, stop dropping packets.
189 if (nacks_left_ == 0)
190 return SEND_PACKET;
191
192 // Check if it's time for a new loss burst.
193 if (sent_rtp_packets_ % kPacketsBetweenLossBursts == 0)
194 packets_left_to_drop_ = kLossBurstSize;
195
196 if (packets_left_to_drop_ > 0) {
197 --packets_left_to_drop_;
198 dropped_packets_.insert(header.sequenceNumber);
199 return DROP_PACKET;
200 }
201
pbos@webrtc.orge7f056e2013-08-19 16:09:34 +0000202 return SEND_PACKET;
pbos@webrtc.orgbbb07e62013-08-05 12:01:36 +0000203 }
204
pbos@webrtc.orge7f056e2013-08-19 16:09:34 +0000205 virtual Action OnReceiveRtcp(const uint8_t* packet, size_t length) OVERRIDE {
206 RTCPUtility::RTCPParserV2 parser(packet, length, true);
207 EXPECT_TRUE(parser.IsValid());
208
pbos@webrtc.orge7f056e2013-08-19 16:09:34 +0000209 RTCPUtility::RTCPPacketTypes packet_type = parser.Begin();
210 while (packet_type != RTCPUtility::kRtcpNotValidCode) {
mflodman@webrtc.org1fa41be2013-12-18 09:44:53 +0000211 if (packet_type == RTCPUtility::kRtcpRtpfbNackCode) {
212 --nacks_left_;
213 break;
214 }
pbos@webrtc.orge7f056e2013-08-19 16:09:34 +0000215 packet_type = parser.Iterate();
216 }
pbos@webrtc.orge7f056e2013-08-19 16:09:34 +0000217 return SEND_PACKET;
218 }
219
220 private:
pbos@webrtc.orgbbb07e62013-08-05 12:01:36 +0000221 scoped_ptr<RtpHeaderParser> rtp_parser_;
222 std::set<uint16_t> dropped_packets_;
223 std::set<uint16_t> retransmitted_packets_;
pbos@webrtc.orgbbb07e62013-08-05 12:01:36 +0000224 uint64_t sent_rtp_packets_;
mflodman@webrtc.org1fa41be2013-12-18 09:44:53 +0000225 int packets_left_to_drop_;
pbos@webrtc.orgbbb07e62013-08-05 12:01:36 +0000226 int nacks_left_;
pbos@webrtc.orgbbb07e62013-08-05 12:01:36 +0000227};
228
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +0000229TEST_F(CallTest, ReceiverCanBeStartedTwice) {
230 test::NullTransport transport;
231 CreateCalls(Call::Config(&transport), Call::Config(&transport));
232
233 CreateTestConfigs();
234 CreateStreams();
235
pbos@webrtc.orga5c8d2c2014-04-24 11:13:21 +0000236 receive_stream_->Start();
237 receive_stream_->Start();
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +0000238
239 DestroyStreams();
240}
241
242TEST_F(CallTest, ReceiverCanBeStoppedTwice) {
243 test::NullTransport transport;
244 CreateCalls(Call::Config(&transport), Call::Config(&transport));
245
246 CreateTestConfigs();
247 CreateStreams();
248
pbos@webrtc.orga5c8d2c2014-04-24 11:13:21 +0000249 receive_stream_->Stop();
250 receive_stream_->Stop();
pbos@webrtc.orgf777cf22014-01-10 18:47:32 +0000251
252 DestroyStreams();
253}
254
pbos@webrtc.orgeb7b7bc2013-12-16 18:24:37 +0000255TEST_F(CallTest, RendersSingleDelayedFrame) {
256 static const int kWidth = 320;
257 static const int kHeight = 240;
258 // This constant is chosen to be higher than the timeout in the video_render
259 // module. This makes sure that frames aren't dropped if there are no other
260 // frames in the queue.
261 static const int kDelayRenderCallbackMs = 1000;
262
263 class Renderer : public VideoRenderer {
264 public:
265 Renderer() : event_(EventWrapper::Create()) {}
266
267 virtual void RenderFrame(const I420VideoFrame& video_frame,
268 int /*time_to_render_ms*/) OVERRIDE {
269 event_->Set();
270 }
271
272 EventTypeWrapper Wait() { return event_->Wait(kDefaultTimeoutMs); }
273
274 scoped_ptr<EventWrapper> event_;
275 } renderer;
276
277 class TestFrameCallback : public I420FrameCallback {
278 public:
279 TestFrameCallback() : event_(EventWrapper::Create()) {}
280
281 EventTypeWrapper Wait() { return event_->Wait(kDefaultTimeoutMs); }
282
283 private:
pbos@webrtc.orgc279a5d2014-01-24 09:30:53 +0000284 virtual void FrameCallback(I420VideoFrame* frame) OVERRIDE {
pbos@webrtc.orgeb7b7bc2013-12-16 18:24:37 +0000285 SleepMs(kDelayRenderCallbackMs);
286 event_->Set();
287 }
288
289 scoped_ptr<EventWrapper> event_;
290 };
291
292 test::DirectTransport sender_transport, receiver_transport;
293
294 CreateCalls(Call::Config(&sender_transport),
295 Call::Config(&receiver_transport));
296
297 sender_transport.SetReceiver(receiver_call_->Receiver());
298 receiver_transport.SetReceiver(sender_call_->Receiver());
299
300 CreateTestConfigs();
301
302 TestFrameCallback pre_render_callback;
303 receive_config_.pre_render_callback = &pre_render_callback;
304 receive_config_.renderer = &renderer;
305
306 CreateStreams();
307 StartSending();
308
309 // Create frames that are smaller than the send width/height, this is done to
310 // check that the callbacks are done after processing video.
311 scoped_ptr<test::FrameGenerator> frame_generator(
312 test::FrameGenerator::Create(kWidth, kHeight));
313 send_stream_->Input()->SwapFrame(frame_generator->NextFrame());
314 EXPECT_EQ(kEventSignaled, pre_render_callback.Wait())
315 << "Timed out while waiting for pre-render callback.";
316 EXPECT_EQ(kEventSignaled, renderer.Wait())
317 << "Timed out while waiting for the frame to render.";
318
319 StopSending();
320
321 sender_transport.StopSending();
322 receiver_transport.StopSending();
323
324 DestroyStreams();
325}
326
pbos@webrtc.orge0536292013-10-21 09:02:30 +0000327TEST_F(CallTest, TransmitsFirstFrame) {
328 class Renderer : public VideoRenderer {
329 public:
330 Renderer() : event_(EventWrapper::Create()) {}
331
332 virtual void RenderFrame(const I420VideoFrame& video_frame,
333 int /*time_to_render_ms*/) OVERRIDE {
334 event_->Set();
335 }
336
337 EventTypeWrapper Wait() { return event_->Wait(kDefaultTimeoutMs); }
338
339 scoped_ptr<EventWrapper> event_;
340 } renderer;
341
342 test::DirectTransport sender_transport, receiver_transport;
343
344 CreateCalls(Call::Config(&sender_transport),
345 Call::Config(&receiver_transport));
346
347 sender_transport.SetReceiver(receiver_call_->Receiver());
348 receiver_transport.SetReceiver(sender_call_->Receiver());
349
350 CreateTestConfigs();
351 receive_config_.renderer = &renderer;
352
353 CreateStreams();
354 StartSending();
355
356 scoped_ptr<test::FrameGenerator> frame_generator(test::FrameGenerator::Create(
pbos@webrtc.org6ae48c62014-06-06 10:49:19 +0000357 video_streams_[0].width, video_streams_[0].height));
pbos@webrtc.org724947b2013-12-11 16:26:16 +0000358 send_stream_->Input()->SwapFrame(frame_generator->NextFrame());
pbos@webrtc.orge0536292013-10-21 09:02:30 +0000359
360 EXPECT_EQ(kEventSignaled, renderer.Wait())
361 << "Timed out while waiting for the frame to render.";
362
363 StopSending();
364
365 sender_transport.StopSending();
366 receiver_transport.StopSending();
367
368 DestroyStreams();
369}
370
pbos@webrtc.orgb613b5a2013-12-03 10:13:04 +0000371TEST_F(CallTest, ReceiverUsesLocalSsrc) {
372 class SyncRtcpObserver : public test::RtpRtcpObserver {
373 public:
374 SyncRtcpObserver() : test::RtpRtcpObserver(kDefaultTimeoutMs) {}
375
376 virtual Action OnReceiveRtcp(const uint8_t* packet,
377 size_t length) OVERRIDE {
378 RTCPUtility::RTCPParserV2 parser(packet, length, true);
379 EXPECT_TRUE(parser.IsValid());
380 uint32_t ssrc = 0;
381 ssrc |= static_cast<uint32_t>(packet[4]) << 24;
382 ssrc |= static_cast<uint32_t>(packet[5]) << 16;
383 ssrc |= static_cast<uint32_t>(packet[6]) << 8;
384 ssrc |= static_cast<uint32_t>(packet[7]) << 0;
385 EXPECT_EQ(kReceiverLocalSsrc, ssrc);
386 observation_complete_->Set();
387
388 return SEND_PACKET;
389 }
390 } observer;
391
392 CreateCalls(Call::Config(observer.SendTransport()),
393 Call::Config(observer.ReceiveTransport()));
394
395 observer.SetReceivers(receiver_call_->Receiver(), sender_call_->Receiver());
396
397 CreateTestConfigs();
398
399 CreateStreams();
400 CreateFrameGenerator();
401 StartSending();
402
403 EXPECT_EQ(kEventSignaled, observer.Wait())
404 << "Timed out while waiting for a receiver RTCP packet to be sent.";
405
406 StopSending();
407
408 observer.StopSending();
409
410 DestroyStreams();
411}
412
pbos@webrtc.org2e246b42013-09-27 10:54:10 +0000413TEST_F(CallTest, ReceivesAndRetransmitsNack) {
pbos@webrtc.orgbbb07e62013-08-05 12:01:36 +0000414 NackObserver observer;
415
pbos@webrtc.orgde74b642013-10-02 13:36:09 +0000416 CreateCalls(Call::Config(observer.SendTransport()),
417 Call::Config(observer.ReceiveTransport()));
pbos@webrtc.orgbbb07e62013-08-05 12:01:36 +0000418
pbos@webrtc.orge7f056e2013-08-19 16:09:34 +0000419 observer.SetReceivers(receiver_call_->Receiver(), sender_call_->Receiver());
pbos@webrtc.orgbbb07e62013-08-05 12:01:36 +0000420
pbos@webrtc.orge7f056e2013-08-19 16:09:34 +0000421 CreateTestConfigs();
422 int rtp_history_ms = 1000;
423 send_config_.rtp.nack.rtp_history_ms = rtp_history_ms;
424 receive_config_.rtp.nack.rtp_history_ms = rtp_history_ms;
pbos@webrtc.orgbbb07e62013-08-05 12:01:36 +0000425
pbos@webrtc.orge7f056e2013-08-19 16:09:34 +0000426 CreateStreams();
427 CreateFrameGenerator();
pbos@webrtc.orge7f056e2013-08-19 16:09:34 +0000428 StartSending();
pbos@webrtc.orgbbb07e62013-08-05 12:01:36 +0000429
pbos@webrtc.orge7f056e2013-08-19 16:09:34 +0000430 // Wait() waits for an event triggered when NACKs have been received, NACKed
431 // packets retransmitted and frames rendered again.
pbos@webrtc.orgbbb07e62013-08-05 12:01:36 +0000432 EXPECT_EQ(kEventSignaled, observer.Wait());
433
pbos@webrtc.orge7f056e2013-08-19 16:09:34 +0000434 StopSending();
pbos@webrtc.orgbbb07e62013-08-05 12:01:36 +0000435
pbos@webrtc.org96684672013-08-12 12:59:04 +0000436 observer.StopSending();
pbos@webrtc.org0181b5f2013-09-09 08:26:30 +0000437
438 DestroyStreams();
pbos@webrtc.orgbbb07e62013-08-05 12:01:36 +0000439}
440
pbos@webrtc.orgf043f792014-04-28 09:00:50 +0000441// TODO(pbos): Flaky, webrtc:3269
442TEST_F(CallTest, DISABLED_CanReceiveFec) {
pbos@webrtc.org2a034982014-04-08 11:21:45 +0000443 class FecRenderObserver : public test::RtpRtcpObserver, public VideoRenderer {
444 public:
445 FecRenderObserver()
446 : RtpRtcpObserver(kDefaultTimeoutMs),
447 state_(kFirstPacket),
448 protected_sequence_number_(0),
449 protected_frame_timestamp_(0) {}
450
451 private:
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +0000452 virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE
453 EXCLUSIVE_LOCKS_REQUIRED(crit_) {
pbos@webrtc.org2a034982014-04-08 11:21:45 +0000454 RTPHeader header;
455 EXPECT_TRUE(parser_->Parse(packet, static_cast<int>(length), &header));
456
457 EXPECT_EQ(kRedPayloadType, header.payloadType);
458 int encapsulated_payload_type =
459 static_cast<int>(packet[header.headerLength]);
460 if (encapsulated_payload_type != kSendPayloadType)
461 EXPECT_EQ(kUlpfecPayloadType, encapsulated_payload_type);
462
463 switch(state_) {
464 case kFirstPacket:
465 state_ = kDropEveryOtherPacketUntilFec;
466 break;
467 case kDropEveryOtherPacketUntilFec:
468 if (encapsulated_payload_type == kUlpfecPayloadType) {
469 state_ = kDropNextMediaPacket;
470 return SEND_PACKET;
471 }
472 if (header.sequenceNumber % 2 == 0)
473 return DROP_PACKET;
474 break;
475 case kDropNextMediaPacket:
476 if (encapsulated_payload_type == kSendPayloadType) {
477 protected_sequence_number_ = header.sequenceNumber;
478 protected_frame_timestamp_ = header.timestamp;
479 state_ = kProtectedPacketDropped;
480 return DROP_PACKET;
481 }
482 break;
483 case kProtectedPacketDropped:
484 EXPECT_NE(header.sequenceNumber, protected_sequence_number_)
485 << "Protected packet retransmitted. Should not happen with FEC.";
486 break;
487 }
488
489 return SEND_PACKET;
490 }
491
492 virtual void RenderFrame(const I420VideoFrame& video_frame,
493 int time_to_render_ms) OVERRIDE {
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +0000494 CriticalSectionScoped lock(crit_.get());
pbos@webrtc.org2a034982014-04-08 11:21:45 +0000495 // Rendering frame with timestamp associated with dropped packet -> FEC
496 // protection worked.
497 if (state_ == kProtectedPacketDropped &&
498 video_frame.timestamp() == protected_frame_timestamp_) {
499 observation_complete_->Set();
500 }
501 }
502
503 enum {
504 kFirstPacket,
505 kDropEveryOtherPacketUntilFec,
506 kDropNextMediaPacket,
507 kProtectedPacketDropped,
508 } state_;
509
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +0000510 uint32_t protected_sequence_number_ GUARDED_BY(crit_);
511 uint32_t protected_frame_timestamp_ GUARDED_BY(crit_);
pbos@webrtc.org2a034982014-04-08 11:21:45 +0000512 } observer;
513
514 CreateCalls(Call::Config(observer.SendTransport()),
515 Call::Config(observer.ReceiveTransport()));
516
517 observer.SetReceivers(receiver_call_->Receiver(), sender_call_->Receiver());
518
519 CreateTestConfigs();
520 // TODO(pbos): Run this test with combined NACK/FEC enabled as well.
521 // int rtp_history_ms = 1000;
522 // receive_config_.rtp.nack.rtp_history_ms = rtp_history_ms;
523 // send_config_.rtp.nack.rtp_history_ms = rtp_history_ms;
524 send_config_.rtp.fec.red_payload_type = kRedPayloadType;
525 send_config_.rtp.fec.ulpfec_payload_type = kUlpfecPayloadType;
526
527 receive_config_.rtp.fec.red_payload_type = kRedPayloadType;
528 receive_config_.rtp.fec.ulpfec_payload_type = kUlpfecPayloadType;
529 receive_config_.renderer = &observer;
530
531 CreateStreams();
532 CreateFrameGenerator();
533 StartSending();
534
535 // Wait() waits for an event triggered when NACKs have been received, NACKed
536 // packets retransmitted and frames rendered again.
537 EXPECT_EQ(kEventSignaled, observer.Wait());
538
539 StopSending();
540
541 observer.StopSending();
542
543 DestroyStreams();
544}
545
pbos@webrtc.orgc279a5d2014-01-24 09:30:53 +0000546// This test drops second RTP packet with a marker bit set, makes sure it's
547// retransmitted and renders. Retransmission SSRCs are also checked.
548void CallTest::DecodesRetransmittedFrame(bool retransmit_over_rtx) {
549 static const int kDroppedFrameNumber = 2;
550 class RetransmissionObserver : public test::RtpRtcpObserver,
551 public I420FrameCallback {
552 public:
553 RetransmissionObserver(bool expect_rtx)
554 : RtpRtcpObserver(kDefaultTimeoutMs),
555 retransmission_ssrc_(expect_rtx ? kSendRtxSsrc : kSendSsrc),
556 retransmission_payload_type_(expect_rtx ? kSendRtxPayloadType
557 : kSendPayloadType),
558 marker_bits_observed_(0),
559 retransmitted_timestamp_(0),
560 frame_retransmitted_(false) {}
561
562 private:
563 virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE {
564 RTPHeader header;
565 EXPECT_TRUE(parser_->Parse(packet, static_cast<int>(length), &header));
566
567 if (header.timestamp == retransmitted_timestamp_) {
568 EXPECT_EQ(retransmission_ssrc_, header.ssrc);
569 EXPECT_EQ(retransmission_payload_type_, header.payloadType);
570 frame_retransmitted_ = true;
571 return SEND_PACKET;
572 }
573
574 EXPECT_EQ(kSendSsrc, header.ssrc);
575 EXPECT_EQ(kSendPayloadType, header.payloadType);
576
577 // Found the second frame's final packet, drop this and expect a
578 // retransmission.
579 if (header.markerBit && ++marker_bits_observed_ == kDroppedFrameNumber) {
580 retransmitted_timestamp_ = header.timestamp;
581 return DROP_PACKET;
582 }
583
584 return SEND_PACKET;
585 }
586
587 virtual void FrameCallback(I420VideoFrame* frame) OVERRIDE {
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +0000588 CriticalSectionScoped lock(crit_.get());
pbos@webrtc.orgc279a5d2014-01-24 09:30:53 +0000589 if (frame->timestamp() == retransmitted_timestamp_) {
590 EXPECT_TRUE(frame_retransmitted_);
591 observation_complete_->Set();
592 }
593 }
594
595 const uint32_t retransmission_ssrc_;
596 const int retransmission_payload_type_;
597 int marker_bits_observed_;
598 uint32_t retransmitted_timestamp_;
599 bool frame_retransmitted_;
600 } observer(retransmit_over_rtx);
601
602 CreateCalls(Call::Config(observer.SendTransport()),
603 Call::Config(observer.ReceiveTransport()));
604
605 observer.SetReceivers(receiver_call_->Receiver(), sender_call_->Receiver());
606
607 CreateTestConfigs();
608 send_config_.rtp.nack.rtp_history_ms =
609 receive_config_.rtp.nack.rtp_history_ms = 1000;
610 if (retransmit_over_rtx) {
611 send_config_.rtp.rtx.ssrcs.push_back(kSendRtxSsrc);
612 send_config_.rtp.rtx.payload_type = kSendRtxPayloadType;
pbos@webrtc.orgf577ae92014-03-19 08:43:57 +0000613 int payload_type = send_config_.encoder_settings.payload_type;
pbos@webrtc.orgc279a5d2014-01-24 09:30:53 +0000614 receive_config_.rtp.rtx[payload_type].ssrc = kSendRtxSsrc;
615 receive_config_.rtp.rtx[payload_type].payload_type = kSendRtxPayloadType;
616 }
617 receive_config_.pre_render_callback = &observer;
618
619 CreateStreams();
620 CreateFrameGenerator();
621 StartSending();
622
623 EXPECT_EQ(kEventSignaled, observer.Wait())
624 << "Timed out while waiting for retransmission to render.";
625
626 StopSending();
627 observer.StopSending();
628 DestroyStreams();
629}
630
631TEST_F(CallTest, DecodesRetransmittedFrame) {
632 DecodesRetransmittedFrame(false);
633}
634
635TEST_F(CallTest, DecodesRetransmittedFrameOverRtx) {
636 DecodesRetransmittedFrame(true);
637}
638
pbos@webrtc.orgfe1ef932013-10-21 10:34:43 +0000639TEST_F(CallTest, UsesFrameCallbacks) {
640 static const int kWidth = 320;
641 static const int kHeight = 240;
642
643 class Renderer : public VideoRenderer {
644 public:
645 Renderer() : event_(EventWrapper::Create()) {}
646
647 virtual void RenderFrame(const I420VideoFrame& video_frame,
648 int /*time_to_render_ms*/) OVERRIDE {
649 EXPECT_EQ(0, *video_frame.buffer(kYPlane))
650 << "Rendered frame should have zero luma which is applied by the "
651 "pre-render callback.";
652 event_->Set();
653 }
654
655 EventTypeWrapper Wait() { return event_->Wait(kDefaultTimeoutMs); }
656 scoped_ptr<EventWrapper> event_;
657 } renderer;
658
659 class TestFrameCallback : public I420FrameCallback {
660 public:
661 TestFrameCallback(int expected_luma_byte, int next_luma_byte)
662 : event_(EventWrapper::Create()),
663 expected_luma_byte_(expected_luma_byte),
664 next_luma_byte_(next_luma_byte) {}
665
666 EventTypeWrapper Wait() { return event_->Wait(kDefaultTimeoutMs); }
667
668 private:
669 virtual void FrameCallback(I420VideoFrame* frame) {
670 EXPECT_EQ(kWidth, frame->width())
671 << "Width not as expected, callback done before resize?";
672 EXPECT_EQ(kHeight, frame->height())
673 << "Height not as expected, callback done before resize?";
674
675 // Previous luma specified, observed luma should be fairly close.
676 if (expected_luma_byte_ != -1) {
677 EXPECT_NEAR(expected_luma_byte_, *frame->buffer(kYPlane), 10);
678 }
679
680 memset(frame->buffer(kYPlane),
681 next_luma_byte_,
682 frame->allocated_size(kYPlane));
683
684 event_->Set();
685 }
686
687 scoped_ptr<EventWrapper> event_;
688 int expected_luma_byte_;
689 int next_luma_byte_;
690 };
691
692 TestFrameCallback pre_encode_callback(-1, 255); // Changes luma to 255.
693 TestFrameCallback pre_render_callback(255, 0); // Changes luma from 255 to 0.
694
695 test::DirectTransport sender_transport, receiver_transport;
696
697 CreateCalls(Call::Config(&sender_transport),
698 Call::Config(&receiver_transport));
699
700 sender_transport.SetReceiver(receiver_call_->Receiver());
701 receiver_transport.SetReceiver(sender_call_->Receiver());
702
703 CreateTestConfigs();
pbos@webrtc.orgf577ae92014-03-19 08:43:57 +0000704 scoped_ptr<VP8Encoder> encoder(VP8Encoder::Create());
705 send_config_.encoder_settings.encoder = encoder.get();
706 send_config_.encoder_settings.payload_name = "VP8";
pbos@webrtc.org6ae48c62014-06-06 10:49:19 +0000707 ASSERT_EQ(1u, video_streams_.size()) << "Test setup error.";
708 video_streams_[0].width = kWidth;
709 video_streams_[0].height = kHeight;
pbos@webrtc.orgfe1ef932013-10-21 10:34:43 +0000710 send_config_.pre_encode_callback = &pre_encode_callback;
pbos@webrtc.orgf577ae92014-03-19 08:43:57 +0000711 receive_config_.codecs.clear();
712 VideoCodec codec =
713 test::CreateDecoderVideoCodec(send_config_.encoder_settings);
714 receive_config_.external_decoders.clear();
715 receive_config_.codecs.push_back(codec);
pbos@webrtc.orgfe1ef932013-10-21 10:34:43 +0000716 receive_config_.pre_render_callback = &pre_render_callback;
717 receive_config_.renderer = &renderer;
718
719 CreateStreams();
720 StartSending();
721
722 // Create frames that are smaller than the send width/height, this is done to
723 // check that the callbacks are done after processing video.
724 scoped_ptr<test::FrameGenerator> frame_generator(
725 test::FrameGenerator::Create(kWidth / 2, kHeight / 2));
pbos@webrtc.org724947b2013-12-11 16:26:16 +0000726 send_stream_->Input()->SwapFrame(frame_generator->NextFrame());
pbos@webrtc.orgfe1ef932013-10-21 10:34:43 +0000727
728 EXPECT_EQ(kEventSignaled, pre_encode_callback.Wait())
729 << "Timed out while waiting for pre-encode callback.";
730 EXPECT_EQ(kEventSignaled, pre_render_callback.Wait())
731 << "Timed out while waiting for pre-render callback.";
732 EXPECT_EQ(kEventSignaled, renderer.Wait())
733 << "Timed out while waiting for the frame to render.";
734
735 StopSending();
736
737 sender_transport.StopSending();
738 receiver_transport.StopSending();
739
740 DestroyStreams();
741}
742
pbos@webrtc.org6917e192013-09-19 14:22:12 +0000743class PliObserver : public test::RtpRtcpObserver, public VideoRenderer {
pbos@webrtc.orge7f056e2013-08-19 16:09:34 +0000744 static const int kInverseDropProbability = 16;
pbos@webrtc.org841c8a42013-09-09 15:04:25 +0000745
pbos@webrtc.orge7f056e2013-08-19 16:09:34 +0000746 public:
pbos@webrtc.org6917e192013-09-19 14:22:12 +0000747 explicit PliObserver(bool nack_enabled)
pbos@webrtc.orgc11148b2013-10-17 14:14:42 +0000748 : test::RtpRtcpObserver(kLongTimeoutMs),
pbos@webrtc.orge7f056e2013-08-19 16:09:34 +0000749 nack_enabled_(nack_enabled),
mflodman@webrtc.orgbcd124c2013-12-18 09:45:45 +0000750 highest_dropped_timestamp_(0),
751 frames_to_drop_(0),
pbos@webrtc.orge7f056e2013-08-19 16:09:34 +0000752 received_pli_(false) {}
753
754 virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE {
755 RTPHeader header;
pbos@webrtc.orgc279a5d2014-01-24 09:30:53 +0000756 EXPECT_TRUE(parser_->Parse(packet, static_cast<int>(length), &header));
pbos@webrtc.orge7f056e2013-08-19 16:09:34 +0000757
mflodman@webrtc.orgbcd124c2013-12-18 09:45:45 +0000758 // Drop all retransmitted packets to force a PLI.
759 if (header.timestamp <= highest_dropped_timestamp_)
pbos@webrtc.orge7f056e2013-08-19 16:09:34 +0000760 return DROP_PACKET;
761
mflodman@webrtc.orgbcd124c2013-12-18 09:45:45 +0000762 if (frames_to_drop_ > 0) {
763 highest_dropped_timestamp_ = header.timestamp;
764 --frames_to_drop_;
pbos@webrtc.orge7f056e2013-08-19 16:09:34 +0000765 return DROP_PACKET;
766 }
767
pbos@webrtc.orge7f056e2013-08-19 16:09:34 +0000768 return SEND_PACKET;
769 }
770
771 virtual Action OnReceiveRtcp(const uint8_t* packet, size_t length) OVERRIDE {
772 RTCPUtility::RTCPParserV2 parser(packet, length, true);
773 EXPECT_TRUE(parser.IsValid());
774
775 for (RTCPUtility::RTCPPacketTypes packet_type = parser.Begin();
776 packet_type != RTCPUtility::kRtcpNotValidCode;
777 packet_type = parser.Iterate()) {
778 if (!nack_enabled_)
779 EXPECT_NE(packet_type, RTCPUtility::kRtcpRtpfbNackCode);
780
781 if (packet_type == RTCPUtility::kRtcpPsfbPliCode) {
782 received_pli_ = true;
783 break;
784 }
785 }
786 return SEND_PACKET;
787 }
788
pbos@webrtc.org6917e192013-09-19 14:22:12 +0000789 virtual void RenderFrame(const I420VideoFrame& video_frame,
790 int time_to_render_ms) OVERRIDE {
pbos@webrtc.orgde1429e2014-04-28 13:00:21 +0000791 CriticalSectionScoped lock(crit_.get());
mflodman@webrtc.orgbcd124c2013-12-18 09:45:45 +0000792 if (received_pli_ && video_frame.timestamp() > highest_dropped_timestamp_) {
pbos@webrtc.org6917e192013-09-19 14:22:12 +0000793 observation_complete_->Set();
pbos@webrtc.orge7f056e2013-08-19 16:09:34 +0000794 }
mflodman@webrtc.orgbcd124c2013-12-18 09:45:45 +0000795 if (!received_pli_)
796 frames_to_drop_ = kPacketsToDrop;
pbos@webrtc.orge7f056e2013-08-19 16:09:34 +0000797 }
798
799 private:
mflodman@webrtc.orgbcd124c2013-12-18 09:45:45 +0000800 static const int kPacketsToDrop = 1;
801
pbos@webrtc.orge7f056e2013-08-19 16:09:34 +0000802 bool nack_enabled_;
mflodman@webrtc.orgbcd124c2013-12-18 09:45:45 +0000803 uint32_t highest_dropped_timestamp_;
804 int frames_to_drop_;
pbos@webrtc.orge7f056e2013-08-19 16:09:34 +0000805 bool received_pli_;
806};
807
pbos@webrtc.org6917e192013-09-19 14:22:12 +0000808void CallTest::ReceivesPliAndRecovers(int rtp_history_ms) {
pbos@webrtc.orge7f056e2013-08-19 16:09:34 +0000809 PliObserver observer(rtp_history_ms > 0);
810
pbos@webrtc.orgde74b642013-10-02 13:36:09 +0000811 CreateCalls(Call::Config(observer.SendTransport()),
812 Call::Config(observer.ReceiveTransport()));
pbos@webrtc.orge7f056e2013-08-19 16:09:34 +0000813
814 observer.SetReceivers(receiver_call_->Receiver(), sender_call_->Receiver());
815
816 CreateTestConfigs();
817 send_config_.rtp.nack.rtp_history_ms = rtp_history_ms;
818 receive_config_.rtp.nack.rtp_history_ms = rtp_history_ms;
pbos@webrtc.org6917e192013-09-19 14:22:12 +0000819 receive_config_.renderer = &observer;
pbos@webrtc.orge7f056e2013-08-19 16:09:34 +0000820
821 CreateStreams();
822 CreateFrameGenerator();
pbos@webrtc.orge7f056e2013-08-19 16:09:34 +0000823 StartSending();
824
825 // Wait() waits for an event triggered when Pli has been received and frames
826 // have been rendered afterwards.
827 EXPECT_EQ(kEventSignaled, observer.Wait());
828
829 StopSending();
830
pbos@webrtc.orge7f056e2013-08-19 16:09:34 +0000831 observer.StopSending();
pbos@webrtc.org0181b5f2013-09-09 08:26:30 +0000832
833 DestroyStreams();
pbos@webrtc.orge7f056e2013-08-19 16:09:34 +0000834}
835
pbos@webrtc.org2e246b42013-09-27 10:54:10 +0000836TEST_F(CallTest, ReceivesPliAndRecoversWithNack) {
pbos@webrtc.orge7f056e2013-08-19 16:09:34 +0000837 ReceivesPliAndRecovers(1000);
838}
839
840// TODO(pbos): Enable this when 2250 is resolved.
pbos@webrtc.org2e246b42013-09-27 10:54:10 +0000841TEST_F(CallTest, DISABLED_ReceivesPliAndRecoversWithoutNack) {
pbos@webrtc.orge7f056e2013-08-19 16:09:34 +0000842 ReceivesPliAndRecovers(0);
843}
844
pbos@webrtc.orgcaba2d22014-05-14 13:57:12 +0000845TEST_F(CallTest, UnknownRtpPacketGivesUnknownSsrcReturnCode) {
pbos@webrtc.org95e51f52013-09-05 12:38:54 +0000846 class PacketInputObserver : public PacketReceiver {
847 public:
848 explicit PacketInputObserver(PacketReceiver* receiver)
849 : receiver_(receiver), delivered_packet_(EventWrapper::Create()) {}
850
pbos@webrtc.orgc11148b2013-10-17 14:14:42 +0000851 EventTypeWrapper Wait() {
852 return delivered_packet_->Wait(kDefaultTimeoutMs);
853 }
pbos@webrtc.org95e51f52013-09-05 12:38:54 +0000854
855 private:
pbos@webrtc.orgcaba2d22014-05-14 13:57:12 +0000856 virtual DeliveryStatus DeliverPacket(const uint8_t* packet,
857 size_t length) OVERRIDE {
pbos@webrtc.org95e51f52013-09-05 12:38:54 +0000858 if (RtpHeaderParser::IsRtcp(packet, static_cast<int>(length))) {
859 return receiver_->DeliverPacket(packet, length);
860 } else {
pbos@webrtc.orgcaba2d22014-05-14 13:57:12 +0000861 DeliveryStatus delivery_status =
862 receiver_->DeliverPacket(packet, length);
863 EXPECT_EQ(DELIVERY_UNKNOWN_SSRC, delivery_status);
pbos@webrtc.org95e51f52013-09-05 12:38:54 +0000864 delivered_packet_->Set();
pbos@webrtc.orgcaba2d22014-05-14 13:57:12 +0000865 return delivery_status;
pbos@webrtc.org95e51f52013-09-05 12:38:54 +0000866 }
867 }
868
869 PacketReceiver* receiver_;
870 scoped_ptr<EventWrapper> delivered_packet_;
871 };
872
873 test::DirectTransport send_transport, receive_transport;
874
pbos@webrtc.orgde74b642013-10-02 13:36:09 +0000875 CreateCalls(Call::Config(&send_transport), Call::Config(&receive_transport));
pbos@webrtc.org95e51f52013-09-05 12:38:54 +0000876 PacketInputObserver input_observer(receiver_call_->Receiver());
877
878 send_transport.SetReceiver(&input_observer);
879 receive_transport.SetReceiver(sender_call_->Receiver());
880
881 CreateTestConfigs();
882
883 CreateStreams();
884 CreateFrameGenerator();
pbos@webrtc.org95e51f52013-09-05 12:38:54 +0000885 StartSending();
886
pbos@webrtc.org2c46f8d2013-11-21 13:49:43 +0000887 receiver_call_->DestroyVideoReceiveStream(receive_stream_);
pbos@webrtc.org95e51f52013-09-05 12:38:54 +0000888 receive_stream_ = NULL;
889
890 // Wait() waits for a received packet.
891 EXPECT_EQ(kEventSignaled, input_observer.Wait());
892
893 StopSending();
894
895 DestroyStreams();
896
897 send_transport.StopSending();
898 receive_transport.StopSending();
899}
pbos@webrtc.orgb74b96f2013-10-01 11:33:24 +0000900
pbos@webrtc.orgc11148b2013-10-17 14:14:42 +0000901void CallTest::RespectsRtcpMode(newapi::RtcpMode rtcp_mode) {
902 static const int kRtpHistoryMs = 1000;
903 static const int kNumCompoundRtcpPacketsToObserve = 10;
904 class RtcpModeObserver : public test::RtpRtcpObserver {
905 public:
pbos@webrtc.orgc49d5b72013-12-05 12:11:47 +0000906 explicit RtcpModeObserver(newapi::RtcpMode rtcp_mode)
pbos@webrtc.orgc11148b2013-10-17 14:14:42 +0000907 : test::RtpRtcpObserver(kDefaultTimeoutMs),
908 rtcp_mode_(rtcp_mode),
909 sent_rtp_(0),
910 sent_rtcp_(0) {}
911
912 private:
913 virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE {
914 if (++sent_rtp_ % 3 == 0)
915 return DROP_PACKET;
916
917 return SEND_PACKET;
918 }
919
920 virtual Action OnReceiveRtcp(const uint8_t* packet,
921 size_t length) OVERRIDE {
922 ++sent_rtcp_;
923 RTCPUtility::RTCPParserV2 parser(packet, length, true);
924 EXPECT_TRUE(parser.IsValid());
925
926 RTCPUtility::RTCPPacketTypes packet_type = parser.Begin();
927 bool has_report_block = false;
928 while (packet_type != RTCPUtility::kRtcpNotValidCode) {
929 EXPECT_NE(RTCPUtility::kRtcpSrCode, packet_type);
930 if (packet_type == RTCPUtility::kRtcpRrCode) {
931 has_report_block = true;
932 break;
933 }
934 packet_type = parser.Iterate();
935 }
936
937 switch (rtcp_mode_) {
938 case newapi::kRtcpCompound:
939 if (!has_report_block) {
940 ADD_FAILURE() << "Received RTCP packet without receiver report for "
941 "kRtcpCompound.";
942 observation_complete_->Set();
943 }
944
945 if (sent_rtcp_ >= kNumCompoundRtcpPacketsToObserve)
946 observation_complete_->Set();
947
948 break;
949 case newapi::kRtcpReducedSize:
950 if (!has_report_block)
951 observation_complete_->Set();
952 break;
953 }
954
955 return SEND_PACKET;
956 }
957
958 newapi::RtcpMode rtcp_mode_;
959 int sent_rtp_;
960 int sent_rtcp_;
961 } observer(rtcp_mode);
962
963 CreateCalls(Call::Config(observer.SendTransport()),
964 Call::Config(observer.ReceiveTransport()));
965
966 observer.SetReceivers(receiver_call_->Receiver(), sender_call_->Receiver());
967
968 CreateTestConfigs();
969 send_config_.rtp.nack.rtp_history_ms = kRtpHistoryMs;
970 receive_config_.rtp.nack.rtp_history_ms = kRtpHistoryMs;
971 receive_config_.rtp.rtcp_mode = rtcp_mode;
972
973 CreateStreams();
974 CreateFrameGenerator();
975 StartSending();
976
977 EXPECT_EQ(kEventSignaled, observer.Wait())
978 << (rtcp_mode == newapi::kRtcpCompound
979 ? "Timed out before observing enough compound packets."
980 : "Timed out before receiving a non-compound RTCP packet.");
981
982 StopSending();
983 observer.StopSending();
984 DestroyStreams();
985}
986
987TEST_F(CallTest, UsesRtcpCompoundMode) {
988 RespectsRtcpMode(newapi::kRtcpCompound);
989}
990
991TEST_F(CallTest, UsesRtcpReducedSizeMode) {
992 RespectsRtcpMode(newapi::kRtcpReducedSize);
993}
994
pbos@webrtc.orgb74b96f2013-10-01 11:33:24 +0000995// Test sets up a Call multiple senders with different resolutions and SSRCs.
996// Another is set up to receive all three of these with different renderers.
997// Each renderer verifies that it receives the expected resolution, and as soon
998// as every renderer has received a frame, the test finishes.
999TEST_F(CallTest, SendsAndReceivesMultipleStreams) {
1000 static const size_t kNumStreams = 3;
1001
1002 class VideoOutputObserver : public VideoRenderer {
1003 public:
pbos@webrtc.org0f3d0bb2013-12-06 15:48:17 +00001004 VideoOutputObserver(test::FrameGeneratorCapturer** capturer,
1005 int width,
1006 int height)
1007 : capturer_(capturer),
1008 width_(width),
1009 height_(height),
1010 done_(EventWrapper::Create()) {}
pbos@webrtc.orgb74b96f2013-10-01 11:33:24 +00001011
1012 virtual void RenderFrame(const I420VideoFrame& video_frame,
1013 int time_to_render_ms) OVERRIDE {
1014 EXPECT_EQ(width_, video_frame.width());
1015 EXPECT_EQ(height_, video_frame.height());
pbos@webrtc.org0f3d0bb2013-12-06 15:48:17 +00001016 (*capturer_)->Stop();
pbos@webrtc.orgb74b96f2013-10-01 11:33:24 +00001017 done_->Set();
1018 }
1019
pbos@webrtc.orgf577ae92014-03-19 08:43:57 +00001020 EventTypeWrapper Wait() { return done_->Wait(kDefaultTimeoutMs); }
pbos@webrtc.orgb74b96f2013-10-01 11:33:24 +00001021
1022 private:
pbos@webrtc.org0f3d0bb2013-12-06 15:48:17 +00001023 test::FrameGeneratorCapturer** capturer_;
pbos@webrtc.orgb74b96f2013-10-01 11:33:24 +00001024 int width_;
1025 int height_;
1026 scoped_ptr<EventWrapper> done_;
1027 };
1028
1029 struct {
1030 uint32_t ssrc;
1031 int width;
1032 int height;
1033 } codec_settings[kNumStreams] = {{1, 640, 480}, {2, 320, 240}, {3, 240, 160}};
1034
1035 test::DirectTransport sender_transport, receiver_transport;
1036 scoped_ptr<Call> sender_call(Call::Create(Call::Config(&sender_transport)));
1037 scoped_ptr<Call> receiver_call(
1038 Call::Create(Call::Config(&receiver_transport)));
1039 sender_transport.SetReceiver(receiver_call->Receiver());
1040 receiver_transport.SetReceiver(sender_call->Receiver());
1041
1042 VideoSendStream* send_streams[kNumStreams];
1043 VideoReceiveStream* receive_streams[kNumStreams];
1044
1045 VideoOutputObserver* observers[kNumStreams];
1046 test::FrameGeneratorCapturer* frame_generators[kNumStreams];
1047
pbos@webrtc.orgf577ae92014-03-19 08:43:57 +00001048 scoped_ptr<VP8Encoder> encoders[kNumStreams];
1049 for (size_t i = 0; i < kNumStreams; ++i)
1050 encoders[i].reset(VP8Encoder::Create());
1051
pbos@webrtc.orgb74b96f2013-10-01 11:33:24 +00001052 for (size_t i = 0; i < kNumStreams; ++i) {
1053 uint32_t ssrc = codec_settings[i].ssrc;
1054 int width = codec_settings[i].width;
1055 int height = codec_settings[i].height;
pbos@webrtc.org0f3d0bb2013-12-06 15:48:17 +00001056 observers[i] = new VideoOutputObserver(&frame_generators[i], width, height);
pbos@webrtc.orgb74b96f2013-10-01 11:33:24 +00001057
pbos@webrtc.orgf577ae92014-03-19 08:43:57 +00001058 VideoSendStream::Config send_config = sender_call->GetDefaultSendConfig();
1059 send_config.rtp.ssrcs.push_back(ssrc);
pbos@webrtc.org6ae48c62014-06-06 10:49:19 +00001060 send_config.encoder_settings.encoder = encoders[i].get();
1061 send_config.encoder_settings.payload_name = "VP8";
1062 send_config.encoder_settings.payload_type = 124;
1063 std::vector<VideoStream> video_streams = test::CreateVideoStreams(1);
1064 VideoStream* stream = &video_streams[0];
pbos@webrtc.orgf577ae92014-03-19 08:43:57 +00001065 stream->width = width;
1066 stream->height = height;
1067 stream->max_framerate = 5;
1068 stream->min_bitrate_bps = stream->target_bitrate_bps =
1069 stream->max_bitrate_bps = 100000;
pbos@webrtc.org6ae48c62014-06-06 10:49:19 +00001070 send_streams[i] =
1071 sender_call->CreateVideoSendStream(send_config, video_streams, NULL);
pbos@webrtc.orga5c8d2c2014-04-24 11:13:21 +00001072 send_streams[i]->Start();
pbos@webrtc.orgf577ae92014-03-19 08:43:57 +00001073
pbos@webrtc.orgb74b96f2013-10-01 11:33:24 +00001074 VideoReceiveStream::Config receive_config =
1075 receiver_call->GetDefaultReceiveConfig();
1076 receive_config.renderer = observers[i];
pbos@webrtc.orgb613b5a2013-12-03 10:13:04 +00001077 receive_config.rtp.remote_ssrc = ssrc;
1078 receive_config.rtp.local_ssrc = kReceiverLocalSsrc;
pbos@webrtc.orgf577ae92014-03-19 08:43:57 +00001079 VideoCodec codec =
1080 test::CreateDecoderVideoCodec(send_config.encoder_settings);
1081 receive_config.codecs.push_back(codec);
pbos@webrtc.org5a636552013-11-20 10:40:25 +00001082 receive_streams[i] =
1083 receiver_call->CreateVideoReceiveStream(receive_config);
pbos@webrtc.orga5c8d2c2014-04-24 11:13:21 +00001084 receive_streams[i]->Start();
pbos@webrtc.orgb74b96f2013-10-01 11:33:24 +00001085
pbos@webrtc.orgb74b96f2013-10-01 11:33:24 +00001086 frame_generators[i] = test::FrameGeneratorCapturer::Create(
1087 send_streams[i]->Input(), width, height, 30, Clock::GetRealTimeClock());
1088 frame_generators[i]->Start();
1089 }
1090
1091 for (size_t i = 0; i < kNumStreams; ++i) {
pbos@webrtc.orgf577ae92014-03-19 08:43:57 +00001092 EXPECT_EQ(kEventSignaled, observers[i]->Wait())
1093 << "Timed out while waiting for observer " << i << " to render.";
pbos@webrtc.orgb74b96f2013-10-01 11:33:24 +00001094 }
1095
1096 for (size_t i = 0; i < kNumStreams; ++i) {
1097 frame_generators[i]->Stop();
pbos@webrtc.org2c46f8d2013-11-21 13:49:43 +00001098 sender_call->DestroyVideoSendStream(send_streams[i]);
1099 receiver_call->DestroyVideoReceiveStream(receive_streams[i]);
pbos@webrtc.org919f87f2013-12-16 14:55:54 +00001100 delete frame_generators[i];
pbos@webrtc.orgb74b96f2013-10-01 11:33:24 +00001101 delete observers[i];
1102 }
1103
1104 sender_transport.StopSending();
1105 receiver_transport.StopSending();
pbos@webrtc.org5ab75672013-12-16 12:24:44 +00001106};
stefan@webrtc.orgb082ade2013-11-18 11:45:11 +00001107
sprang@webrtc.org40709352013-11-26 11:41:59 +00001108TEST_F(CallTest, ObserversEncodedFrames) {
1109 class EncodedFrameTestObserver : public EncodedFrameObserver {
1110 public:
pbos@webrtc.orgc279a5d2014-01-24 09:30:53 +00001111 EncodedFrameTestObserver()
1112 : length_(0),
1113 frame_type_(kFrameEmpty),
1114 called_(EventWrapper::Create()) {}
sprang@webrtc.org40709352013-11-26 11:41:59 +00001115 virtual ~EncodedFrameTestObserver() {}
1116
1117 virtual void EncodedFrameCallback(const EncodedFrame& encoded_frame) {
1118 frame_type_ = encoded_frame.frame_type_;
1119 length_ = encoded_frame.length_;
1120 buffer_.reset(new uint8_t[length_]);
1121 memcpy(buffer_.get(), encoded_frame.data_, length_);
1122 called_->Set();
1123 }
1124
pbos@webrtc.orgc279a5d2014-01-24 09:30:53 +00001125 EventTypeWrapper Wait() { return called_->Wait(kDefaultTimeoutMs); }
sprang@webrtc.org40709352013-11-26 11:41:59 +00001126
1127 void ExpectEqualFrames(const EncodedFrameTestObserver& observer) {
1128 ASSERT_EQ(length_, observer.length_)
1129 << "Observed frames are of different lengths.";
1130 EXPECT_EQ(frame_type_, observer.frame_type_)
1131 << "Observed frames have different frame types.";
1132 EXPECT_EQ(0, memcmp(buffer_.get(), observer.buffer_.get(), length_))
1133 << "Observed encoded frames have different content.";
1134 }
1135
1136 private:
1137 scoped_ptr<uint8_t[]> buffer_;
1138 size_t length_;
1139 FrameType frame_type_;
1140 scoped_ptr<EventWrapper> called_;
1141 };
1142
1143 EncodedFrameTestObserver post_encode_observer;
1144 EncodedFrameTestObserver pre_decode_observer;
1145
1146 test::DirectTransport sender_transport, receiver_transport;
1147
1148 CreateCalls(Call::Config(&sender_transport),
1149 Call::Config(&receiver_transport));
1150
1151 sender_transport.SetReceiver(receiver_call_->Receiver());
1152 receiver_transport.SetReceiver(sender_call_->Receiver());
1153
1154 CreateTestConfigs();
1155 send_config_.post_encode_callback = &post_encode_observer;
1156 receive_config_.pre_decode_callback = &pre_decode_observer;
1157
1158 CreateStreams();
1159 StartSending();
1160
1161 scoped_ptr<test::FrameGenerator> frame_generator(test::FrameGenerator::Create(
pbos@webrtc.org6ae48c62014-06-06 10:49:19 +00001162 video_streams_[0].width, video_streams_[0].height));
pbos@webrtc.org724947b2013-12-11 16:26:16 +00001163 send_stream_->Input()->SwapFrame(frame_generator->NextFrame());
sprang@webrtc.org40709352013-11-26 11:41:59 +00001164
1165 EXPECT_EQ(kEventSignaled, post_encode_observer.Wait())
1166 << "Timed out while waiting for send-side encoded-frame callback.";
1167
1168 EXPECT_EQ(kEventSignaled, pre_decode_observer.Wait())
1169 << "Timed out while waiting for pre-decode encoded-frame callback.";
1170
1171 post_encode_observer.ExpectEqualFrames(pre_decode_observer);
1172
1173 StopSending();
1174
1175 sender_transport.StopSending();
1176 receiver_transport.StopSending();
1177
1178 DestroyStreams();
1179}
mflodman@webrtc.org92c27932013-12-13 16:36:28 +00001180
1181TEST_F(CallTest, ReceiveStreamSendsRemb) {
1182 class RembObserver : public test::RtpRtcpObserver {
1183 public:
1184 RembObserver() : test::RtpRtcpObserver(kDefaultTimeoutMs) {}
1185
1186 virtual Action OnReceiveRtcp(const uint8_t* packet,
1187 size_t length) OVERRIDE {
1188 RTCPUtility::RTCPParserV2 parser(packet, length, true);
1189 EXPECT_TRUE(parser.IsValid());
1190
1191 bool received_psfb = false;
1192 bool received_remb = false;
1193 RTCPUtility::RTCPPacketTypes packet_type = parser.Begin();
1194 while (packet_type != RTCPUtility::kRtcpNotValidCode) {
1195 if (packet_type == RTCPUtility::kRtcpPsfbRembCode) {
1196 const RTCPUtility::RTCPPacket& packet = parser.Packet();
1197 EXPECT_EQ(packet.PSFBAPP.SenderSSRC, kReceiverLocalSsrc);
1198 received_psfb = true;
1199 } else if (packet_type == RTCPUtility::kRtcpPsfbRembItemCode) {
1200 const RTCPUtility::RTCPPacket& packet = parser.Packet();
1201 EXPECT_GT(packet.REMBItem.BitRate, 0u);
1202 EXPECT_EQ(packet.REMBItem.NumberOfSSRCs, 1u);
1203 EXPECT_EQ(packet.REMBItem.SSRCs[0], kSendSsrc);
1204 received_remb = true;
1205 }
1206 packet_type = parser.Iterate();
1207 }
1208 if (received_psfb && received_remb)
1209 observation_complete_->Set();
1210 return SEND_PACKET;
1211 }
1212 } observer;
1213
1214 CreateCalls(Call::Config(observer.SendTransport()),
1215 Call::Config(observer.ReceiveTransport()));
1216 observer.SetReceivers(receiver_call_->Receiver(), sender_call_->Receiver());
1217 CreateTestConfigs();
1218 CreateStreams();
1219 CreateFrameGenerator();
1220 StartSending();
1221
1222 EXPECT_EQ(kEventSignaled, observer.Wait())
1223 << "Timed out while waiting for a receiver RTCP REMB packet to be sent.";
1224
1225 StopSending();
1226 observer.StopSending();
1227 DestroyStreams();
1228}
asapersson@webrtc.orgefaeda02014-01-20 08:34:49 +00001229
1230void CallTest::TestXrReceiverReferenceTimeReport(bool enable_rrtr) {
1231 static const int kNumRtcpReportPacketsToObserve = 5;
1232 class RtcpXrObserver : public test::RtpRtcpObserver {
1233 public:
1234 explicit RtcpXrObserver(bool enable_rrtr)
1235 : test::RtpRtcpObserver(kDefaultTimeoutMs),
1236 enable_rrtr_(enable_rrtr),
1237 sent_rtcp_sr_(0),
1238 sent_rtcp_rr_(0),
1239 sent_rtcp_rrtr_(0),
1240 sent_rtcp_dlrr_(0) {}
pbos@webrtc.orgc279a5d2014-01-24 09:30:53 +00001241
asapersson@webrtc.orgefaeda02014-01-20 08:34:49 +00001242 private:
1243 // Receive stream should send RR packets (and RRTR packets if enabled).
1244 virtual Action OnReceiveRtcp(const uint8_t* packet,
1245 size_t length) OVERRIDE {
1246 RTCPUtility::RTCPParserV2 parser(packet, length, true);
1247 EXPECT_TRUE(parser.IsValid());
1248
1249 RTCPUtility::RTCPPacketTypes packet_type = parser.Begin();
1250 while (packet_type != RTCPUtility::kRtcpNotValidCode) {
1251 if (packet_type == RTCPUtility::kRtcpRrCode) {
1252 ++sent_rtcp_rr_;
pbos@webrtc.orgc279a5d2014-01-24 09:30:53 +00001253 } else if (packet_type ==
1254 RTCPUtility::kRtcpXrReceiverReferenceTimeCode) {
asapersson@webrtc.orgefaeda02014-01-20 08:34:49 +00001255 ++sent_rtcp_rrtr_;
1256 }
1257 EXPECT_NE(packet_type, RTCPUtility::kRtcpSrCode);
1258 EXPECT_NE(packet_type, RTCPUtility::kRtcpXrDlrrReportBlockItemCode);
1259 packet_type = parser.Iterate();
1260 }
1261 return SEND_PACKET;
1262 }
1263 // Send stream should send SR packets (and DLRR packets if enabled).
1264 virtual Action OnSendRtcp(const uint8_t* packet, size_t length) {
1265 RTCPUtility::RTCPParserV2 parser(packet, length, true);
1266 EXPECT_TRUE(parser.IsValid());
1267
1268 RTCPUtility::RTCPPacketTypes packet_type = parser.Begin();
1269 while (packet_type != RTCPUtility::kRtcpNotValidCode) {
1270 if (packet_type == RTCPUtility::kRtcpSrCode) {
1271 ++sent_rtcp_sr_;
1272 } else if (packet_type == RTCPUtility::kRtcpXrDlrrReportBlockItemCode) {
1273 ++sent_rtcp_dlrr_;
1274 }
1275 EXPECT_NE(packet_type, RTCPUtility::kRtcpXrReceiverReferenceTimeCode);
1276 packet_type = parser.Iterate();
1277 }
1278 if (sent_rtcp_sr_ > kNumRtcpReportPacketsToObserve &&
1279 sent_rtcp_rr_ > kNumRtcpReportPacketsToObserve) {
1280 if (enable_rrtr_) {
1281 EXPECT_GT(sent_rtcp_rrtr_, 0);
1282 EXPECT_GT(sent_rtcp_dlrr_, 0);
1283 } else {
1284 EXPECT_EQ(0, sent_rtcp_rrtr_);
1285 EXPECT_EQ(0, sent_rtcp_dlrr_);
1286 }
1287 observation_complete_->Set();
1288 }
1289 return SEND_PACKET;
1290 }
1291 bool enable_rrtr_;
1292 int sent_rtcp_sr_;
1293 int sent_rtcp_rr_;
1294 int sent_rtcp_rrtr_;
1295 int sent_rtcp_dlrr_;
1296 } observer(enable_rrtr);
1297
1298 CreateCalls(Call::Config(observer.SendTransport()),
1299 Call::Config(observer.ReceiveTransport()));
pbos@webrtc.orgc279a5d2014-01-24 09:30:53 +00001300 observer.SetReceivers(receiver_call_->Receiver(), sender_call_->Receiver());
asapersson@webrtc.orgefaeda02014-01-20 08:34:49 +00001301
1302 CreateTestConfigs();
1303 receive_config_.rtp.rtcp_mode = newapi::kRtcpReducedSize;
1304 receive_config_.rtp.rtcp_xr.receiver_reference_time_report = enable_rrtr;
1305
1306 CreateStreams();
1307 CreateFrameGenerator();
1308 StartSending();
1309
1310 EXPECT_EQ(kEventSignaled, observer.Wait())
1311 << "Timed out while waiting for RTCP SR/RR packets to be sent.";
1312
1313 StopSending();
1314 observer.StopSending();
1315 DestroyStreams();
1316}
1317
sprang@webrtc.org09315702014-02-07 12:06:29 +00001318class StatsObserver : public test::RtpRtcpObserver, public I420FrameCallback {
1319 public:
1320 StatsObserver()
1321 : test::RtpRtcpObserver(kLongTimeoutMs),
1322 receive_stream_(NULL),
1323 send_stream_(NULL),
1324 expected_receive_ssrc_(),
1325 expected_send_ssrcs_(),
1326 check_stats_event_(EventWrapper::Create()) {}
1327
1328 void SetExpectedReceiveSsrc(uint32_t ssrc) { expected_receive_ssrc_ = ssrc; }
1329
1330 void SetExpectedSendSsrcs(const std::vector<uint32_t>& ssrcs) {
1331 for (std::vector<uint32_t>::const_iterator it = ssrcs.begin();
1332 it != ssrcs.end();
1333 ++it) {
1334 expected_send_ssrcs_.insert(*it);
1335 }
1336 }
1337
1338 void SetExpectedCName(std::string cname) { expected_cname_ = cname; }
1339
1340 void SetReceiveStream(VideoReceiveStream* stream) {
1341 receive_stream_ = stream;
1342 }
1343
1344 void SetSendStream(VideoSendStream* stream) { send_stream_ = stream; }
1345
1346 void WaitForFilledStats() {
1347 Clock* clock = Clock::GetRealTimeClock();
1348 int64_t now = clock->TimeInMilliseconds();
1349 int64_t stop_time = now + kLongTimeoutMs;
1350 bool receive_ok = false;
1351 bool send_ok = false;
1352
1353 while (now < stop_time) {
1354 if (!receive_ok)
1355 receive_ok = CheckReceiveStats();
1356 if (!send_ok)
1357 send_ok = CheckSendStats();
1358
1359 if (receive_ok && send_ok)
1360 return;
1361
1362 int64_t time_until_timout_ = stop_time - now;
1363 if (time_until_timout_ > 0)
1364 check_stats_event_->Wait(time_until_timout_);
1365 now = clock->TimeInMilliseconds();
1366 }
1367
1368 ADD_FAILURE() << "Timed out waiting for filled stats.";
1369 for (std::map<std::string, bool>::const_iterator it =
1370 receive_stats_filled_.begin();
1371 it != receive_stats_filled_.end();
1372 ++it) {
1373 if (!it->second) {
1374 ADD_FAILURE() << "Missing receive stats: " << it->first;
1375 }
1376 }
1377
1378 for (std::map<std::string, bool>::const_iterator it =
1379 send_stats_filled_.begin();
1380 it != send_stats_filled_.end();
1381 ++it) {
1382 if (!it->second) {
1383 ADD_FAILURE() << "Missing send stats: " << it->first;
1384 }
1385 }
1386 }
1387
1388 private:
1389 virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE {
1390 check_stats_event_->Set();
1391 return SEND_PACKET;
1392 }
1393
1394 virtual Action OnSendRtcp(const uint8_t* packet, size_t length) OVERRIDE {
1395 check_stats_event_->Set();
1396 return SEND_PACKET;
1397 }
1398
1399 virtual Action OnReceiveRtp(const uint8_t* packet, size_t length) OVERRIDE {
1400 check_stats_event_->Set();
1401 return SEND_PACKET;
1402 }
1403
1404 virtual Action OnReceiveRtcp(const uint8_t* packet, size_t length) OVERRIDE {
1405 check_stats_event_->Set();
1406 return SEND_PACKET;
1407 }
1408
1409 virtual void FrameCallback(I420VideoFrame* video_frame) OVERRIDE {
1410 // Ensure that we have at least 5ms send side delay.
1411 int64_t render_time = video_frame->render_time_ms();
1412 if (render_time > 0)
1413 video_frame->set_render_time_ms(render_time - 5);
1414 }
1415
1416 bool CheckReceiveStats() {
1417 assert(receive_stream_ != NULL);
1418 VideoReceiveStream::Stats stats = receive_stream_->GetStats();
1419 EXPECT_EQ(expected_receive_ssrc_, stats.ssrc);
1420
1421 // Make sure all fields have been populated.
1422
1423 receive_stats_filled_["IncomingRate"] |=
1424 stats.network_frame_rate != 0 || stats.bitrate_bps != 0;
1425
1426 receive_stats_filled_["FrameCallback"] |= stats.decode_frame_rate != 0;
1427
1428 receive_stats_filled_["FrameRendered"] |= stats.render_frame_rate != 0;
1429
1430 receive_stats_filled_["StatisticsUpdated"] |=
1431 stats.rtcp_stats.cumulative_lost != 0 ||
1432 stats.rtcp_stats.extended_max_sequence_number != 0 ||
1433 stats.rtcp_stats.fraction_lost != 0 || stats.rtcp_stats.jitter != 0;
1434
1435 receive_stats_filled_["DataCountersUpdated"] |=
1436 stats.rtp_stats.bytes != 0 || stats.rtp_stats.fec_packets != 0 ||
1437 stats.rtp_stats.header_bytes != 0 || stats.rtp_stats.packets != 0 ||
1438 stats.rtp_stats.padding_bytes != 0 ||
1439 stats.rtp_stats.retransmitted_packets != 0;
1440
1441 receive_stats_filled_["CodecStats"] |=
1442 stats.avg_delay_ms != 0 || stats.discarded_packets != 0 ||
1443 stats.key_frames != 0 || stats.delta_frames != 0;
1444
1445 receive_stats_filled_["CName"] |= stats.c_name == expected_cname_;
1446
1447 return AllStatsFilled(receive_stats_filled_);
1448 }
1449
1450 bool CheckSendStats() {
1451 assert(send_stream_ != NULL);
1452 VideoSendStream::Stats stats = send_stream_->GetStats();
1453
1454 send_stats_filled_["NumStreams"] |=
1455 stats.substreams.size() == expected_send_ssrcs_.size();
1456
1457 send_stats_filled_["Delay"] |=
1458 stats.avg_delay_ms != 0 || stats.max_delay_ms != 0;
1459
1460 receive_stats_filled_["CName"] |= stats.c_name == expected_cname_;
1461
1462 for (std::map<uint32_t, StreamStats>::const_iterator it =
1463 stats.substreams.begin();
1464 it != stats.substreams.end();
1465 ++it) {
1466 EXPECT_TRUE(expected_send_ssrcs_.find(it->first) !=
1467 expected_send_ssrcs_.end());
1468
1469 send_stats_filled_[CompoundKey("IncomingRate", it->first)] |=
1470 stats.input_frame_rate != 0;
1471
1472 const StreamStats& stream_stats = it->second;
1473
1474 send_stats_filled_[CompoundKey("StatisticsUpdated", it->first)] |=
1475 stream_stats.rtcp_stats.cumulative_lost != 0 ||
1476 stream_stats.rtcp_stats.extended_max_sequence_number != 0 ||
1477 stream_stats.rtcp_stats.fraction_lost != 0;
1478
1479 send_stats_filled_[CompoundKey("DataCountersUpdated", it->first)] |=
1480 stream_stats.rtp_stats.fec_packets != 0 ||
1481 stream_stats.rtp_stats.padding_bytes != 0 ||
1482 stream_stats.rtp_stats.retransmitted_packets != 0 ||
1483 stream_stats.rtp_stats.packets != 0;
1484
1485 send_stats_filled_[CompoundKey("BitrateStatisticsObserver", it->first)] |=
1486 stream_stats.bitrate_bps != 0;
1487
1488 send_stats_filled_[CompoundKey("FrameCountObserver", it->first)] |=
1489 stream_stats.delta_frames != 0 || stream_stats.key_frames != 0;
1490
1491 send_stats_filled_[CompoundKey("OutgoingRate", it->first)] |=
1492 stats.encode_frame_rate != 0;
1493 }
1494
1495 return AllStatsFilled(send_stats_filled_);
1496 }
1497
1498 std::string CompoundKey(const char* name, uint32_t ssrc) {
1499 std::ostringstream oss;
1500 oss << name << "_" << ssrc;
1501 return oss.str();
1502 }
1503
1504 bool AllStatsFilled(const std::map<std::string, bool>& stats_map) {
1505 for (std::map<std::string, bool>::const_iterator it = stats_map.begin();
1506 it != stats_map.end();
1507 ++it) {
1508 if (!it->second)
1509 return false;
1510 }
1511 return true;
1512 }
1513
1514 VideoReceiveStream* receive_stream_;
1515 std::map<std::string, bool> receive_stats_filled_;
1516
1517 VideoSendStream* send_stream_;
1518 std::map<std::string, bool> send_stats_filled_;
1519
1520 uint32_t expected_receive_ssrc_;
1521 std::set<uint32_t> expected_send_ssrcs_;
1522 std::string expected_cname_;
1523
1524 scoped_ptr<EventWrapper> check_stats_event_;
1525};
1526
1527TEST_F(CallTest, GetStats) {
1528 StatsObserver observer;
1529
1530 CreateCalls(Call::Config(observer.SendTransport()),
1531 Call::Config(observer.ReceiveTransport()));
1532
1533 observer.SetReceivers(receiver_call_->Receiver(), sender_call_->Receiver());
1534
1535 CreateTestConfigs();
1536 send_config_.pre_encode_callback = &observer; // Used to inject delay.
1537 send_config_.rtp.c_name = "SomeCName";
1538
1539 observer.SetExpectedReceiveSsrc(receive_config_.rtp.local_ssrc);
1540 observer.SetExpectedSendSsrcs(send_config_.rtp.ssrcs);
1541 observer.SetExpectedCName(send_config_.rtp.c_name);
1542
1543 CreateStreams();
1544 observer.SetReceiveStream(receive_stream_);
1545 observer.SetSendStream(send_stream_);
1546 CreateFrameGenerator();
1547 StartSending();
1548
1549 observer.WaitForFilledStats();
1550
1551 StopSending();
1552 observer.StopSending();
1553 DestroyStreams();
1554}
1555
asapersson@webrtc.orgefaeda02014-01-20 08:34:49 +00001556TEST_F(CallTest, ReceiverReferenceTimeReportEnabled) {
1557 TestXrReceiverReferenceTimeReport(true);
1558}
1559
1560TEST_F(CallTest, ReceiverReferenceTimeReportDisabled) {
1561 TestXrReceiverReferenceTimeReport(false);
1562}
pbos@webrtc.org3349ae02014-03-13 12:52:27 +00001563
asapersson@webrtc.org1457b472014-05-26 13:06:04 +00001564TEST_F(CallTest, TestReceivedRtpPacketStats) {
1565 static const size_t kNumRtpPacketsToSend = 5;
1566 class ReceivedRtpStatsObserver : public test::RtpRtcpObserver {
1567 public:
1568 ReceivedRtpStatsObserver()
1569 : test::RtpRtcpObserver(kDefaultTimeoutMs),
1570 receive_stream_(NULL),
1571 sent_rtp_(0) {}
1572
1573 void SetReceiveStream(VideoReceiveStream* stream) {
1574 receive_stream_ = stream;
1575 }
1576
1577 private:
1578 virtual Action OnSendRtp(const uint8_t* packet, size_t length) OVERRIDE {
1579 if (sent_rtp_ >= kNumRtpPacketsToSend) {
1580 VideoReceiveStream::Stats stats = receive_stream_->GetStats();
1581 if (kNumRtpPacketsToSend == stats.rtp_stats.packets) {
1582 observation_complete_->Set();
1583 }
1584 return DROP_PACKET;
1585 }
1586 ++sent_rtp_;
1587 return SEND_PACKET;
1588 }
1589
1590 VideoReceiveStream* receive_stream_;
1591 uint32_t sent_rtp_;
1592 } observer;
1593
1594 CreateCalls(Call::Config(observer.SendTransport()),
1595 Call::Config(observer.ReceiveTransport()));
1596 observer.SetReceivers(receiver_call_->Receiver(), sender_call_->Receiver());
1597
1598 CreateTestConfigs();
1599 CreateStreams();
1600 observer.SetReceiveStream(receive_stream_);
1601 CreateFrameGenerator();
1602 StartSending();
1603
1604 EXPECT_EQ(kEventSignaled, observer.Wait())
1605 << "Timed out while verifying number of received RTP packets.";
1606
1607 StopSending();
1608 observer.StopSending();
1609 DestroyStreams();
1610}
1611
pbos@webrtc.orgbbb07e62013-08-05 12:01:36 +00001612} // namespace webrtc