blob: e5b12ce0b1e96027dfac849543c2965303307bca [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 */
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000010#include <algorithm>
danilchap5c35cf92016-02-03 14:14:49 -080011#include <list>
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000012#include <map>
kwiberg27f982b2016-03-01 11:52:33 -080013#include <memory>
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000014#include <sstream>
15#include <string>
kwiberg4a206a92016-03-31 10:24:26 -070016#include <vector>
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000017
18#include "testing/gtest/include/gtest/gtest.h"
19
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +000020#include "webrtc/base/checks.h"
Erik Språng6b8d3552015-09-24 15:06:57 +020021#include "webrtc/base/event.h"
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000022#include "webrtc/call.h"
Peter Boström5c389d32015-09-25 13:58:30 +020023#include "webrtc/call/transport_adapter.h"
pbosa96b60b2016-04-18 21:12:48 -070024#include "webrtc/common_video/include/frame_callback.h"
danilchap5c35cf92016-02-03 14:14:49 -080025#include "webrtc/modules/include/module_common_types.h"
stefan32f81542016-01-20 07:13:58 -080026#include "webrtc/modules/rtp_rtcp/include/rtp_rtcp.h"
sprang861c55e2015-10-16 10:01:21 -070027#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000028#include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
hbosbab934b2016-01-27 01:36:03 -080029#include "webrtc/modules/video_coding/codecs/h264/include/h264.h"
marpan@webrtc.org5b883172014-11-01 06:10:48 +000030#include "webrtc/modules/video_coding/codecs/vp8/include/vp8.h"
31#include "webrtc/modules/video_coding/codecs/vp9/include/vp9.h"
Henrik Kjellander2557b862015-11-18 22:00:21 +010032#include "webrtc/modules/video_coding/include/video_coding_defines.h"
Henrik Kjellander98f53512015-10-28 18:17:40 +010033#include "webrtc/system_wrappers/include/metrics.h"
asapersson01d70a32016-05-20 06:29:46 -070034#include "webrtc/system_wrappers/include/metrics_default.h"
Henrik Kjellander98f53512015-10-28 18:17:40 +010035#include "webrtc/system_wrappers/include/sleep.h"
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000036#include "webrtc/test/call_test.h"
37#include "webrtc/test/direct_transport.h"
38#include "webrtc/test/encoder_settings.h"
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000039#include "webrtc/test/fake_decoder.h"
40#include "webrtc/test/fake_encoder.h"
41#include "webrtc/test/frame_generator.h"
42#include "webrtc/test/frame_generator_capturer.h"
43#include "webrtc/test/null_transport.h"
asapersson@webrtc.org37c05592015-01-28 13:58:27 +000044#include "webrtc/test/rtcp_packet_parser.h"
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000045#include "webrtc/test/rtp_rtcp_observer.h"
46#include "webrtc/test/testsupport/fileutils.h"
47#include "webrtc/test/testsupport/perf_test.h"
pbos@webrtc.orgab990ae2014-09-17 09:02:25 +000048#include "webrtc/video_encoder.h"
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000049
50namespace webrtc {
51
Peter Boström5811a392015-12-10 13:02:50 +010052static const int kSilenceTimeoutMs = 2000;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000053
54class EndToEndTest : public test::CallTest {
55 public:
56 EndToEndTest() {}
57
58 virtual ~EndToEndTest() {
stefanff483612015-12-21 03:14:00 -080059 EXPECT_EQ(nullptr, video_send_stream_);
60 EXPECT_TRUE(video_receive_streams_.empty());
pbos@webrtc.org994d0b72014-06-27 08:47:52 +000061 }
62
63 protected:
pbos2d566682015-09-28 09:59:31 -070064 class UnusedTransport : public Transport {
pbos@webrtc.org26c0c412014-09-03 16:17:12 +000065 private:
stefan1d8a5062015-10-02 03:39:33 -070066 bool SendRtp(const uint8_t* packet,
67 size_t length,
68 const PacketOptions& options) override {
pbos@webrtc.org26c0c412014-09-03 16:17:12 +000069 ADD_FAILURE() << "Unexpected RTP sent.";
70 return false;
71 }
72
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000073 bool SendRtcp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org26c0c412014-09-03 16:17:12 +000074 ADD_FAILURE() << "Unexpected RTCP sent.";
75 return false;
76 }
77 };
78
skvlad7a43d252016-03-22 15:32:27 -070079 class RequiredTransport : public Transport {
80 public:
81 RequiredTransport(bool rtp_required, bool rtcp_required)
82 : need_rtp_(rtp_required), need_rtcp_(rtcp_required) {}
83 ~RequiredTransport() {
84 if (need_rtp_) {
85 ADD_FAILURE() << "Expected RTP packet not sent.";
86 }
87 if (need_rtcp_) {
88 ADD_FAILURE() << "Expected RTCP packet not sent.";
89 }
90 }
91
92 private:
93 bool SendRtp(const uint8_t* packet,
94 size_t length,
95 const PacketOptions& options) override {
96 need_rtp_ = false;
97 return true;
98 }
99
100 bool SendRtcp(const uint8_t* packet, size_t length) override {
101 need_rtcp_ = false;
102 return true;
103 }
104 bool need_rtp_;
105 bool need_rtcp_;
106 };
107
Peter Boström39593972016-02-15 11:27:15 +0100108 void DecodesRetransmittedFrame(bool enable_rtx, bool enable_red);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000109 void ReceivesPliAndRecovers(int rtp_history_ms);
pbosda903ea2015-10-02 02:36:56 -0700110 void RespectsRtcpMode(RtcpMode rtcp_mode);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000111 void TestXrReceiverReferenceTimeReport(bool enable_rrtr);
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000112 void TestSendsSetSsrcs(size_t num_ssrcs, bool send_single_ssrc_first);
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +0000113 void TestRtpStatePreservation(bool use_rtx);
sprangb4a1ae52015-12-03 08:10:08 -0800114 void VerifyHistogramStats(bool use_rtx, bool use_red, bool screenshare);
skvlad7a43d252016-03-22 15:32:27 -0700115 void VerifyNewVideoSendStreamsRespectNetworkState(
116 MediaType network_to_bring_down,
117 VideoEncoder* encoder,
118 Transport* transport);
119 void VerifyNewVideoReceiveStreamsRespectNetworkState(
120 MediaType network_to_bring_down,
121 Transport* transport);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000122};
123
124TEST_F(EndToEndTest, ReceiverCanBeStartedTwice) {
solenberg4fbae2b2015-08-28 04:07:10 -0700125 CreateCalls(Call::Config(), Call::Config());
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000126
solenberg4fbae2b2015-08-28 04:07:10 -0700127 test::NullTransport transport;
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100128 CreateSendConfig(1, 0, &transport);
solenberg4fbae2b2015-08-28 04:07:10 -0700129 CreateMatchingReceiveConfigs(&transport);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000130
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100131 CreateVideoStreams();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000132
stefanff483612015-12-21 03:14:00 -0800133 video_receive_streams_[0]->Start();
134 video_receive_streams_[0]->Start();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000135
136 DestroyStreams();
137}
138
139TEST_F(EndToEndTest, ReceiverCanBeStoppedTwice) {
solenberg4fbae2b2015-08-28 04:07:10 -0700140 CreateCalls(Call::Config(), Call::Config());
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000141
solenberg4fbae2b2015-08-28 04:07:10 -0700142 test::NullTransport transport;
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100143 CreateSendConfig(1, 0, &transport);
solenberg4fbae2b2015-08-28 04:07:10 -0700144 CreateMatchingReceiveConfigs(&transport);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000145
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100146 CreateVideoStreams();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000147
stefanff483612015-12-21 03:14:00 -0800148 video_receive_streams_[0]->Stop();
149 video_receive_streams_[0]->Stop();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000150
151 DestroyStreams();
152}
153
154TEST_F(EndToEndTest, RendersSingleDelayedFrame) {
155 static const int kWidth = 320;
156 static const int kHeight = 240;
157 // This constant is chosen to be higher than the timeout in the video_render
158 // module. This makes sure that frames aren't dropped if there are no other
159 // frames in the queue.
160 static const int kDelayRenderCallbackMs = 1000;
161
nisse7ade7b32016-03-23 04:48:10 -0700162 class Renderer : public rtc::VideoSinkInterface<VideoFrame> {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000163 public:
Peter Boström5811a392015-12-10 13:02:50 +0100164 Renderer() : event_(false, false) {}
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000165
nisseeb83a1a2016-03-21 01:27:56 -0700166 void OnFrame(const VideoFrame& video_frame) override { event_.Set(); }
pbos@webrtc.org0d852d52015-02-09 15:14:36 +0000167
Peter Boström5811a392015-12-10 13:02:50 +0100168 bool Wait() { return event_.Wait(kDefaultTimeoutMs); }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000169
Peter Boström5811a392015-12-10 13:02:50 +0100170 rtc::Event event_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000171 } renderer;
172
173 class TestFrameCallback : public I420FrameCallback {
174 public:
Peter Boström5811a392015-12-10 13:02:50 +0100175 TestFrameCallback() : event_(false, false) {}
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000176
Peter Boström5811a392015-12-10 13:02:50 +0100177 bool Wait() { return event_.Wait(kDefaultTimeoutMs); }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000178
179 private:
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -0700180 void FrameCallback(VideoFrame* frame) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000181 SleepMs(kDelayRenderCallbackMs);
Peter Boström5811a392015-12-10 13:02:50 +0100182 event_.Set();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000183 }
184
Peter Boström5811a392015-12-10 13:02:50 +0100185 rtc::Event event_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000186 };
187
solenberg4fbae2b2015-08-28 04:07:10 -0700188 CreateCalls(Call::Config(), Call::Config());
189
stefanf116bd02015-10-27 08:29:42 -0700190 test::DirectTransport sender_transport(sender_call_.get());
191 test::DirectTransport receiver_transport(receiver_call_.get());
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000192 sender_transport.SetReceiver(receiver_call_->Receiver());
193 receiver_transport.SetReceiver(sender_call_->Receiver());
194
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100195 CreateSendConfig(1, 0, &sender_transport);
solenberg4fbae2b2015-08-28 04:07:10 -0700196 CreateMatchingReceiveConfigs(&receiver_transport);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000197
198 TestFrameCallback pre_render_callback;
stefanff483612015-12-21 03:14:00 -0800199 video_receive_configs_[0].pre_render_callback = &pre_render_callback;
200 video_receive_configs_[0].renderer = &renderer;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000201
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100202 CreateVideoStreams();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000203 Start();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000204
205 // Create frames that are smaller than the send width/height, this is done to
206 // check that the callbacks are done after processing video.
kwiberg27f982b2016-03-01 11:52:33 -0800207 std::unique_ptr<test::FrameGenerator> frame_generator(
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000208 test::FrameGenerator::CreateChromaGenerator(kWidth, kHeight));
stefanff483612015-12-21 03:14:00 -0800209 video_send_stream_->Input()->IncomingCapturedFrame(
210 *frame_generator->NextFrame());
Peter Boström5811a392015-12-10 13:02:50 +0100211 EXPECT_TRUE(pre_render_callback.Wait())
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000212 << "Timed out while waiting for pre-render callback.";
Peter Boström5811a392015-12-10 13:02:50 +0100213 EXPECT_TRUE(renderer.Wait())
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000214 << "Timed out while waiting for the frame to render.";
215
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000216 Stop();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000217
218 sender_transport.StopSending();
219 receiver_transport.StopSending();
220
221 DestroyStreams();
222}
223
224TEST_F(EndToEndTest, TransmitsFirstFrame) {
nisse7ade7b32016-03-23 04:48:10 -0700225 class Renderer : public rtc::VideoSinkInterface<VideoFrame> {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000226 public:
Peter Boström5811a392015-12-10 13:02:50 +0100227 Renderer() : event_(false, false) {}
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000228
nisseeb83a1a2016-03-21 01:27:56 -0700229 void OnFrame(const VideoFrame& video_frame) override { event_.Set(); }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000230
Peter Boström5811a392015-12-10 13:02:50 +0100231 bool Wait() { return event_.Wait(kDefaultTimeoutMs); }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000232
Peter Boström5811a392015-12-10 13:02:50 +0100233 rtc::Event event_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000234 } renderer;
235
solenberg4fbae2b2015-08-28 04:07:10 -0700236 CreateCalls(Call::Config(), Call::Config());
237
stefanf116bd02015-10-27 08:29:42 -0700238 test::DirectTransport sender_transport(sender_call_.get());
239 test::DirectTransport receiver_transport(receiver_call_.get());
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000240 sender_transport.SetReceiver(receiver_call_->Receiver());
241 receiver_transport.SetReceiver(sender_call_->Receiver());
242
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100243 CreateSendConfig(1, 0, &sender_transport);
solenberg4fbae2b2015-08-28 04:07:10 -0700244 CreateMatchingReceiveConfigs(&receiver_transport);
stefanff483612015-12-21 03:14:00 -0800245 video_receive_configs_[0].renderer = &renderer;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000246
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100247 CreateVideoStreams();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000248 Start();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000249
kwiberg27f982b2016-03-01 11:52:33 -0800250 std::unique_ptr<test::FrameGenerator> frame_generator(
sprang@webrtc.org131bea82015-02-18 12:46:06 +0000251 test::FrameGenerator::CreateChromaGenerator(
stefanff483612015-12-21 03:14:00 -0800252 video_encoder_config_.streams[0].width,
253 video_encoder_config_.streams[0].height));
254 video_send_stream_->Input()->IncomingCapturedFrame(
255 *frame_generator->NextFrame());
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000256
Peter Boström5811a392015-12-10 13:02:50 +0100257 EXPECT_TRUE(renderer.Wait())
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000258 << "Timed out while waiting for the frame to render.";
259
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000260 Stop();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000261
262 sender_transport.StopSending();
263 receiver_transport.StopSending();
264
265 DestroyStreams();
266}
267
Perba7dc722016-04-19 15:01:23 +0200268class CodecObserver : public test::EndToEndTest,
nisse7ade7b32016-03-23 04:48:10 -0700269 public rtc::VideoSinkInterface<VideoFrame> {
Perba7dc722016-04-19 15:01:23 +0200270 public:
271 CodecObserver(int no_frames_to_wait_for,
272 VideoRotation rotation_to_test,
273 const std::string& payload_name,
274 webrtc::VideoEncoder* encoder,
275 webrtc::VideoDecoder* decoder)
276 : EndToEndTest(2 * webrtc::EndToEndTest::kDefaultTimeoutMs),
277 no_frames_to_wait_for_(no_frames_to_wait_for),
278 expected_rotation_(rotation_to_test),
279 payload_name_(payload_name),
280 encoder_(encoder),
281 decoder_(decoder),
282 frame_counter_(0) {}
marpan@webrtc.org5b883172014-11-01 06:10:48 +0000283
Perba7dc722016-04-19 15:01:23 +0200284 void PerformTest() override {
285 EXPECT_TRUE(Wait())
286 << "Timed out while waiting for enough frames to be decoded.";
287 }
marpan@webrtc.org5b883172014-11-01 06:10:48 +0000288
Perba7dc722016-04-19 15:01:23 +0200289 void ModifyVideoConfigs(
290 VideoSendStream::Config* send_config,
291 std::vector<VideoReceiveStream::Config>* receive_configs,
292 VideoEncoderConfig* encoder_config) override {
293 send_config->encoder_settings.encoder = encoder_.get();
294 send_config->encoder_settings.payload_name = payload_name_;
295 send_config->encoder_settings.payload_type = 126;
296 encoder_config->streams[0].min_bitrate_bps = 50000;
297 encoder_config->streams[0].target_bitrate_bps =
298 encoder_config->streams[0].max_bitrate_bps = 2000000;
marpan@webrtc.org5b883172014-11-01 06:10:48 +0000299
Perba7dc722016-04-19 15:01:23 +0200300 (*receive_configs)[0].renderer = this;
301 (*receive_configs)[0].decoders.resize(1);
302 (*receive_configs)[0].decoders[0].payload_type =
303 send_config->encoder_settings.payload_type;
304 (*receive_configs)[0].decoders[0].payload_name =
305 send_config->encoder_settings.payload_name;
306 (*receive_configs)[0].decoders[0].decoder = decoder_.get();
307 }
marpan@webrtc.org5b883172014-11-01 06:10:48 +0000308
Perba7dc722016-04-19 15:01:23 +0200309 void OnFrame(const VideoFrame& video_frame) override {
310 EXPECT_EQ(expected_rotation_, video_frame.rotation());
311 if (++frame_counter_ == no_frames_to_wait_for_)
312 observation_complete_.Set();
313 }
marpan@webrtc.org5b883172014-11-01 06:10:48 +0000314
Perba7dc722016-04-19 15:01:23 +0200315 void OnFrameGeneratorCapturerCreated(
316 test::FrameGeneratorCapturer* frame_generator_capturer) override {
317 frame_generator_capturer->SetFakeRotation(expected_rotation_);
318 }
marpan@webrtc.org5b883172014-11-01 06:10:48 +0000319
Perba7dc722016-04-19 15:01:23 +0200320 private:
321 int no_frames_to_wait_for_;
322 VideoRotation expected_rotation_;
323 std::string payload_name_;
324 std::unique_ptr<webrtc::VideoEncoder> encoder_;
325 std::unique_ptr<webrtc::VideoDecoder> decoder_;
326 int frame_counter_;
327};
328
329TEST_F(EndToEndTest, SendsAndReceivesVP8Rotation90) {
330 CodecObserver test(5, kVideoRotation_90, "VP8",
331 VideoEncoder::Create(VideoEncoder::kVp8),
332 VP8Decoder::Create());
333 RunBaseTest(&test);
334}
335
Peter Boström12996152016-05-14 02:03:18 +0200336#if !defined(RTC_DISABLE_VP9)
Perba7dc722016-04-19 15:01:23 +0200337TEST_F(EndToEndTest, SendsAndReceivesVP9) {
338 CodecObserver test(500, kVideoRotation_0, "VP9",
339 VideoEncoder::Create(VideoEncoder::kVp9),
340 VP9Decoder::Create());
341 RunBaseTest(&test);
342}
343
344TEST_F(EndToEndTest, SendsAndReceivesVP9VideoRotation90) {
345 CodecObserver test(5, kVideoRotation_90, "VP9",
346 VideoEncoder::Create(VideoEncoder::kVp9),
347 VP9Decoder::Create());
stefane74eef12016-01-08 06:47:13 -0800348 RunBaseTest(&test);
marpan@webrtc.org5b883172014-11-01 06:10:48 +0000349}
Peter Boström12996152016-05-14 02:03:18 +0200350#endif // !defined(RTC_DISABLE_VP9)
marpan@webrtc.org5b883172014-11-01 06:10:48 +0000351
hbosbab934b2016-01-27 01:36:03 -0800352#if defined(WEBRTC_END_TO_END_H264_TESTS)
353
stefan@webrtc.org79c33592014-08-06 09:24:53 +0000354TEST_F(EndToEndTest, SendsAndReceivesH264) {
Perba7dc722016-04-19 15:01:23 +0200355 CodecObserver test(500, kVideoRotation_0, "H264",
356 VideoEncoder::Create(VideoEncoder::kH264),
357 H264Decoder::Create());
358 RunBaseTest(&test);
359}
stefan@webrtc.org79c33592014-08-06 09:24:53 +0000360
Perba7dc722016-04-19 15:01:23 +0200361TEST_F(EndToEndTest, SendsAndReceivesH264VideoRotation90) {
362 CodecObserver test(5, kVideoRotation_90, "H264",
363 VideoEncoder::Create(VideoEncoder::kH264),
364 H264Decoder::Create());
stefane74eef12016-01-08 06:47:13 -0800365 RunBaseTest(&test);
stefan@webrtc.org79c33592014-08-06 09:24:53 +0000366}
367
hbosbab934b2016-01-27 01:36:03 -0800368#endif // defined(WEBRTC_END_TO_END_H264_TESTS)
369
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000370TEST_F(EndToEndTest, ReceiverUsesLocalSsrc) {
371 class SyncRtcpObserver : public test::EndToEndTest {
372 public:
373 SyncRtcpObserver() : EndToEndTest(kDefaultTimeoutMs) {}
374
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000375 Action OnReceiveRtcp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000376 RTCPUtility::RTCPParserV2 parser(packet, length, true);
377 EXPECT_TRUE(parser.IsValid());
378 uint32_t ssrc = 0;
379 ssrc |= static_cast<uint32_t>(packet[4]) << 24;
380 ssrc |= static_cast<uint32_t>(packet[5]) << 16;
381 ssrc |= static_cast<uint32_t>(packet[6]) << 8;
382 ssrc |= static_cast<uint32_t>(packet[7]) << 0;
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100383 EXPECT_EQ(kReceiverLocalVideoSsrc, ssrc);
Peter Boström5811a392015-12-10 13:02:50 +0100384 observation_complete_.Set();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000385
386 return SEND_PACKET;
387 }
388
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000389 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100390 EXPECT_TRUE(Wait())
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000391 << "Timed out while waiting for a receiver RTCP packet to be sent.";
392 }
393 } test;
394
stefane74eef12016-01-08 06:47:13 -0800395 RunBaseTest(&test);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000396}
397
398TEST_F(EndToEndTest, ReceivesAndRetransmitsNack) {
399 static const int kNumberOfNacksToObserve = 2;
400 static const int kLossBurstSize = 2;
401 static const int kPacketsBetweenLossBursts = 9;
402 class NackObserver : public test::EndToEndTest {
403 public:
404 NackObserver()
405 : EndToEndTest(kLongTimeoutMs),
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000406 sent_rtp_packets_(0),
407 packets_left_to_drop_(0),
408 nacks_left_(kNumberOfNacksToObserve) {}
409
410 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000411 Action OnSendRtp(const uint8_t* packet, size_t length) override {
stefanf116bd02015-10-27 08:29:42 -0700412 rtc::CritScope lock(&crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000413 RTPHeader header;
Peter Boström03671cb2015-12-07 15:22:24 +0100414 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000415
416 // Never drop retransmitted packets.
417 if (dropped_packets_.find(header.sequenceNumber) !=
418 dropped_packets_.end()) {
419 retransmitted_packets_.insert(header.sequenceNumber);
Stefan Holmer586b19b2015-09-18 11:14:31 +0200420 if (nacks_left_ <= 0 &&
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000421 retransmitted_packets_.size() == dropped_packets_.size()) {
Peter Boström5811a392015-12-10 13:02:50 +0100422 observation_complete_.Set();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000423 }
424 return SEND_PACKET;
425 }
426
427 ++sent_rtp_packets_;
428
429 // Enough NACKs received, stop dropping packets.
Stefan Holmer586b19b2015-09-18 11:14:31 +0200430 if (nacks_left_ <= 0)
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000431 return SEND_PACKET;
432
433 // Check if it's time for a new loss burst.
434 if (sent_rtp_packets_ % kPacketsBetweenLossBursts == 0)
435 packets_left_to_drop_ = kLossBurstSize;
436
Stefan Holmer01b48882015-05-05 10:21:24 +0200437 // Never drop padding packets as those won't be retransmitted.
438 if (packets_left_to_drop_ > 0 && header.paddingLength == 0) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000439 --packets_left_to_drop_;
440 dropped_packets_.insert(header.sequenceNumber);
441 return DROP_PACKET;
442 }
443
444 return SEND_PACKET;
445 }
446
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000447 Action OnReceiveRtcp(const uint8_t* packet, size_t length) override {
stefanf116bd02015-10-27 08:29:42 -0700448 rtc::CritScope lock(&crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000449 RTCPUtility::RTCPParserV2 parser(packet, length, true);
450 EXPECT_TRUE(parser.IsValid());
451
452 RTCPUtility::RTCPPacketTypes packet_type = parser.Begin();
Erik Språng242e22b2015-05-11 10:17:43 +0200453 while (packet_type != RTCPUtility::RTCPPacketTypes::kInvalid) {
454 if (packet_type == RTCPUtility::RTCPPacketTypes::kRtpfbNack) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000455 --nacks_left_;
456 break;
457 }
458 packet_type = parser.Iterate();
459 }
460 return SEND_PACKET;
461 }
462
stefanff483612015-12-21 03:14:00 -0800463 void ModifyVideoConfigs(
464 VideoSendStream::Config* send_config,
465 std::vector<VideoReceiveStream::Config>* receive_configs,
466 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000467 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000468 (*receive_configs)[0].rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000469 }
470
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000471 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100472 EXPECT_TRUE(Wait())
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000473 << "Timed out waiting for packets to be NACKed, retransmitted and "
474 "rendered.";
475 }
476
stefanf116bd02015-10-27 08:29:42 -0700477 rtc::CriticalSection crit_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000478 std::set<uint16_t> dropped_packets_;
479 std::set<uint16_t> retransmitted_packets_;
480 uint64_t sent_rtp_packets_;
481 int packets_left_to_drop_;
stefanf116bd02015-10-27 08:29:42 -0700482 int nacks_left_ GUARDED_BY(&crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000483 } test;
484
stefane74eef12016-01-08 06:47:13 -0800485 RunBaseTest(&test);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000486}
487
pbos@webrtc.orga9c2d452014-11-13 14:40:15 +0000488TEST_F(EndToEndTest, CanReceiveFec) {
nisse7ade7b32016-03-23 04:48:10 -0700489 class FecRenderObserver : public test::EndToEndTest,
490 public rtc::VideoSinkInterface<VideoFrame> {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000491 public:
492 FecRenderObserver()
pbos@webrtc.orga9c2d452014-11-13 14:40:15 +0000493 : EndToEndTest(kDefaultTimeoutMs), state_(kFirstPacket) {}
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000494
495 private:
stefanf116bd02015-10-27 08:29:42 -0700496 Action OnSendRtp(const uint8_t* packet, size_t length) override {
497 rtc::CritScope lock(&crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000498 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000499 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000500
Stefan Holmer01b48882015-05-05 10:21:24 +0200501 int encapsulated_payload_type = -1;
502 if (header.payloadType == kRedPayloadType) {
503 encapsulated_payload_type =
504 static_cast<int>(packet[header.headerLength]);
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100505 if (encapsulated_payload_type != kFakeVideoSendPayloadType)
Stefan Holmer01b48882015-05-05 10:21:24 +0200506 EXPECT_EQ(kUlpfecPayloadType, encapsulated_payload_type);
507 } else {
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100508 EXPECT_EQ(kFakeVideoSendPayloadType, header.payloadType);
Stefan Holmer01b48882015-05-05 10:21:24 +0200509 }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000510
pbos@webrtc.orga9c2d452014-11-13 14:40:15 +0000511 if (protected_sequence_numbers_.count(header.sequenceNumber) != 0) {
512 // Retransmitted packet, should not count.
513 protected_sequence_numbers_.erase(header.sequenceNumber);
514 EXPECT_GT(protected_timestamps_.count(header.timestamp), 0u);
515 protected_timestamps_.erase(header.timestamp);
516 return SEND_PACKET;
517 }
518
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000519 switch (state_) {
520 case kFirstPacket:
521 state_ = kDropEveryOtherPacketUntilFec;
522 break;
523 case kDropEveryOtherPacketUntilFec:
524 if (encapsulated_payload_type == kUlpfecPayloadType) {
525 state_ = kDropNextMediaPacket;
526 return SEND_PACKET;
527 }
528 if (header.sequenceNumber % 2 == 0)
529 return DROP_PACKET;
530 break;
531 case kDropNextMediaPacket:
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100532 if (encapsulated_payload_type == kFakeVideoSendPayloadType) {
pbos@webrtc.orga9c2d452014-11-13 14:40:15 +0000533 protected_sequence_numbers_.insert(header.sequenceNumber);
534 protected_timestamps_.insert(header.timestamp);
535 state_ = kDropEveryOtherPacketUntilFec;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000536 return DROP_PACKET;
537 }
538 break;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000539 }
540
541 return SEND_PACKET;
542 }
543
nisseeb83a1a2016-03-21 01:27:56 -0700544 void OnFrame(const VideoFrame& video_frame) override {
Peter Boströmf2f82832015-05-01 13:00:41 +0200545 rtc::CritScope lock(&crit_);
pbos@webrtc.orga9c2d452014-11-13 14:40:15 +0000546 // Rendering frame with timestamp of packet that was dropped -> FEC
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000547 // protection worked.
pbos@webrtc.orga9c2d452014-11-13 14:40:15 +0000548 if (protected_timestamps_.count(video_frame.timestamp()) != 0)
Peter Boström5811a392015-12-10 13:02:50 +0100549 observation_complete_.Set();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000550 }
551
552 enum {
553 kFirstPacket,
554 kDropEveryOtherPacketUntilFec,
555 kDropNextMediaPacket,
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000556 } state_;
557
stefanff483612015-12-21 03:14:00 -0800558 void ModifyVideoConfigs(
559 VideoSendStream::Config* send_config,
560 std::vector<VideoReceiveStream::Config>* receive_configs,
561 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000562 // TODO(pbos): Run this test with combined NACK/FEC enabled as well.
563 // int rtp_history_ms = 1000;
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000564 // (*receive_configs)[0].rtp.nack.rtp_history_ms = rtp_history_ms;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000565 // send_config->rtp.nack.rtp_history_ms = rtp_history_ms;
566 send_config->rtp.fec.red_payload_type = kRedPayloadType;
567 send_config->rtp.fec.ulpfec_payload_type = kUlpfecPayloadType;
568
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000569 (*receive_configs)[0].rtp.fec.red_payload_type = kRedPayloadType;
570 (*receive_configs)[0].rtp.fec.ulpfec_payload_type = kUlpfecPayloadType;
571 (*receive_configs)[0].renderer = this;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000572 }
573
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000574 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100575 EXPECT_TRUE(Wait())
pbos@webrtc.orga9c2d452014-11-13 14:40:15 +0000576 << "Timed out waiting for dropped frames frames to be rendered.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000577 }
578
stefanf116bd02015-10-27 08:29:42 -0700579 rtc::CriticalSection crit_;
pbos@webrtc.orga9c2d452014-11-13 14:40:15 +0000580 std::set<uint32_t> protected_sequence_numbers_ GUARDED_BY(crit_);
581 std::set<uint32_t> protected_timestamps_ GUARDED_BY(crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000582 } test;
583
stefane74eef12016-01-08 06:47:13 -0800584 RunBaseTest(&test);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000585}
586
Danil Chapovalov895a2d22016-05-27 14:12:09 +0200587TEST_F(EndToEndTest, ReceivedFecPacketsNotNacked) {
asapersson@webrtc.org37c05592015-01-28 13:58:27 +0000588 class FecNackObserver : public test::EndToEndTest {
589 public:
mflodmand1590b22015-12-09 07:07:59 -0800590 FecNackObserver()
stefanf116bd02015-10-27 08:29:42 -0700591 : EndToEndTest(kDefaultTimeoutMs),
asapersson@webrtc.org5c928eb2015-02-25 11:47:11 +0000592 state_(kFirstPacket),
asapersson@webrtc.org37c05592015-01-28 13:58:27 +0000593 fec_sequence_number_(0),
594 has_last_sequence_number_(false),
Danil Chapovalov895a2d22016-05-27 14:12:09 +0200595 last_sequence_number_(0),
596 encoder_(VideoEncoder::Create(VideoEncoder::EncoderType::kVp8)),
597 decoder_(VP8Decoder::Create()) {}
asapersson@webrtc.org37c05592015-01-28 13:58:27 +0000598
599 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000600 Action OnSendRtp(const uint8_t* packet, size_t length) override {
stefan608213e2015-11-01 14:56:10 -0800601 rtc::CritScope lock_(&crit_);
asapersson@webrtc.org37c05592015-01-28 13:58:27 +0000602 RTPHeader header;
603 EXPECT_TRUE(parser_->Parse(packet, length, &header));
asapersson@webrtc.org37c05592015-01-28 13:58:27 +0000604
Stefan Holmer01b48882015-05-05 10:21:24 +0200605 int encapsulated_payload_type = -1;
606 if (header.payloadType == kRedPayloadType) {
607 encapsulated_payload_type =
608 static_cast<int>(packet[header.headerLength]);
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100609 if (encapsulated_payload_type != kFakeVideoSendPayloadType)
Stefan Holmer01b48882015-05-05 10:21:24 +0200610 EXPECT_EQ(kUlpfecPayloadType, encapsulated_payload_type);
611 } else {
Stefan Holmer9fea80f2016-01-07 17:43:18 +0100612 EXPECT_EQ(kFakeVideoSendPayloadType, header.payloadType);
Stefan Holmer01b48882015-05-05 10:21:24 +0200613 }
asapersson@webrtc.org37c05592015-01-28 13:58:27 +0000614
615 if (has_last_sequence_number_ &&
616 !IsNewerSequenceNumber(header.sequenceNumber,
617 last_sequence_number_)) {
618 // Drop retransmitted packets.
619 return DROP_PACKET;
620 }
621 last_sequence_number_ = header.sequenceNumber;
622 has_last_sequence_number_ = true;
623
624 bool fec_packet = encapsulated_payload_type == kUlpfecPayloadType;
625 switch (state_) {
asapersson@webrtc.org5c928eb2015-02-25 11:47:11 +0000626 case kFirstPacket:
627 state_ = kDropEveryOtherPacketUntilFec;
628 break;
asapersson@webrtc.org37c05592015-01-28 13:58:27 +0000629 case kDropEveryOtherPacketUntilFec:
630 if (fec_packet) {
631 state_ = kDropAllMediaPacketsUntilFec;
632 } else if (header.sequenceNumber % 2 == 0) {
633 return DROP_PACKET;
634 }
635 break;
636 case kDropAllMediaPacketsUntilFec:
637 if (!fec_packet)
638 return DROP_PACKET;
639 fec_sequence_number_ = header.sequenceNumber;
Danil Chapovalov895a2d22016-05-27 14:12:09 +0200640 state_ = kDropOneMediaPacket;
641 break;
642 case kDropOneMediaPacket:
643 if (fec_packet)
644 return DROP_PACKET;
645 state_ = kPassOneMediaPacket;
646 return DROP_PACKET;
647 break;
648 case kPassOneMediaPacket:
649 if (fec_packet)
650 return DROP_PACKET;
651 // Pass one media packet after dropped packet after last FEC,
652 // otherwise receiver might never see a seq_no after
653 // |fec_sequence_number_|
asapersson@webrtc.org37c05592015-01-28 13:58:27 +0000654 state_ = kVerifyFecPacketNotInNackList;
655 break;
656 case kVerifyFecPacketNotInNackList:
657 // Continue to drop packets. Make sure no frame can be decoded.
658 if (fec_packet || header.sequenceNumber % 2 == 0)
659 return DROP_PACKET;
660 break;
661 }
662 return SEND_PACKET;
663 }
664
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000665 Action OnReceiveRtcp(const uint8_t* packet, size_t length) override {
stefan608213e2015-11-01 14:56:10 -0800666 rtc::CritScope lock_(&crit_);
asapersson@webrtc.org37c05592015-01-28 13:58:27 +0000667 if (state_ == kVerifyFecPacketNotInNackList) {
668 test::RtcpPacketParser rtcp_parser;
669 rtcp_parser.Parse(packet, length);
670 std::vector<uint16_t> nacks = rtcp_parser.nack_item()->last_nack_list();
Danil Chapovalov895a2d22016-05-27 14:12:09 +0200671 EXPECT_TRUE(std::find(nacks.begin(), nacks.end(),
672 fec_sequence_number_) == nacks.end())
673 << "Got nack for FEC packet";
asapersson@webrtc.org37c05592015-01-28 13:58:27 +0000674 if (!nacks.empty() &&
675 IsNewerSequenceNumber(nacks.back(), fec_sequence_number_)) {
Peter Boström5811a392015-12-10 13:02:50 +0100676 observation_complete_.Set();
asapersson@webrtc.org37c05592015-01-28 13:58:27 +0000677 }
678 }
679 return SEND_PACKET;
680 }
681
stefane74eef12016-01-08 06:47:13 -0800682 test::PacketTransport* CreateSendTransport(Call* sender_call) override {
683 // At low RTT (< kLowRttNackMs) -> NACK only, no FEC.
684 // Configure some network delay.
685 const int kNetworkDelayMs = 50;
686 FakeNetworkPipe::Config config;
687 config.queue_delay_ms = kNetworkDelayMs;
688 return new test::PacketTransport(sender_call, this,
689 test::PacketTransport::kSender, config);
690 }
691
Stefan Holmere5904162015-03-26 11:11:06 +0100692 // TODO(holmer): Investigate why we don't send FEC packets when the bitrate
693 // is 10 kbps.
694 Call::Config GetSenderCallConfig() override {
solenberg4fbae2b2015-08-28 04:07:10 -0700695 Call::Config config;
Stefan Holmere5904162015-03-26 11:11:06 +0100696 const int kMinBitrateBps = 30000;
697 config.bitrate_config.min_bitrate_bps = kMinBitrateBps;
698 return config;
699 }
700
stefanff483612015-12-21 03:14:00 -0800701 void ModifyVideoConfigs(
702 VideoSendStream::Config* send_config,
703 std::vector<VideoReceiveStream::Config>* receive_configs,
704 VideoEncoderConfig* encoder_config) override {
asapersson@webrtc.org37c05592015-01-28 13:58:27 +0000705 // Configure hybrid NACK/FEC.
706 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
707 send_config->rtp.fec.red_payload_type = kRedPayloadType;
708 send_config->rtp.fec.ulpfec_payload_type = kUlpfecPayloadType;
Danil Chapovalov895a2d22016-05-27 14:12:09 +0200709 // Set codec to VP8, otherwise NACK/FEC hybrid will be disabled.
710 send_config->encoder_settings.encoder = encoder_.get();
711 send_config->encoder_settings.payload_name = "VP8";
712 send_config->encoder_settings.payload_type = kFakeVideoSendPayloadType;
713 encoder_config->streams[0].min_bitrate_bps = 50000;
714 encoder_config->streams[0].max_bitrate_bps =
715 encoder_config->streams[0].target_bitrate_bps = 2000000;
716
asapersson@webrtc.org37c05592015-01-28 13:58:27 +0000717 (*receive_configs)[0].rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
718 (*receive_configs)[0].rtp.fec.red_payload_type = kRedPayloadType;
719 (*receive_configs)[0].rtp.fec.ulpfec_payload_type = kUlpfecPayloadType;
Danil Chapovalov895a2d22016-05-27 14:12:09 +0200720
721 (*receive_configs)[0].decoders.resize(1);
722 (*receive_configs)[0].decoders[0].payload_type =
723 send_config->encoder_settings.payload_type;
724 (*receive_configs)[0].decoders[0].payload_name =
725 send_config->encoder_settings.payload_name;
726 (*receive_configs)[0].decoders[0].decoder = decoder_.get();
asapersson@webrtc.org37c05592015-01-28 13:58:27 +0000727 }
728
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000729 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100730 EXPECT_TRUE(Wait())
asapersson@webrtc.org37c05592015-01-28 13:58:27 +0000731 << "Timed out while waiting for FEC packets to be received.";
732 }
733
734 enum {
asapersson@webrtc.org5c928eb2015-02-25 11:47:11 +0000735 kFirstPacket,
asapersson@webrtc.org37c05592015-01-28 13:58:27 +0000736 kDropEveryOtherPacketUntilFec,
737 kDropAllMediaPacketsUntilFec,
Danil Chapovalov895a2d22016-05-27 14:12:09 +0200738 kDropOneMediaPacket,
739 kPassOneMediaPacket,
asapersson@webrtc.org37c05592015-01-28 13:58:27 +0000740 kVerifyFecPacketNotInNackList,
741 } state_;
742
stefan608213e2015-11-01 14:56:10 -0800743 rtc::CriticalSection crit_;
744 uint16_t fec_sequence_number_ GUARDED_BY(&crit_);
asapersson@webrtc.org37c05592015-01-28 13:58:27 +0000745 bool has_last_sequence_number_;
746 uint16_t last_sequence_number_;
Danil Chapovalov895a2d22016-05-27 14:12:09 +0200747 std::unique_ptr<webrtc::VideoEncoder> encoder_;
748 std::unique_ptr<webrtc::VideoDecoder> decoder_;
stefanf116bd02015-10-27 08:29:42 -0700749 } test;
asapersson@webrtc.org37c05592015-01-28 13:58:27 +0000750
stefane74eef12016-01-08 06:47:13 -0800751 RunBaseTest(&test);
asapersson@webrtc.org37c05592015-01-28 13:58:27 +0000752}
753
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000754// This test drops second RTP packet with a marker bit set, makes sure it's
755// retransmitted and renders. Retransmission SSRCs are also checked.
Peter Boström39593972016-02-15 11:27:15 +0100756void EndToEndTest::DecodesRetransmittedFrame(bool enable_rtx, bool enable_red) {
Peter Boström67680c12016-02-17 11:10:04 +0100757 static const int kDroppedFrameNumber = 10;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000758 class RetransmissionObserver : public test::EndToEndTest,
759 public I420FrameCallback {
760 public:
Peter Boström39593972016-02-15 11:27:15 +0100761 RetransmissionObserver(bool enable_rtx, bool enable_red)
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000762 : EndToEndTest(kDefaultTimeoutMs),
Peter Boström39593972016-02-15 11:27:15 +0100763 payload_type_(GetPayloadType(false, enable_red)),
764 retransmission_ssrc_(enable_rtx ? kSendRtxSsrcs[0]
765 : kVideoSendSsrcs[0]),
766 retransmission_payload_type_(GetPayloadType(enable_rtx, enable_red)),
767 encoder_(VideoEncoder::Create(VideoEncoder::EncoderType::kVp8)),
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000768 marker_bits_observed_(0),
769 retransmitted_timestamp_(0),
770 frame_retransmitted_(false) {}
771
772 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000773 Action OnSendRtp(const uint8_t* packet, size_t length) override {
stefanf116bd02015-10-27 08:29:42 -0700774 rtc::CritScope lock(&crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000775 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000776 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000777
Peter Boström67680c12016-02-17 11:10:04 +0100778 // Ignore padding-only packets over RTX.
779 if (header.payloadType != payload_type_) {
780 EXPECT_EQ(retransmission_ssrc_, header.ssrc);
781 if (length == header.headerLength + header.paddingLength)
782 return SEND_PACKET;
Stefan Holmer586b19b2015-09-18 11:14:31 +0200783 }
Peter Boström67680c12016-02-17 11:10:04 +0100784
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000785 if (header.timestamp == retransmitted_timestamp_) {
786 EXPECT_EQ(retransmission_ssrc_, header.ssrc);
787 EXPECT_EQ(retransmission_payload_type_, header.payloadType);
788 frame_retransmitted_ = true;
789 return SEND_PACKET;
790 }
791
Stefan Holmer10880012016-02-03 13:29:59 +0100792 EXPECT_EQ(kVideoSendSsrcs[0], header.ssrc)
Danil Chapovalov18c65a42016-06-29 15:29:34 +0200793 << "Unexpected packet length " << length
794 << ", header_length " << header.headerLength
795 << ", padding_length " << header.paddingLength
796 << ", timestamp " << header.timestamp
797 << ", expected timestamp " << retransmitted_timestamp_
798 << ", payload type " << static_cast<int>(header.payloadType);
Shao Changbine62202f2015-04-21 20:24:50 +0800799 EXPECT_EQ(payload_type_, header.payloadType);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000800
Stefan Holmer586b19b2015-09-18 11:14:31 +0200801 // Found the final packet of the frame to inflict loss to, drop this and
802 // expect a retransmission.
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000803 if (header.markerBit && ++marker_bits_observed_ == kDroppedFrameNumber) {
Danil Chapovalov18c65a42016-06-29 15:29:34 +0200804 // This should be the only dropped packet.
805 EXPECT_EQ(0u, retransmitted_timestamp_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000806 retransmitted_timestamp_ = header.timestamp;
807 return DROP_PACKET;
808 }
809
810 return SEND_PACKET;
811 }
812
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -0700813 void FrameCallback(VideoFrame* frame) override {
Peter Boströmf2f82832015-05-01 13:00:41 +0200814 rtc::CritScope lock(&crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000815 if (frame->timestamp() == retransmitted_timestamp_) {
816 EXPECT_TRUE(frame_retransmitted_);
Peter Boström5811a392015-12-10 13:02:50 +0100817 observation_complete_.Set();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000818 }
819 }
820
stefanff483612015-12-21 03:14:00 -0800821 void ModifyVideoConfigs(
822 VideoSendStream::Config* send_config,
823 std::vector<VideoReceiveStream::Config>* receive_configs,
824 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000825 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000826 (*receive_configs)[0].pre_render_callback = this;
827 (*receive_configs)[0].rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
Shao Changbine62202f2015-04-21 20:24:50 +0800828
829 if (payload_type_ == kRedPayloadType) {
830 send_config->rtp.fec.ulpfec_payload_type = kUlpfecPayloadType;
831 send_config->rtp.fec.red_payload_type = kRedPayloadType;
Stefan Holmer10880012016-02-03 13:29:59 +0100832 if (retransmission_ssrc_ == kSendRtxSsrcs[0])
833 send_config->rtp.fec.red_rtx_payload_type = kRtxRedPayloadType;
834 (*receive_configs)[0].rtp.fec.ulpfec_payload_type =
835 send_config->rtp.fec.ulpfec_payload_type;
836 (*receive_configs)[0].rtp.fec.red_payload_type =
837 send_config->rtp.fec.red_payload_type;
838 (*receive_configs)[0].rtp.fec.red_rtx_payload_type =
839 send_config->rtp.fec.red_rtx_payload_type;
Shao Changbine62202f2015-04-21 20:24:50 +0800840 }
841
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +0000842 if (retransmission_ssrc_ == kSendRtxSsrcs[0]) {
843 send_config->rtp.rtx.ssrcs.push_back(kSendRtxSsrcs[0]);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000844 send_config->rtp.rtx.payload_type = kSendRtxPayloadType;
Stefan Holmer10880012016-02-03 13:29:59 +0100845 (*receive_configs)[0].rtp.rtx[payload_type_].ssrc = kSendRtxSsrcs[0];
846 (*receive_configs)[0].rtp.rtx[payload_type_].payload_type =
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000847 kSendRtxPayloadType;
848 }
Peter Boström39593972016-02-15 11:27:15 +0100849 // Configure encoding and decoding with VP8, since generic packetization
850 // doesn't support FEC with NACK.
851 RTC_DCHECK_EQ(1u, (*receive_configs)[0].decoders.size());
852 send_config->encoder_settings.encoder = encoder_.get();
853 send_config->encoder_settings.payload_name = "VP8";
854 (*receive_configs)[0].decoders[0].payload_name = "VP8";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000855 }
856
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000857 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100858 EXPECT_TRUE(Wait())
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000859 << "Timed out while waiting for retransmission to render.";
860 }
861
Shao Changbine62202f2015-04-21 20:24:50 +0800862 int GetPayloadType(bool use_rtx, bool use_red) {
Stefan Holmer10880012016-02-03 13:29:59 +0100863 if (use_red) {
864 if (use_rtx)
865 return kRtxRedPayloadType;
866 return kRedPayloadType;
867 }
868 if (use_rtx)
869 return kSendRtxPayloadType;
870 return kFakeVideoSendPayloadType;
Shao Changbine62202f2015-04-21 20:24:50 +0800871 }
872
stefanf116bd02015-10-27 08:29:42 -0700873 rtc::CriticalSection crit_;
Shao Changbine62202f2015-04-21 20:24:50 +0800874 const int payload_type_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000875 const uint32_t retransmission_ssrc_;
876 const int retransmission_payload_type_;
kwiberg27f982b2016-03-01 11:52:33 -0800877 std::unique_ptr<VideoEncoder> encoder_;
Peter Boström39593972016-02-15 11:27:15 +0100878 const std::string payload_name_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000879 int marker_bits_observed_;
stefanf116bd02015-10-27 08:29:42 -0700880 uint32_t retransmitted_timestamp_ GUARDED_BY(&crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000881 bool frame_retransmitted_;
Peter Boström39593972016-02-15 11:27:15 +0100882 } test(enable_rtx, enable_red);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000883
stefane74eef12016-01-08 06:47:13 -0800884 RunBaseTest(&test);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000885}
886
887TEST_F(EndToEndTest, DecodesRetransmittedFrame) {
Shao Changbine62202f2015-04-21 20:24:50 +0800888 DecodesRetransmittedFrame(false, false);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000889}
890
891TEST_F(EndToEndTest, DecodesRetransmittedFrameOverRtx) {
Shao Changbine62202f2015-04-21 20:24:50 +0800892 DecodesRetransmittedFrame(true, false);
893}
894
895TEST_F(EndToEndTest, DecodesRetransmittedFrameByRed) {
896 DecodesRetransmittedFrame(false, true);
897}
898
899TEST_F(EndToEndTest, DecodesRetransmittedFrameByRedOverRtx) {
900 DecodesRetransmittedFrame(true, true);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000901}
902
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000903void EndToEndTest::ReceivesPliAndRecovers(int rtp_history_ms) {
904 static const int kPacketsToDrop = 1;
905
nisse7ade7b32016-03-23 04:48:10 -0700906 class PliObserver : public test::EndToEndTest,
907 public rtc::VideoSinkInterface<VideoFrame> {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000908 public:
909 explicit PliObserver(int rtp_history_ms)
910 : EndToEndTest(kLongTimeoutMs),
911 rtp_history_ms_(rtp_history_ms),
912 nack_enabled_(rtp_history_ms > 0),
913 highest_dropped_timestamp_(0),
914 frames_to_drop_(0),
915 received_pli_(false) {}
916
917 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000918 Action OnSendRtp(const uint8_t* packet, size_t length) override {
stefanf116bd02015-10-27 08:29:42 -0700919 rtc::CritScope lock(&crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000920 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +0000921 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000922
923 // Drop all retransmitted packets to force a PLI.
924 if (header.timestamp <= highest_dropped_timestamp_)
925 return DROP_PACKET;
926
927 if (frames_to_drop_ > 0) {
928 highest_dropped_timestamp_ = header.timestamp;
929 --frames_to_drop_;
930 return DROP_PACKET;
931 }
932
933 return SEND_PACKET;
934 }
935
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000936 Action OnReceiveRtcp(const uint8_t* packet, size_t length) override {
stefanf116bd02015-10-27 08:29:42 -0700937 rtc::CritScope lock(&crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000938 RTCPUtility::RTCPParserV2 parser(packet, length, true);
939 EXPECT_TRUE(parser.IsValid());
940
941 for (RTCPUtility::RTCPPacketTypes packet_type = parser.Begin();
Erik Språng242e22b2015-05-11 10:17:43 +0200942 packet_type != RTCPUtility::RTCPPacketTypes::kInvalid;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000943 packet_type = parser.Iterate()) {
944 if (!nack_enabled_)
Erik Språng242e22b2015-05-11 10:17:43 +0200945 EXPECT_NE(packet_type, RTCPUtility::RTCPPacketTypes::kRtpfbNack);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000946
Erik Språng242e22b2015-05-11 10:17:43 +0200947 if (packet_type == RTCPUtility::RTCPPacketTypes::kPsfbPli) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000948 received_pli_ = true;
949 break;
950 }
951 }
952 return SEND_PACKET;
953 }
954
nisseeb83a1a2016-03-21 01:27:56 -0700955 void OnFrame(const VideoFrame& video_frame) override {
Peter Boströmf2f82832015-05-01 13:00:41 +0200956 rtc::CritScope lock(&crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000957 if (received_pli_ &&
958 video_frame.timestamp() > highest_dropped_timestamp_) {
Peter Boström5811a392015-12-10 13:02:50 +0100959 observation_complete_.Set();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000960 }
961 if (!received_pli_)
962 frames_to_drop_ = kPacketsToDrop;
963 }
964
stefanff483612015-12-21 03:14:00 -0800965 void ModifyVideoConfigs(
966 VideoSendStream::Config* send_config,
967 std::vector<VideoReceiveStream::Config>* receive_configs,
968 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000969 send_config->rtp.nack.rtp_history_ms = rtp_history_ms_;
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +0000970 (*receive_configs)[0].rtp.nack.rtp_history_ms = rtp_history_ms_;
971 (*receive_configs)[0].renderer = this;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000972 }
973
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +0000974 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +0100975 EXPECT_TRUE(Wait()) << "Timed out waiting for PLI to be "
976 "received and a frame to be "
977 "rendered afterwards.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000978 }
979
stefanf116bd02015-10-27 08:29:42 -0700980 rtc::CriticalSection crit_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000981 int rtp_history_ms_;
982 bool nack_enabled_;
stefanf116bd02015-10-27 08:29:42 -0700983 uint32_t highest_dropped_timestamp_ GUARDED_BY(&crit_);
984 int frames_to_drop_ GUARDED_BY(&crit_);
985 bool received_pli_ GUARDED_BY(&crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000986 } test(rtp_history_ms);
987
stefane74eef12016-01-08 06:47:13 -0800988 RunBaseTest(&test);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000989}
990
991TEST_F(EndToEndTest, ReceivesPliAndRecoversWithNack) {
992 ReceivesPliAndRecovers(1000);
993}
994
jbauchdb81ffd2015-11-23 03:59:02 -0800995TEST_F(EndToEndTest, ReceivesPliAndRecoversWithoutNack) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +0000996 ReceivesPliAndRecovers(0);
997}
998
999TEST_F(EndToEndTest, UnknownRtpPacketGivesUnknownSsrcReturnCode) {
1000 class PacketInputObserver : public PacketReceiver {
1001 public:
1002 explicit PacketInputObserver(PacketReceiver* receiver)
Peter Boström5811a392015-12-10 13:02:50 +01001003 : receiver_(receiver), delivered_packet_(false, false) {}
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001004
Peter Boström5811a392015-12-10 13:02:50 +01001005 bool Wait() { return delivered_packet_.Wait(kDefaultTimeoutMs); }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001006
1007 private:
stefan68786d22015-09-08 05:36:15 -07001008 DeliveryStatus DeliverPacket(MediaType media_type,
1009 const uint8_t* packet,
1010 size_t length,
1011 const PacketTime& packet_time) override {
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00001012 if (RtpHeaderParser::IsRtcp(packet, length)) {
stefan68786d22015-09-08 05:36:15 -07001013 return receiver_->DeliverPacket(media_type, packet, length,
1014 packet_time);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001015 } else {
1016 DeliveryStatus delivery_status =
stefan68786d22015-09-08 05:36:15 -07001017 receiver_->DeliverPacket(media_type, packet, length, packet_time);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001018 EXPECT_EQ(DELIVERY_UNKNOWN_SSRC, delivery_status);
Peter Boström5811a392015-12-10 13:02:50 +01001019 delivered_packet_.Set();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001020 return delivery_status;
1021 }
1022 }
1023
1024 PacketReceiver* receiver_;
Peter Boström5811a392015-12-10 13:02:50 +01001025 rtc::Event delivered_packet_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001026 };
1027
solenberg4fbae2b2015-08-28 04:07:10 -07001028 CreateCalls(Call::Config(), Call::Config());
1029
stefanf116bd02015-10-27 08:29:42 -07001030 test::DirectTransport send_transport(sender_call_.get());
1031 test::DirectTransport receive_transport(receiver_call_.get());
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001032 PacketInputObserver input_observer(receiver_call_->Receiver());
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001033 send_transport.SetReceiver(&input_observer);
1034 receive_transport.SetReceiver(sender_call_->Receiver());
1035
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001036 CreateSendConfig(1, 0, &send_transport);
solenberg4fbae2b2015-08-28 04:07:10 -07001037 CreateMatchingReceiveConfigs(&receive_transport);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001038
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001039 CreateVideoStreams();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001040 CreateFrameGeneratorCapturer();
1041 Start();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001042
stefanff483612015-12-21 03:14:00 -08001043 receiver_call_->DestroyVideoReceiveStream(video_receive_streams_[0]);
1044 video_receive_streams_.clear();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001045
1046 // Wait() waits for a received packet.
Peter Boström5811a392015-12-10 13:02:50 +01001047 EXPECT_TRUE(input_observer.Wait());
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001048
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001049 Stop();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001050
1051 DestroyStreams();
1052
1053 send_transport.StopSending();
1054 receive_transport.StopSending();
1055}
1056
pbosda903ea2015-10-02 02:36:56 -07001057void EndToEndTest::RespectsRtcpMode(RtcpMode rtcp_mode) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001058 static const int kNumCompoundRtcpPacketsToObserve = 10;
1059 class RtcpModeObserver : public test::EndToEndTest {
1060 public:
pbosda903ea2015-10-02 02:36:56 -07001061 explicit RtcpModeObserver(RtcpMode rtcp_mode)
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001062 : EndToEndTest(kDefaultTimeoutMs),
1063 rtcp_mode_(rtcp_mode),
1064 sent_rtp_(0),
1065 sent_rtcp_(0) {}
1066
1067 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001068 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001069 if (++sent_rtp_ % 3 == 0)
1070 return DROP_PACKET;
1071
1072 return SEND_PACKET;
1073 }
1074
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001075 Action OnReceiveRtcp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001076 ++sent_rtcp_;
1077 RTCPUtility::RTCPParserV2 parser(packet, length, true);
1078 EXPECT_TRUE(parser.IsValid());
1079
1080 RTCPUtility::RTCPPacketTypes packet_type = parser.Begin();
1081 bool has_report_block = false;
Erik Språng242e22b2015-05-11 10:17:43 +02001082 while (packet_type != RTCPUtility::RTCPPacketTypes::kInvalid) {
1083 EXPECT_NE(RTCPUtility::RTCPPacketTypes::kSr, packet_type);
1084 if (packet_type == RTCPUtility::RTCPPacketTypes::kRr) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001085 has_report_block = true;
1086 break;
1087 }
1088 packet_type = parser.Iterate();
1089 }
1090
1091 switch (rtcp_mode_) {
pbosda903ea2015-10-02 02:36:56 -07001092 case RtcpMode::kCompound:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001093 if (!has_report_block) {
1094 ADD_FAILURE() << "Received RTCP packet without receiver report for "
pbosda903ea2015-10-02 02:36:56 -07001095 "RtcpMode::kCompound.";
Peter Boström5811a392015-12-10 13:02:50 +01001096 observation_complete_.Set();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001097 }
1098
1099 if (sent_rtcp_ >= kNumCompoundRtcpPacketsToObserve)
Peter Boström5811a392015-12-10 13:02:50 +01001100 observation_complete_.Set();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001101
1102 break;
pbosda903ea2015-10-02 02:36:56 -07001103 case RtcpMode::kReducedSize:
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001104 if (!has_report_block)
Peter Boström5811a392015-12-10 13:02:50 +01001105 observation_complete_.Set();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001106 break;
pbosda903ea2015-10-02 02:36:56 -07001107 case RtcpMode::kOff:
1108 RTC_NOTREACHED();
1109 break;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001110 }
1111
1112 return SEND_PACKET;
1113 }
1114
stefanff483612015-12-21 03:14:00 -08001115 void ModifyVideoConfigs(
1116 VideoSendStream::Config* send_config,
1117 std::vector<VideoReceiveStream::Config>* receive_configs,
1118 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001119 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001120 (*receive_configs)[0].rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
1121 (*receive_configs)[0].rtp.rtcp_mode = rtcp_mode_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001122 }
1123
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001124 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001125 EXPECT_TRUE(Wait())
pbosda903ea2015-10-02 02:36:56 -07001126 << (rtcp_mode_ == RtcpMode::kCompound
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001127 ? "Timed out before observing enough compound packets."
1128 : "Timed out before receiving a non-compound RTCP packet.");
1129 }
1130
pbosda903ea2015-10-02 02:36:56 -07001131 RtcpMode rtcp_mode_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001132 int sent_rtp_;
1133 int sent_rtcp_;
1134 } test(rtcp_mode);
1135
stefane74eef12016-01-08 06:47:13 -08001136 RunBaseTest(&test);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001137}
1138
1139TEST_F(EndToEndTest, UsesRtcpCompoundMode) {
pbosda903ea2015-10-02 02:36:56 -07001140 RespectsRtcpMode(RtcpMode::kCompound);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001141}
1142
1143TEST_F(EndToEndTest, UsesRtcpReducedSizeMode) {
pbosda903ea2015-10-02 02:36:56 -07001144 RespectsRtcpMode(RtcpMode::kReducedSize);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001145}
1146
1147// Test sets up a Call multiple senders with different resolutions and SSRCs.
1148// Another is set up to receive all three of these with different renderers.
sprang867fb522015-08-03 04:38:41 -07001149class MultiStreamTest {
1150 public:
1151 static const size_t kNumStreams = 3;
1152 struct CodecSettings {
1153 uint32_t ssrc;
1154 int width;
1155 int height;
1156 } codec_settings[kNumStreams];
1157
1158 MultiStreamTest() {
1159 // TODO(sprang): Cleanup when msvc supports explicit initializers for array.
1160 codec_settings[0] = {1, 640, 480};
1161 codec_settings[1] = {2, 320, 240};
1162 codec_settings[2] = {3, 240, 160};
1163 }
1164
1165 virtual ~MultiStreamTest() {}
1166
1167 void RunTest() {
kwiberg27f982b2016-03-01 11:52:33 -08001168 std::unique_ptr<Call> sender_call(Call::Create(Call::Config()));
1169 std::unique_ptr<Call> receiver_call(Call::Create(Call::Config()));
1170 std::unique_ptr<test::DirectTransport> sender_transport(
stefanf116bd02015-10-27 08:29:42 -07001171 CreateSendTransport(sender_call.get()));
kwiberg27f982b2016-03-01 11:52:33 -08001172 std::unique_ptr<test::DirectTransport> receiver_transport(
stefanf116bd02015-10-27 08:29:42 -07001173 CreateReceiveTransport(receiver_call.get()));
sprang867fb522015-08-03 04:38:41 -07001174 sender_transport->SetReceiver(receiver_call->Receiver());
1175 receiver_transport->SetReceiver(sender_call->Receiver());
1176
kwiberg27f982b2016-03-01 11:52:33 -08001177 std::unique_ptr<VideoEncoder> encoders[kNumStreams];
sprang867fb522015-08-03 04:38:41 -07001178 for (size_t i = 0; i < kNumStreams; ++i)
1179 encoders[i].reset(VideoEncoder::Create(VideoEncoder::kVp8));
1180
1181 VideoSendStream* send_streams[kNumStreams];
1182 VideoReceiveStream* receive_streams[kNumStreams];
1183
1184 test::FrameGeneratorCapturer* frame_generators[kNumStreams];
kwiberg4a206a92016-03-31 10:24:26 -07001185 std::vector<std::unique_ptr<VideoDecoder>> allocated_decoders;
sprang867fb522015-08-03 04:38:41 -07001186 for (size_t i = 0; i < kNumStreams; ++i) {
1187 uint32_t ssrc = codec_settings[i].ssrc;
1188 int width = codec_settings[i].width;
1189 int height = codec_settings[i].height;
1190
solenberg4fbae2b2015-08-28 04:07:10 -07001191 VideoSendStream::Config send_config(sender_transport.get());
sprang867fb522015-08-03 04:38:41 -07001192 send_config.rtp.ssrcs.push_back(ssrc);
1193 send_config.encoder_settings.encoder = encoders[i].get();
1194 send_config.encoder_settings.payload_name = "VP8";
1195 send_config.encoder_settings.payload_type = 124;
1196 VideoEncoderConfig encoder_config;
1197 encoder_config.streams = test::CreateVideoStreams(1);
1198 VideoStream* stream = &encoder_config.streams[0];
1199 stream->width = width;
1200 stream->height = height;
1201 stream->max_framerate = 5;
1202 stream->min_bitrate_bps = stream->target_bitrate_bps =
1203 stream->max_bitrate_bps = 100000;
1204
1205 UpdateSendConfig(i, &send_config, &encoder_config, &frame_generators[i]);
1206
1207 send_streams[i] =
1208 sender_call->CreateVideoSendStream(send_config, encoder_config);
1209 send_streams[i]->Start();
1210
solenberg4fbae2b2015-08-28 04:07:10 -07001211 VideoReceiveStream::Config receive_config(receiver_transport.get());
sprang867fb522015-08-03 04:38:41 -07001212 receive_config.rtp.remote_ssrc = ssrc;
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001213 receive_config.rtp.local_ssrc = test::CallTest::kReceiverLocalVideoSsrc;
sprang867fb522015-08-03 04:38:41 -07001214 VideoReceiveStream::Decoder decoder =
1215 test::CreateMatchingDecoder(send_config.encoder_settings);
kwiberg4a206a92016-03-31 10:24:26 -07001216 allocated_decoders.push_back(
1217 std::unique_ptr<VideoDecoder>(decoder.decoder));
sprang867fb522015-08-03 04:38:41 -07001218 receive_config.decoders.push_back(decoder);
1219
1220 UpdateReceiveConfig(i, &receive_config);
1221
1222 receive_streams[i] =
Tommi733b5472016-06-10 17:58:01 +02001223 receiver_call->CreateVideoReceiveStream(std::move(receive_config));
sprang867fb522015-08-03 04:38:41 -07001224 receive_streams[i]->Start();
1225
1226 frame_generators[i] = test::FrameGeneratorCapturer::Create(
1227 send_streams[i]->Input(), width, height, 30,
1228 Clock::GetRealTimeClock());
1229 frame_generators[i]->Start();
1230 }
1231
1232 Wait();
1233
1234 for (size_t i = 0; i < kNumStreams; ++i) {
1235 frame_generators[i]->Stop();
1236 sender_call->DestroyVideoSendStream(send_streams[i]);
1237 receiver_call->DestroyVideoReceiveStream(receive_streams[i]);
1238 delete frame_generators[i];
1239 }
1240
1241 sender_transport->StopSending();
1242 receiver_transport->StopSending();
1243 }
1244
1245 protected:
1246 virtual void Wait() = 0;
1247 // Note: frame_generator is a point-to-pointer, since the actual instance
1248 // hasn't been created at the time of this call. Only when packets/frames
1249 // start flowing should this be dereferenced.
1250 virtual void UpdateSendConfig(
1251 size_t stream_index,
1252 VideoSendStream::Config* send_config,
1253 VideoEncoderConfig* encoder_config,
1254 test::FrameGeneratorCapturer** frame_generator) {}
1255 virtual void UpdateReceiveConfig(size_t stream_index,
1256 VideoReceiveStream::Config* receive_config) {
1257 }
stefanf116bd02015-10-27 08:29:42 -07001258 virtual test::DirectTransport* CreateSendTransport(Call* sender_call) {
1259 return new test::DirectTransport(sender_call);
sprang867fb522015-08-03 04:38:41 -07001260 }
stefanf116bd02015-10-27 08:29:42 -07001261 virtual test::DirectTransport* CreateReceiveTransport(Call* receiver_call) {
1262 return new test::DirectTransport(receiver_call);
sprang867fb522015-08-03 04:38:41 -07001263 }
1264};
1265
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001266// Each renderer verifies that it receives the expected resolution, and as soon
1267// as every renderer has received a frame, the test finishes.
andresp@webrtc.org02686112014-09-19 08:24:19 +00001268TEST_F(EndToEndTest, SendsAndReceivesMultipleStreams) {
nisse7ade7b32016-03-23 04:48:10 -07001269 class VideoOutputObserver : public rtc::VideoSinkInterface<VideoFrame> {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001270 public:
sprang867fb522015-08-03 04:38:41 -07001271 VideoOutputObserver(const MultiStreamTest::CodecSettings& settings,
1272 uint32_t ssrc,
1273 test::FrameGeneratorCapturer** frame_generator)
1274 : settings_(settings),
1275 ssrc_(ssrc),
1276 frame_generator_(frame_generator),
Peter Boström5811a392015-12-10 13:02:50 +01001277 done_(false, false) {}
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001278
nisseeb83a1a2016-03-21 01:27:56 -07001279 void OnFrame(const VideoFrame& video_frame) override {
sprang867fb522015-08-03 04:38:41 -07001280 EXPECT_EQ(settings_.width, video_frame.width());
1281 EXPECT_EQ(settings_.height, video_frame.height());
1282 (*frame_generator_)->Stop();
Peter Boström5811a392015-12-10 13:02:50 +01001283 done_.Set();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001284 }
1285
sprang867fb522015-08-03 04:38:41 -07001286 uint32_t Ssrc() { return ssrc_; }
1287
Peter Boström5811a392015-12-10 13:02:50 +01001288 bool Wait() { return done_.Wait(kDefaultTimeoutMs); }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001289
1290 private:
sprang867fb522015-08-03 04:38:41 -07001291 const MultiStreamTest::CodecSettings& settings_;
1292 const uint32_t ssrc_;
1293 test::FrameGeneratorCapturer** const frame_generator_;
Peter Boström5811a392015-12-10 13:02:50 +01001294 rtc::Event done_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001295 };
1296
sprang867fb522015-08-03 04:38:41 -07001297 class Tester : public MultiStreamTest {
1298 public:
1299 Tester() {}
1300 virtual ~Tester() {}
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001301
sprang867fb522015-08-03 04:38:41 -07001302 protected:
1303 void Wait() override {
1304 for (const auto& observer : observers_) {
Peter Boström5811a392015-12-10 13:02:50 +01001305 EXPECT_TRUE(observer->Wait()) << "Time out waiting for from on ssrc "
1306 << observer->Ssrc();
sprang867fb522015-08-03 04:38:41 -07001307 }
1308 }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001309
sprang867fb522015-08-03 04:38:41 -07001310 void UpdateSendConfig(
1311 size_t stream_index,
1312 VideoSendStream::Config* send_config,
1313 VideoEncoderConfig* encoder_config,
1314 test::FrameGeneratorCapturer** frame_generator) override {
1315 observers_[stream_index].reset(new VideoOutputObserver(
1316 codec_settings[stream_index], send_config->rtp.ssrcs.front(),
1317 frame_generator));
1318 }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001319
sprang867fb522015-08-03 04:38:41 -07001320 void UpdateReceiveConfig(
1321 size_t stream_index,
1322 VideoReceiveStream::Config* receive_config) override {
1323 receive_config->renderer = observers_[stream_index].get();
1324 }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001325
sprang867fb522015-08-03 04:38:41 -07001326 private:
kwiberg27f982b2016-03-01 11:52:33 -08001327 std::unique_ptr<VideoOutputObserver> observers_[kNumStreams];
sprang867fb522015-08-03 04:38:41 -07001328 } tester;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001329
sprang867fb522015-08-03 04:38:41 -07001330 tester.RunTest();
1331}
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001332
sprang867fb522015-08-03 04:38:41 -07001333TEST_F(EndToEndTest, AssignsTransportSequenceNumbers) {
sprang867fb522015-08-03 04:38:41 -07001334 static const int kExtensionId = 5;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001335
sprang867fb522015-08-03 04:38:41 -07001336 class RtpExtensionHeaderObserver : public test::DirectTransport {
1337 public:
stefanf116bd02015-10-27 08:29:42 -07001338 RtpExtensionHeaderObserver(Call* sender_call,
1339 const uint32_t& first_media_ssrc,
sprang861c55e2015-10-16 10:01:21 -07001340 const std::map<uint32_t, uint32_t>& ssrc_map)
stefanf116bd02015-10-27 08:29:42 -07001341 : DirectTransport(sender_call),
Peter Boström5811a392015-12-10 13:02:50 +01001342 done_(false, false),
sprang867fb522015-08-03 04:38:41 -07001343 parser_(RtpHeaderParser::Create()),
sprang861c55e2015-10-16 10:01:21 -07001344 first_media_ssrc_(first_media_ssrc),
1345 rtx_to_media_ssrcs_(ssrc_map),
sprang867fb522015-08-03 04:38:41 -07001346 padding_observed_(false),
sprang861c55e2015-10-16 10:01:21 -07001347 rtx_padding_observed_(false),
1348 retransmit_observed_(false),
1349 started_(false) {
sprang867fb522015-08-03 04:38:41 -07001350 parser_->RegisterRtpHeaderExtension(kRtpExtensionTransportSequenceNumber,
1351 kExtensionId);
1352 }
1353 virtual ~RtpExtensionHeaderObserver() {}
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001354
stefan1d8a5062015-10-02 03:39:33 -07001355 bool SendRtp(const uint8_t* data,
1356 size_t length,
1357 const PacketOptions& options) override {
sprang861c55e2015-10-16 10:01:21 -07001358 {
1359 rtc::CritScope cs(&lock_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001360
Erik Språng8d629712015-08-04 16:24:03 +02001361 if (IsDone())
sprang861c55e2015-10-16 10:01:21 -07001362 return false;
1363
1364 if (started_) {
1365 RTPHeader header;
1366 EXPECT_TRUE(parser_->Parse(data, length, &header));
1367 bool drop_packet = false;
1368
1369 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
1370 EXPECT_EQ(options.packet_id,
1371 header.extension.transportSequenceNumber);
1372 if (!streams_observed_.empty()) {
1373 // Unwrap packet id and verify uniqueness.
1374 int64_t packet_id = unwrapper_.Unwrap(options.packet_id);
1375 EXPECT_TRUE(received_packed_ids_.insert(packet_id).second);
1376 }
1377
1378 // Drop (up to) every 17th packet, so we get retransmits.
1379 // Only drop media, and not on the first stream (otherwise it will be
1380 // hard to distinguish from padding, which is always sent on the first
1381 // stream).
1382 if (header.payloadType != kSendRtxPayloadType &&
1383 header.ssrc != first_media_ssrc_ &&
1384 header.extension.transportSequenceNumber % 17 == 0) {
1385 dropped_seq_[header.ssrc].insert(header.sequenceNumber);
1386 drop_packet = true;
1387 }
1388
1389 size_t payload_length =
1390 length - (header.headerLength + header.paddingLength);
1391 if (payload_length == 0) {
1392 padding_observed_ = true;
1393 } else if (header.payloadType == kSendRtxPayloadType) {
1394 uint16_t original_sequence_number =
1395 ByteReader<uint16_t>::ReadBigEndian(&data[header.headerLength]);
1396 uint32_t original_ssrc =
1397 rtx_to_media_ssrcs_.find(header.ssrc)->second;
1398 std::set<uint16_t>* seq_no_map = &dropped_seq_[original_ssrc];
1399 auto it = seq_no_map->find(original_sequence_number);
1400 if (it != seq_no_map->end()) {
1401 retransmit_observed_ = true;
1402 seq_no_map->erase(it);
1403 } else {
1404 rtx_padding_observed_ = true;
1405 }
1406 } else {
1407 streams_observed_.insert(header.ssrc);
1408 }
1409
1410 if (IsDone())
Peter Boström5811a392015-12-10 13:02:50 +01001411 done_.Set();
sprang861c55e2015-10-16 10:01:21 -07001412
1413 if (drop_packet)
1414 return true;
1415 }
sprang867fb522015-08-03 04:38:41 -07001416 }
sprang861c55e2015-10-16 10:01:21 -07001417
stefan1d8a5062015-10-02 03:39:33 -07001418 return test::DirectTransport::SendRtp(data, length, options);
sprang867fb522015-08-03 04:38:41 -07001419 }
1420
Erik Språng8d629712015-08-04 16:24:03 +02001421 bool IsDone() {
sprang861c55e2015-10-16 10:01:21 -07001422 bool observed_types_ok =
1423 streams_observed_.size() == MultiStreamTest::kNumStreams &&
1424 padding_observed_ && retransmit_observed_ && rtx_padding_observed_;
1425 if (!observed_types_ok)
1426 return false;
1427 // We should not have any gaps in the sequence number range.
1428 size_t seqno_range =
1429 *received_packed_ids_.rbegin() - *received_packed_ids_.begin() + 1;
1430 return seqno_range == received_packed_ids_.size();
Erik Språng8d629712015-08-04 16:24:03 +02001431 }
1432
Peter Boström5811a392015-12-10 13:02:50 +01001433 bool Wait() {
sprang861c55e2015-10-16 10:01:21 -07001434 {
1435 // Can't be sure until this point that rtx_to_media_ssrcs_ etc have
1436 // been initialized and are OK to read.
1437 rtc::CritScope cs(&lock_);
1438 started_ = true;
1439 }
Peter Boström5811a392015-12-10 13:02:50 +01001440 return done_.Wait(kDefaultTimeoutMs);
sprang861c55e2015-10-16 10:01:21 -07001441 }
sprang867fb522015-08-03 04:38:41 -07001442
sprang861c55e2015-10-16 10:01:21 -07001443 rtc::CriticalSection lock_;
Peter Boström5811a392015-12-10 13:02:50 +01001444 rtc::Event done_;
kwiberg27f982b2016-03-01 11:52:33 -08001445 std::unique_ptr<RtpHeaderParser> parser_;
sprang861c55e2015-10-16 10:01:21 -07001446 SequenceNumberUnwrapper unwrapper_;
1447 std::set<int64_t> received_packed_ids_;
sprang867fb522015-08-03 04:38:41 -07001448 std::set<uint32_t> streams_observed_;
sprang861c55e2015-10-16 10:01:21 -07001449 std::map<uint32_t, std::set<uint16_t>> dropped_seq_;
1450 const uint32_t& first_media_ssrc_;
1451 const std::map<uint32_t, uint32_t>& rtx_to_media_ssrcs_;
sprang867fb522015-08-03 04:38:41 -07001452 bool padding_observed_;
1453 bool rtx_padding_observed_;
sprang861c55e2015-10-16 10:01:21 -07001454 bool retransmit_observed_;
1455 bool started_;
sprang867fb522015-08-03 04:38:41 -07001456 };
1457
1458 class TransportSequenceNumberTester : public MultiStreamTest {
1459 public:
sprang861c55e2015-10-16 10:01:21 -07001460 TransportSequenceNumberTester()
1461 : first_media_ssrc_(0), observer_(nullptr) {}
sprang867fb522015-08-03 04:38:41 -07001462 virtual ~TransportSequenceNumberTester() {}
1463
1464 protected:
1465 void Wait() override {
Peter Boström74f6e9e2016-04-04 17:56:10 +02001466 RTC_DCHECK(observer_);
Peter Boström5811a392015-12-10 13:02:50 +01001467 EXPECT_TRUE(observer_->Wait());
sprang867fb522015-08-03 04:38:41 -07001468 }
1469
1470 void UpdateSendConfig(
1471 size_t stream_index,
1472 VideoSendStream::Config* send_config,
1473 VideoEncoderConfig* encoder_config,
1474 test::FrameGeneratorCapturer** frame_generator) override {
1475 send_config->rtp.extensions.clear();
isheriff6f8d6862016-05-26 11:24:55 -07001476 send_config->rtp.extensions.push_back(RtpExtension(
1477 RtpExtension::kTransportSequenceNumberUri, kExtensionId));
sprang867fb522015-08-03 04:38:41 -07001478
1479 // Force some padding to be sent.
1480 const int kPaddingBitrateBps = 50000;
1481 int total_target_bitrate = 0;
1482 for (const VideoStream& stream : encoder_config->streams)
1483 total_target_bitrate += stream.target_bitrate_bps;
1484 encoder_config->min_transmit_bitrate_bps =
1485 total_target_bitrate + kPaddingBitrateBps;
1486
1487 // Configure RTX for redundant payload padding.
1488 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
sprang861c55e2015-10-16 10:01:21 -07001489 send_config->rtp.rtx.ssrcs.push_back(kSendRtxSsrcs[stream_index]);
sprang867fb522015-08-03 04:38:41 -07001490 send_config->rtp.rtx.payload_type = kSendRtxPayloadType;
sprang861c55e2015-10-16 10:01:21 -07001491 rtx_to_media_ssrcs_[kSendRtxSsrcs[stream_index]] =
1492 send_config->rtp.ssrcs[0];
1493
1494 if (stream_index == 0)
1495 first_media_ssrc_ = send_config->rtp.ssrcs[0];
sprang867fb522015-08-03 04:38:41 -07001496 }
1497
1498 void UpdateReceiveConfig(
1499 size_t stream_index,
1500 VideoReceiveStream::Config* receive_config) override {
sprang861c55e2015-10-16 10:01:21 -07001501 receive_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
sprang867fb522015-08-03 04:38:41 -07001502 receive_config->rtp.extensions.clear();
isheriff6f8d6862016-05-26 11:24:55 -07001503 receive_config->rtp.extensions.push_back(RtpExtension(
1504 RtpExtension::kTransportSequenceNumberUri, kExtensionId));
sprang867fb522015-08-03 04:38:41 -07001505 }
1506
stefanf116bd02015-10-27 08:29:42 -07001507 test::DirectTransport* CreateSendTransport(Call* sender_call) override {
1508 observer_ = new RtpExtensionHeaderObserver(sender_call, first_media_ssrc_,
sprang861c55e2015-10-16 10:01:21 -07001509 rtx_to_media_ssrcs_);
sprang867fb522015-08-03 04:38:41 -07001510 return observer_;
1511 }
1512
1513 private:
sprang861c55e2015-10-16 10:01:21 -07001514 uint32_t first_media_ssrc_;
1515 std::map<uint32_t, uint32_t> rtx_to_media_ssrcs_;
sprang867fb522015-08-03 04:38:41 -07001516 RtpExtensionHeaderObserver* observer_;
1517 } tester;
1518
1519 tester.RunTest();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001520}
1521
Stefan Holmer04cb7632016-01-14 20:34:30 +01001522class TransportFeedbackTester : public test::EndToEndTest {
1523 public:
1524 explicit TransportFeedbackTester(bool feedback_enabled,
1525 size_t num_video_streams,
1526 size_t num_audio_streams)
1527 : EndToEndTest(::webrtc::EndToEndTest::kDefaultTimeoutMs),
1528 feedback_enabled_(feedback_enabled),
1529 num_video_streams_(num_video_streams),
1530 num_audio_streams_(num_audio_streams) {
1531 // Only one stream of each supported for now.
1532 EXPECT_LE(num_video_streams, 1u);
1533 EXPECT_LE(num_audio_streams, 1u);
1534 }
1535
1536 protected:
1537 Action OnSendRtcp(const uint8_t* data, size_t length) override {
1538 EXPECT_FALSE(HasTransportFeedback(data, length));
1539 return SEND_PACKET;
1540 }
1541
1542 Action OnReceiveRtcp(const uint8_t* data, size_t length) override {
1543 if (HasTransportFeedback(data, length))
1544 observation_complete_.Set();
1545 return SEND_PACKET;
1546 }
1547
1548 bool HasTransportFeedback(const uint8_t* data, size_t length) const {
1549 RTCPUtility::RTCPParserV2 parser(data, length, true);
1550 EXPECT_TRUE(parser.IsValid());
1551
1552 RTCPUtility::RTCPPacketTypes packet_type = parser.Begin();
1553 while (packet_type != RTCPUtility::RTCPPacketTypes::kInvalid) {
1554 if (packet_type == RTCPUtility::RTCPPacketTypes::kTransportFeedback)
1555 return true;
1556 packet_type = parser.Iterate();
1557 }
1558
1559 return false;
1560 }
1561
1562 void PerformTest() override {
1563 const int64_t kDisabledFeedbackTimeoutMs = 5000;
1564 EXPECT_EQ(feedback_enabled_,
1565 observation_complete_.Wait(feedback_enabled_
1566 ? test::CallTest::kDefaultTimeoutMs
1567 : kDisabledFeedbackTimeoutMs));
1568 }
1569
1570 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1571 receiver_call_ = receiver_call;
1572 }
1573
1574 size_t GetNumVideoStreams() const override { return num_video_streams_; }
1575 size_t GetNumAudioStreams() const override { return num_audio_streams_; }
1576
1577 void ModifyVideoConfigs(
1578 VideoSendStream::Config* send_config,
1579 std::vector<VideoReceiveStream::Config>* receive_configs,
1580 VideoEncoderConfig* encoder_config) override {
1581 send_config->rtp.extensions.clear();
1582 send_config->rtp.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001583 RtpExtension(RtpExtension::kTransportSequenceNumberUri, kExtensionId));
Stefan Holmer04cb7632016-01-14 20:34:30 +01001584 (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
1585 (*receive_configs)[0].rtp.transport_cc = feedback_enabled_;
1586 }
1587
1588 void ModifyAudioConfigs(
1589 AudioSendStream::Config* send_config,
1590 std::vector<AudioReceiveStream::Config>* receive_configs) override {
1591 send_config->rtp.extensions.clear();
1592 send_config->rtp.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001593 RtpExtension(RtpExtension::kTransportSequenceNumberUri, kExtensionId));
Stefan Holmer04cb7632016-01-14 20:34:30 +01001594 (*receive_configs)[0].rtp.extensions.clear();
1595 (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
1596 (*receive_configs)[0].rtp.transport_cc = feedback_enabled_;
Stefan Holmer04cb7632016-01-14 20:34:30 +01001597 }
1598
1599 private:
Erik Språng6b8d3552015-09-24 15:06:57 +02001600 static const int kExtensionId = 5;
Stefan Holmer04cb7632016-01-14 20:34:30 +01001601 const bool feedback_enabled_;
1602 const size_t num_video_streams_;
1603 const size_t num_audio_streams_;
1604 Call* receiver_call_;
1605};
Erik Språng6b8d3552015-09-24 15:06:57 +02001606
Stefan Holmer04cb7632016-01-14 20:34:30 +01001607TEST_F(EndToEndTest, VideoReceivesTransportFeedback) {
1608 TransportFeedbackTester test(true, 1, 0);
1609 RunBaseTest(&test);
Erik Språng6b8d3552015-09-24 15:06:57 +02001610}
stefan43edf0f2015-11-20 18:05:48 -08001611
Stefan Holmer04cb7632016-01-14 20:34:30 +01001612TEST_F(EndToEndTest, VideoTransportFeedbackNotConfigured) {
1613 TransportFeedbackTester test(false, 1, 0);
1614 RunBaseTest(&test);
stefan43edf0f2015-11-20 18:05:48 -08001615}
1616
Stefan Holmer04cb7632016-01-14 20:34:30 +01001617TEST_F(EndToEndTest, AudioReceivesTransportFeedback) {
1618 TransportFeedbackTester test(true, 0, 1);
1619 RunBaseTest(&test);
1620}
1621
1622TEST_F(EndToEndTest, AudioTransportFeedbackNotConfigured) {
1623 TransportFeedbackTester test(false, 0, 1);
1624 RunBaseTest(&test);
1625}
1626
1627TEST_F(EndToEndTest, AudioVideoReceivesTransportFeedback) {
1628 TransportFeedbackTester test(true, 1, 1);
1629 RunBaseTest(&test);
stefan43edf0f2015-11-20 18:05:48 -08001630}
1631
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001632TEST_F(EndToEndTest, ObserversEncodedFrames) {
1633 class EncodedFrameTestObserver : public EncodedFrameObserver {
1634 public:
1635 EncodedFrameTestObserver()
Peter Boström5811a392015-12-10 13:02:50 +01001636 : length_(0), frame_type_(kEmptyFrame), called_(false, false) {}
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001637 virtual ~EncodedFrameTestObserver() {}
1638
1639 virtual void EncodedFrameCallback(const EncodedFrame& encoded_frame) {
1640 frame_type_ = encoded_frame.frame_type_;
1641 length_ = encoded_frame.length_;
1642 buffer_.reset(new uint8_t[length_]);
1643 memcpy(buffer_.get(), encoded_frame.data_, length_);
Peter Boström5811a392015-12-10 13:02:50 +01001644 called_.Set();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001645 }
1646
Peter Boström5811a392015-12-10 13:02:50 +01001647 bool Wait() { return called_.Wait(kDefaultTimeoutMs); }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001648
1649 void ExpectEqualFrames(const EncodedFrameTestObserver& observer) {
1650 ASSERT_EQ(length_, observer.length_)
1651 << "Observed frames are of different lengths.";
1652 EXPECT_EQ(frame_type_, observer.frame_type_)
1653 << "Observed frames have different frame types.";
1654 EXPECT_EQ(0, memcmp(buffer_.get(), observer.buffer_.get(), length_))
1655 << "Observed encoded frames have different content.";
1656 }
1657
1658 private:
kwiberg27f982b2016-03-01 11:52:33 -08001659 std::unique_ptr<uint8_t[]> buffer_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001660 size_t length_;
1661 FrameType frame_type_;
Peter Boström5811a392015-12-10 13:02:50 +01001662 rtc::Event called_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001663 };
1664
1665 EncodedFrameTestObserver post_encode_observer;
1666 EncodedFrameTestObserver pre_decode_observer;
1667
solenberg4fbae2b2015-08-28 04:07:10 -07001668 CreateCalls(Call::Config(), Call::Config());
1669
stefanf116bd02015-10-27 08:29:42 -07001670 test::DirectTransport sender_transport(sender_call_.get());
1671 test::DirectTransport receiver_transport(receiver_call_.get());
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001672 sender_transport.SetReceiver(receiver_call_->Receiver());
1673 receiver_transport.SetReceiver(sender_call_->Receiver());
1674
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001675 CreateSendConfig(1, 0, &sender_transport);
solenberg4fbae2b2015-08-28 04:07:10 -07001676 CreateMatchingReceiveConfigs(&receiver_transport);
stefanff483612015-12-21 03:14:00 -08001677 video_send_config_.post_encode_callback = &post_encode_observer;
1678 video_receive_configs_[0].pre_decode_callback = &pre_decode_observer;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001679
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001680 CreateVideoStreams();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001681 Start();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001682
kwiberg27f982b2016-03-01 11:52:33 -08001683 std::unique_ptr<test::FrameGenerator> frame_generator(
sprang@webrtc.org131bea82015-02-18 12:46:06 +00001684 test::FrameGenerator::CreateChromaGenerator(
stefanff483612015-12-21 03:14:00 -08001685 video_encoder_config_.streams[0].width,
1686 video_encoder_config_.streams[0].height));
1687 video_send_stream_->Input()->IncomingCapturedFrame(
1688 *frame_generator->NextFrame());
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001689
Peter Boström5811a392015-12-10 13:02:50 +01001690 EXPECT_TRUE(post_encode_observer.Wait())
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001691 << "Timed out while waiting for send-side encoded-frame callback.";
1692
Peter Boström5811a392015-12-10 13:02:50 +01001693 EXPECT_TRUE(pre_decode_observer.Wait())
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001694 << "Timed out while waiting for pre-decode encoded-frame callback.";
1695
1696 post_encode_observer.ExpectEqualFrames(pre_decode_observer);
1697
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00001698 Stop();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001699
1700 sender_transport.StopSending();
1701 receiver_transport.StopSending();
1702
1703 DestroyStreams();
1704}
1705
1706TEST_F(EndToEndTest, ReceiveStreamSendsRemb) {
1707 class RembObserver : public test::EndToEndTest {
1708 public:
1709 RembObserver() : EndToEndTest(kDefaultTimeoutMs) {}
1710
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001711 Action OnReceiveRtcp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001712 RTCPUtility::RTCPParserV2 parser(packet, length, true);
1713 EXPECT_TRUE(parser.IsValid());
1714
1715 bool received_psfb = false;
1716 bool received_remb = false;
1717 RTCPUtility::RTCPPacketTypes packet_type = parser.Begin();
Erik Språng242e22b2015-05-11 10:17:43 +02001718 while (packet_type != RTCPUtility::RTCPPacketTypes::kInvalid) {
1719 if (packet_type == RTCPUtility::RTCPPacketTypes::kPsfbRemb) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001720 const RTCPUtility::RTCPPacket& packet = parser.Packet();
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001721 EXPECT_EQ(packet.PSFBAPP.SenderSSRC, kReceiverLocalVideoSsrc);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001722 received_psfb = true;
Erik Språng242e22b2015-05-11 10:17:43 +02001723 } else if (packet_type == RTCPUtility::RTCPPacketTypes::kPsfbRembItem) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001724 const RTCPUtility::RTCPPacket& packet = parser.Packet();
1725 EXPECT_GT(packet.REMBItem.BitRate, 0u);
1726 EXPECT_EQ(packet.REMBItem.NumberOfSSRCs, 1u);
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001727 EXPECT_EQ(packet.REMBItem.SSRCs[0], kVideoSendSsrcs[0]);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001728 received_remb = true;
1729 }
1730 packet_type = parser.Iterate();
1731 }
1732 if (received_psfb && received_remb)
Peter Boström5811a392015-12-10 13:02:50 +01001733 observation_complete_.Set();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001734 return SEND_PACKET;
1735 }
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001736 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001737 EXPECT_TRUE(Wait()) << "Timed out while waiting for a "
1738 "receiver RTCP REMB packet to be "
1739 "sent.";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001740 }
1741 } test;
1742
stefane74eef12016-01-08 06:47:13 -08001743 RunBaseTest(&test);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00001744}
1745
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001746TEST_F(EndToEndTest, VerifyBandwidthStats) {
stefanf116bd02015-10-27 08:29:42 -07001747 class RtcpObserver : public test::EndToEndTest {
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001748 public:
1749 RtcpObserver()
1750 : EndToEndTest(kDefaultTimeoutMs),
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +00001751 sender_call_(nullptr),
1752 receiver_call_(nullptr),
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001753 has_seen_pacer_delay_(false) {}
1754
stefanf116bd02015-10-27 08:29:42 -07001755 Action OnSendRtp(const uint8_t* packet, size_t length) override {
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001756 Call::Stats sender_stats = sender_call_->GetStats();
1757 Call::Stats receiver_stats = receiver_call_->GetStats();
1758 if (!has_seen_pacer_delay_)
1759 has_seen_pacer_delay_ = sender_stats.pacer_delay_ms > 0;
1760 if (sender_stats.send_bandwidth_bps > 0 &&
pbos@webrtc.org2b19f062014-12-11 13:26:09 +00001761 receiver_stats.recv_bandwidth_bps > 0 && has_seen_pacer_delay_) {
Peter Boström5811a392015-12-10 13:02:50 +01001762 observation_complete_.Set();
pbos@webrtc.org2b19f062014-12-11 13:26:09 +00001763 }
stefanf116bd02015-10-27 08:29:42 -07001764 return SEND_PACKET;
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001765 }
1766
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001767 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001768 sender_call_ = sender_call;
1769 receiver_call_ = receiver_call;
1770 }
1771
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00001772 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01001773 EXPECT_TRUE(Wait()) << "Timed out while waiting for "
1774 "non-zero bandwidth stats.";
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001775 }
1776
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001777 private:
1778 Call* sender_call_;
1779 Call* receiver_call_;
1780 bool has_seen_pacer_delay_;
1781 } test;
1782
stefane74eef12016-01-08 06:47:13 -08001783 RunBaseTest(&test);
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00001784}
1785
stefan32f81542016-01-20 07:13:58 -08001786
1787// Verifies that it's possible to limit the send BWE by sending a REMB.
1788// This is verified by allowing the send BWE to ramp-up to >1000 kbps,
1789// then have the test generate a REMB of 500 kbps and verify that the send BWE
1790// is reduced to exactly 500 kbps. Then a REMB of 1000 kbps is generated and the
1791// test verifies that the send BWE ramps back up to exactly 1000 kbps.
1792TEST_F(EndToEndTest, RembWithSendSideBwe) {
1793 class BweObserver : public test::EndToEndTest {
1794 public:
1795 BweObserver()
1796 : EndToEndTest(kDefaultTimeoutMs),
1797 sender_call_(nullptr),
1798 clock_(Clock::GetRealTimeClock()),
1799 sender_ssrc_(0),
1800 remb_bitrate_bps_(1000000),
1801 receive_transport_(nullptr),
1802 event_(false, false),
1803 poller_thread_(&BitrateStatsPollingThread,
1804 this,
1805 "BitrateStatsPollingThread"),
1806 state_(kWaitForFirstRampUp) {}
1807
1808 ~BweObserver() {}
1809
nisseef8b61e2016-04-29 06:09:15 -07001810 test::PacketTransport* CreateReceiveTransport() override {
stefan32f81542016-01-20 07:13:58 -08001811 receive_transport_ = new test::PacketTransport(
1812 nullptr, this, test::PacketTransport::kReceiver,
1813 FakeNetworkPipe::Config());
1814 return receive_transport_;
1815 }
1816
1817 Call::Config GetSenderCallConfig() override {
1818 Call::Config config;
1819 // Set a high start bitrate to reduce the test completion time.
1820 config.bitrate_config.start_bitrate_bps = remb_bitrate_bps_;
1821 return config;
1822 }
1823
1824 void ModifyVideoConfigs(
1825 VideoSendStream::Config* send_config,
1826 std::vector<VideoReceiveStream::Config>* receive_configs,
1827 VideoEncoderConfig* encoder_config) override {
1828 ASSERT_EQ(1u, send_config->rtp.ssrcs.size());
1829 send_config->rtp.extensions.clear();
1830 send_config->rtp.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07001831 RtpExtension(RtpExtension::kTransportSequenceNumberUri,
stefan32f81542016-01-20 07:13:58 -08001832 test::kTransportSequenceNumberExtensionId));
1833 sender_ssrc_ = send_config->rtp.ssrcs[0];
1834
1835 encoder_config->streams[0].max_bitrate_bps =
1836 encoder_config->streams[0].target_bitrate_bps = 2000000;
1837
1838 ASSERT_EQ(1u, receive_configs->size());
1839 (*receive_configs)[0].rtp.remb = false;
1840 (*receive_configs)[0].rtp.transport_cc = true;
1841 (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
1842 RtpRtcp::Configuration config;
1843 config.receiver_only = true;
1844 config.clock = clock_;
1845 config.outgoing_transport = receive_transport_;
1846 rtp_rtcp_.reset(RtpRtcp::CreateRtpRtcp(config));
1847 rtp_rtcp_->SetRemoteSSRC((*receive_configs)[0].rtp.remote_ssrc);
1848 rtp_rtcp_->SetSSRC((*receive_configs)[0].rtp.local_ssrc);
1849 rtp_rtcp_->SetREMBStatus(true);
1850 rtp_rtcp_->SetSendingStatus(true);
1851 rtp_rtcp_->SetRTCPStatus(RtcpMode::kReducedSize);
1852 }
1853
1854 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
1855 sender_call_ = sender_call;
1856 }
1857
1858 static bool BitrateStatsPollingThread(void* obj) {
1859 return static_cast<BweObserver*>(obj)->PollStats();
1860 }
1861
1862 bool PollStats() {
1863 if (sender_call_) {
1864 Call::Stats stats = sender_call_->GetStats();
1865 switch (state_) {
1866 case kWaitForFirstRampUp:
1867 if (stats.send_bandwidth_bps >= remb_bitrate_bps_) {
1868 state_ = kWaitForRemb;
1869 remb_bitrate_bps_ /= 2;
1870 rtp_rtcp_->SetREMBData(
1871 remb_bitrate_bps_,
1872 std::vector<uint32_t>(&sender_ssrc_, &sender_ssrc_ + 1));
1873 rtp_rtcp_->SendRTCP(kRtcpRr);
1874 }
1875 break;
1876
1877 case kWaitForRemb:
1878 if (stats.send_bandwidth_bps == remb_bitrate_bps_) {
1879 state_ = kWaitForSecondRampUp;
1880 remb_bitrate_bps_ *= 2;
1881 rtp_rtcp_->SetREMBData(
1882 remb_bitrate_bps_,
1883 std::vector<uint32_t>(&sender_ssrc_, &sender_ssrc_ + 1));
1884 rtp_rtcp_->SendRTCP(kRtcpRr);
1885 }
1886 break;
1887
1888 case kWaitForSecondRampUp:
1889 if (stats.send_bandwidth_bps == remb_bitrate_bps_) {
1890 observation_complete_.Set();
1891 }
1892 break;
1893 }
1894 }
1895
1896 return !event_.Wait(1000);
1897 }
1898
1899 void PerformTest() override {
1900 poller_thread_.Start();
1901 EXPECT_TRUE(Wait())
1902 << "Timed out while waiting for bitrate to change according to REMB.";
1903 poller_thread_.Stop();
1904 }
1905
1906 private:
1907 enum TestState { kWaitForFirstRampUp, kWaitForRemb, kWaitForSecondRampUp };
1908
1909 Call* sender_call_;
1910 Clock* const clock_;
1911 uint32_t sender_ssrc_;
1912 int remb_bitrate_bps_;
kwiberg27f982b2016-03-01 11:52:33 -08001913 std::unique_ptr<RtpRtcp> rtp_rtcp_;
stefan32f81542016-01-20 07:13:58 -08001914 test::PacketTransport* receive_transport_;
1915 rtc::Event event_;
1916 rtc::PlatformThread poller_thread_;
1917 TestState state_;
1918 } test;
1919
1920 RunBaseTest(&test);
1921}
1922
Åsa Persson352b2d72015-04-15 18:00:40 +02001923TEST_F(EndToEndTest, VerifyNackStats) {
1924 static const int kPacketNumberToDrop = 200;
1925 class NackObserver : public test::EndToEndTest {
1926 public:
1927 NackObserver()
1928 : EndToEndTest(kLongTimeoutMs),
1929 sent_rtp_packets_(0),
1930 dropped_rtp_packet_(0),
1931 dropped_rtp_packet_requested_(false),
1932 send_stream_(nullptr),
1933 start_runtime_ms_(-1) {}
1934
1935 private:
1936 Action OnSendRtp(const uint8_t* packet, size_t length) override {
stefan608213e2015-11-01 14:56:10 -08001937 rtc::CritScope lock(&crit_);
Åsa Persson352b2d72015-04-15 18:00:40 +02001938 if (++sent_rtp_packets_ == kPacketNumberToDrop) {
kwiberg27f982b2016-03-01 11:52:33 -08001939 std::unique_ptr<RtpHeaderParser> parser(RtpHeaderParser::Create());
Åsa Persson352b2d72015-04-15 18:00:40 +02001940 RTPHeader header;
1941 EXPECT_TRUE(parser->Parse(packet, length, &header));
1942 dropped_rtp_packet_ = header.sequenceNumber;
1943 return DROP_PACKET;
1944 }
1945 VerifyStats();
1946 return SEND_PACKET;
1947 }
1948
1949 Action OnReceiveRtcp(const uint8_t* packet, size_t length) override {
stefan608213e2015-11-01 14:56:10 -08001950 rtc::CritScope lock(&crit_);
Åsa Persson352b2d72015-04-15 18:00:40 +02001951 test::RtcpPacketParser rtcp_parser;
1952 rtcp_parser.Parse(packet, length);
1953 std::vector<uint16_t> nacks = rtcp_parser.nack_item()->last_nack_list();
1954 if (!nacks.empty() && std::find(
1955 nacks.begin(), nacks.end(), dropped_rtp_packet_) != nacks.end()) {
1956 dropped_rtp_packet_requested_ = true;
1957 }
1958 return SEND_PACKET;
1959 }
1960
stefan608213e2015-11-01 14:56:10 -08001961 void VerifyStats() EXCLUSIVE_LOCKS_REQUIRED(&crit_) {
Åsa Persson352b2d72015-04-15 18:00:40 +02001962 if (!dropped_rtp_packet_requested_)
1963 return;
1964 int send_stream_nack_packets = 0;
1965 int receive_stream_nack_packets = 0;
1966 VideoSendStream::Stats stats = send_stream_->GetStats();
1967 for (std::map<uint32_t, VideoSendStream::StreamStats>::const_iterator it =
1968 stats.substreams.begin(); it != stats.substreams.end(); ++it) {
1969 const VideoSendStream::StreamStats& stream_stats = it->second;
1970 send_stream_nack_packets +=
1971 stream_stats.rtcp_packet_type_counts.nack_packets;
1972 }
1973 for (size_t i = 0; i < receive_streams_.size(); ++i) {
1974 VideoReceiveStream::Stats stats = receive_streams_[i]->GetStats();
1975 receive_stream_nack_packets +=
1976 stats.rtcp_packet_type_counts.nack_packets;
1977 }
Stefan Holmer9fea80f2016-01-07 17:43:18 +01001978 if (send_stream_nack_packets >= 1 && receive_stream_nack_packets >= 1) {
Åsa Persson352b2d72015-04-15 18:00:40 +02001979 // NACK packet sent on receive stream and received on sent stream.
1980 if (MinMetricRunTimePassed())
Peter Boström5811a392015-12-10 13:02:50 +01001981 observation_complete_.Set();
Åsa Persson352b2d72015-04-15 18:00:40 +02001982 }
1983 }
1984
1985 bool MinMetricRunTimePassed() {
1986 int64_t now = Clock::GetRealTimeClock()->TimeInMilliseconds();
1987 if (start_runtime_ms_ == -1) {
1988 start_runtime_ms_ = now;
1989 return false;
1990 }
1991 int64_t elapsed_sec = (now - start_runtime_ms_) / 1000;
1992 return elapsed_sec > metrics::kMinRunTimeInSeconds;
1993 }
1994
stefanff483612015-12-21 03:14:00 -08001995 void ModifyVideoConfigs(
1996 VideoSendStream::Config* send_config,
1997 std::vector<VideoReceiveStream::Config>* receive_configs,
1998 VideoEncoderConfig* encoder_config) override {
Åsa Persson352b2d72015-04-15 18:00:40 +02001999 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
2000 (*receive_configs)[0].rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
2001 }
2002
stefanff483612015-12-21 03:14:00 -08002003 void OnVideoStreamsCreated(
Åsa Persson352b2d72015-04-15 18:00:40 +02002004 VideoSendStream* send_stream,
2005 const std::vector<VideoReceiveStream*>& receive_streams) override {
2006 send_stream_ = send_stream;
2007 receive_streams_ = receive_streams;
2008 }
2009
2010 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002011 EXPECT_TRUE(Wait()) << "Timed out waiting for packet to be NACKed.";
Åsa Persson352b2d72015-04-15 18:00:40 +02002012 }
2013
stefan608213e2015-11-01 14:56:10 -08002014 rtc::CriticalSection crit_;
Åsa Persson352b2d72015-04-15 18:00:40 +02002015 uint64_t sent_rtp_packets_;
stefan608213e2015-11-01 14:56:10 -08002016 uint16_t dropped_rtp_packet_ GUARDED_BY(&crit_);
2017 bool dropped_rtp_packet_requested_ GUARDED_BY(&crit_);
Åsa Persson352b2d72015-04-15 18:00:40 +02002018 std::vector<VideoReceiveStream*> receive_streams_;
2019 VideoSendStream* send_stream_;
2020 int64_t start_runtime_ms_;
2021 } test;
2022
asapersson01d70a32016-05-20 06:29:46 -07002023 metrics::Reset();
stefane74eef12016-01-08 06:47:13 -08002024 RunBaseTest(&test);
Åsa Persson352b2d72015-04-15 18:00:40 +02002025
asapersson01d70a32016-05-20 06:29:46 -07002026 EXPECT_EQ(
2027 1, metrics::NumSamples("WebRTC.Video.UniqueNackRequestsSentInPercent"));
2028 EXPECT_EQ(1, metrics::NumSamples(
2029 "WebRTC.Video.UniqueNackRequestsReceivedInPercent"));
2030 EXPECT_GT(metrics::MinSample("WebRTC.Video.NackPacketsSentPerMinute"), 0);
Åsa Persson352b2d72015-04-15 18:00:40 +02002031}
2032
sprangb4a1ae52015-12-03 08:10:08 -08002033void EndToEndTest::VerifyHistogramStats(bool use_rtx,
2034 bool use_red,
2035 bool screenshare) {
tommi2e82f382016-06-21 00:26:43 -07002036 class StatsObserver : public test::EndToEndTest,
2037 public rtc::VideoSinkInterface<VideoFrame> {
Åsa Persson3c391cb2015-04-27 10:09:49 +02002038 public:
sprangb4a1ae52015-12-03 08:10:08 -08002039 StatsObserver(bool use_rtx, bool use_red, bool screenshare)
Åsa Persson3c391cb2015-04-27 10:09:49 +02002040 : EndToEndTest(kLongTimeoutMs),
2041 use_rtx_(use_rtx),
2042 use_red_(use_red),
sprangb4a1ae52015-12-03 08:10:08 -08002043 screenshare_(screenshare),
Peter Boström39593972016-02-15 11:27:15 +01002044 // This test uses NACK, so to send FEC we can't use a fake encoder.
2045 vp8_encoder_(
2046 use_red ? VideoEncoder::Create(VideoEncoder::EncoderType::kVp8)
2047 : nullptr),
Åsa Persson3c391cb2015-04-27 10:09:49 +02002048 sender_call_(nullptr),
2049 receiver_call_(nullptr),
2050 start_runtime_ms_(-1) {}
2051
2052 private:
tommi2e82f382016-06-21 00:26:43 -07002053 void OnFrame(const VideoFrame& video_frame) override {}
2054
Åsa Persson3c391cb2015-04-27 10:09:49 +02002055 Action OnSendRtp(const uint8_t* packet, size_t length) override {
2056 if (MinMetricRunTimePassed())
Peter Boström5811a392015-12-10 13:02:50 +01002057 observation_complete_.Set();
Åsa Persson3c391cb2015-04-27 10:09:49 +02002058
stefanf116bd02015-10-27 08:29:42 -07002059 return SEND_PACKET;
Åsa Persson3c391cb2015-04-27 10:09:49 +02002060 }
2061
2062 bool MinMetricRunTimePassed() {
2063 int64_t now = Clock::GetRealTimeClock()->TimeInMilliseconds();
2064 if (start_runtime_ms_ == -1) {
2065 start_runtime_ms_ = now;
2066 return false;
2067 }
2068 int64_t elapsed_sec = (now - start_runtime_ms_) / 1000;
2069 return elapsed_sec > metrics::kMinRunTimeInSeconds * 2;
2070 }
2071
stefanff483612015-12-21 03:14:00 -08002072 void ModifyVideoConfigs(
2073 VideoSendStream::Config* send_config,
2074 std::vector<VideoReceiveStream::Config>* receive_configs,
2075 VideoEncoderConfig* encoder_config) override {
Åsa Persson3c391cb2015-04-27 10:09:49 +02002076 // NACK
2077 send_config->rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
2078 (*receive_configs)[0].rtp.nack.rtp_history_ms = kNackRtpHistoryMs;
tommi2e82f382016-06-21 00:26:43 -07002079 (*receive_configs)[0].renderer = this;
Åsa Persson3c391cb2015-04-27 10:09:49 +02002080 // FEC
2081 if (use_red_) {
2082 send_config->rtp.fec.ulpfec_payload_type = kUlpfecPayloadType;
2083 send_config->rtp.fec.red_payload_type = kRedPayloadType;
Peter Boström39593972016-02-15 11:27:15 +01002084 send_config->encoder_settings.encoder = vp8_encoder_.get();
2085 send_config->encoder_settings.payload_name = "VP8";
2086 (*receive_configs)[0].decoders[0].payload_name = "VP8";
Åsa Persson3c391cb2015-04-27 10:09:49 +02002087 (*receive_configs)[0].rtp.fec.red_payload_type = kRedPayloadType;
2088 (*receive_configs)[0].rtp.fec.ulpfec_payload_type = kUlpfecPayloadType;
2089 }
2090 // RTX
2091 if (use_rtx_) {
2092 send_config->rtp.rtx.ssrcs.push_back(kSendRtxSsrcs[0]);
2093 send_config->rtp.rtx.payload_type = kSendRtxPayloadType;
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002094 (*receive_configs)[0].rtp.rtx[kFakeVideoSendPayloadType].ssrc =
Åsa Persson3c391cb2015-04-27 10:09:49 +02002095 kSendRtxSsrcs[0];
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002096 (*receive_configs)[0].rtp.rtx[kFakeVideoSendPayloadType].payload_type =
Åsa Persson3c391cb2015-04-27 10:09:49 +02002097 kSendRtxPayloadType;
2098 }
sprangb4a1ae52015-12-03 08:10:08 -08002099 encoder_config->content_type =
2100 screenshare_ ? VideoEncoderConfig::ContentType::kScreen
2101 : VideoEncoderConfig::ContentType::kRealtimeVideo;
Åsa Persson3c391cb2015-04-27 10:09:49 +02002102 }
2103
2104 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
2105 sender_call_ = sender_call;
2106 receiver_call_ = receiver_call;
2107 }
2108
Åsa Persson3c391cb2015-04-27 10:09:49 +02002109 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002110 EXPECT_TRUE(Wait()) << "Timed out waiting for packet to be NACKed.";
Åsa Persson3c391cb2015-04-27 10:09:49 +02002111 }
2112
sprangb4a1ae52015-12-03 08:10:08 -08002113 const bool use_rtx_;
2114 const bool use_red_;
2115 const bool screenshare_;
kwiberg27f982b2016-03-01 11:52:33 -08002116 const std::unique_ptr<VideoEncoder> vp8_encoder_;
Åsa Persson3c391cb2015-04-27 10:09:49 +02002117 Call* sender_call_;
2118 Call* receiver_call_;
2119 int64_t start_runtime_ms_;
sprangb4a1ae52015-12-03 08:10:08 -08002120 } test(use_rtx, use_red, screenshare);
Åsa Persson3c391cb2015-04-27 10:09:49 +02002121
asapersson01d70a32016-05-20 06:29:46 -07002122 metrics::Reset();
stefane74eef12016-01-08 06:47:13 -08002123 RunBaseTest(&test);
Åsa Persson3c391cb2015-04-27 10:09:49 +02002124
stefan91d92602015-11-11 10:13:02 -08002125 // Delete the call for Call stats to be reported.
stefan18adf0a2015-11-17 06:24:56 -08002126 sender_call_.reset();
stefan91d92602015-11-11 10:13:02 -08002127 receiver_call_.reset();
2128
sprangb4a1ae52015-12-03 08:10:08 -08002129 std::string video_prefix =
2130 screenshare ? "WebRTC.Video.Screenshare." : "WebRTC.Video.";
2131
Åsa Persson3c391cb2015-04-27 10:09:49 +02002132 // Verify that stats have been updated once.
asapersson01d70a32016-05-20 06:29:46 -07002133 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Call.VideoBitrateReceivedInKbps"));
2134 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Call.RtcpBitrateReceivedInBps"));
2135 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Call.BitrateReceivedInKbps"));
2136 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Call.EstimatedSendBitrateInKbps"));
2137 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Call.PacerBitrateInKbps"));
2138
2139 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.NackPacketsSentPerMinute"));
stefan91d92602015-11-11 10:13:02 -08002140 EXPECT_EQ(1,
asapersson01d70a32016-05-20 06:29:46 -07002141 metrics::NumSamples(video_prefix + "NackPacketsReceivedPerMinute"));
2142 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.FirPacketsSentPerMinute"));
asaperssond89920b2015-07-22 06:52:00 -07002143 EXPECT_EQ(1,
asapersson01d70a32016-05-20 06:29:46 -07002144 metrics::NumSamples(video_prefix + "FirPacketsReceivedPerMinute"));
2145 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.PliPacketsSentPerMinute"));
sprangb4a1ae52015-12-03 08:10:08 -08002146 EXPECT_EQ(1,
asapersson01d70a32016-05-20 06:29:46 -07002147 metrics::NumSamples(video_prefix + "PliPacketsReceivedPerMinute"));
Åsa Persson3c391cb2015-04-27 10:09:49 +02002148
asapersson01d70a32016-05-20 06:29:46 -07002149 EXPECT_EQ(1, metrics::NumSamples(video_prefix + "KeyFramesSentInPermille"));
2150 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.KeyFramesReceivedInPermille"));
2151
2152 EXPECT_EQ(1, metrics::NumSamples(video_prefix + "SentPacketsLostInPercent"));
2153 EXPECT_EQ(1,
2154 metrics::NumSamples("WebRTC.Video.ReceivedPacketsLostInPercent"));
2155
2156 EXPECT_EQ(1, metrics::NumSamples(video_prefix + "InputWidthInPixels"));
2157 EXPECT_EQ(1, metrics::NumSamples(video_prefix + "InputHeightInPixels"));
2158 EXPECT_EQ(1, metrics::NumSamples(video_prefix + "SentWidthInPixels"));
2159 EXPECT_EQ(1, metrics::NumSamples(video_prefix + "SentHeightInPixels"));
2160 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.ReceivedWidthInPixels"));
2161 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.ReceivedHeightInPixels"));
2162
2163 EXPECT_EQ(1, metrics::NumEvents(
2164 video_prefix + "InputWidthInPixels",
2165 static_cast<int>(video_encoder_config_.streams[0].width)));
2166 EXPECT_EQ(1, metrics::NumEvents(
2167 video_prefix + "InputHeightInPixels",
2168 static_cast<int>(video_encoder_config_.streams[0].height)));
2169 EXPECT_EQ(1, metrics::NumEvents(
2170 video_prefix + "SentWidthInPixels",
2171 static_cast<int>(video_encoder_config_.streams[0].width)));
2172 EXPECT_EQ(1, metrics::NumEvents(
2173 video_prefix + "SentHeightInPixels",
2174 static_cast<int>(video_encoder_config_.streams[0].height)));
2175 EXPECT_EQ(1, metrics::NumEvents(
2176 "WebRTC.Video.ReceivedWidthInPixels",
2177 static_cast<int>(video_encoder_config_.streams[0].width)));
2178 EXPECT_EQ(1, metrics::NumEvents(
2179 "WebRTC.Video.ReceivedHeightInPixels",
2180 static_cast<int>(video_encoder_config_.streams[0].height)));
2181
2182 EXPECT_EQ(1, metrics::NumSamples(video_prefix + "InputFramesPerSecond"));
2183 EXPECT_EQ(1, metrics::NumSamples(video_prefix + "SentFramesPerSecond"));
2184 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.DecodedFramesPerSecond"));
2185 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.RenderFramesPerSecond"));
2186
2187 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.JitterBufferDelayInMs"));
2188 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.TargetDelayInMs"));
2189 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.CurrentDelayInMs"));
2190 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.OnewayDelayInMs"));
2191
2192 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.RenderSqrtPixelsPerSecond"));
2193
2194 EXPECT_EQ(1, metrics::NumSamples(video_prefix + "EncodeTimeInMs"));
2195 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.DecodeTimeInMs"));
2196
2197 EXPECT_EQ(1, metrics::NumSamples(video_prefix + "BitrateSentInKbps"));
2198 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.BitrateReceivedInKbps"));
2199 EXPECT_EQ(1, metrics::NumSamples(video_prefix + "MediaBitrateSentInKbps"));
2200 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.MediaBitrateReceivedInKbps"));
2201 EXPECT_EQ(1, metrics::NumSamples(video_prefix + "PaddingBitrateSentInKbps"));
2202 EXPECT_EQ(1,
2203 metrics::NumSamples("WebRTC.Video.PaddingBitrateReceivedInKbps"));
asapersson6f14be82015-11-16 00:40:49 -08002204 EXPECT_EQ(
asapersson01d70a32016-05-20 06:29:46 -07002205 1, metrics::NumSamples(video_prefix + "RetransmittedBitrateSentInKbps"));
2206 EXPECT_EQ(1, metrics::NumSamples(
2207 "WebRTC.Video.RetransmittedBitrateReceivedInKbps"));
asapersson6f14be82015-11-16 00:40:49 -08002208
asapersson01d70a32016-05-20 06:29:46 -07002209 EXPECT_EQ(1, metrics::NumSamples("WebRTC.Video.SendDelayInMs"));
2210 EXPECT_EQ(1, metrics::NumSamples(video_prefix + "SendSideDelayInMs"));
2211 EXPECT_EQ(1, metrics::NumSamples(video_prefix + "SendSideDelayMaxInMs"));
asapersson6f14be82015-11-16 00:40:49 -08002212
Åsa Persson3c391cb2015-04-27 10:09:49 +02002213 int num_rtx_samples = use_rtx ? 1 : 0;
asapersson01d70a32016-05-20 06:29:46 -07002214 EXPECT_EQ(num_rtx_samples,
2215 metrics::NumSamples("WebRTC.Video.RtxBitrateSentInKbps"));
2216 EXPECT_EQ(num_rtx_samples,
2217 metrics::NumSamples("WebRTC.Video.RtxBitrateReceivedInKbps"));
Åsa Persson3c391cb2015-04-27 10:09:49 +02002218
2219 int num_red_samples = use_red ? 1 : 0;
asapersson01d70a32016-05-20 06:29:46 -07002220 EXPECT_EQ(num_red_samples,
2221 metrics::NumSamples("WebRTC.Video.FecBitrateSentInKbps"));
2222 EXPECT_EQ(num_red_samples,
2223 metrics::NumSamples("WebRTC.Video.FecBitrateReceivedInKbps"));
2224 EXPECT_EQ(num_red_samples,
2225 metrics::NumSamples("WebRTC.Video.ReceivedFecPacketsInPercent"));
Åsa Persson3c391cb2015-04-27 10:09:49 +02002226}
2227
2228TEST_F(EndToEndTest, VerifyHistogramStatsWithRtx) {
2229 const bool kEnabledRtx = true;
2230 const bool kEnabledRed = false;
sprangb4a1ae52015-12-03 08:10:08 -08002231 const bool kScreenshare = false;
2232 VerifyHistogramStats(kEnabledRtx, kEnabledRed, kScreenshare);
Åsa Persson3c391cb2015-04-27 10:09:49 +02002233}
2234
2235TEST_F(EndToEndTest, VerifyHistogramStatsWithRed) {
2236 const bool kEnabledRtx = false;
2237 const bool kEnabledRed = true;
sprangb4a1ae52015-12-03 08:10:08 -08002238 const bool kScreenshare = false;
2239 VerifyHistogramStats(kEnabledRtx, kEnabledRed, kScreenshare);
2240}
2241
2242TEST_F(EndToEndTest, VerifyHistogramStatsWithScreenshare) {
2243 const bool kEnabledRtx = false;
2244 const bool kEnabledRed = false;
2245 const bool kScreenshare = true;
2246 VerifyHistogramStats(kEnabledRtx, kEnabledRed, kScreenshare);
Åsa Persson3c391cb2015-04-27 10:09:49 +02002247}
2248
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002249void EndToEndTest::TestXrReceiverReferenceTimeReport(bool enable_rrtr) {
2250 static const int kNumRtcpReportPacketsToObserve = 5;
2251 class RtcpXrObserver : public test::EndToEndTest {
2252 public:
2253 explicit RtcpXrObserver(bool enable_rrtr)
2254 : EndToEndTest(kDefaultTimeoutMs),
2255 enable_rrtr_(enable_rrtr),
2256 sent_rtcp_sr_(0),
2257 sent_rtcp_rr_(0),
2258 sent_rtcp_rrtr_(0),
2259 sent_rtcp_dlrr_(0) {}
2260
2261 private:
2262 // Receive stream should send RR packets (and RRTR packets if enabled).
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002263 Action OnReceiveRtcp(const uint8_t* packet, size_t length) override {
stefan608213e2015-11-01 14:56:10 -08002264 rtc::CritScope lock(&crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002265 RTCPUtility::RTCPParserV2 parser(packet, length, true);
2266 EXPECT_TRUE(parser.IsValid());
2267
2268 RTCPUtility::RTCPPacketTypes packet_type = parser.Begin();
Erik Språng242e22b2015-05-11 10:17:43 +02002269 while (packet_type != RTCPUtility::RTCPPacketTypes::kInvalid) {
2270 if (packet_type == RTCPUtility::RTCPPacketTypes::kRr) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002271 ++sent_rtcp_rr_;
2272 } else if (packet_type ==
Erik Språng242e22b2015-05-11 10:17:43 +02002273 RTCPUtility::RTCPPacketTypes::kXrReceiverReferenceTime) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002274 ++sent_rtcp_rrtr_;
2275 }
Erik Språng242e22b2015-05-11 10:17:43 +02002276 EXPECT_NE(packet_type, RTCPUtility::RTCPPacketTypes::kSr);
2277 EXPECT_NE(packet_type,
2278 RTCPUtility::RTCPPacketTypes::kXrDlrrReportBlockItem);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002279 packet_type = parser.Iterate();
2280 }
2281 return SEND_PACKET;
2282 }
2283 // Send stream should send SR packets (and DLRR packets if enabled).
nisseef8b61e2016-04-29 06:09:15 -07002284 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
stefan608213e2015-11-01 14:56:10 -08002285 rtc::CritScope lock(&crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002286 RTCPUtility::RTCPParserV2 parser(packet, length, true);
2287 EXPECT_TRUE(parser.IsValid());
2288
2289 RTCPUtility::RTCPPacketTypes packet_type = parser.Begin();
Erik Språng242e22b2015-05-11 10:17:43 +02002290 while (packet_type != RTCPUtility::RTCPPacketTypes::kInvalid) {
2291 if (packet_type == RTCPUtility::RTCPPacketTypes::kSr) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002292 ++sent_rtcp_sr_;
Erik Språng242e22b2015-05-11 10:17:43 +02002293 } else if (packet_type ==
2294 RTCPUtility::RTCPPacketTypes::kXrDlrrReportBlockItem) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002295 ++sent_rtcp_dlrr_;
2296 }
Erik Språng242e22b2015-05-11 10:17:43 +02002297 EXPECT_NE(packet_type,
2298 RTCPUtility::RTCPPacketTypes::kXrReceiverReferenceTime);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002299 packet_type = parser.Iterate();
2300 }
2301 if (sent_rtcp_sr_ > kNumRtcpReportPacketsToObserve &&
2302 sent_rtcp_rr_ > kNumRtcpReportPacketsToObserve) {
2303 if (enable_rrtr_) {
2304 EXPECT_GT(sent_rtcp_rrtr_, 0);
2305 EXPECT_GT(sent_rtcp_dlrr_, 0);
2306 } else {
2307 EXPECT_EQ(0, sent_rtcp_rrtr_);
2308 EXPECT_EQ(0, sent_rtcp_dlrr_);
2309 }
Peter Boström5811a392015-12-10 13:02:50 +01002310 observation_complete_.Set();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002311 }
2312 return SEND_PACKET;
2313 }
2314
stefanff483612015-12-21 03:14:00 -08002315 void ModifyVideoConfigs(
2316 VideoSendStream::Config* send_config,
2317 std::vector<VideoReceiveStream::Config>* receive_configs,
2318 VideoEncoderConfig* encoder_config) override {
pbosda903ea2015-10-02 02:36:56 -07002319 (*receive_configs)[0].rtp.rtcp_mode = RtcpMode::kReducedSize;
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00002320 (*receive_configs)[0].rtp.rtcp_xr.receiver_reference_time_report =
2321 enable_rrtr_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002322 }
2323
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002324 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002325 EXPECT_TRUE(Wait())
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002326 << "Timed out while waiting for RTCP SR/RR packets to be sent.";
2327 }
2328
stefan608213e2015-11-01 14:56:10 -08002329 rtc::CriticalSection crit_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002330 bool enable_rrtr_;
2331 int sent_rtcp_sr_;
stefan608213e2015-11-01 14:56:10 -08002332 int sent_rtcp_rr_ GUARDED_BY(&crit_);
2333 int sent_rtcp_rrtr_ GUARDED_BY(&crit_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002334 int sent_rtcp_dlrr_;
2335 } test(enable_rrtr);
2336
stefane74eef12016-01-08 06:47:13 -08002337 RunBaseTest(&test);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002338}
2339
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00002340void EndToEndTest::TestSendsSetSsrcs(size_t num_ssrcs,
2341 bool send_single_ssrc_first) {
2342 class SendsSetSsrcs : public test::EndToEndTest {
2343 public:
2344 SendsSetSsrcs(const uint32_t* ssrcs,
2345 size_t num_ssrcs,
2346 bool send_single_ssrc_first)
2347 : EndToEndTest(kDefaultTimeoutMs),
2348 num_ssrcs_(num_ssrcs),
2349 send_single_ssrc_first_(send_single_ssrc_first),
2350 ssrcs_to_observe_(num_ssrcs),
sprang867fb522015-08-03 04:38:41 -07002351 expect_single_ssrc_(send_single_ssrc_first),
2352 send_stream_(nullptr) {
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00002353 for (size_t i = 0; i < num_ssrcs; ++i)
2354 valid_ssrcs_[ssrcs[i]] = true;
2355 }
2356
2357 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002358 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00002359 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00002360 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00002361
2362 EXPECT_TRUE(valid_ssrcs_[header.ssrc])
2363 << "Received unknown SSRC: " << header.ssrc;
2364
2365 if (!valid_ssrcs_[header.ssrc])
Peter Boström5811a392015-12-10 13:02:50 +01002366 observation_complete_.Set();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00002367
2368 if (!is_observed_[header.ssrc]) {
2369 is_observed_[header.ssrc] = true;
2370 --ssrcs_to_observe_;
2371 if (expect_single_ssrc_) {
2372 expect_single_ssrc_ = false;
Peter Boström5811a392015-12-10 13:02:50 +01002373 observation_complete_.Set();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00002374 }
2375 }
2376
2377 if (ssrcs_to_observe_ == 0)
Peter Boström5811a392015-12-10 13:02:50 +01002378 observation_complete_.Set();
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00002379
2380 return SEND_PACKET;
2381 }
2382
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002383 size_t GetNumVideoStreams() const override { return num_ssrcs_; }
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00002384
stefanff483612015-12-21 03:14:00 -08002385 void ModifyVideoConfigs(
2386 VideoSendStream::Config* send_config,
2387 std::vector<VideoReceiveStream::Config>* receive_configs,
2388 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00002389 if (num_ssrcs_ > 1) {
2390 // Set low simulcast bitrates to not have to wait for bandwidth ramp-up.
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002391 for (size_t i = 0; i < encoder_config->streams.size(); ++i) {
2392 encoder_config->streams[i].min_bitrate_bps = 10000;
2393 encoder_config->streams[i].target_bitrate_bps = 15000;
2394 encoder_config->streams[i].max_bitrate_bps = 20000;
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00002395 }
2396 }
2397
stefanff483612015-12-21 03:14:00 -08002398 video_encoder_config_all_streams_ = *encoder_config;
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00002399 if (send_single_ssrc_first_)
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002400 encoder_config->streams.resize(1);
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00002401 }
2402
stefanff483612015-12-21 03:14:00 -08002403 void OnVideoStreamsCreated(
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00002404 VideoSendStream* send_stream,
pbos@webrtc.org0d852d52015-02-09 15:14:36 +00002405 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00002406 send_stream_ = send_stream;
2407 }
2408
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002409 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002410 EXPECT_TRUE(Wait()) << "Timed out while waiting for "
2411 << (send_single_ssrc_first_ ? "first SSRC."
2412 : "SSRCs.");
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00002413
2414 if (send_single_ssrc_first_) {
2415 // Set full simulcast and continue with the rest of the SSRCs.
stefanff483612015-12-21 03:14:00 -08002416 send_stream_->ReconfigureVideoEncoder(
2417 video_encoder_config_all_streams_);
Peter Boström5811a392015-12-10 13:02:50 +01002418 EXPECT_TRUE(Wait()) << "Timed out while waiting on additional SSRCs.";
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00002419 }
2420 }
2421
2422 private:
2423 std::map<uint32_t, bool> valid_ssrcs_;
2424 std::map<uint32_t, bool> is_observed_;
2425
2426 const size_t num_ssrcs_;
2427 const bool send_single_ssrc_first_;
2428
2429 size_t ssrcs_to_observe_;
2430 bool expect_single_ssrc_;
2431
2432 VideoSendStream* send_stream_;
stefanff483612015-12-21 03:14:00 -08002433 VideoEncoderConfig video_encoder_config_all_streams_;
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002434 } test(kVideoSendSsrcs, num_ssrcs, send_single_ssrc_first);
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00002435
stefane74eef12016-01-08 06:47:13 -08002436 RunBaseTest(&test);
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00002437}
2438
pbos@webrtc.org891d4832015-02-26 13:15:22 +00002439TEST_F(EndToEndTest, ReportsSetEncoderRates) {
2440 class EncoderRateStatsTest : public test::EndToEndTest,
2441 public test::FakeEncoder {
2442 public:
2443 EncoderRateStatsTest()
2444 : EndToEndTest(kDefaultTimeoutMs),
sprang867fb522015-08-03 04:38:41 -07002445 FakeEncoder(Clock::GetRealTimeClock()),
2446 send_stream_(nullptr),
2447 bitrate_kbps_(0) {}
pbos@webrtc.org891d4832015-02-26 13:15:22 +00002448
stefanff483612015-12-21 03:14:00 -08002449 void OnVideoStreamsCreated(
pbos@webrtc.org891d4832015-02-26 13:15:22 +00002450 VideoSendStream* send_stream,
2451 const std::vector<VideoReceiveStream*>& receive_streams) override {
2452 send_stream_ = send_stream;
2453 }
2454
stefanff483612015-12-21 03:14:00 -08002455 void ModifyVideoConfigs(
2456 VideoSendStream::Config* send_config,
2457 std::vector<VideoReceiveStream::Config>* receive_configs,
2458 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org891d4832015-02-26 13:15:22 +00002459 send_config->encoder_settings.encoder = this;
perkj57c21f92016-06-17 07:27:16 -07002460 RTC_DCHECK_EQ(1u, encoder_config->streams.size());
pbos@webrtc.org891d4832015-02-26 13:15:22 +00002461 }
2462
2463 int32_t SetRates(uint32_t new_target_bitrate, uint32_t framerate) override {
2464 // Make sure not to trigger on any default zero bitrates.
2465 if (new_target_bitrate == 0)
2466 return 0;
Peter Boströmf2f82832015-05-01 13:00:41 +02002467 rtc::CritScope lock(&crit_);
pbos@webrtc.org891d4832015-02-26 13:15:22 +00002468 bitrate_kbps_ = new_target_bitrate;
Peter Boström5811a392015-12-10 13:02:50 +01002469 observation_complete_.Set();
pbos@webrtc.org891d4832015-02-26 13:15:22 +00002470 return 0;
2471 }
2472
2473 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002474 ASSERT_TRUE(Wait())
pbos@webrtc.org891d4832015-02-26 13:15:22 +00002475 << "Timed out while waiting for encoder SetRates() call.";
2476 // Wait for GetStats to report a corresponding bitrate.
Peter Boström5811a392015-12-10 13:02:50 +01002477 for (int i = 0; i < kDefaultTimeoutMs; ++i) {
pbos@webrtc.org891d4832015-02-26 13:15:22 +00002478 VideoSendStream::Stats stats = send_stream_->GetStats();
2479 {
Peter Boströmf2f82832015-05-01 13:00:41 +02002480 rtc::CritScope lock(&crit_);
pbos@webrtc.org891d4832015-02-26 13:15:22 +00002481 if ((stats.target_media_bitrate_bps + 500) / 1000 ==
2482 static_cast<int>(bitrate_kbps_)) {
2483 return;
2484 }
2485 }
2486 SleepMs(1);
2487 }
2488 FAIL()
2489 << "Timed out waiting for stats reporting the currently set bitrate.";
2490 }
2491
2492 private:
stefanf116bd02015-10-27 08:29:42 -07002493 rtc::CriticalSection crit_;
pbos@webrtc.org891d4832015-02-26 13:15:22 +00002494 VideoSendStream* send_stream_;
2495 uint32_t bitrate_kbps_ GUARDED_BY(crit_);
2496 } test;
2497
stefane74eef12016-01-08 06:47:13 -08002498 RunBaseTest(&test);
pbos@webrtc.org891d4832015-02-26 13:15:22 +00002499}
2500
pbos@webrtc.orgba253472014-11-25 09:39:04 +00002501TEST_F(EndToEndTest, GetStats) {
2502 static const int kStartBitrateBps = 3000000;
Peter Boströmdef398832015-05-27 17:59:11 +02002503 static const int kExpectedRenderDelayMs = 20;
tommi2e82f382016-06-21 00:26:43 -07002504
2505 class ReceiveStreamRenderer : public rtc::VideoSinkInterface<VideoFrame> {
2506 public:
2507 ReceiveStreamRenderer() {}
2508
2509 private:
2510 void OnFrame(const VideoFrame& video_frame) override {}
2511 };
2512
nissed30a1112016-04-18 05:15:22 -07002513 class StatsObserver : public test::EndToEndTest,
2514 public rtc::VideoSinkInterface<VideoFrame> {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002515 public:
stefanf116bd02015-10-27 08:29:42 -07002516 StatsObserver()
2517 : EndToEndTest(kLongTimeoutMs),
Peter Boströmc6e16e32016-02-05 14:15:53 +01002518 encoder_(Clock::GetRealTimeClock(), 10),
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +00002519 send_stream_(nullptr),
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002520 expected_send_ssrcs_(),
Peter Boström5811a392015-12-10 13:02:50 +01002521 check_stats_event_(false, false) {}
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002522
2523 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002524 Action OnSendRtp(const uint8_t* packet, size_t length) override {
Peter Boström5811a392015-12-10 13:02:50 +01002525 check_stats_event_.Set();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002526 return SEND_PACKET;
2527 }
2528
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002529 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
Peter Boström5811a392015-12-10 13:02:50 +01002530 check_stats_event_.Set();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002531 return SEND_PACKET;
2532 }
2533
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002534 Action OnReceiveRtp(const uint8_t* packet, size_t length) override {
Peter Boström5811a392015-12-10 13:02:50 +01002535 check_stats_event_.Set();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002536 return SEND_PACKET;
2537 }
2538
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002539 Action OnReceiveRtcp(const uint8_t* packet, size_t length) override {
Peter Boström5811a392015-12-10 13:02:50 +01002540 check_stats_event_.Set();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002541 return SEND_PACKET;
2542 }
2543
nissed30a1112016-04-18 05:15:22 -07002544 void OnFrame(const VideoFrame& video_frame) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002545 // Ensure that we have at least 5ms send side delay.
nissed30a1112016-04-18 05:15:22 -07002546 SleepMs(5);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002547 }
2548
2549 bool CheckReceiveStats() {
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00002550 for (size_t i = 0; i < receive_streams_.size(); ++i) {
2551 VideoReceiveStream::Stats stats = receive_streams_[i]->GetStats();
2552 EXPECT_EQ(expected_receive_ssrcs_[i], stats.ssrc);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002553
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00002554 // Make sure all fields have been populated.
2555 // TODO(pbos): Use CompoundKey if/when we ever know that all stats are
2556 // always filled for all receivers.
2557 receive_stats_filled_["IncomingRate"] |=
2558 stats.network_frame_rate != 0 || stats.total_bitrate_bps != 0;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002559
Peter Boströmb7d9a972015-12-18 16:01:11 +01002560 send_stats_filled_["DecoderImplementationName"] |=
2561 stats.decoder_implementation_name ==
2562 test::FakeDecoder::kImplementationName;
Peter Boströmdef398832015-05-27 17:59:11 +02002563 receive_stats_filled_["RenderDelayAsHighAsExpected"] |=
2564 stats.render_delay_ms >= kExpectedRenderDelayMs;
2565
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00002566 receive_stats_filled_["FrameCallback"] |= stats.decode_frame_rate != 0;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002567
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00002568 receive_stats_filled_["FrameRendered"] |= stats.render_frame_rate != 0;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002569
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00002570 receive_stats_filled_["StatisticsUpdated"] |=
2571 stats.rtcp_stats.cumulative_lost != 0 ||
2572 stats.rtcp_stats.extended_max_sequence_number != 0 ||
2573 stats.rtcp_stats.fraction_lost != 0 || stats.rtcp_stats.jitter != 0;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002574
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00002575 receive_stats_filled_["DataCountersUpdated"] |=
2576 stats.rtp_stats.transmitted.payload_bytes != 0 ||
2577 stats.rtp_stats.fec.packets != 0 ||
2578 stats.rtp_stats.transmitted.header_bytes != 0 ||
2579 stats.rtp_stats.transmitted.packets != 0 ||
2580 stats.rtp_stats.transmitted.padding_bytes != 0 ||
2581 stats.rtp_stats.retransmitted.packets != 0;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002582
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00002583 receive_stats_filled_["CodecStats"] |=
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00002584 stats.target_delay_ms != 0 || stats.discarded_packets != 0;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002585
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00002586 receive_stats_filled_["FrameCounts"] |=
2587 stats.frame_counts.key_frames != 0 ||
2588 stats.frame_counts.delta_frames != 0;
pbos@webrtc.orgce4e9a32014-12-18 13:50:16 +00002589
pbosbb36fdf2015-07-09 07:48:14 -07002590 receive_stats_filled_["CName"] |= !stats.c_name.empty();
pbos@webrtc.orgce4e9a32014-12-18 13:50:16 +00002591
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00002592 receive_stats_filled_["RtcpPacketTypeCount"] |=
2593 stats.rtcp_packet_type_counts.fir_packets != 0 ||
2594 stats.rtcp_packet_type_counts.nack_packets != 0 ||
2595 stats.rtcp_packet_type_counts.pli_packets != 0 ||
2596 stats.rtcp_packet_type_counts.nack_requests != 0 ||
2597 stats.rtcp_packet_type_counts.unique_nack_requests != 0;
pbosf42376c2015-08-28 07:35:32 -07002598
2599 assert(stats.current_payload_type == -1 ||
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002600 stats.current_payload_type == kFakeVideoSendPayloadType);
pbosf42376c2015-08-28 07:35:32 -07002601 receive_stats_filled_["IncomingPayloadType"] |=
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002602 stats.current_payload_type == kFakeVideoSendPayloadType;
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00002603 }
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002604
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002605 return AllStatsFilled(receive_stats_filled_);
2606 }
2607
2608 bool CheckSendStats() {
Peter Boström74f6e9e2016-04-04 17:56:10 +02002609 RTC_DCHECK(send_stream_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002610 VideoSendStream::Stats stats = send_stream_->GetStats();
2611
2612 send_stats_filled_["NumStreams"] |=
2613 stats.substreams.size() == expected_send_ssrcs_.size();
2614
pbos@webrtc.org3e6e2712015-02-26 12:19:31 +00002615 send_stats_filled_["CpuOveruseMetrics"] |=
Peter Boströme4499152016-02-05 11:13:28 +01002616 stats.avg_encode_time_ms != 0 && stats.encode_usage_percent != 0;
pbos@webrtc.org3e6e2712015-02-26 12:19:31 +00002617
Peter Boströmb7d9a972015-12-18 16:01:11 +01002618 send_stats_filled_["EncoderImplementationName"] |=
2619 stats.encoder_implementation_name ==
2620 test::FakeEncoder::kImplementationName;
2621
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00002622 for (std::map<uint32_t, VideoSendStream::StreamStats>::const_iterator it =
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002623 stats.substreams.begin();
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00002624 it != stats.substreams.end(); ++it) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002625 EXPECT_TRUE(expected_send_ssrcs_.find(it->first) !=
2626 expected_send_ssrcs_.end());
2627
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00002628 send_stats_filled_[CompoundKey("CapturedFrameRate", it->first)] |=
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002629 stats.input_frame_rate != 0;
2630
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00002631 const VideoSendStream::StreamStats& stream_stats = it->second;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002632
2633 send_stats_filled_[CompoundKey("StatisticsUpdated", it->first)] |=
2634 stream_stats.rtcp_stats.cumulative_lost != 0 ||
2635 stream_stats.rtcp_stats.extended_max_sequence_number != 0 ||
2636 stream_stats.rtcp_stats.fraction_lost != 0;
2637
2638 send_stats_filled_[CompoundKey("DataCountersUpdated", it->first)] |=
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +00002639 stream_stats.rtp_stats.fec.packets != 0 ||
2640 stream_stats.rtp_stats.transmitted.padding_bytes != 0 ||
2641 stream_stats.rtp_stats.retransmitted.packets != 0 ||
2642 stream_stats.rtp_stats.transmitted.packets != 0;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002643
2644 send_stats_filled_[CompoundKey("BitrateStatisticsObserver",
2645 it->first)] |=
stefan@webrtc.org0bae1fa2014-11-05 14:05:29 +00002646 stream_stats.total_bitrate_bps != 0;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002647
2648 send_stats_filled_[CompoundKey("FrameCountObserver", it->first)] |=
pbos@webrtc.orgce4e9a32014-12-18 13:50:16 +00002649 stream_stats.frame_counts.delta_frames != 0 ||
2650 stream_stats.frame_counts.key_frames != 0;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002651
2652 send_stats_filled_[CompoundKey("OutgoingRate", it->first)] |=
2653 stats.encode_frame_rate != 0;
stefan@webrtc.org168f23f2014-07-11 13:44:02 +00002654
2655 send_stats_filled_[CompoundKey("Delay", it->first)] |=
2656 stream_stats.avg_delay_ms != 0 || stream_stats.max_delay_ms != 0;
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00002657
2658 // TODO(pbos): Use CompoundKey when the test makes sure that all SSRCs
2659 // report dropped packets.
2660 send_stats_filled_["RtcpPacketTypeCount"] |=
2661 stream_stats.rtcp_packet_type_counts.fir_packets != 0 ||
2662 stream_stats.rtcp_packet_type_counts.nack_packets != 0 ||
2663 stream_stats.rtcp_packet_type_counts.pli_packets != 0 ||
2664 stream_stats.rtcp_packet_type_counts.nack_requests != 0 ||
2665 stream_stats.rtcp_packet_type_counts.unique_nack_requests != 0;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002666 }
2667
2668 return AllStatsFilled(send_stats_filled_);
2669 }
2670
2671 std::string CompoundKey(const char* name, uint32_t ssrc) {
2672 std::ostringstream oss;
2673 oss << name << "_" << ssrc;
2674 return oss.str();
2675 }
2676
2677 bool AllStatsFilled(const std::map<std::string, bool>& stats_map) {
2678 for (std::map<std::string, bool>::const_iterator it = stats_map.begin();
2679 it != stats_map.end();
2680 ++it) {
2681 if (!it->second)
2682 return false;
2683 }
2684 return true;
2685 }
2686
stefane74eef12016-01-08 06:47:13 -08002687 test::PacketTransport* CreateSendTransport(Call* sender_call) override {
2688 FakeNetworkPipe::Config network_config;
2689 network_config.loss_percent = 5;
2690 return new test::PacketTransport(
2691 sender_call, this, test::PacketTransport::kSender, network_config);
2692 }
2693
pbos@webrtc.org0d852d52015-02-09 15:14:36 +00002694 Call::Config GetSenderCallConfig() override {
pbos@webrtc.orgba253472014-11-25 09:39:04 +00002695 Call::Config config = EndToEndTest::GetSenderCallConfig();
Stefan Holmere5904162015-03-26 11:11:06 +01002696 config.bitrate_config.start_bitrate_bps = kStartBitrateBps;
pbos@webrtc.orgba253472014-11-25 09:39:04 +00002697 return config;
2698 }
2699
stefanff483612015-12-21 03:14:00 -08002700 void ModifyVideoConfigs(
2701 VideoSendStream::Config* send_config,
2702 std::vector<VideoReceiveStream::Config>* receive_configs,
2703 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002704 send_config->pre_encode_callback = this; // Used to inject delay.
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00002705 expected_cname_ = send_config->rtp.c_name = "SomeCName";
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002706
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002707 const std::vector<uint32_t>& ssrcs = send_config->rtp.ssrcs;
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00002708 for (size_t i = 0; i < ssrcs.size(); ++i) {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002709 expected_send_ssrcs_.insert(ssrcs[i]);
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00002710 expected_receive_ssrcs_.push_back(
2711 (*receive_configs)[i].rtp.remote_ssrc);
Peter Boströmdef398832015-05-27 17:59:11 +02002712 (*receive_configs)[i].render_delay_ms = kExpectedRenderDelayMs;
tommi2e82f382016-06-21 00:26:43 -07002713 (*receive_configs)[i].renderer = &receive_stream_renderer_;
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00002714 }
Peter Boströmc6e16e32016-02-05 14:15:53 +01002715 // Use a delayed encoder to make sure we see CpuOveruseMetrics stats that
2716 // are non-zero.
2717 send_config->encoder_settings.encoder = &encoder_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002718 }
2719
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002720 size_t GetNumVideoStreams() const override { return kNumSsrcs; }
pbos@webrtc.orgece38902014-11-14 11:52:04 +00002721
stefanff483612015-12-21 03:14:00 -08002722 void OnVideoStreamsCreated(
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00002723 VideoSendStream* send_stream,
pbos@webrtc.org0d852d52015-02-09 15:14:36 +00002724 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002725 send_stream_ = send_stream;
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00002726 receive_streams_ = receive_streams;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002727 }
2728
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002729 void PerformTest() override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002730 Clock* clock = Clock::GetRealTimeClock();
2731 int64_t now = clock->TimeInMilliseconds();
2732 int64_t stop_time = now + test::CallTest::kLongTimeoutMs;
2733 bool receive_ok = false;
2734 bool send_ok = false;
2735
2736 while (now < stop_time) {
2737 if (!receive_ok)
2738 receive_ok = CheckReceiveStats();
2739 if (!send_ok)
2740 send_ok = CheckSendStats();
2741
2742 if (receive_ok && send_ok)
2743 return;
2744
2745 int64_t time_until_timout_ = stop_time - now;
2746 if (time_until_timout_ > 0)
Peter Boström5811a392015-12-10 13:02:50 +01002747 check_stats_event_.Wait(time_until_timout_);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002748 now = clock->TimeInMilliseconds();
2749 }
2750
2751 ADD_FAILURE() << "Timed out waiting for filled stats.";
2752 for (std::map<std::string, bool>::const_iterator it =
2753 receive_stats_filled_.begin();
2754 it != receive_stats_filled_.end();
2755 ++it) {
2756 if (!it->second) {
2757 ADD_FAILURE() << "Missing receive stats: " << it->first;
2758 }
2759 }
2760
2761 for (std::map<std::string, bool>::const_iterator it =
2762 send_stats_filled_.begin();
2763 it != send_stats_filled_.end();
2764 ++it) {
2765 if (!it->second) {
2766 ADD_FAILURE() << "Missing send stats: " << it->first;
2767 }
2768 }
2769 }
2770
Peter Boströmc6e16e32016-02-05 14:15:53 +01002771 test::DelayedEncoder encoder_;
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00002772 std::vector<VideoReceiveStream*> receive_streams_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002773 std::map<std::string, bool> receive_stats_filled_;
2774
2775 VideoSendStream* send_stream_;
2776 std::map<std::string, bool> send_stats_filled_;
2777
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00002778 std::vector<uint32_t> expected_receive_ssrcs_;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002779 std::set<uint32_t> expected_send_ssrcs_;
2780 std::string expected_cname_;
2781
Peter Boström5811a392015-12-10 13:02:50 +01002782 rtc::Event check_stats_event_;
tommi2e82f382016-06-21 00:26:43 -07002783 ReceiveStreamRenderer receive_stream_renderer_;
stefanf116bd02015-10-27 08:29:42 -07002784 } test;
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002785
stefane74eef12016-01-08 06:47:13 -08002786 RunBaseTest(&test);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002787}
2788
2789TEST_F(EndToEndTest, ReceiverReferenceTimeReportEnabled) {
2790 TestXrReceiverReferenceTimeReport(true);
2791}
2792
2793TEST_F(EndToEndTest, ReceiverReferenceTimeReportDisabled) {
2794 TestXrReceiverReferenceTimeReport(false);
2795}
2796
2797TEST_F(EndToEndTest, TestReceivedRtpPacketStats) {
2798 static const size_t kNumRtpPacketsToSend = 5;
2799 class ReceivedRtpStatsObserver : public test::EndToEndTest {
2800 public:
2801 ReceivedRtpStatsObserver()
2802 : EndToEndTest(kDefaultTimeoutMs),
pbos@webrtc.org2b4ce3a2015-03-23 13:12:24 +00002803 receive_stream_(nullptr),
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002804 sent_rtp_(0) {}
2805
2806 private:
stefanff483612015-12-21 03:14:00 -08002807 void OnVideoStreamsCreated(
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00002808 VideoSendStream* send_stream,
pbos@webrtc.org0d852d52015-02-09 15:14:36 +00002809 const std::vector<VideoReceiveStream*>& receive_streams) override {
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00002810 receive_stream_ = receive_streams[0];
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002811 }
2812
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002813 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002814 if (sent_rtp_ >= kNumRtpPacketsToSend) {
2815 VideoReceiveStream::Stats stats = receive_stream_->GetStats();
asapersson@webrtc.orgcfd82df2015-01-22 09:39:59 +00002816 if (kNumRtpPacketsToSend == stats.rtp_stats.transmitted.packets) {
Peter Boström5811a392015-12-10 13:02:50 +01002817 observation_complete_.Set();
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002818 }
2819 return DROP_PACKET;
2820 }
2821 ++sent_rtp_;
2822 return SEND_PACKET;
2823 }
2824
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002825 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002826 EXPECT_TRUE(Wait())
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002827 << "Timed out while verifying number of received RTP packets.";
2828 }
2829
2830 VideoReceiveStream* receive_stream_;
2831 uint32_t sent_rtp_;
2832 } test;
2833
stefane74eef12016-01-08 06:47:13 -08002834 RunBaseTest(&test);
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00002835}
2836
pbos@webrtc.orgbe9d2a42014-06-30 13:19:09 +00002837TEST_F(EndToEndTest, SendsSetSsrc) { TestSendsSetSsrcs(1, false); }
2838
2839TEST_F(EndToEndTest, SendsSetSimulcastSsrcs) {
2840 TestSendsSetSsrcs(kNumSsrcs, false);
2841}
2842
2843TEST_F(EndToEndTest, CanSwitchToUseAllSsrcs) {
2844 TestSendsSetSsrcs(kNumSsrcs, true);
2845}
2846
mflodman@webrtc.orgf9460682014-07-24 16:41:25 +00002847TEST_F(EndToEndTest, DISABLED_RedundantPayloadsTransmittedOnAllSsrcs) {
pbos@webrtc.org20c1f562014-07-04 10:58:12 +00002848 class ObserveRedundantPayloads: public test::EndToEndTest {
2849 public:
2850 ObserveRedundantPayloads()
2851 : EndToEndTest(kDefaultTimeoutMs), ssrcs_to_observe_(kNumSsrcs) {
pbos@webrtc.orgdde16f12014-08-05 23:35:43 +00002852 for (size_t i = 0; i < kNumSsrcs; ++i) {
pbos@webrtc.org20c1f562014-07-04 10:58:12 +00002853 registered_rtx_ssrc_[kSendRtxSsrcs[i]] = true;
2854 }
2855 }
2856
2857 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002858 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org20c1f562014-07-04 10:58:12 +00002859 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00002860 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.org20c1f562014-07-04 10:58:12 +00002861
2862 if (!registered_rtx_ssrc_[header.ssrc])
2863 return SEND_PACKET;
2864
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00002865 EXPECT_LE(header.headerLength + header.paddingLength, length);
pbos@webrtc.org20c1f562014-07-04 10:58:12 +00002866 const bool packet_is_redundant_payload =
pkasting@chromium.org4591fbd2014-11-20 22:28:14 +00002867 header.headerLength + header.paddingLength < length;
pbos@webrtc.org20c1f562014-07-04 10:58:12 +00002868
2869 if (!packet_is_redundant_payload)
2870 return SEND_PACKET;
2871
2872 if (!observed_redundant_retransmission_[header.ssrc]) {
2873 observed_redundant_retransmission_[header.ssrc] = true;
2874 if (--ssrcs_to_observe_ == 0)
Peter Boström5811a392015-12-10 13:02:50 +01002875 observation_complete_.Set();
pbos@webrtc.org20c1f562014-07-04 10:58:12 +00002876 }
2877
2878 return SEND_PACKET;
2879 }
2880
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002881 size_t GetNumVideoStreams() const override { return kNumSsrcs; }
pbos@webrtc.org20c1f562014-07-04 10:58:12 +00002882
stefanff483612015-12-21 03:14:00 -08002883 void ModifyVideoConfigs(
2884 VideoSendStream::Config* send_config,
2885 std::vector<VideoReceiveStream::Config>* receive_configs,
2886 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org20c1f562014-07-04 10:58:12 +00002887 // Set low simulcast bitrates to not have to wait for bandwidth ramp-up.
pbos@webrtc.orgbbe0a852014-09-19 12:30:25 +00002888 for (size_t i = 0; i < encoder_config->streams.size(); ++i) {
2889 encoder_config->streams[i].min_bitrate_bps = 10000;
2890 encoder_config->streams[i].target_bitrate_bps = 15000;
2891 encoder_config->streams[i].max_bitrate_bps = 20000;
pbos@webrtc.org20c1f562014-07-04 10:58:12 +00002892 }
pbos@webrtc.org20c1f562014-07-04 10:58:12 +00002893
2894 send_config->rtp.rtx.payload_type = kSendRtxPayloadType;
pbos@webrtc.org20c1f562014-07-04 10:58:12 +00002895
2896 for (size_t i = 0; i < kNumSsrcs; ++i)
2897 send_config->rtp.rtx.ssrcs.push_back(kSendRtxSsrcs[i]);
pbos@webrtc.orgad3b5a52014-10-24 09:23:21 +00002898
2899 // Significantly higher than max bitrates for all video streams -> forcing
2900 // padding to trigger redundant padding on all RTX SSRCs.
2901 encoder_config->min_transmit_bitrate_bps = 100000;
pbos@webrtc.org20c1f562014-07-04 10:58:12 +00002902 }
2903
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002904 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01002905 EXPECT_TRUE(Wait())
pbos@webrtc.org20c1f562014-07-04 10:58:12 +00002906 << "Timed out while waiting for redundant payloads on all SSRCs.";
2907 }
2908
2909 private:
2910 size_t ssrcs_to_observe_;
2911 std::map<uint32_t, bool> observed_redundant_retransmission_;
2912 std::map<uint32_t, bool> registered_rtx_ssrc_;
2913 } test;
2914
stefane74eef12016-01-08 06:47:13 -08002915 RunBaseTest(&test);
pbos@webrtc.org20c1f562014-07-04 10:58:12 +00002916}
2917
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +00002918void EndToEndTest::TestRtpStatePreservation(bool use_rtx) {
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +00002919 class RtpSequenceObserver : public test::RtpRtcpObserver {
2920 public:
pbos@webrtc.orgdde16f12014-08-05 23:35:43 +00002921 explicit RtpSequenceObserver(bool use_rtx)
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +00002922 : test::RtpRtcpObserver(kDefaultTimeoutMs),
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +00002923 ssrcs_to_observe_(kNumSsrcs) {
2924 for (size_t i = 0; i < kNumSsrcs; ++i) {
Stefan Holmer9fea80f2016-01-07 17:43:18 +01002925 configured_ssrcs_[kVideoSendSsrcs[i]] = true;
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +00002926 if (use_rtx)
2927 configured_ssrcs_[kSendRtxSsrcs[i]] = true;
2928 }
2929 }
2930
2931 void ResetExpectedSsrcs(size_t num_expected_ssrcs) {
Peter Boströmf2f82832015-05-01 13:00:41 +02002932 rtc::CritScope lock(&crit_);
danilchap34877ee2016-02-01 08:25:04 -08002933 ssrc_observed_.clear();
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +00002934 ssrcs_to_observe_ = num_expected_ssrcs;
2935 }
2936
2937 private:
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002938 Action OnSendRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +00002939 RTPHeader header;
pbos@webrtc.org62bafae2014-07-08 12:10:51 +00002940 EXPECT_TRUE(parser_->Parse(packet, length, &header));
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +00002941 const uint32_t ssrc = header.ssrc;
danilchap5c35cf92016-02-03 14:14:49 -08002942 const int64_t sequence_number =
2943 seq_numbers_unwrapper_.Unwrap(header.sequenceNumber);
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +00002944 const uint32_t timestamp = header.timestamp;
danilchap34877ee2016-02-01 08:25:04 -08002945 const bool only_padding =
2946 header.headerLength + header.paddingLength == length;
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +00002947
2948 EXPECT_TRUE(configured_ssrcs_[ssrc])
2949 << "Received SSRC that wasn't configured: " << ssrc;
2950
danilchap5c35cf92016-02-03 14:14:49 -08002951 static const int64_t kMaxSequenceNumberGap = 100;
2952 std::list<int64_t>* seq_numbers = &last_observed_seq_numbers_[ssrc];
2953 if (seq_numbers->empty()) {
2954 seq_numbers->push_back(sequence_number);
2955 } else {
2956 // We shouldn't get replays of previous sequence numbers.
2957 for (int64_t observed : *seq_numbers) {
2958 EXPECT_NE(observed, sequence_number)
2959 << "Received sequence number " << sequence_number
2960 << " for SSRC " << ssrc << " 2nd time.";
2961 }
2962 // Verify sequence numbers are reasonably close.
2963 int64_t latest_observed = seq_numbers->back();
2964 int64_t sequence_number_gap = sequence_number - latest_observed;
2965 EXPECT_LE(std::abs(sequence_number_gap), kMaxSequenceNumberGap)
2966 << "Gap in sequence numbers (" << latest_observed << " -> "
2967 << sequence_number << ") too large for SSRC: " << ssrc << ".";
2968 seq_numbers->push_back(sequence_number);
2969 if (seq_numbers->size() >= kMaxSequenceNumberGap) {
2970 seq_numbers->pop_front();
2971 }
2972 }
2973
2974 static const int32_t kMaxTimestampGap = kDefaultTimeoutMs * 90;
2975 auto timestamp_it = last_observed_timestamp_.find(ssrc);
2976 if (timestamp_it == last_observed_timestamp_.end()) {
perkj71ee44c2016-06-15 00:47:53 -07002977 EXPECT_FALSE(only_padding);
danilchap34877ee2016-02-01 08:25:04 -08002978 last_observed_timestamp_[ssrc] = timestamp;
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +00002979 } else {
danilchap5c35cf92016-02-03 14:14:49 -08002980 // Verify timestamps are reasonably close.
2981 uint32_t latest_observed = timestamp_it->second;
Honghai Zhang82d78622016-05-06 11:29:15 -07002982 // Wraparound handling is unnecessary here as long as an int variable
2983 // is used to store the result.
2984 int32_t timestamp_gap = timestamp - latest_observed;
danilchap5c35cf92016-02-03 14:14:49 -08002985 EXPECT_LE(std::abs(timestamp_gap), kMaxTimestampGap)
2986 << "Gap in timestamps (" << latest_observed << " -> "
2987 << timestamp << ") too large for SSRC: " << ssrc << ".";
2988 timestamp_it->second = timestamp;
danilchapf4b9c772016-01-28 06:14:24 -08002989 }
danilchap34877ee2016-02-01 08:25:04 -08002990
2991 rtc::CritScope lock(&crit_);
2992 // Wait for media packets on all ssrcs.
2993 if (!ssrc_observed_[ssrc] && !only_padding) {
2994 ssrc_observed_[ssrc] = true;
2995 if (--ssrcs_to_observe_ == 0)
2996 observation_complete_.Set();
2997 }
2998
danilchapf4b9c772016-01-28 06:14:24 -08002999 return SEND_PACKET;
3000 }
3001
danilchap5c35cf92016-02-03 14:14:49 -08003002 SequenceNumberUnwrapper seq_numbers_unwrapper_;
3003 std::map<uint32_t, std::list<int64_t>> last_observed_seq_numbers_;
danilchap34877ee2016-02-01 08:25:04 -08003004 std::map<uint32_t, uint32_t> last_observed_timestamp_;
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +00003005 std::map<uint32_t, bool> configured_ssrcs_;
3006
Peter Boströmf2f82832015-05-01 13:00:41 +02003007 rtc::CriticalSection crit_;
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +00003008 size_t ssrcs_to_observe_ GUARDED_BY(crit_);
danilchap34877ee2016-02-01 08:25:04 -08003009 std::map<uint32_t, bool> ssrc_observed_ GUARDED_BY(crit_);
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +00003010 } observer(use_rtx);
3011
solenberg4fbae2b2015-08-28 04:07:10 -07003012 CreateCalls(Call::Config(), Call::Config());
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +00003013
stefanf116bd02015-10-27 08:29:42 -07003014 test::PacketTransport send_transport(sender_call_.get(), &observer,
3015 test::PacketTransport::kSender,
3016 FakeNetworkPipe::Config());
3017 test::PacketTransport receive_transport(nullptr, &observer,
3018 test::PacketTransport::kReceiver,
3019 FakeNetworkPipe::Config());
3020 send_transport.SetReceiver(receiver_call_->Receiver());
3021 receive_transport.SetReceiver(sender_call_->Receiver());
3022
Stefan Holmer9fea80f2016-01-07 17:43:18 +01003023 CreateSendConfig(kNumSsrcs, 0, &send_transport);
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +00003024
3025 if (use_rtx) {
3026 for (size_t i = 0; i < kNumSsrcs; ++i) {
stefanff483612015-12-21 03:14:00 -08003027 video_send_config_.rtp.rtx.ssrcs.push_back(kSendRtxSsrcs[i]);
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +00003028 }
stefanff483612015-12-21 03:14:00 -08003029 video_send_config_.rtp.rtx.payload_type = kSendRtxPayloadType;
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +00003030 }
3031
3032 // Lower bitrates so that all streams send initially.
stefanff483612015-12-21 03:14:00 -08003033 for (size_t i = 0; i < video_encoder_config_.streams.size(); ++i) {
3034 video_encoder_config_.streams[i].min_bitrate_bps = 10000;
3035 video_encoder_config_.streams[i].target_bitrate_bps = 15000;
3036 video_encoder_config_.streams[i].max_bitrate_bps = 20000;
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +00003037 }
3038
pbos@webrtc.org32452b22014-10-22 12:15:24 +00003039 // Use the same total bitrates when sending a single stream to avoid lowering
3040 // the bitrate estimate and requiring a subsequent rampup.
stefanff483612015-12-21 03:14:00 -08003041 VideoEncoderConfig one_stream = video_encoder_config_;
pbos@webrtc.org32452b22014-10-22 12:15:24 +00003042 one_stream.streams.resize(1);
stefanff483612015-12-21 03:14:00 -08003043 for (size_t i = 1; i < video_encoder_config_.streams.size(); ++i) {
pbos@webrtc.org32452b22014-10-22 12:15:24 +00003044 one_stream.streams.front().min_bitrate_bps +=
stefanff483612015-12-21 03:14:00 -08003045 video_encoder_config_.streams[i].min_bitrate_bps;
pbos@webrtc.org32452b22014-10-22 12:15:24 +00003046 one_stream.streams.front().target_bitrate_bps +=
stefanff483612015-12-21 03:14:00 -08003047 video_encoder_config_.streams[i].target_bitrate_bps;
pbos@webrtc.org32452b22014-10-22 12:15:24 +00003048 one_stream.streams.front().max_bitrate_bps +=
stefanff483612015-12-21 03:14:00 -08003049 video_encoder_config_.streams[i].max_bitrate_bps;
pbos@webrtc.org32452b22014-10-22 12:15:24 +00003050 }
3051
stefanf116bd02015-10-27 08:29:42 -07003052 CreateMatchingReceiveConfigs(&receive_transport);
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +00003053
Stefan Holmer9fea80f2016-01-07 17:43:18 +01003054 CreateVideoStreams();
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +00003055 CreateFrameGeneratorCapturer();
3056
3057 Start();
Peter Boström5811a392015-12-10 13:02:50 +01003058 EXPECT_TRUE(observer.Wait())
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +00003059 << "Timed out waiting for all SSRCs to send packets.";
3060
3061 // Test stream resetting more than once to make sure that the state doesn't
3062 // get set once (this could be due to using std::map::insert for instance).
3063 for (size_t i = 0; i < 3; ++i) {
3064 frame_generator_capturer_->Stop();
stefanff483612015-12-21 03:14:00 -08003065 sender_call_->DestroyVideoSendStream(video_send_stream_);
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +00003066
3067 // Re-create VideoSendStream with only one stream.
stefanff483612015-12-21 03:14:00 -08003068 video_send_stream_ =
3069 sender_call_->CreateVideoSendStream(video_send_config_, one_stream);
3070 video_send_stream_->Start();
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +00003071 CreateFrameGeneratorCapturer();
3072 frame_generator_capturer_->Start();
3073
3074 observer.ResetExpectedSsrcs(1);
Peter Boström5811a392015-12-10 13:02:50 +01003075 EXPECT_TRUE(observer.Wait()) << "Timed out waiting for single RTP packet.";
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +00003076
3077 // Reconfigure back to use all streams.
stefanff483612015-12-21 03:14:00 -08003078 video_send_stream_->ReconfigureVideoEncoder(video_encoder_config_);
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +00003079 observer.ResetExpectedSsrcs(kNumSsrcs);
Peter Boström5811a392015-12-10 13:02:50 +01003080 EXPECT_TRUE(observer.Wait())
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +00003081 << "Timed out waiting for all SSRCs to send packets.";
3082
3083 // Reconfigure down to one stream.
stefanff483612015-12-21 03:14:00 -08003084 video_send_stream_->ReconfigureVideoEncoder(one_stream);
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +00003085 observer.ResetExpectedSsrcs(1);
Peter Boström5811a392015-12-10 13:02:50 +01003086 EXPECT_TRUE(observer.Wait()) << "Timed out waiting for single RTP packet.";
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +00003087
3088 // Reconfigure back to use all streams.
stefanff483612015-12-21 03:14:00 -08003089 video_send_stream_->ReconfigureVideoEncoder(video_encoder_config_);
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +00003090 observer.ResetExpectedSsrcs(kNumSsrcs);
Peter Boström5811a392015-12-10 13:02:50 +01003091 EXPECT_TRUE(observer.Wait())
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +00003092 << "Timed out waiting for all SSRCs to send packets.";
3093 }
3094
stefanf116bd02015-10-27 08:29:42 -07003095 send_transport.StopSending();
3096 receive_transport.StopSending();
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +00003097
3098 Stop();
3099 DestroyStreams();
3100}
3101
Peter Boströmfc968a22016-02-19 16:14:37 +01003102TEST_F(EndToEndTest, RestartingSendStreamPreservesRtpState) {
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +00003103 TestRtpStatePreservation(false);
3104}
3105
deadbeef1caff882016-06-27 13:09:52 -07003106// This test is flaky. See:
3107// https://bugs.chromium.org/p/webrtc/issues/detail?id=4332
3108TEST_F(EndToEndTest, DISABLED_RestartingSendStreamPreservesRtpStatesWithRtx) {
pbos@webrtc.org2bb1bda2014-07-07 13:06:48 +00003109 TestRtpStatePreservation(true);
3110}
3111
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00003112TEST_F(EndToEndTest, RespectsNetworkState) {
3113 // TODO(pbos): Remove accepted downtime packets etc. when signaling network
3114 // down blocks until no more packets will be sent.
3115
3116 // Pacer will send from its packet list and then send required padding before
3117 // checking paused_ again. This should be enough for one round of pacing,
3118 // otherwise increase.
3119 static const int kNumAcceptedDowntimeRtp = 5;
3120 // A single RTCP may be in the pipeline.
3121 static const int kNumAcceptedDowntimeRtcp = 1;
3122 class NetworkStateTest : public test::EndToEndTest, public test::FakeEncoder {
3123 public:
3124 NetworkStateTest()
3125 : EndToEndTest(kDefaultTimeoutMs),
3126 FakeEncoder(Clock::GetRealTimeClock()),
Peter Boström5811a392015-12-10 13:02:50 +01003127 encoded_frames_(false, false),
3128 packet_event_(false, false),
sprang867fb522015-08-03 04:38:41 -07003129 sender_call_(nullptr),
3130 receiver_call_(nullptr),
Jelena Marusiccd670222015-07-16 09:30:09 +02003131 sender_state_(kNetworkUp),
pbos@webrtc.orgd5ce2e62015-02-13 14:58:18 +00003132 sender_rtp_(0),
3133 sender_rtcp_(0),
3134 receiver_rtcp_(0),
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00003135 down_frames_(0) {}
3136
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00003137 Action OnSendRtp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02003138 rtc::CritScope lock(&test_crit_);
pbos@webrtc.orgd5ce2e62015-02-13 14:58:18 +00003139 ++sender_rtp_;
Peter Boström5811a392015-12-10 13:02:50 +01003140 packet_event_.Set();
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00003141 return SEND_PACKET;
3142 }
3143
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00003144 Action OnSendRtcp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02003145 rtc::CritScope lock(&test_crit_);
pbos@webrtc.orgd5ce2e62015-02-13 14:58:18 +00003146 ++sender_rtcp_;
Peter Boström5811a392015-12-10 13:02:50 +01003147 packet_event_.Set();
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00003148 return SEND_PACKET;
3149 }
3150
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00003151 Action OnReceiveRtp(const uint8_t* packet, size_t length) override {
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00003152 ADD_FAILURE() << "Unexpected receiver RTP, should not be sending.";
3153 return SEND_PACKET;
3154 }
3155
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00003156 Action OnReceiveRtcp(const uint8_t* packet, size_t length) override {
Peter Boströmf2f82832015-05-01 13:00:41 +02003157 rtc::CritScope lock(&test_crit_);
pbos@webrtc.orgd5ce2e62015-02-13 14:58:18 +00003158 ++receiver_rtcp_;
Peter Boström5811a392015-12-10 13:02:50 +01003159 packet_event_.Set();
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00003160 return SEND_PACKET;
3161 }
3162
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00003163 void OnCallsCreated(Call* sender_call, Call* receiver_call) override {
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00003164 sender_call_ = sender_call;
3165 receiver_call_ = receiver_call;
3166 }
3167
stefanff483612015-12-21 03:14:00 -08003168 void ModifyVideoConfigs(
3169 VideoSendStream::Config* send_config,
3170 std::vector<VideoReceiveStream::Config>* receive_configs,
3171 VideoEncoderConfig* encoder_config) override {
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00003172 send_config->encoder_settings.encoder = this;
3173 }
3174
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00003175 void PerformTest() override {
Peter Boström5811a392015-12-10 13:02:50 +01003176 EXPECT_TRUE(encoded_frames_.Wait(kDefaultTimeoutMs))
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00003177 << "No frames received by the encoder.";
pbos@webrtc.orgd5ce2e62015-02-13 14:58:18 +00003178 // Wait for packets from both sender/receiver.
3179 WaitForPacketsOrSilence(false, false);
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00003180
skvlad7a43d252016-03-22 15:32:27 -07003181 // Sender-side network down for audio; there should be no effect on video
3182 sender_call_->SignalChannelNetworkState(MediaType::AUDIO, kNetworkDown);
3183 WaitForPacketsOrSilence(false, false);
3184
3185 // Receiver-side network down for audio; no change expected
3186 receiver_call_->SignalChannelNetworkState(MediaType::AUDIO, kNetworkDown);
3187 WaitForPacketsOrSilence(false, false);
3188
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00003189 // Sender-side network down.
skvlad7a43d252016-03-22 15:32:27 -07003190 sender_call_->SignalChannelNetworkState(MediaType::VIDEO, kNetworkDown);
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00003191 {
Peter Boströmf2f82832015-05-01 13:00:41 +02003192 rtc::CritScope lock(&test_crit_);
pbos@webrtc.orgd5ce2e62015-02-13 14:58:18 +00003193 // After network goes down we shouldn't be encoding more frames.
Jelena Marusiccd670222015-07-16 09:30:09 +02003194 sender_state_ = kNetworkDown;
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00003195 }
pbos@webrtc.orgd5ce2e62015-02-13 14:58:18 +00003196 // Wait for receiver-packets and no sender packets.
3197 WaitForPacketsOrSilence(true, false);
3198
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00003199 // Receiver-side network down.
skvlad7a43d252016-03-22 15:32:27 -07003200 receiver_call_->SignalChannelNetworkState(MediaType::VIDEO, kNetworkDown);
3201 WaitForPacketsOrSilence(true, true);
3202
3203 // Network up for audio for both sides; video is still not expected to
3204 // start
3205 sender_call_->SignalChannelNetworkState(MediaType::AUDIO, kNetworkUp);
3206 receiver_call_->SignalChannelNetworkState(MediaType::AUDIO, kNetworkUp);
pbos@webrtc.orgd5ce2e62015-02-13 14:58:18 +00003207 WaitForPacketsOrSilence(true, true);
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00003208
3209 // Network back up again for both.
3210 {
Peter Boströmf2f82832015-05-01 13:00:41 +02003211 rtc::CritScope lock(&test_crit_);
pbos@webrtc.orgd5ce2e62015-02-13 14:58:18 +00003212 // It's OK to encode frames again, as we're about to bring up the
3213 // network.
Jelena Marusiccd670222015-07-16 09:30:09 +02003214 sender_state_ = kNetworkUp;
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00003215 }
skvlad7a43d252016-03-22 15:32:27 -07003216 sender_call_->SignalChannelNetworkState(MediaType::VIDEO, kNetworkUp);
3217 receiver_call_->SignalChannelNetworkState(MediaType::VIDEO, kNetworkUp);
pbos@webrtc.orgd5ce2e62015-02-13 14:58:18 +00003218 WaitForPacketsOrSilence(false, false);
skvlad7a43d252016-03-22 15:32:27 -07003219
3220 // TODO(skvlad): add tests to verify that the audio streams are stopped
3221 // when the network goes down for audio once the workaround in
3222 // paced_sender.cc is removed.
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00003223 }
3224
Miguel Casas-Sanchez47650702015-05-29 17:21:40 -07003225 int32_t Encode(const VideoFrame& input_image,
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00003226 const CodecSpecificInfo* codec_specific_info,
pbos22993e12015-10-19 02:39:06 -07003227 const std::vector<FrameType>* frame_types) override {
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00003228 {
Peter Boströmf2f82832015-05-01 13:00:41 +02003229 rtc::CritScope lock(&test_crit_);
Jelena Marusiccd670222015-07-16 09:30:09 +02003230 if (sender_state_ == kNetworkDown) {
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00003231 ++down_frames_;
3232 EXPECT_LE(down_frames_, 1)
3233 << "Encoding more than one frame while network is down.";
3234 if (down_frames_ > 1)
Peter Boström5811a392015-12-10 13:02:50 +01003235 encoded_frames_.Set();
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00003236 } else {
Peter Boström5811a392015-12-10 13:02:50 +01003237 encoded_frames_.Set();
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00003238 }
3239 }
3240 return test::FakeEncoder::Encode(
3241 input_image, codec_specific_info, frame_types);
3242 }
3243
3244 private:
pbos@webrtc.orgd5ce2e62015-02-13 14:58:18 +00003245 void WaitForPacketsOrSilence(bool sender_down, bool receiver_down) {
3246 int64_t initial_time_ms = clock_->TimeInMilliseconds();
3247 int initial_sender_rtp;
3248 int initial_sender_rtcp;
3249 int initial_receiver_rtcp;
3250 {
Peter Boströmf2f82832015-05-01 13:00:41 +02003251 rtc::CritScope lock(&test_crit_);
pbos@webrtc.orgd5ce2e62015-02-13 14:58:18 +00003252 initial_sender_rtp = sender_rtp_;
3253 initial_sender_rtcp = sender_rtcp_;
3254 initial_receiver_rtcp = receiver_rtcp_;
3255 }
3256 bool sender_done = false;
3257 bool receiver_done = false;
mflodmand1590b22015-12-09 07:07:59 -08003258 while (!sender_done || !receiver_done) {
Peter Boström5811a392015-12-10 13:02:50 +01003259 packet_event_.Wait(kSilenceTimeoutMs);
pbos@webrtc.orgd5ce2e62015-02-13 14:58:18 +00003260 int64_t time_now_ms = clock_->TimeInMilliseconds();
Peter Boströmf2f82832015-05-01 13:00:41 +02003261 rtc::CritScope lock(&test_crit_);
pbos@webrtc.orgd5ce2e62015-02-13 14:58:18 +00003262 if (sender_down) {
3263 ASSERT_LE(sender_rtp_ - initial_sender_rtp, kNumAcceptedDowntimeRtp)
3264 << "RTP sent during sender-side downtime.";
3265 ASSERT_LE(sender_rtcp_ - initial_sender_rtcp,
3266 kNumAcceptedDowntimeRtcp)
3267 << "RTCP sent during sender-side downtime.";
3268 if (time_now_ms - initial_time_ms >=
3269 static_cast<int64_t>(kSilenceTimeoutMs)) {
3270 sender_done = true;
3271 }
3272 } else {
skvlad7a43d252016-03-22 15:32:27 -07003273 if (sender_rtp_ > initial_sender_rtp + kNumAcceptedDowntimeRtp)
pbos@webrtc.orgd5ce2e62015-02-13 14:58:18 +00003274 sender_done = true;
3275 }
3276 if (receiver_down) {
3277 ASSERT_LE(receiver_rtcp_ - initial_receiver_rtcp,
3278 kNumAcceptedDowntimeRtcp)
3279 << "RTCP sent during receiver-side downtime.";
3280 if (time_now_ms - initial_time_ms >=
3281 static_cast<int64_t>(kSilenceTimeoutMs)) {
3282 receiver_done = true;
3283 }
3284 } else {
skvlad7a43d252016-03-22 15:32:27 -07003285 if (receiver_rtcp_ > initial_receiver_rtcp + kNumAcceptedDowntimeRtcp)
pbos@webrtc.orgd5ce2e62015-02-13 14:58:18 +00003286 receiver_done = true;
3287 }
3288 }
3289 }
3290
Peter Boströmf2f82832015-05-01 13:00:41 +02003291 rtc::CriticalSection test_crit_;
Peter Boström5811a392015-12-10 13:02:50 +01003292 rtc::Event encoded_frames_;
3293 rtc::Event packet_event_;
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00003294 Call* sender_call_;
3295 Call* receiver_call_;
Jelena Marusiccd670222015-07-16 09:30:09 +02003296 NetworkState sender_state_ GUARDED_BY(test_crit_);
pbos@webrtc.orgd5ce2e62015-02-13 14:58:18 +00003297 int sender_rtp_ GUARDED_BY(test_crit_);
3298 int sender_rtcp_ GUARDED_BY(test_crit_);
3299 int receiver_rtcp_ GUARDED_BY(test_crit_);
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00003300 int down_frames_ GUARDED_BY(test_crit_);
3301 } test;
3302
stefane74eef12016-01-08 06:47:13 -08003303 RunBaseTest(&test);
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00003304}
3305
danilchapa6a70072016-06-01 11:20:43 -07003306TEST_F(EndToEndTest, CallReportsRttForSender) {
pbos@webrtc.org2b19f062014-12-11 13:26:09 +00003307 static const int kSendDelayMs = 30;
3308 static const int kReceiveDelayMs = 70;
3309
solenberg4fbae2b2015-08-28 04:07:10 -07003310 CreateCalls(Call::Config(), Call::Config());
3311
pbos@webrtc.org2b19f062014-12-11 13:26:09 +00003312 FakeNetworkPipe::Config config;
3313 config.queue_delay_ms = kSendDelayMs;
stefanf116bd02015-10-27 08:29:42 -07003314 test::DirectTransport sender_transport(config, sender_call_.get());
pbos@webrtc.org2b19f062014-12-11 13:26:09 +00003315 config.queue_delay_ms = kReceiveDelayMs;
stefanf116bd02015-10-27 08:29:42 -07003316 test::DirectTransport receiver_transport(config, receiver_call_.get());
pbos@webrtc.org2b19f062014-12-11 13:26:09 +00003317 sender_transport.SetReceiver(receiver_call_->Receiver());
3318 receiver_transport.SetReceiver(sender_call_->Receiver());
3319
Stefan Holmer9fea80f2016-01-07 17:43:18 +01003320 CreateSendConfig(1, 0, &sender_transport);
solenberg4fbae2b2015-08-28 04:07:10 -07003321 CreateMatchingReceiveConfigs(&receiver_transport);
pbos@webrtc.org2b19f062014-12-11 13:26:09 +00003322
Stefan Holmer9fea80f2016-01-07 17:43:18 +01003323 CreateVideoStreams();
pbos@webrtc.org2b19f062014-12-11 13:26:09 +00003324 CreateFrameGeneratorCapturer();
3325 Start();
3326
3327 int64_t start_time_ms = clock_->TimeInMilliseconds();
3328 while (true) {
3329 Call::Stats stats = sender_call_->GetStats();
3330 ASSERT_GE(start_time_ms + kDefaultTimeoutMs,
3331 clock_->TimeInMilliseconds())
3332 << "No RTT stats before timeout!";
3333 if (stats.rtt_ms != -1) {
3334 EXPECT_GE(stats.rtt_ms, kSendDelayMs + kReceiveDelayMs);
3335 break;
3336 }
3337 SleepMs(10);
3338 }
3339
3340 Stop();
3341 DestroyStreams();
3342}
3343
skvlad7a43d252016-03-22 15:32:27 -07003344void EndToEndTest::VerifyNewVideoSendStreamsRespectNetworkState(
3345 MediaType network_to_bring_down,
3346 VideoEncoder* encoder,
3347 Transport* transport) {
solenberg4fbae2b2015-08-28 04:07:10 -07003348 CreateSenderCall(Call::Config());
skvlad7a43d252016-03-22 15:32:27 -07003349 sender_call_->SignalChannelNetworkState(network_to_bring_down, kNetworkDown);
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00003350
skvlad7a43d252016-03-22 15:32:27 -07003351 CreateSendConfig(1, 0, transport);
3352 video_send_config_.encoder_settings.encoder = encoder;
Stefan Holmer9fea80f2016-01-07 17:43:18 +01003353 CreateVideoStreams();
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00003354 CreateFrameGeneratorCapturer();
3355
3356 Start();
3357 SleepMs(kSilenceTimeoutMs);
3358 Stop();
3359
3360 DestroyStreams();
3361}
3362
skvlad7a43d252016-03-22 15:32:27 -07003363void EndToEndTest::VerifyNewVideoReceiveStreamsRespectNetworkState(
3364 MediaType network_to_bring_down,
3365 Transport* transport) {
solenberg4fbae2b2015-08-28 04:07:10 -07003366 CreateCalls(Call::Config(), Call::Config());
skvlad7a43d252016-03-22 15:32:27 -07003367 receiver_call_->SignalChannelNetworkState(network_to_bring_down,
3368 kNetworkDown);
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00003369
stefanf116bd02015-10-27 08:29:42 -07003370 test::DirectTransport sender_transport(sender_call_.get());
solenberg4fbae2b2015-08-28 04:07:10 -07003371 sender_transport.SetReceiver(receiver_call_->Receiver());
Stefan Holmer9fea80f2016-01-07 17:43:18 +01003372 CreateSendConfig(1, 0, &sender_transport);
skvlad7a43d252016-03-22 15:32:27 -07003373 CreateMatchingReceiveConfigs(transport);
Stefan Holmer9fea80f2016-01-07 17:43:18 +01003374 CreateVideoStreams();
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00003375 CreateFrameGeneratorCapturer();
3376
3377 Start();
3378 SleepMs(kSilenceTimeoutMs);
3379 Stop();
3380
3381 sender_transport.StopSending();
3382
3383 DestroyStreams();
3384}
pbos@webrtc.org09cc6862014-11-04 13:48:15 +00003385
skvlad7a43d252016-03-22 15:32:27 -07003386TEST_F(EndToEndTest, NewVideoSendStreamsRespectVideoNetworkDown) {
3387 class UnusedEncoder : public test::FakeEncoder {
3388 public:
3389 UnusedEncoder() : FakeEncoder(Clock::GetRealTimeClock()) {}
perkjfea93092016-05-14 00:58:48 -07003390
3391 int32_t InitEncode(const VideoCodec* config,
3392 int32_t number_of_cores,
3393 size_t max_payload_size) override {
3394 EXPECT_GT(config->startBitrate, 0u);
3395 return 0;
3396 }
skvlad7a43d252016-03-22 15:32:27 -07003397 int32_t Encode(const VideoFrame& input_image,
3398 const CodecSpecificInfo* codec_specific_info,
3399 const std::vector<FrameType>* frame_types) override {
3400 ADD_FAILURE() << "Unexpected frame encode.";
3401 return test::FakeEncoder::Encode(input_image, codec_specific_info,
3402 frame_types);
3403 }
3404 };
3405
3406 UnusedEncoder unused_encoder;
3407 UnusedTransport unused_transport;
3408 VerifyNewVideoSendStreamsRespectNetworkState(
3409 MediaType::VIDEO, &unused_encoder, &unused_transport);
3410}
3411
3412TEST_F(EndToEndTest, NewVideoSendStreamsIgnoreAudioNetworkDown) {
3413 class RequiredEncoder : public test::FakeEncoder {
3414 public:
3415 RequiredEncoder()
3416 : FakeEncoder(Clock::GetRealTimeClock()), encoded_frame_(false) {}
3417 ~RequiredEncoder() {
3418 if (!encoded_frame_) {
3419 ADD_FAILURE() << "Didn't encode an expected frame";
3420 }
3421 }
3422 int32_t Encode(const VideoFrame& input_image,
3423 const CodecSpecificInfo* codec_specific_info,
3424 const std::vector<FrameType>* frame_types) override {
3425 encoded_frame_ = true;
3426 return test::FakeEncoder::Encode(input_image, codec_specific_info,
3427 frame_types);
3428 }
3429
3430 private:
3431 bool encoded_frame_;
3432 };
3433
3434 RequiredTransport required_transport(true /*rtp*/, false /*rtcp*/);
3435 RequiredEncoder required_encoder;
3436 VerifyNewVideoSendStreamsRespectNetworkState(
3437 MediaType::AUDIO, &required_encoder, &required_transport);
3438}
3439
3440TEST_F(EndToEndTest, NewVideoReceiveStreamsRespectVideoNetworkDown) {
3441 UnusedTransport transport;
3442 VerifyNewVideoReceiveStreamsRespectNetworkState(MediaType::VIDEO, &transport);
3443}
3444
3445TEST_F(EndToEndTest, NewVideoReceiveStreamsIgnoreAudioNetworkDown) {
3446 RequiredTransport transport(false /*rtp*/, true /*rtcp*/);
3447 VerifyNewVideoReceiveStreamsRespectNetworkState(MediaType::AUDIO, &transport);
3448}
3449
Peter Boströmd7da1202015-06-05 14:09:38 +02003450void VerifyEmptyNackConfig(const NackConfig& config) {
3451 EXPECT_EQ(0, config.rtp_history_ms)
3452 << "Enabling NACK requires rtcp-fb: nack negotiation.";
3453}
3454
3455void VerifyEmptyFecConfig(const FecConfig& config) {
3456 EXPECT_EQ(-1, config.ulpfec_payload_type)
3457 << "Enabling FEC requires rtpmap: ulpfec negotiation.";
3458 EXPECT_EQ(-1, config.red_payload_type)
3459 << "Enabling FEC requires rtpmap: red negotiation.";
3460 EXPECT_EQ(-1, config.red_rtx_payload_type)
3461 << "Enabling RTX in FEC requires rtpmap: rtx negotiation.";
3462}
3463
3464TEST_F(EndToEndTest, VerifyDefaultSendConfigParameters) {
solenberg4fbae2b2015-08-28 04:07:10 -07003465 VideoSendStream::Config default_send_config(nullptr);
Peter Boströmd7da1202015-06-05 14:09:38 +02003466 EXPECT_EQ(0, default_send_config.rtp.nack.rtp_history_ms)
3467 << "Enabling NACK require rtcp-fb: nack negotiation.";
3468 EXPECT_TRUE(default_send_config.rtp.rtx.ssrcs.empty())
3469 << "Enabling RTX requires rtpmap: rtx negotiation.";
3470 EXPECT_TRUE(default_send_config.rtp.extensions.empty())
3471 << "Enabling RTP extensions require negotiation.";
3472
3473 VerifyEmptyNackConfig(default_send_config.rtp.nack);
3474 VerifyEmptyFecConfig(default_send_config.rtp.fec);
3475}
3476
3477TEST_F(EndToEndTest, VerifyDefaultReceiveConfigParameters) {
solenberg4fbae2b2015-08-28 04:07:10 -07003478 VideoReceiveStream::Config default_receive_config(nullptr);
pbosda903ea2015-10-02 02:36:56 -07003479 EXPECT_EQ(RtcpMode::kCompound, default_receive_config.rtp.rtcp_mode)
Peter Boströmd7da1202015-06-05 14:09:38 +02003480 << "Reduced-size RTCP require rtcp-rsize to be negotiated.";
3481 EXPECT_FALSE(default_receive_config.rtp.remb)
3482 << "REMB require rtcp-fb: goog-remb to be negotiated.";
3483 EXPECT_FALSE(
3484 default_receive_config.rtp.rtcp_xr.receiver_reference_time_report)
3485 << "RTCP XR settings require rtcp-xr to be negotiated.";
3486 EXPECT_TRUE(default_receive_config.rtp.rtx.empty())
3487 << "Enabling RTX requires rtpmap: rtx negotiation.";
3488 EXPECT_TRUE(default_receive_config.rtp.extensions.empty())
3489 << "Enabling RTP extensions require negotiation.";
3490
3491 VerifyEmptyNackConfig(default_receive_config.rtp.nack);
3492 VerifyEmptyFecConfig(default_receive_config.rtp.fec);
3493}
3494
Stefan Holmer9fea80f2016-01-07 17:43:18 +01003495TEST_F(EndToEndTest, TransportSeqNumOnAudioAndVideo) {
3496 static const int kExtensionId = 8;
3497 class TransportSequenceNumberTest : public test::EndToEndTest {
3498 public:
3499 TransportSequenceNumberTest()
3500 : EndToEndTest(kDefaultTimeoutMs),
3501 video_observed_(false),
3502 audio_observed_(false) {
3503 parser_->RegisterRtpHeaderExtension(kRtpExtensionTransportSequenceNumber,
3504 kExtensionId);
3505 }
3506
3507 size_t GetNumVideoStreams() const override { return 1; }
3508 size_t GetNumAudioStreams() const override { return 1; }
3509
3510 void ModifyVideoConfigs(
3511 VideoSendStream::Config* send_config,
3512 std::vector<VideoReceiveStream::Config>* receive_configs,
3513 VideoEncoderConfig* encoder_config) override {
3514 send_config->rtp.extensions.clear();
isheriff6f8d6862016-05-26 11:24:55 -07003515 send_config->rtp.extensions.push_back(RtpExtension(
3516 RtpExtension::kTransportSequenceNumberUri, kExtensionId));
Stefan Holmer9fea80f2016-01-07 17:43:18 +01003517 (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
3518 }
3519
3520 void ModifyAudioConfigs(
3521 AudioSendStream::Config* send_config,
3522 std::vector<AudioReceiveStream::Config>* receive_configs) override {
3523 send_config->rtp.extensions.clear();
isheriff6f8d6862016-05-26 11:24:55 -07003524 send_config->rtp.extensions.push_back(RtpExtension(
3525 RtpExtension::kTransportSequenceNumberUri, kExtensionId));
Stefan Holmer9fea80f2016-01-07 17:43:18 +01003526 (*receive_configs)[0].rtp.extensions.clear();
3527 (*receive_configs)[0].rtp.extensions = send_config->rtp.extensions;
3528 }
3529
3530 Action OnSendRtp(const uint8_t* packet, size_t length) override {
3531 RTPHeader header;
3532 EXPECT_TRUE(parser_->Parse(packet, length, &header));
3533 EXPECT_TRUE(header.extension.hasTransportSequenceNumber);
3534 // Unwrap packet id and verify uniqueness.
3535 int64_t packet_id =
3536 unwrapper_.Unwrap(header.extension.transportSequenceNumber);
3537 EXPECT_TRUE(received_packet_ids_.insert(packet_id).second);
3538
3539 if (header.ssrc == kVideoSendSsrcs[0])
3540 video_observed_ = true;
3541 if (header.ssrc == kAudioSendSsrc)
3542 audio_observed_ = true;
3543 if (audio_observed_ && video_observed_ &&
3544 received_packet_ids_.size() == 50) {
3545 size_t packet_id_range =
3546 *received_packet_ids_.rbegin() - *received_packet_ids_.begin() + 1;
3547 EXPECT_EQ(received_packet_ids_.size(), packet_id_range);
3548 observation_complete_.Set();
3549 }
3550 return SEND_PACKET;
3551 }
3552
3553 void PerformTest() override {
3554 EXPECT_TRUE(Wait()) << "Timed out while waiting for audio and video "
3555 "packets with transport sequence number.";
3556 }
3557
3558 private:
3559 bool video_observed_;
3560 bool audio_observed_;
3561 SequenceNumberUnwrapper unwrapper_;
3562 std::set<int64_t> received_packet_ids_;
3563 } test;
3564
stefane74eef12016-01-08 06:47:13 -08003565 RunBaseTest(&test);
Stefan Holmer9fea80f2016-01-07 17:43:18 +01003566}
pbos@webrtc.org994d0b72014-06-27 08:47:52 +00003567} // namespace webrtc