blob: dd22598ca7b2d7ed814c8f3111d03aa4b56c604b [file] [log] [blame]
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001/*
kjellander1afca732016-02-07 20:46:45 -08002 * Copyright (c) 2004 The WebRTC project authors. All Rights Reserved.
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003 *
kjellander1afca732016-02-07 20:46:45 -08004 * 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.
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00009 */
10
11#include <map>
kwiberg686a8ef2016-02-26 03:00:35 -080012#include <memory>
Elad Alon040dc432019-05-22 15:40:02 +020013#include <string>
Steve Antone78bcb92017-10-31 09:53:08 -070014#include <utility>
pbos@webrtc.org86f613d2014-06-10 08:53:05 +000015#include <vector>
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000016
Steve Anton2c9ebef2019-01-28 17:27:58 -080017#include "absl/algorithm/container.h"
Niels Möller805a27e2019-01-21 12:21:27 +010018#include "absl/memory/memory.h"
Niels Möller039743e2018-10-23 10:07:25 +020019#include "absl/strings/match.h"
Anton Sukhanov4f08faa2019-05-21 11:12:57 -070020#include "api/media_transport_config.h"
Steve Anton10542f22019-01-11 09:11:00 -080021#include "api/rtp_parameters.h"
Piotr (Peter) Slatala946b9682019-03-18 10:25:02 -070022#include "api/test/fake_media_transport.h"
Jiawei Ouc2ebe212018-11-08 10:02:56 -080023#include "api/test/mock_video_bitrate_allocator.h"
24#include "api/test/mock_video_bitrate_allocator_factory.h"
Emircan Uysalerdbcac7f2017-10-30 23:10:12 -070025#include "api/test/mock_video_decoder_factory.h"
26#include "api/test/mock_video_encoder_factory.h"
Jonas Oreland49ac5952018-09-26 16:04:32 +020027#include "api/units/time_delta.h"
Jiawei Ouc2ebe212018-11-08 10:02:56 -080028#include "api/video/builtin_video_bitrate_allocator_factory.h"
Niels Möller805a27e2019-01-21 12:21:27 +010029#include "api/video/i420_buffer.h"
Åsa Persson23eba222018-10-02 14:47:06 +020030#include "api/video/video_bitrate_allocation.h"
Anders Carlsson5f2bb622018-05-14 09:48:06 +020031#include "api/video_codecs/builtin_video_decoder_factory.h"
32#include "api/video_codecs/builtin_video_encoder_factory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020033#include "api/video_codecs/sdp_video_format.h"
34#include "api/video_codecs/video_decoder_factory.h"
35#include "api/video_codecs/video_encoder.h"
36#include "api/video_codecs/video_encoder_factory.h"
37#include "call/flexfec_receive_stream.h"
38#include "common_video/h264/profile_level_id.h"
39#include "logging/rtc_event_log/rtc_event_log.h"
Niels Möller805a27e2019-01-21 12:21:27 +010040#include "media/base/fake_frame_source.h"
Steve Anton10542f22019-01-11 09:11:00 -080041#include "media/base/fake_network_interface.h"
Steve Anton10542f22019-01-11 09:11:00 -080042#include "media/base/fake_video_renderer.h"
43#include "media/base/media_constants.h"
44#include "media/base/rtp_utils.h"
45#include "media/base/test_utils.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020046#include "media/engine/constants.h"
Steve Anton10542f22019-01-11 09:11:00 -080047#include "media/engine/fake_webrtc_call.h"
48#include "media/engine/fake_webrtc_video_engine.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020049#include "media/engine/simulcast.h"
Steve Anton10542f22019-01-11 09:11:00 -080050#include "media/engine/webrtc_video_engine.h"
51#include "media/engine/webrtc_voice_engine.h"
Åsa Persson23cd45a2018-07-03 10:40:40 +020052#include "modules/rtp_rtcp/include/rtp_header_parser.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020053#include "rtc_base/arraysize.h"
Steve Anton10542f22019-01-11 09:11:00 -080054#include "rtc_base/fake_clock.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020055#include "rtc_base/gunit.h"
Yves Gerey665174f2018-06-19 15:03:05 +020056#include "rtc_base/numerics/safe_conversions.h"
Steve Antonf3802842019-01-24 19:07:40 -080057#include "rtc_base/time_utils.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020058#include "test/field_trial.h"
Niels Möllerd0f0f682019-01-14 09:09:53 +010059#include "test/frame_generator.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020060#include "test/gmock.h"
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000061
Mirko Bonadei6a489f22019-04-09 15:11:12 +020062using ::testing::Field;
Sebastian Jansson8f83b422018-02-21 13:07:13 +010063using webrtc::BitrateConstraints;
isheriff6f8d6862016-05-26 11:24:55 -070064using webrtc::RtpExtension;
65
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000066namespace {
buildbot@webrtc.orga8530772014-12-10 09:01:18 +000067static const int kDefaultQpMax = 56;
buildbot@webrtc.orga8530772014-12-10 09:01:18 +000068
noahricd10a68e2015-07-10 11:27:55 -070069static const uint8_t kRedRtxPayloadType = 125;
70
Niels Möller6557d0c2018-04-11 15:18:34 +020071static const uint32_t kTimeout = 5000U;
72static const uint32_t kDefaultReceiveSsrc = 0;
73static const uint32_t kSsrc = 1234u;
74static const uint32_t kSsrcs4[] = {1, 2, 3, 4};
75static const int kVideoWidth = 640;
76static const int kVideoHeight = 360;
77static const int kFramerate = 30;
78
Peter Boström0c4e06b2015-10-07 12:23:21 +020079static const uint32_t kSsrcs1[] = {1};
80static const uint32_t kSsrcs3[] = {1, 2, 3};
81static const uint32_t kRtxSsrcs1[] = {4};
brandtr468da7c2016-11-22 02:16:47 -080082static const uint32_t kFlexfecSsrc = 5;
Peter Boström0c4e06b2015-10-07 12:23:21 +020083static const uint32_t kIncomingUnsignalledSsrc = 0xC0FFEE;
mzanaty8a855d62017-02-17 15:46:43 -080084static const uint32_t kDefaultRecvSsrc = 0;
85
pbos@webrtc.org3c107582014-07-20 15:27:35 +000086static const char kUnsupportedExtensionName[] =
87 "urn:ietf:params:rtp-hdrext:unsupported";
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +000088
magjed509e4fe2016-11-18 01:34:11 -080089cricket::VideoCodec RemoveFeedbackParams(cricket::VideoCodec&& codec) {
90 codec.feedback_params = cricket::FeedbackParams();
Mirko Bonadei29a8d102018-04-25 23:58:26 +020091 return std::move(codec);
magjed509e4fe2016-11-18 01:34:11 -080092}
93
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +000094void VerifyCodecHasDefaultFeedbackParams(const cricket::VideoCodec& codec) {
95 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
96 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty)));
97 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
98 cricket::kRtcpFbParamNack, cricket::kRtcpFbNackParamPli)));
99 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
100 cricket::kRtcpFbParamRemb, cricket::kParamValueEmpty)));
101 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
stefan43edf0f2015-11-20 18:05:48 -0800102 cricket::kRtcpFbParamTransportCc, cricket::kParamValueEmpty)));
103 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +0000104 cricket::kRtcpFbParamCcm, cricket::kRtcpFbCcmParamFir)));
105}
106
magjed725e4842016-11-16 00:48:13 -0800107// Return true if any codec in |codecs| is an RTX codec with associated payload
108// type |payload_type|.
109bool HasRtxCodec(const std::vector<cricket::VideoCodec>& codecs,
110 int payload_type) {
111 for (const cricket::VideoCodec& codec : codecs) {
112 int associated_payload_type;
Niels Möller039743e2018-10-23 10:07:25 +0200113 if (absl::EqualsIgnoreCase(codec.name.c_str(), "rtx") &&
magjed725e4842016-11-16 00:48:13 -0800114 codec.GetParam(cricket::kCodecParamAssociatedPayloadType,
115 &associated_payload_type) &&
116 associated_payload_type == payload_type) {
117 return true;
118 }
119 }
120 return false;
121}
122
nisseca5706d2017-09-11 02:32:16 -0700123// TODO(nisse): Duplicated in call.cc.
124const int* FindKeyByValue(const std::map<int, int>& m, int v) {
125 for (const auto& kv : m) {
126 if (kv.second == v)
127 return &kv.first;
128 }
129 return nullptr;
130}
131
Yves Gerey665174f2018-06-19 15:03:05 +0200132bool HasRtxReceiveAssociation(const webrtc::VideoReceiveStream::Config& config,
133 int payload_type) {
nisseca5706d2017-09-11 02:32:16 -0700134 return FindKeyByValue(config.rtp.rtx_associated_payload_types,
135 payload_type) != nullptr;
136}
137
138// Check that there's an Rtx payload type for each decoder.
139bool VerifyRtxReceiveAssociations(
140 const webrtc::VideoReceiveStream::Config& config) {
141 for (const auto& decoder : config.decoders) {
142 if (!HasRtxReceiveAssociation(config, decoder.payload_type))
143 return false;
144 }
145 return true;
146}
147
brandtrffc61182016-11-28 06:02:22 -0800148rtc::scoped_refptr<webrtc::VideoFrameBuffer> CreateBlackFrameBuffer(
nisse64ec8f82016-09-27 00:17:25 -0700149 int width,
150 int height) {
151 rtc::scoped_refptr<webrtc::I420Buffer> buffer =
152 webrtc::I420Buffer::Create(width, height);
nisseaf916892017-01-10 07:44:26 -0800153 webrtc::I420Buffer::SetBlack(buffer);
nisse64ec8f82016-09-27 00:17:25 -0700154 return buffer;
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +0000155}
156
Shao Changbine62202f2015-04-21 20:24:50 +0800157void VerifySendStreamHasRtxTypes(const webrtc::VideoSendStream::Config& config,
158 const std::map<int, int>& rtx_types) {
159 std::map<int, int>::const_iterator it;
Niels Möller259a4972018-04-05 15:36:51 +0200160 it = rtx_types.find(config.rtp.payload_type);
Shao Changbine62202f2015-04-21 20:24:50 +0800161 EXPECT_TRUE(it != rtx_types.end() &&
162 it->second == config.rtp.rtx.payload_type);
163
brandtrb5f2c3f2016-10-04 23:28:39 -0700164 if (config.rtp.ulpfec.red_rtx_payload_type != -1) {
165 it = rtx_types.find(config.rtp.ulpfec.red_payload_type);
Shao Changbine62202f2015-04-21 20:24:50 +0800166 EXPECT_TRUE(it != rtx_types.end() &&
brandtrb5f2c3f2016-10-04 23:28:39 -0700167 it->second == config.rtp.ulpfec.red_rtx_payload_type);
Shao Changbine62202f2015-04-21 20:24:50 +0800168 }
169}
kthelgason2bc68642017-02-07 07:02:22 -0800170
171cricket::MediaConfig GetMediaConfig() {
172 cricket::MediaConfig media_config;
Niels Möller1d7ecd22018-01-18 15:25:12 +0100173 media_config.video.enable_cpu_adaptation = false;
kthelgason2bc68642017-02-07 07:02:22 -0800174 return media_config;
175}
nisse26e3abb2017-08-25 04:44:25 -0700176
Åsa Perssonbdee46d2018-06-25 11:28:06 +0200177// Values from GetMaxDefaultVideoBitrateKbps in webrtcvideoengine.cc.
178int GetMaxDefaultBitrateBps(size_t width, size_t height) {
179 if (width * height <= 320 * 240) {
180 return 600000;
181 } else if (width * height <= 640 * 480) {
182 return 1700000;
183 } else if (width * height <= 960 * 540) {
184 return 2000000;
185 } else {
186 return 2500000;
187 }
188}
189
Niels Möller731a2c22018-07-30 15:08:07 +0200190class MockVideoSource : public rtc::VideoSourceInterface<webrtc::VideoFrame> {
191 public:
192 MOCK_METHOD2(AddOrUpdateSink,
193 void(rtc::VideoSinkInterface<webrtc::VideoFrame>* sink,
194 const rtc::VideoSinkWants& wants));
195 MOCK_METHOD1(RemoveSink,
196 void(rtc::VideoSinkInterface<webrtc::VideoFrame>* sink));
197};
198
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000199} // namespace
200
Yves Gerey665174f2018-06-19 15:03:05 +0200201#define EXPECT_FRAME_WAIT(c, w, h, t) \
Niels Möller6557d0c2018-04-11 15:18:34 +0200202 EXPECT_EQ_WAIT((c), renderer_.num_rendered_frames(), (t)); \
Yves Gerey665174f2018-06-19 15:03:05 +0200203 EXPECT_EQ((w), renderer_.width()); \
204 EXPECT_EQ((h), renderer_.height()); \
Niels Möller6557d0c2018-04-11 15:18:34 +0200205 EXPECT_EQ(0, renderer_.errors());
206
Yves Gerey665174f2018-06-19 15:03:05 +0200207#define EXPECT_FRAME_ON_RENDERER_WAIT(r, c, w, h, t) \
Niels Möller6557d0c2018-04-11 15:18:34 +0200208 EXPECT_EQ_WAIT((c), (r).num_rendered_frames(), (t)); \
Yves Gerey665174f2018-06-19 15:03:05 +0200209 EXPECT_EQ((w), (r).width()); \
210 EXPECT_EQ((h), (r).height()); \
Niels Möller6557d0c2018-04-11 15:18:34 +0200211 EXPECT_EQ(0, (r).errors());
212
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000213namespace cricket {
eladalonf1841382017-06-12 01:16:46 -0700214class WebRtcVideoEngineTest : public ::testing::Test {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000215 public:
eladalonf1841382017-06-12 01:16:46 -0700216 WebRtcVideoEngineTest() : WebRtcVideoEngineTest("") {}
Elad Alon040dc432019-05-22 15:40:02 +0200217 explicit WebRtcVideoEngineTest(const std::string& field_trials)
218 : override_field_trials_(
219 field_trials.empty()
220 ? nullptr
221 : absl::make_unique<webrtc::test::ScopedFieldTrials>(
222 field_trials)),
skvlad11a9cbf2016-10-07 11:53:05 -0700223 call_(webrtc::Call::Create(webrtc::Call::Config(&event_log_))),
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200224 encoder_factory_(new cricket::FakeWebRtcVideoEncoderFactory),
225 decoder_factory_(new cricket::FakeWebRtcVideoDecoderFactory),
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +0200226 video_bitrate_allocator_factory_(
227 webrtc::CreateBuiltinVideoBitrateAllocatorFactory()),
Anders Carlsson67537952018-05-03 11:28:29 +0200228 engine_(std::unique_ptr<cricket::FakeWebRtcVideoEncoderFactory>(
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200229 encoder_factory_),
Anders Carlsson67537952018-05-03 11:28:29 +0200230 std::unique_ptr<cricket::FakeWebRtcVideoDecoderFactory>(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +0200231 decoder_factory_)) {
Ilya Nikolaevskiy9c38c472018-09-03 16:11:42 +0200232 // Ensure fake clock doesn't return 0, which will cause some initializations
233 // fail inside RTP senders.
Sebastian Jansson40889f32019-04-17 12:11:20 +0200234 fake_clock_.AdvanceTime(webrtc::TimeDelta::us(1));
Ilya Nikolaevskiy9c38c472018-09-03 16:11:42 +0200235 }
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000236
237 protected:
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200238 void AssignDefaultAptRtxTypes();
239 void AssignDefaultCodec();
240
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +0100241 // Find the index of the codec in the engine with the given name. The codec
242 // must be present.
Oleh Prypina40f8242017-12-21 13:32:23 +0100243 size_t GetEngineCodecIndex(const std::string& name) const;
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +0100244
magjed509e4fe2016-11-18 01:34:11 -0800245 // Find the codec in the engine with the given name. The codec must be
246 // present.
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +0100247 cricket::VideoCodec GetEngineCodec(const std::string& name) const;
magjed509e4fe2016-11-18 01:34:11 -0800248
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200249 VideoMediaChannel* SetSendParamsWithAllSupportedCodecs();
pbos@webrtc.orgfa553ef2014-10-20 11:07:07 +0000250
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200251 VideoMediaChannel* SetRecvParamsWithSupportedCodecs(
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000252 const std::vector<VideoCodec>& codecs);
253
Elad Alon157540a2019-02-08 23:37:52 +0100254 void ExpectRtpCapabilitySupport(const char* uri, bool supported) const;
Peter Boströme4499152016-02-05 11:13:28 +0100255
Ilya Nikolaevskiy9c38c472018-09-03 16:11:42 +0200256 // Has to be the first one, so it is initialized before the call or there is a
257 // race condition in the clock access.
258 rtc::ScopedFakeClock fake_clock_;
Elad Alon040dc432019-05-22 15:40:02 +0200259 std::unique_ptr<webrtc::test::ScopedFieldTrials> override_field_trials_;
skvlad11a9cbf2016-10-07 11:53:05 -0700260 webrtc::RtcEventLogNullImpl event_log_;
eladalonf1841382017-06-12 01:16:46 -0700261 // Used in WebRtcVideoEngineVoiceTest, but defined here so it's properly
pbos@webrtc.orgf1f0d9a2015-03-02 13:30:15 +0000262 // initialized when the constructor is called.
kwiberg686a8ef2016-02-26 03:00:35 -0800263 std::unique_ptr<webrtc::Call> call_;
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200264 cricket::FakeWebRtcVideoEncoderFactory* encoder_factory_;
265 cricket::FakeWebRtcVideoDecoderFactory* decoder_factory_;
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +0200266 std::unique_ptr<webrtc::VideoBitrateAllocatorFactory>
267 video_bitrate_allocator_factory_;
eladalonf1841382017-06-12 01:16:46 -0700268 WebRtcVideoEngine engine_;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000269 VideoCodec default_codec_;
Shao Changbine62202f2015-04-21 20:24:50 +0800270 std::map<int, int> default_apt_rtx_types_;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000271};
272
eladalonf1841382017-06-12 01:16:46 -0700273TEST_F(WebRtcVideoEngineTest, DefaultRtxCodecHasAssociatedPayloadTypeSet) {
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200274 encoder_factory_->AddSupportedVideoCodecType("VP8");
275 AssignDefaultCodec();
276
pbos@webrtc.orge322a172014-06-13 11:47:28 +0000277 std::vector<VideoCodec> engine_codecs = engine_.codecs();
278 for (size_t i = 0; i < engine_codecs.size(); ++i) {
279 if (engine_codecs[i].name != kRtxCodecName)
280 continue;
281 int associated_payload_type;
282 EXPECT_TRUE(engine_codecs[i].GetParam(kCodecParamAssociatedPayloadType,
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000283 &associated_payload_type));
pbos@webrtc.orge322a172014-06-13 11:47:28 +0000284 EXPECT_EQ(default_codec_.id, associated_payload_type);
285 return;
286 }
287 FAIL() << "No RTX codec found among default codecs.";
288}
289
eladalonf1841382017-06-12 01:16:46 -0700290TEST_F(WebRtcVideoEngineTest, SupportsTimestampOffsetHeaderExtension) {
Elad Alon157540a2019-02-08 23:37:52 +0100291 ExpectRtpCapabilitySupport(RtpExtension::kTimestampOffsetUri, true);
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000292}
293
eladalonf1841382017-06-12 01:16:46 -0700294TEST_F(WebRtcVideoEngineTest, SupportsAbsoluteSenderTimeHeaderExtension) {
Elad Alon157540a2019-02-08 23:37:52 +0100295 ExpectRtpCapabilitySupport(RtpExtension::kAbsSendTimeUri, true);
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000296}
297
eladalonf1841382017-06-12 01:16:46 -0700298TEST_F(WebRtcVideoEngineTest, SupportsTransportSequenceNumberHeaderExtension) {
Elad Alon157540a2019-02-08 23:37:52 +0100299 ExpectRtpCapabilitySupport(RtpExtension::kTransportSequenceNumberUri, true);
stefanc1aeaf02015-10-15 07:26:07 -0700300}
301
eladalonf1841382017-06-12 01:16:46 -0700302TEST_F(WebRtcVideoEngineTest, SupportsVideoRotationHeaderExtension) {
Elad Alon157540a2019-02-08 23:37:52 +0100303 ExpectRtpCapabilitySupport(RtpExtension::kVideoRotationUri, true);
304}
305
306TEST_F(WebRtcVideoEngineTest, SupportsPlayoutDelayHeaderExtension) {
307 ExpectRtpCapabilitySupport(RtpExtension::kPlayoutDelayUri, true);
308}
309
310TEST_F(WebRtcVideoEngineTest, SupportsVideoContentTypeHeaderExtension) {
311 ExpectRtpCapabilitySupport(RtpExtension::kVideoContentTypeUri, true);
312}
313
314TEST_F(WebRtcVideoEngineTest, SupportsVideoTimingHeaderExtension) {
315 ExpectRtpCapabilitySupport(RtpExtension::kVideoTimingUri, true);
316}
317
318TEST_F(WebRtcVideoEngineTest, SupportsFrameMarkingHeaderExtension) {
319 ExpectRtpCapabilitySupport(RtpExtension::kFrameMarkingUri, true);
Johannes Krond0b69a82018-12-03 14:18:53 +0100320}
321
322TEST_F(WebRtcVideoEngineTest, SupportsColorSpaceHeaderExtension) {
Elad Alon157540a2019-02-08 23:37:52 +0100323 ExpectRtpCapabilitySupport(RtpExtension::kColorSpaceUri, true);
324}
325
Elad Alonccb9b752019-02-19 13:01:31 +0100326TEST_F(WebRtcVideoEngineTest, AdvertiseGenericDescriptor00) {
327 ExpectRtpCapabilitySupport(RtpExtension::kGenericFrameDescriptorUri00, false);
328}
329
330TEST_F(WebRtcVideoEngineTest, AdvertiseGenericDescriptor01) {
331 ExpectRtpCapabilitySupport(RtpExtension::kGenericFrameDescriptorUri01, false);
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700332}
333
philipel1e054862018-10-08 16:13:53 +0200334class WebRtcVideoEngineTestWithGenericDescriptor
335 : public WebRtcVideoEngineTest {
336 public:
337 WebRtcVideoEngineTestWithGenericDescriptor()
338 : WebRtcVideoEngineTest("WebRTC-GenericDescriptorAdvertised/Enabled/") {}
339};
340
Elad Alonccb9b752019-02-19 13:01:31 +0100341TEST_F(WebRtcVideoEngineTestWithGenericDescriptor,
342 AdvertiseGenericDescriptor00) {
343 ExpectRtpCapabilitySupport(RtpExtension::kGenericFrameDescriptorUri00, true);
344}
345
346TEST_F(WebRtcVideoEngineTestWithGenericDescriptor,
347 AdvertiseGenericDescriptor01) {
348 ExpectRtpCapabilitySupport(RtpExtension::kGenericFrameDescriptorUri01, true);
philipel1e054862018-10-08 16:13:53 +0200349}
350
eladalonf1841382017-06-12 01:16:46 -0700351TEST_F(WebRtcVideoEngineTest, CVOSetHeaderExtensionBeforeCapturer) {
Niels Möller731a2c22018-07-30 15:08:07 +0200352 // Allocate the source first to prevent early destruction before channel's
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700353 // dtor is called.
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200354 ::testing::NiceMock<MockVideoSource> video_source;
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700355
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200356 encoder_factory_->AddSupportedVideoCodecType("VP8");
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700357
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200358 std::unique_ptr<VideoMediaChannel> channel(
359 SetSendParamsWithAllSupportedCodecs());
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700360 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(kSsrc)));
361
362 // Add CVO extension.
363 const int id = 1;
magjed509e4fe2016-11-18 01:34:11 -0800364 cricket::VideoSendParameters parameters;
365 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200366 parameters.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -0700367 RtpExtension(RtpExtension::kVideoRotationUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200368 EXPECT_TRUE(channel->SetSendParameters(parameters));
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700369
Niels Möller731a2c22018-07-30 15:08:07 +0200370 EXPECT_CALL(
371 video_source,
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200372 AddOrUpdateSink(::testing::_,
Niels Möller731a2c22018-07-30 15:08:07 +0200373 Field(&rtc::VideoSinkWants::rotation_applied, false)));
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700374 // Set capturer.
Niels Möller731a2c22018-07-30 15:08:07 +0200375 EXPECT_TRUE(channel->SetVideoSend(kSsrc, nullptr, &video_source));
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700376
377 // Verify capturer has turned off applying rotation.
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200378 ::testing::Mock::VerifyAndClear(&video_source);
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700379
380 // Verify removing header extension turns on applying rotation.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200381 parameters.extensions.clear();
Niels Möller731a2c22018-07-30 15:08:07 +0200382 EXPECT_CALL(
383 video_source,
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200384 AddOrUpdateSink(::testing::_,
Niels Möller731a2c22018-07-30 15:08:07 +0200385 Field(&rtc::VideoSinkWants::rotation_applied, true)));
386
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200387 EXPECT_TRUE(channel->SetSendParameters(parameters));
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700388}
389
eladalonf1841382017-06-12 01:16:46 -0700390TEST_F(WebRtcVideoEngineTest, CVOSetHeaderExtensionBeforeAddSendStream) {
Niels Möller731a2c22018-07-30 15:08:07 +0200391 // Allocate the source first to prevent early destruction before channel's
perkj91e1c152016-03-02 05:34:00 -0800392 // dtor is called.
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200393 ::testing::NiceMock<MockVideoSource> video_source;
perkj91e1c152016-03-02 05:34:00 -0800394
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200395 encoder_factory_->AddSupportedVideoCodecType("VP8");
perkj91e1c152016-03-02 05:34:00 -0800396
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200397 std::unique_ptr<VideoMediaChannel> channel(
398 SetSendParamsWithAllSupportedCodecs());
perkj91e1c152016-03-02 05:34:00 -0800399 // Add CVO extension.
400 const int id = 1;
magjed509e4fe2016-11-18 01:34:11 -0800401 cricket::VideoSendParameters parameters;
402 parameters.codecs.push_back(GetEngineCodec("VP8"));
perkj91e1c152016-03-02 05:34:00 -0800403 parameters.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -0700404 RtpExtension(RtpExtension::kVideoRotationUri, id));
perkj91e1c152016-03-02 05:34:00 -0800405 EXPECT_TRUE(channel->SetSendParameters(parameters));
406 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(kSsrc)));
407
Niels Möller731a2c22018-07-30 15:08:07 +0200408 // Set source.
409 EXPECT_CALL(
410 video_source,
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200411 AddOrUpdateSink(::testing::_,
Niels Möller731a2c22018-07-30 15:08:07 +0200412 Field(&rtc::VideoSinkWants::rotation_applied, false)));
413 EXPECT_TRUE(channel->SetVideoSend(kSsrc, nullptr, &video_source));
perkj91e1c152016-03-02 05:34:00 -0800414}
415
eladalonf1841382017-06-12 01:16:46 -0700416TEST_F(WebRtcVideoEngineTest, CVOSetHeaderExtensionAfterCapturer) {
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200417 ::testing::NiceMock<MockVideoSource> video_source;
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700418
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200419 encoder_factory_->AddSupportedVideoCodecType("VP8");
420 encoder_factory_->AddSupportedVideoCodecType("VP9");
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700421
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200422 std::unique_ptr<VideoMediaChannel> channel(
423 SetSendParamsWithAllSupportedCodecs());
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700424 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(kSsrc)));
425
426 // Set capturer.
Niels Möller731a2c22018-07-30 15:08:07 +0200427 EXPECT_CALL(
428 video_source,
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200429 AddOrUpdateSink(::testing::_,
Niels Möller731a2c22018-07-30 15:08:07 +0200430 Field(&rtc::VideoSinkWants::rotation_applied, true)));
431 EXPECT_TRUE(channel->SetVideoSend(kSsrc, nullptr, &video_source));
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700432
perkjcaafdba2016-03-20 07:34:29 -0700433 // Verify capturer has turned on applying rotation.
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200434 ::testing::Mock::VerifyAndClear(&video_source);
perkjcaafdba2016-03-20 07:34:29 -0700435
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700436 // Add CVO extension.
437 const int id = 1;
magjed509e4fe2016-11-18 01:34:11 -0800438 cricket::VideoSendParameters parameters;
439 parameters.codecs.push_back(GetEngineCodec("VP8"));
440 parameters.codecs.push_back(GetEngineCodec("VP9"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200441 parameters.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -0700442 RtpExtension(RtpExtension::kVideoRotationUri, id));
perkjcaafdba2016-03-20 07:34:29 -0700443 // Also remove the first codec to trigger a codec change as well.
444 parameters.codecs.erase(parameters.codecs.begin());
Niels Möller731a2c22018-07-30 15:08:07 +0200445 EXPECT_CALL(
446 video_source,
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200447 AddOrUpdateSink(::testing::_,
Niels Möller731a2c22018-07-30 15:08:07 +0200448 Field(&rtc::VideoSinkWants::rotation_applied, false)));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200449 EXPECT_TRUE(channel->SetSendParameters(parameters));
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700450
451 // Verify capturer has turned off applying rotation.
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200452 ::testing::Mock::VerifyAndClear(&video_source);
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700453
454 // Verify removing header extension turns on applying rotation.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200455 parameters.extensions.clear();
Niels Möller731a2c22018-07-30 15:08:07 +0200456 EXPECT_CALL(
457 video_source,
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200458 AddOrUpdateSink(::testing::_,
Niels Möller731a2c22018-07-30 15:08:07 +0200459 Field(&rtc::VideoSinkWants::rotation_applied, true)));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200460 EXPECT_TRUE(channel->SetSendParameters(parameters));
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700461}
462
eladalonf1841382017-06-12 01:16:46 -0700463TEST_F(WebRtcVideoEngineTest, SetSendFailsBeforeSettingCodecs) {
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200464 encoder_factory_->AddSupportedVideoCodecType("VP8");
465
Sebastian Jansson84848f22018-11-16 10:40:36 +0100466 std::unique_ptr<VideoMediaChannel> channel(engine_.CreateMediaChannel(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +0200467 call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
468 video_bitrate_allocator_factory_.get()));
pbos@webrtc.org5301b0f2014-07-17 08:51:46 +0000469
470 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(123)));
471
472 EXPECT_FALSE(channel->SetSend(true))
473 << "Channel should not start without codecs.";
474 EXPECT_TRUE(channel->SetSend(false))
475 << "Channel should be stoppable even without set codecs.";
476}
477
eladalonf1841382017-06-12 01:16:46 -0700478TEST_F(WebRtcVideoEngineTest, GetStatsWithoutSendCodecsSetDoesNotCrash) {
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200479 encoder_factory_->AddSupportedVideoCodecType("VP8");
480
Sebastian Jansson84848f22018-11-16 10:40:36 +0100481 std::unique_ptr<VideoMediaChannel> channel(engine_.CreateMediaChannel(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +0200482 call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
483 video_bitrate_allocator_factory_.get()));
pbos@webrtc.orgc3d2bd22014-08-12 20:55:10 +0000484 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(123)));
485 VideoMediaInfo info;
486 channel->GetStats(&info);
487}
488
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200489TEST_F(WebRtcVideoEngineTest, UseFactoryForVp8WhenSupported) {
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200490 encoder_factory_->AddSupportedVideoCodecType("VP8");
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000491
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200492 std::unique_ptr<VideoMediaChannel> channel(
493 SetSendParamsWithAllSupportedCodecs());
Sergey Ulanove2b15012016-11-22 16:08:30 -0800494 channel->OnReadyToSend(true);
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000495
496 EXPECT_TRUE(
497 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200498 EXPECT_EQ(0, encoder_factory_->GetNumCreatedEncoders());
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000499 EXPECT_TRUE(channel->SetSend(true));
Niels Möllerd0f0f682019-01-14 09:09:53 +0100500 webrtc::test::FrameForwarder frame_forwarder;
501 cricket::FakeFrameSource frame_source(1280, 720,
502 rtc::kNumMicrosecsPerSec / 30);
503 EXPECT_TRUE(channel->SetVideoSend(kSsrc, nullptr, &frame_forwarder));
504 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
Per21d45d22016-10-30 21:37:57 +0100505 // Sending one frame will have allocate the encoder.
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200506 ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(1));
507 EXPECT_TRUE_WAIT(encoder_factory_->encoders()[0]->GetNumEncodedFrames() > 0,
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000508 kTimeout);
509
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200510 int num_created_encoders = encoder_factory_->GetNumCreatedEncoders();
Per21d45d22016-10-30 21:37:57 +0100511 EXPECT_EQ(num_created_encoders, 1);
pbos@webrtc.org86196c42015-02-16 21:02:00 +0000512
513 // Setting codecs of the same type should not reallocate any encoders
514 // (expecting a no-op).
magjed509e4fe2016-11-18 01:34:11 -0800515 cricket::VideoSendParameters parameters;
516 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200517 EXPECT_TRUE(channel->SetSendParameters(parameters));
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200518 EXPECT_EQ(num_created_encoders, encoder_factory_->GetNumCreatedEncoders());
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000519
520 // Remove stream previously added to free the external encoder instance.
521 EXPECT_TRUE(channel->RemoveSendStream(kSsrc));
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200522 EXPECT_EQ(0u, encoder_factory_->encoders().size());
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000523}
524
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200525// Test that when an encoder factory supports H264, we add an RTX
526// codec for it.
527// TODO(deadbeef): This test should be updated if/when we start
528// adding RTX codecs for unrecognized codec names.
529TEST_F(WebRtcVideoEngineTest, RtxCodecAddedForH264Codec) {
magjed725e4842016-11-16 00:48:13 -0800530 using webrtc::H264::ProfileLevelIdToString;
531 using webrtc::H264::ProfileLevelId;
532 using webrtc::H264::kLevel1;
Anders Carlsson67537952018-05-03 11:28:29 +0200533 webrtc::SdpVideoFormat h264_constrained_baseline("H264");
534 h264_constrained_baseline.parameters[kH264FmtpProfileLevelId] =
magjed725e4842016-11-16 00:48:13 -0800535 *ProfileLevelIdToString(
536 ProfileLevelId(webrtc::H264::kProfileConstrainedBaseline, kLevel1));
Anders Carlsson67537952018-05-03 11:28:29 +0200537 webrtc::SdpVideoFormat h264_constrained_high("H264");
538 h264_constrained_high.parameters[kH264FmtpProfileLevelId] =
magjed725e4842016-11-16 00:48:13 -0800539 *ProfileLevelIdToString(
540 ProfileLevelId(webrtc::H264::kProfileConstrainedHigh, kLevel1));
Anders Carlsson67537952018-05-03 11:28:29 +0200541 webrtc::SdpVideoFormat h264_high("H264");
542 h264_high.parameters[kH264FmtpProfileLevelId] = *ProfileLevelIdToString(
magjed725e4842016-11-16 00:48:13 -0800543 ProfileLevelId(webrtc::H264::kProfileHigh, kLevel1));
544
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200545 encoder_factory_->AddSupportedVideoCodec(h264_constrained_baseline);
546 encoder_factory_->AddSupportedVideoCodec(h264_constrained_high);
547 encoder_factory_->AddSupportedVideoCodec(h264_high);
Taylor Brandstetter6c3e7882016-06-29 11:14:19 -0700548
magjed725e4842016-11-16 00:48:13 -0800549 // First figure out what payload types the test codecs got assigned.
550 const std::vector<cricket::VideoCodec> codecs = engine_.codecs();
magjed509e4fe2016-11-18 01:34:11 -0800551 // Now search for RTX codecs for them. Expect that they all have associated
552 // RTX codecs.
magjed725e4842016-11-16 00:48:13 -0800553 EXPECT_TRUE(HasRtxCodec(
Anders Carlsson67537952018-05-03 11:28:29 +0200554 codecs,
555 FindMatchingCodec(codecs, cricket::VideoCodec(h264_constrained_baseline))
556 ->id));
magjed725e4842016-11-16 00:48:13 -0800557 EXPECT_TRUE(HasRtxCodec(
Anders Carlsson67537952018-05-03 11:28:29 +0200558 codecs,
559 FindMatchingCodec(codecs, cricket::VideoCodec(h264_constrained_high))
560 ->id));
magjed509e4fe2016-11-18 01:34:11 -0800561 EXPECT_TRUE(HasRtxCodec(
Anders Carlsson67537952018-05-03 11:28:29 +0200562 codecs, FindMatchingCodec(codecs, cricket::VideoCodec(h264_high))->id));
Taylor Brandstetter6c3e7882016-06-29 11:14:19 -0700563}
564
Mirko Bonadei8ef57932018-11-16 14:38:03 +0100565#if defined(RTC_ENABLE_VP9)
eladalonf1841382017-06-12 01:16:46 -0700566TEST_F(WebRtcVideoEngineTest, CanConstructDecoderForVp9EncoderFactory) {
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200567 encoder_factory_->AddSupportedVideoCodecType("VP9");
Peter Boström53eda3d2015-03-27 15:53:18 +0100568
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200569 std::unique_ptr<VideoMediaChannel> channel(
570 SetSendParamsWithAllSupportedCodecs());
Peter Boström53eda3d2015-03-27 15:53:18 +0100571
572 EXPECT_TRUE(
573 channel->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
574}
Mirko Bonadei8ef57932018-11-16 14:38:03 +0100575#endif // defined(RTC_ENABLE_VP9)
Peter Boström53eda3d2015-03-27 15:53:18 +0100576
eladalonf1841382017-06-12 01:16:46 -0700577TEST_F(WebRtcVideoEngineTest, PropagatesInputFrameTimestamp) {
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200578 encoder_factory_->AddSupportedVideoCodecType("VP8");
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100579 FakeCall* fake_call = new FakeCall();
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200580 call_.reset(fake_call);
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200581 std::unique_ptr<VideoMediaChannel> channel(
582 SetSendParamsWithAllSupportedCodecs());
qiangchenc27d89f2015-07-16 10:27:16 -0700583
584 EXPECT_TRUE(
585 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
586
Niels Möllerd0f0f682019-01-14 09:09:53 +0100587 webrtc::test::FrameForwarder frame_forwarder;
588 cricket::FakeFrameSource frame_source(1280, 720,
589 rtc::kNumMicrosecsPerSec / 60);
590 EXPECT_TRUE(channel->SetVideoSend(kSsrc, nullptr, &frame_forwarder));
qiangchenc27d89f2015-07-16 10:27:16 -0700591 channel->SetSend(true);
592
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200593 FakeVideoSendStream* stream = fake_call->GetVideoSendStreams()[0];
qiangchenc27d89f2015-07-16 10:27:16 -0700594
Niels Möllerd0f0f682019-01-14 09:09:53 +0100595 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
pbos1cb121d2015-09-14 11:38:38 -0700596 int64_t last_timestamp = stream->GetLastTimestamp();
qiangchenc27d89f2015-07-16 10:27:16 -0700597 for (int i = 0; i < 10; i++) {
Niels Möllerd0f0f682019-01-14 09:09:53 +0100598 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
pbos1cb121d2015-09-14 11:38:38 -0700599 int64_t timestamp = stream->GetLastTimestamp();
qiangchenc27d89f2015-07-16 10:27:16 -0700600 int64_t interval = timestamp - last_timestamp;
601
602 // Precision changes from nanosecond to millisecond.
603 // Allow error to be no more than 1.
604 EXPECT_NEAR(cricket::VideoFormat::FpsToInterval(60) / 1E6, interval, 1);
605
606 last_timestamp = timestamp;
607 }
608
Niels Möllerd0f0f682019-01-14 09:09:53 +0100609 frame_forwarder.IncomingCapturedFrame(
610 frame_source.GetFrame(1280, 720, webrtc::VideoRotation::kVideoRotation_0,
611 rtc::kNumMicrosecsPerSec / 30));
qiangchenc27d89f2015-07-16 10:27:16 -0700612 last_timestamp = stream->GetLastTimestamp();
613 for (int i = 0; i < 10; i++) {
Niels Möllerd0f0f682019-01-14 09:09:53 +0100614 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame(
615 1280, 720, webrtc::VideoRotation::kVideoRotation_0,
616 rtc::kNumMicrosecsPerSec / 30));
pbos1cb121d2015-09-14 11:38:38 -0700617 int64_t timestamp = stream->GetLastTimestamp();
qiangchenc27d89f2015-07-16 10:27:16 -0700618 int64_t interval = timestamp - last_timestamp;
619
620 // Precision changes from nanosecond to millisecond.
621 // Allow error to be no more than 1.
622 EXPECT_NEAR(cricket::VideoFormat::FpsToInterval(30) / 1E6, interval, 1);
623
624 last_timestamp = timestamp;
625 }
626
627 // Remove stream previously added to free the external encoder instance.
628 EXPECT_TRUE(channel->RemoveSendStream(kSsrc));
629}
630
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200631void WebRtcVideoEngineTest::AssignDefaultAptRtxTypes() {
632 std::vector<VideoCodec> engine_codecs = engine_.codecs();
633 RTC_DCHECK(!engine_codecs.empty());
634 for (const cricket::VideoCodec& codec : engine_codecs) {
635 if (codec.name == "rtx") {
636 int associated_payload_type;
637 if (codec.GetParam(kCodecParamAssociatedPayloadType,
638 &associated_payload_type)) {
639 default_apt_rtx_types_[associated_payload_type] = codec.id;
640 }
641 }
642 }
643}
644
645void WebRtcVideoEngineTest::AssignDefaultCodec() {
646 std::vector<VideoCodec> engine_codecs = engine_.codecs();
647 RTC_DCHECK(!engine_codecs.empty());
648 bool codec_set = false;
649 for (const cricket::VideoCodec& codec : engine_codecs) {
650 if (!codec_set && codec.name != "rtx" && codec.name != "red" &&
651 codec.name != "ulpfec") {
652 default_codec_ = codec;
653 codec_set = true;
654 }
655 }
656
657 RTC_DCHECK(codec_set);
658}
659
Oleh Prypina40f8242017-12-21 13:32:23 +0100660size_t WebRtcVideoEngineTest::GetEngineCodecIndex(
661 const std::string& name) const {
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +0100662 const std::vector<cricket::VideoCodec> codecs = engine_.codecs();
663 for (size_t i = 0; i < codecs.size(); ++i) {
664 const cricket::VideoCodec engine_codec = codecs[i];
Niels Möller039743e2018-10-23 10:07:25 +0200665 if (!absl::EqualsIgnoreCase(name, engine_codec.name))
Magnus Jedvert8deb8182017-10-05 13:13:32 +0200666 continue;
667 // The tests only use H264 Constrained Baseline. Make sure we don't return
668 // an internal H264 codec from the engine with a different H264 profile.
Niels Möller039743e2018-10-23 10:07:25 +0200669 if (absl::EqualsIgnoreCase(name.c_str(), kH264CodecName)) {
Danil Chapovalov00c71832018-06-15 15:58:38 +0200670 const absl::optional<webrtc::H264::ProfileLevelId> profile_level_id =
Magnus Jedvert8deb8182017-10-05 13:13:32 +0200671 webrtc::H264::ParseSdpProfileLevelId(engine_codec.params);
672 if (profile_level_id->profile !=
673 webrtc::H264::kProfileConstrainedBaseline) {
674 continue;
675 }
676 }
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +0100677 return i;
magjed509e4fe2016-11-18 01:34:11 -0800678 }
679 // This point should never be reached.
680 ADD_FAILURE() << "Unrecognized codec name: " << name;
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +0100681 return -1;
682}
683
684cricket::VideoCodec WebRtcVideoEngineTest::GetEngineCodec(
685 const std::string& name) const {
686 return engine_.codecs()[GetEngineCodecIndex(name)];
magjed509e4fe2016-11-18 01:34:11 -0800687}
688
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200689VideoMediaChannel*
690WebRtcVideoEngineTest::SetSendParamsWithAllSupportedCodecs() {
Sebastian Jansson84848f22018-11-16 10:40:36 +0100691 VideoMediaChannel* channel = engine_.CreateMediaChannel(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +0200692 call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
693 video_bitrate_allocator_factory_.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200694 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -0800695 // We need to look up the codec in the engine to get the correct payload type.
Anders Carlsson67537952018-05-03 11:28:29 +0200696 for (const webrtc::SdpVideoFormat& format :
697 encoder_factory_->GetSupportedFormats()) {
698 cricket::VideoCodec engine_codec = GetEngineCodec(format.name);
Steve Anton2c9ebef2019-01-28 17:27:58 -0800699 if (!absl::c_linear_search(parameters.codecs, engine_codec)) {
Anders Carlsson67537952018-05-03 11:28:29 +0200700 parameters.codecs.push_back(engine_codec);
701 }
702 }
magjed509e4fe2016-11-18 01:34:11 -0800703
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200704 EXPECT_TRUE(channel->SetSendParameters(parameters));
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000705
706 return channel;
707}
708
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200709VideoMediaChannel* WebRtcVideoEngineTest::SetRecvParamsWithSupportedCodecs(
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000710 const std::vector<VideoCodec>& codecs) {
Sebastian Jansson84848f22018-11-16 10:40:36 +0100711 VideoMediaChannel* channel = engine_.CreateMediaChannel(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +0200712 call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
713 video_bitrate_allocator_factory_.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200714 cricket::VideoRecvParameters parameters;
715 parameters.codecs = codecs;
716 EXPECT_TRUE(channel->SetRecvParameters(parameters));
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000717
718 return channel;
719}
720
Elad Alon157540a2019-02-08 23:37:52 +0100721void WebRtcVideoEngineTest::ExpectRtpCapabilitySupport(const char* uri,
722 bool supported) const {
723 const RtpCapabilities capabilities = engine_.GetCapabilities();
724 if (supported) {
725 EXPECT_THAT(capabilities.header_extensions,
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200726 ::testing::Contains(::testing::Field(&RtpExtension::uri, uri)));
Elad Alon157540a2019-02-08 23:37:52 +0100727 } else {
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200728 EXPECT_THAT(capabilities.header_extensions,
729 ::testing::Each(::testing::Field(&RtpExtension::uri,
730 ::testing::StrNe(uri))));
Elad Alon157540a2019-02-08 23:37:52 +0100731 }
732}
733
eladalonf1841382017-06-12 01:16:46 -0700734TEST_F(WebRtcVideoEngineTest, UsesSimulcastAdapterForVp8Factories) {
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200735 encoder_factory_->AddSupportedVideoCodecType("VP8");
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000736
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200737 std::unique_ptr<VideoMediaChannel> channel(
738 SetSendParamsWithAllSupportedCodecs());
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000739
Peter Boström0c4e06b2015-10-07 12:23:21 +0200740 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000741
Yves Gerey665174f2018-06-19 15:03:05 +0200742 EXPECT_TRUE(channel->AddSendStream(CreateSimStreamParams("cname", ssrcs)));
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000743 EXPECT_TRUE(channel->SetSend(true));
744
Niels Möller805a27e2019-01-21 12:21:27 +0100745 webrtc::test::FrameForwarder frame_forwarder;
746 cricket::FakeFrameSource frame_source(1280, 720,
747 rtc::kNumMicrosecsPerSec / 60);
748 EXPECT_TRUE(channel->SetVideoSend(ssrcs.front(), nullptr, &frame_forwarder));
749 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
pbos@webrtc.org86196c42015-02-16 21:02:00 +0000750
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200751 ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(2));
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000752
753 // Verify that encoders are configured for simulcast through adapter
754 // (increasing resolution and only configured to send one stream each).
755 int prev_width = -1;
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200756 for (size_t i = 0; i < encoder_factory_->encoders().size(); ++i) {
757 ASSERT_TRUE(encoder_factory_->encoders()[i]->WaitForInitEncode());
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000758 webrtc::VideoCodec codec_settings =
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200759 encoder_factory_->encoders()[i]->GetCodecSettings();
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000760 EXPECT_EQ(0, codec_settings.numberOfSimulcastStreams);
761 EXPECT_GT(codec_settings.width, prev_width);
762 prev_width = codec_settings.width;
763 }
pbos@webrtc.org86196c42015-02-16 21:02:00 +0000764
Niels Möllerff40b142018-04-09 08:49:14 +0200765 EXPECT_TRUE(channel->SetVideoSend(ssrcs.front(), nullptr, nullptr));
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000766
767 channel.reset();
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200768 ASSERT_EQ(0u, encoder_factory_->encoders().size());
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000769}
770
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200771TEST_F(WebRtcVideoEngineTest, ChannelWithH264CanChangeToVp8) {
772 encoder_factory_->AddSupportedVideoCodecType("VP8");
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200773 encoder_factory_->AddSupportedVideoCodecType("H264");
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000774
Niels Möllerd0f0f682019-01-14 09:09:53 +0100775 // Frame source.
776 webrtc::test::FrameForwarder frame_forwarder;
777 cricket::FakeFrameSource frame_source(1280, 720,
778 rtc::kNumMicrosecsPerSec / 30);
Niels Möller4db138e2018-04-19 09:04:13 +0200779
Sebastian Jansson84848f22018-11-16 10:40:36 +0100780 std::unique_ptr<VideoMediaChannel> channel(engine_.CreateMediaChannel(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +0200781 call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
782 video_bitrate_allocator_factory_.get()));
Anders Carlsson67537952018-05-03 11:28:29 +0200783 cricket::VideoSendParameters parameters;
784 parameters.codecs.push_back(GetEngineCodec("H264"));
785 EXPECT_TRUE(channel->SetSendParameters(parameters));
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000786
787 EXPECT_TRUE(
788 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
Niels Möllerd0f0f682019-01-14 09:09:53 +0100789 EXPECT_TRUE(channel->SetVideoSend(kSsrc, nullptr, &frame_forwarder));
Niels Möller4db138e2018-04-19 09:04:13 +0200790 // Sending one frame will have allocate the encoder.
Niels Möllerd0f0f682019-01-14 09:09:53 +0100791 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
Niels Möller4db138e2018-04-19 09:04:13 +0200792
793 ASSERT_EQ_WAIT(1u, encoder_factory_->encoders().size(), kTimeout);
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000794
Anders Carlsson67537952018-05-03 11:28:29 +0200795 cricket::VideoSendParameters new_parameters;
796 new_parameters.codecs.push_back(GetEngineCodec("VP8"));
797 EXPECT_TRUE(channel->SetSendParameters(new_parameters));
Niels Möller4db138e2018-04-19 09:04:13 +0200798
799 // Sending one frame will switch encoder.
Niels Möllerd0f0f682019-01-14 09:09:53 +0100800 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
Niels Möller4db138e2018-04-19 09:04:13 +0200801
Anders Carlsson8a150d92018-05-14 12:40:04 +0200802 EXPECT_EQ_WAIT(1u, encoder_factory_->encoders().size(), kTimeout);
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000803}
804
eladalonf1841382017-06-12 01:16:46 -0700805TEST_F(WebRtcVideoEngineTest,
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000806 UsesSimulcastAdapterForVp8WithCombinedVP8AndH264Factory) {
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200807 encoder_factory_->AddSupportedVideoCodecType("VP8");
808 encoder_factory_->AddSupportedVideoCodecType("H264");
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000809
Sebastian Jansson84848f22018-11-16 10:40:36 +0100810 std::unique_ptr<VideoMediaChannel> channel(engine_.CreateMediaChannel(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +0200811 call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
812 video_bitrate_allocator_factory_.get()));
magjed509e4fe2016-11-18 01:34:11 -0800813 cricket::VideoSendParameters parameters;
814 parameters.codecs.push_back(GetEngineCodec("VP8"));
815 EXPECT_TRUE(channel->SetSendParameters(parameters));
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000816
Peter Boström0c4e06b2015-10-07 12:23:21 +0200817 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000818
Yves Gerey665174f2018-06-19 15:03:05 +0200819 EXPECT_TRUE(channel->AddSendStream(CreateSimStreamParams("cname", ssrcs)));
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000820 EXPECT_TRUE(channel->SetSend(true));
821
822 // Send a fake frame, or else the media engine will configure the simulcast
823 // encoder adapter at a low-enough size that it'll only create a single
824 // encoder layer.
Niels Möller805a27e2019-01-21 12:21:27 +0100825 webrtc::test::FrameForwarder frame_forwarder;
826 cricket::FakeFrameSource frame_source(1280, 720,
827 rtc::kNumMicrosecsPerSec / 30);
828 EXPECT_TRUE(channel->SetVideoSend(ssrcs.front(), nullptr, &frame_forwarder));
829 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000830
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200831 ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(2));
832 ASSERT_TRUE(encoder_factory_->encoders()[0]->WaitForInitEncode());
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000833 EXPECT_EQ(webrtc::kVideoCodecVP8,
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200834 encoder_factory_->encoders()[0]->GetCodecSettings().codecType);
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000835
836 channel.reset();
837 // Make sure DestroyVideoEncoder was called on the factory.
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200838 EXPECT_EQ(0u, encoder_factory_->encoders().size());
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000839}
840
eladalonf1841382017-06-12 01:16:46 -0700841TEST_F(WebRtcVideoEngineTest,
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000842 DestroysNonSimulcastEncoderFromCombinedVP8AndH264Factory) {
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200843 encoder_factory_->AddSupportedVideoCodecType("VP8");
844 encoder_factory_->AddSupportedVideoCodecType("H264");
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000845
Sebastian Jansson84848f22018-11-16 10:40:36 +0100846 std::unique_ptr<VideoMediaChannel> channel(engine_.CreateMediaChannel(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +0200847 call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
848 video_bitrate_allocator_factory_.get()));
magjed509e4fe2016-11-18 01:34:11 -0800849 cricket::VideoSendParameters parameters;
850 parameters.codecs.push_back(GetEngineCodec("H264"));
851 EXPECT_TRUE(channel->SetSendParameters(parameters));
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000852
853 EXPECT_TRUE(
854 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
Per21d45d22016-10-30 21:37:57 +0100855
856 // Send a frame of 720p. This should trigger a "real" encoder initialization.
Niels Möller805a27e2019-01-21 12:21:27 +0100857 webrtc::test::FrameForwarder frame_forwarder;
858 cricket::FakeFrameSource frame_source(1280, 720,
859 rtc::kNumMicrosecsPerSec / 30);
860 EXPECT_TRUE(channel->SetVideoSend(kSsrc, nullptr, &frame_forwarder));
861 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
Niels Möller4db138e2018-04-19 09:04:13 +0200862 ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(1));
863 ASSERT_EQ(1u, encoder_factory_->encoders().size());
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200864 ASSERT_TRUE(encoder_factory_->encoders()[0]->WaitForInitEncode());
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000865 EXPECT_EQ(webrtc::kVideoCodecH264,
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200866 encoder_factory_->encoders()[0]->GetCodecSettings().codecType);
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000867
868 channel.reset();
869 // Make sure DestroyVideoEncoder was called on the factory.
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200870 ASSERT_EQ(0u, encoder_factory_->encoders().size());
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000871}
872
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200873TEST_F(WebRtcVideoEngineTest, SimulcastEnabledForH264BehindFieldTrial) {
Elad Alon040dc432019-05-22 15:40:02 +0200874 RTC_DCHECK(!override_field_trials_);
875 override_field_trials_ = absl::make_unique<webrtc::test::ScopedFieldTrials>(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200876 "WebRTC-H264Simulcast/Enabled/");
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200877 encoder_factory_->AddSupportedVideoCodecType("H264");
noahricfdac5162015-08-27 01:59:29 -0700878
Sebastian Jansson84848f22018-11-16 10:40:36 +0100879 std::unique_ptr<VideoMediaChannel> channel(engine_.CreateMediaChannel(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +0200880 call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
881 video_bitrate_allocator_factory_.get()));
Anders Carlsson67537952018-05-03 11:28:29 +0200882 cricket::VideoSendParameters parameters;
883 parameters.codecs.push_back(GetEngineCodec("H264"));
884 EXPECT_TRUE(channel->SetSendParameters(parameters));
noahricfdac5162015-08-27 01:59:29 -0700885
Peter Boström0c4e06b2015-10-07 12:23:21 +0200886 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
noahricfdac5162015-08-27 01:59:29 -0700887 EXPECT_TRUE(
888 channel->AddSendStream(cricket::CreateSimStreamParams("cname", ssrcs)));
Peter Boströmce23bee2016-02-02 14:14:30 +0100889
890 // Send a frame of 720p. This should trigger a "real" encoder initialization.
Niels Möller805a27e2019-01-21 12:21:27 +0100891 webrtc::test::FrameForwarder frame_forwarder;
892 cricket::FakeFrameSource frame_source(1280, 720,
893 rtc::kNumMicrosecsPerSec / 30);
894 EXPECT_TRUE(channel->SetVideoSend(ssrcs[0], nullptr, &frame_forwarder));
895 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
Peter Boströmce23bee2016-02-02 14:14:30 +0100896
Niels Möller4db138e2018-04-19 09:04:13 +0200897 ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(1));
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200898 ASSERT_EQ(1u, encoder_factory_->encoders().size());
899 FakeWebRtcVideoEncoder* encoder = encoder_factory_->encoders()[0];
900 ASSERT_TRUE(encoder_factory_->encoders()[0]->WaitForInitEncode());
noahricfdac5162015-08-27 01:59:29 -0700901 EXPECT_EQ(webrtc::kVideoCodecH264, encoder->GetCodecSettings().codecType);
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200902 EXPECT_LT(1u, encoder->GetCodecSettings().numberOfSimulcastStreams);
Niels Möllerff40b142018-04-09 08:49:14 +0200903 EXPECT_TRUE(channel->SetVideoSend(ssrcs[0], nullptr, nullptr));
noahricfdac5162015-08-27 01:59:29 -0700904}
905
brandtrffc61182016-11-28 06:02:22 -0800906// Test that the FlexFEC field trial properly alters the output of
eladalonf1841382017-06-12 01:16:46 -0700907// WebRtcVideoEngine::codecs(), for an existing |engine_| object.
brandtrffc61182016-11-28 06:02:22 -0800908//
909// TODO(brandtr): Remove this test, when the FlexFEC field trial is gone.
eladalonf1841382017-06-12 01:16:46 -0700910TEST_F(WebRtcVideoEngineTest,
brandtrffc61182016-11-28 06:02:22 -0800911 Flexfec03SupportedAsInternalCodecBehindFieldTrial) {
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200912 encoder_factory_->AddSupportedVideoCodecType("VP8");
913
Steve Anton2c9ebef2019-01-28 17:27:58 -0800914 auto flexfec = Field("name", &VideoCodec::name, "flexfec-03");
brandtrffc61182016-11-28 06:02:22 -0800915
916 // FlexFEC is not active without field trial.
Steve Anton2c9ebef2019-01-28 17:27:58 -0800917 EXPECT_THAT(engine_.codecs(), Not(Contains(flexfec)));
brandtrffc61182016-11-28 06:02:22 -0800918
919 // FlexFEC is active with field trial.
Elad Alon040dc432019-05-22 15:40:02 +0200920 RTC_DCHECK(!override_field_trials_);
921 override_field_trials_ = absl::make_unique<webrtc::test::ScopedFieldTrials>(
brandtr340e3fd2017-02-28 15:43:10 -0800922 "WebRTC-FlexFEC-03-Advertised/Enabled/");
Steve Anton2c9ebef2019-01-28 17:27:58 -0800923 EXPECT_THAT(engine_.codecs(), Contains(flexfec));
brandtrffc61182016-11-28 06:02:22 -0800924}
925
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200926// Test that codecs are added in the order they are reported from the factory.
927TEST_F(WebRtcVideoEngineTest, ReportSupportedCodecs) {
928 encoder_factory_->AddSupportedVideoCodecType("VP8");
929 const char* kFakeCodecName = "FakeCodec";
930 encoder_factory_->AddSupportedVideoCodecType(kFakeCodecName);
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000931
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200932 // The last reported codec should appear after the first codec in the vector.
Oleh Prypina40f8242017-12-21 13:32:23 +0100933 const size_t vp8_index = GetEngineCodecIndex("VP8");
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200934 const size_t fake_codec_index = GetEngineCodecIndex(kFakeCodecName);
935 EXPECT_LT(vp8_index, fake_codec_index);
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000936}
937
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200938// Test that a codec that was added after the engine was initialized
brandtrffc61182016-11-28 06:02:22 -0800939// does show up in the codec list after it was added.
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200940TEST_F(WebRtcVideoEngineTest, ReportSupportedAddedCodec) {
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +0100941 const char* kFakeExternalCodecName1 = "FakeExternalCodec1";
942 const char* kFakeExternalCodecName2 = "FakeExternalCodec2";
Magnus Jedvert154ee1f2017-11-15 19:27:11 +0100943
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +0100944 // Set up external encoder factory with first codec, and initialize engine.
945 encoder_factory_->AddSupportedVideoCodecType(kFakeExternalCodecName1);
946
brandtrffc61182016-11-28 06:02:22 -0800947 std::vector<cricket::VideoCodec> codecs_before(engine_.codecs());
brandtrffc61182016-11-28 06:02:22 -0800948
949 // Add second codec.
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +0100950 encoder_factory_->AddSupportedVideoCodecType(kFakeExternalCodecName2);
brandtrffc61182016-11-28 06:02:22 -0800951 std::vector<cricket::VideoCodec> codecs_after(engine_.codecs());
Sami Kalliomäkie9a18b22018-07-13 10:28:21 +0200952 // The codec itself and RTX should have been added.
953 EXPECT_EQ(codecs_before.size() + 2, codecs_after.size());
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +0100954
955 // Check that both fake codecs are present and that the second fake codec
956 // appears after the first fake codec.
Oleh Prypina40f8242017-12-21 13:32:23 +0100957 const size_t fake_codec_index1 = GetEngineCodecIndex(kFakeExternalCodecName1);
958 const size_t fake_codec_index2 = GetEngineCodecIndex(kFakeExternalCodecName2);
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +0100959 EXPECT_LT(fake_codec_index1, fake_codec_index2);
brandtrffc61182016-11-28 06:02:22 -0800960}
961
Sami Kalliomäkie9a18b22018-07-13 10:28:21 +0200962TEST_F(WebRtcVideoEngineTest, ReportRtxForExternalCodec) {
963 const char* kFakeCodecName = "FakeCodec";
964 encoder_factory_->AddSupportedVideoCodecType(kFakeCodecName);
965
966 const size_t fake_codec_index = GetEngineCodecIndex(kFakeCodecName);
967 EXPECT_EQ("rtx", engine_.codecs().at(fake_codec_index + 1).name);
968}
969
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200970TEST_F(WebRtcVideoEngineTest, RegisterDecodersIfSupported) {
971 encoder_factory_->AddSupportedVideoCodecType("VP8");
Anders Carlsson67537952018-05-03 11:28:29 +0200972 decoder_factory_->AddSupportedVideoCodecType(webrtc::SdpVideoFormat("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200973 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -0800974 parameters.codecs.push_back(GetEngineCodec("VP8"));
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000975
kwiberg686a8ef2016-02-26 03:00:35 -0800976 std::unique_ptr<VideoMediaChannel> channel(
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200977 SetRecvParamsWithSupportedCodecs(parameters.codecs));
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000978
979 EXPECT_TRUE(
980 channel->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200981 ASSERT_EQ(1u, decoder_factory_->decoders().size());
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000982
983 // Setting codecs of the same type should not reallocate the decoder.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200984 EXPECT_TRUE(channel->SetRecvParameters(parameters));
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200985 EXPECT_EQ(1, decoder_factory_->GetNumCreatedDecoders());
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000986
987 // Remove stream previously added to free the external decoder instance.
988 EXPECT_TRUE(channel->RemoveRecvStream(kSsrc));
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200989 EXPECT_EQ(0u, decoder_factory_->decoders().size());
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000990}
991
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200992// Verifies that we can set up decoders.
993TEST_F(WebRtcVideoEngineTest, RegisterH264DecoderIfSupported) {
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000994 // TODO(pbos): Do not assume that encoder/decoder support is symmetric. We
995 // can't even query the WebRtcVideoDecoderFactory for supported codecs.
996 // For now we add a FakeWebRtcVideoEncoderFactory to add H264 to supported
997 // codecs.
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200998 encoder_factory_->AddSupportedVideoCodecType("H264");
Anders Carlsson67537952018-05-03 11:28:29 +0200999 decoder_factory_->AddSupportedVideoCodecType(webrtc::SdpVideoFormat("H264"));
pbos@webrtc.org96a93252014-11-03 14:46:44 +00001000 std::vector<cricket::VideoCodec> codecs;
magjed509e4fe2016-11-18 01:34:11 -08001001 codecs.push_back(GetEngineCodec("H264"));
pbos@webrtc.org96a93252014-11-03 14:46:44 +00001002
kwiberg686a8ef2016-02-26 03:00:35 -08001003 std::unique_ptr<VideoMediaChannel> channel(
Anders Carlsson5f2bb622018-05-14 09:48:06 +02001004 SetRecvParamsWithSupportedCodecs(codecs));
pbos@webrtc.org96a93252014-11-03 14:46:44 +00001005
1006 EXPECT_TRUE(
1007 channel->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001008 ASSERT_EQ(1u, decoder_factory_->decoders().size());
pbos@webrtc.org96a93252014-11-03 14:46:44 +00001009}
1010
Jonas Oreland49ac5952018-09-26 16:04:32 +02001011// Tests when GetSources is called with non-existing ssrc, it will return an
1012// empty list of RtpSource without crashing.
1013TEST_F(WebRtcVideoEngineTest, GetSourcesWithNonExistingSsrc) {
1014 // Setup an recv stream with |kSsrc|.
1015 encoder_factory_->AddSupportedVideoCodecType("VP8");
1016 decoder_factory_->AddSupportedVideoCodecType(webrtc::SdpVideoFormat("VP8"));
1017 cricket::VideoRecvParameters parameters;
1018 parameters.codecs.push_back(GetEngineCodec("VP8"));
1019 std::unique_ptr<VideoMediaChannel> channel(
1020 SetRecvParamsWithSupportedCodecs(parameters.codecs));
1021
1022 EXPECT_TRUE(
1023 channel->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
1024
1025 // Call GetSources with |kSsrc + 1| which doesn't exist.
1026 std::vector<webrtc::RtpSource> sources = channel->GetSources(kSsrc + 1);
1027 EXPECT_EQ(0u, sources.size());
1028}
1029
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001030TEST(WebRtcVideoEngineNewVideoCodecFactoryTest, NullFactories) {
1031 std::unique_ptr<webrtc::VideoEncoderFactory> encoder_factory;
1032 std::unique_ptr<webrtc::VideoDecoderFactory> decoder_factory;
1033 WebRtcVideoEngine engine(std::move(encoder_factory),
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02001034 std::move(decoder_factory));
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001035 EXPECT_EQ(0u, engine.codecs().size());
1036}
1037
1038TEST(WebRtcVideoEngineNewVideoCodecFactoryTest, EmptyFactories) {
1039 // |engine| take ownership of the factories.
Emircan Uysalerdbcac7f2017-10-30 23:10:12 -07001040 webrtc::MockVideoEncoderFactory* encoder_factory =
1041 new webrtc::MockVideoEncoderFactory();
1042 webrtc::MockVideoDecoderFactory* decoder_factory =
1043 new webrtc::MockVideoDecoderFactory();
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001044 WebRtcVideoEngine engine(
1045 (std::unique_ptr<webrtc::VideoEncoderFactory>(encoder_factory)),
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02001046 (std::unique_ptr<webrtc::VideoDecoderFactory>(decoder_factory)));
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001047 EXPECT_CALL(*encoder_factory, GetSupportedFormats());
1048 EXPECT_EQ(0u, engine.codecs().size());
1049 EXPECT_CALL(*encoder_factory, Die());
1050 EXPECT_CALL(*decoder_factory, Die());
1051}
1052
1053// Test full behavior in the video engine when video codec factories of the new
1054// type are injected supporting the single codec Vp8. Check the returned codecs
1055// from the engine and that we will create a Vp8 encoder and decoder using the
1056// new factories.
1057TEST(WebRtcVideoEngineNewVideoCodecFactoryTest, Vp8) {
1058 // |engine| take ownership of the factories.
Emircan Uysalerdbcac7f2017-10-30 23:10:12 -07001059 webrtc::MockVideoEncoderFactory* encoder_factory =
1060 new webrtc::MockVideoEncoderFactory();
1061 webrtc::MockVideoDecoderFactory* decoder_factory =
1062 new webrtc::MockVideoDecoderFactory();
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02001063 std::unique_ptr<webrtc::MockVideoBitrateAllocatorFactory>
1064 rate_allocator_factory =
1065 absl::make_unique<webrtc::MockVideoBitrateAllocatorFactory>();
Jiawei Ouc2ebe212018-11-08 10:02:56 -08001066 EXPECT_CALL(*rate_allocator_factory,
1067 CreateVideoBitrateAllocatorProxy(Field(
1068 &webrtc::VideoCodec::codecType, webrtc::kVideoCodecVP8)))
Mirko Bonadei6a489f22019-04-09 15:11:12 +02001069 .WillOnce(::testing::Return(new webrtc::MockVideoBitrateAllocator()));
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001070 WebRtcVideoEngine engine(
1071 (std::unique_ptr<webrtc::VideoEncoderFactory>(encoder_factory)),
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02001072 (std::unique_ptr<webrtc::VideoDecoderFactory>(decoder_factory)));
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001073 const webrtc::SdpVideoFormat vp8_format("VP8");
1074 const std::vector<webrtc::SdpVideoFormat> supported_formats = {vp8_format};
1075 EXPECT_CALL(*encoder_factory, GetSupportedFormats())
Mirko Bonadei6a489f22019-04-09 15:11:12 +02001076 .WillRepeatedly(::testing::Return(supported_formats));
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001077
1078 // Verify the codecs from the engine.
1079 const std::vector<VideoCodec> engine_codecs = engine.codecs();
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +01001080 // Verify default codecs has been added correctly.
1081 EXPECT_EQ(5u, engine_codecs.size());
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001082 EXPECT_EQ("VP8", engine_codecs.at(0).name);
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +01001083
1084 // RTX codec for VP8.
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001085 EXPECT_EQ("rtx", engine_codecs.at(1).name);
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +01001086 int vp8_associated_payload;
1087 EXPECT_TRUE(engine_codecs.at(1).GetParam(kCodecParamAssociatedPayloadType,
1088 &vp8_associated_payload));
1089 EXPECT_EQ(vp8_associated_payload, engine_codecs.at(0).id);
1090
1091 EXPECT_EQ(kRedCodecName, engine_codecs.at(2).name);
1092
1093 // RTX codec for RED.
1094 EXPECT_EQ("rtx", engine_codecs.at(3).name);
1095 int red_associated_payload;
1096 EXPECT_TRUE(engine_codecs.at(3).GetParam(kCodecParamAssociatedPayloadType,
1097 &red_associated_payload));
1098 EXPECT_EQ(red_associated_payload, engine_codecs.at(2).id);
1099
1100 EXPECT_EQ(kUlpfecCodecName, engine_codecs.at(4).name);
1101
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001102 int associated_payload_type;
1103 EXPECT_TRUE(engine_codecs.at(1).GetParam(
1104 cricket::kCodecParamAssociatedPayloadType, &associated_payload_type));
1105 EXPECT_EQ(engine_codecs.at(0).id, associated_payload_type);
1106 // Verify default parameters has been added to the VP8 codec.
1107 VerifyCodecHasDefaultFeedbackParams(engine_codecs.at(0));
1108
1109 // Mock encoder creation. |engine| take ownership of the encoder.
Mirta Dvornicic1ec2a162018-12-10 09:47:34 +00001110 webrtc::VideoEncoderFactory::CodecInfo codec_info;
1111 codec_info.is_hardware_accelerated = false;
1112 codec_info.has_internal_source = false;
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001113 const webrtc::SdpVideoFormat format("VP8");
Mirta Dvornicic1ec2a162018-12-10 09:47:34 +00001114 EXPECT_CALL(*encoder_factory, QueryVideoEncoder(format))
Mirko Bonadei6a489f22019-04-09 15:11:12 +02001115 .WillRepeatedly(::testing::Return(codec_info));
Anders Carlsson67537952018-05-03 11:28:29 +02001116 FakeWebRtcVideoEncoder* const encoder = new FakeWebRtcVideoEncoder(nullptr);
Niels Möllerc572ff32018-11-07 08:43:50 +01001117 rtc::Event encoder_created;
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001118 EXPECT_CALL(*encoder_factory, CreateVideoEncoderProxy(format))
Niels Möller4db138e2018-04-19 09:04:13 +02001119 .WillOnce(
1120 ::testing::DoAll(::testing::InvokeWithoutArgs(
1121 [&encoder_created]() { encoder_created.Set(); }),
1122 ::testing::Return(encoder)));
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001123
1124 // Mock decoder creation. |engine| take ownership of the decoder.
Anders Carlsson67537952018-05-03 11:28:29 +02001125 FakeWebRtcVideoDecoder* const decoder = new FakeWebRtcVideoDecoder(nullptr);
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001126 EXPECT_CALL(*decoder_factory, CreateVideoDecoderProxy(format))
Mirko Bonadei6a489f22019-04-09 15:11:12 +02001127 .WillOnce(::testing::Return(decoder));
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001128
1129 // Create a call.
1130 webrtc::RtcEventLogNullImpl event_log;
1131 std::unique_ptr<webrtc::Call> call(
1132 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
1133
1134 // Create send channel.
1135 const int send_ssrc = 123;
Sebastian Jansson84848f22018-11-16 10:40:36 +01001136 std::unique_ptr<VideoMediaChannel> send_channel(engine.CreateMediaChannel(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02001137 call.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
1138 rate_allocator_factory.get()));
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001139 cricket::VideoSendParameters send_parameters;
1140 send_parameters.codecs.push_back(engine_codecs.at(0));
1141 EXPECT_TRUE(send_channel->SetSendParameters(send_parameters));
1142 send_channel->OnReadyToSend(true);
1143 EXPECT_TRUE(
1144 send_channel->AddSendStream(StreamParams::CreateLegacy(send_ssrc)));
1145 EXPECT_TRUE(send_channel->SetSend(true));
1146
Niels Möller4db138e2018-04-19 09:04:13 +02001147 // Set capturer.
Niels Möller805a27e2019-01-21 12:21:27 +01001148 webrtc::test::FrameForwarder frame_forwarder;
1149 cricket::FakeFrameSource frame_source(1280, 720,
1150 rtc::kNumMicrosecsPerSec / 30);
1151 EXPECT_TRUE(send_channel->SetVideoSend(send_ssrc, nullptr, &frame_forwarder));
Niels Möller4db138e2018-04-19 09:04:13 +02001152 // Sending one frame will allocate the encoder.
Niels Möller805a27e2019-01-21 12:21:27 +01001153 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
Niels Möller4db138e2018-04-19 09:04:13 +02001154 encoder_created.Wait(kTimeout);
1155
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001156 // Create recv channel.
1157 const int recv_ssrc = 321;
Sebastian Jansson84848f22018-11-16 10:40:36 +01001158 std::unique_ptr<VideoMediaChannel> recv_channel(engine.CreateMediaChannel(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02001159 call.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
1160 rate_allocator_factory.get()));
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001161 cricket::VideoRecvParameters recv_parameters;
1162 recv_parameters.codecs.push_back(engine_codecs.at(0));
1163 EXPECT_TRUE(recv_channel->SetRecvParameters(recv_parameters));
1164 EXPECT_TRUE(recv_channel->AddRecvStream(
1165 cricket::StreamParams::CreateLegacy(recv_ssrc)));
1166
1167 // Remove streams previously added to free the encoder and decoder instance.
1168 EXPECT_CALL(*encoder_factory, Die());
1169 EXPECT_CALL(*decoder_factory, Die());
Jiawei Ouc2ebe212018-11-08 10:02:56 -08001170 EXPECT_CALL(*rate_allocator_factory, Die());
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001171 EXPECT_TRUE(send_channel->RemoveSendStream(send_ssrc));
1172 EXPECT_TRUE(recv_channel->RemoveRecvStream(recv_ssrc));
1173}
1174
Magnus Jedvert7501b1c2017-11-09 13:43:42 +01001175// Test behavior when decoder factory fails to create a decoder (returns null).
1176TEST(WebRtcVideoEngineNewVideoCodecFactoryTest, NullDecoder) {
1177 // |engine| take ownership of the factories.
1178 webrtc::MockVideoEncoderFactory* encoder_factory =
Jiawei Ouc2ebe212018-11-08 10:02:56 -08001179 new webrtc::MockVideoEncoderFactory();
Magnus Jedvert7501b1c2017-11-09 13:43:42 +01001180 webrtc::MockVideoDecoderFactory* decoder_factory =
Jiawei Ouc2ebe212018-11-08 10:02:56 -08001181 new webrtc::MockVideoDecoderFactory();
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02001182 std::unique_ptr<webrtc::MockVideoBitrateAllocatorFactory>
1183 rate_allocator_factory =
1184 absl::make_unique<webrtc::MockVideoBitrateAllocatorFactory>();
Magnus Jedvert7501b1c2017-11-09 13:43:42 +01001185 WebRtcVideoEngine engine(
1186 (std::unique_ptr<webrtc::VideoEncoderFactory>(encoder_factory)),
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02001187 (std::unique_ptr<webrtc::VideoDecoderFactory>(decoder_factory)));
Magnus Jedvert7501b1c2017-11-09 13:43:42 +01001188 const webrtc::SdpVideoFormat vp8_format("VP8");
1189 const std::vector<webrtc::SdpVideoFormat> supported_formats = {vp8_format};
1190 EXPECT_CALL(*encoder_factory, GetSupportedFormats())
Mirko Bonadei6a489f22019-04-09 15:11:12 +02001191 .WillRepeatedly(::testing::Return(supported_formats));
Magnus Jedvert7501b1c2017-11-09 13:43:42 +01001192
1193 // Decoder creation fails.
Mirko Bonadei6a489f22019-04-09 15:11:12 +02001194 EXPECT_CALL(*decoder_factory, CreateVideoDecoderProxy(::testing::_))
1195 .WillOnce(::testing::Return(nullptr));
Magnus Jedvert7501b1c2017-11-09 13:43:42 +01001196
1197 // Create a call.
1198 webrtc::RtcEventLogNullImpl event_log;
1199 std::unique_ptr<webrtc::Call> call(
1200 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
1201
1202 // Create recv channel.
1203 const int recv_ssrc = 321;
Sebastian Jansson84848f22018-11-16 10:40:36 +01001204 std::unique_ptr<VideoMediaChannel> recv_channel(engine.CreateMediaChannel(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02001205 call.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
1206 rate_allocator_factory.get()));
Magnus Jedvert7501b1c2017-11-09 13:43:42 +01001207 cricket::VideoRecvParameters recv_parameters;
1208 recv_parameters.codecs.push_back(engine.codecs().front());
1209 EXPECT_TRUE(recv_channel->SetRecvParameters(recv_parameters));
1210 EXPECT_TRUE(recv_channel->AddRecvStream(
1211 cricket::StreamParams::CreateLegacy(recv_ssrc)));
1212
1213 // Remove streams previously added to free the encoder and decoder instance.
1214 EXPECT_TRUE(recv_channel->RemoveRecvStream(recv_ssrc));
1215}
1216
eladalonf1841382017-06-12 01:16:46 -07001217TEST_F(WebRtcVideoEngineTest, DISABLED_RecreatesEncoderOnContentTypeChange) {
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001218 encoder_factory_->AddSupportedVideoCodecType("VP8");
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001219 std::unique_ptr<FakeCall> fake_call(new FakeCall());
Anders Carlsson5f2bb622018-05-14 09:48:06 +02001220 std::unique_ptr<VideoMediaChannel> channel(
1221 SetSendParamsWithAllSupportedCodecs());
sprangf24a0642017-02-28 13:23:26 -08001222 ASSERT_TRUE(
1223 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
1224 cricket::VideoCodec codec = GetEngineCodec("VP8");
1225 cricket::VideoSendParameters parameters;
1226 parameters.codecs.push_back(codec);
1227 channel->OnReadyToSend(true);
1228 channel->SetSend(true);
1229 ASSERT_TRUE(channel->SetSendParameters(parameters));
1230
Niels Möller805a27e2019-01-21 12:21:27 +01001231 webrtc::test::FrameForwarder frame_forwarder;
1232 cricket::FakeFrameSource frame_source(1280, 720,
1233 rtc::kNumMicrosecsPerSec / 30);
sprangf24a0642017-02-28 13:23:26 -08001234 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01001235 EXPECT_TRUE(channel->SetVideoSend(kSsrc, &options, &frame_forwarder));
sprangf24a0642017-02-28 13:23:26 -08001236
Niels Möller805a27e2019-01-21 12:21:27 +01001237 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001238 ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(1));
Niels Möllere3cf3d02018-06-13 11:52:16 +02001239 EXPECT_EQ(webrtc::VideoCodecMode::kRealtimeVideo,
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001240 encoder_factory_->encoders().back()->GetCodecSettings().mode);
sprangf24a0642017-02-28 13:23:26 -08001241
Niels Möller805a27e2019-01-21 12:21:27 +01001242 EXPECT_TRUE(channel->SetVideoSend(kSsrc, &options, &frame_forwarder));
1243 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
sprangf24a0642017-02-28 13:23:26 -08001244 // No change in content type, keep current encoder.
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001245 EXPECT_EQ(1, encoder_factory_->GetNumCreatedEncoders());
sprangf24a0642017-02-28 13:23:26 -08001246
1247 options.is_screencast.emplace(true);
Niels Möller805a27e2019-01-21 12:21:27 +01001248 EXPECT_TRUE(channel->SetVideoSend(kSsrc, &options, &frame_forwarder));
1249 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
sprangf24a0642017-02-28 13:23:26 -08001250 // Change to screen content, recreate encoder. For the simulcast encoder
1251 // adapter case, this will result in two calls since InitEncode triggers a
1252 // a new instance.
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001253 ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(2));
Niels Möllere3cf3d02018-06-13 11:52:16 +02001254 EXPECT_EQ(webrtc::VideoCodecMode::kScreensharing,
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001255 encoder_factory_->encoders().back()->GetCodecSettings().mode);
sprangf24a0642017-02-28 13:23:26 -08001256
Niels Möller805a27e2019-01-21 12:21:27 +01001257 EXPECT_TRUE(channel->SetVideoSend(kSsrc, &options, &frame_forwarder));
1258 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
sprangf24a0642017-02-28 13:23:26 -08001259 // Still screen content, no need to update encoder.
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001260 EXPECT_EQ(2, encoder_factory_->GetNumCreatedEncoders());
sprangf24a0642017-02-28 13:23:26 -08001261
1262 options.is_screencast.emplace(false);
1263 options.video_noise_reduction.emplace(false);
Niels Möller805a27e2019-01-21 12:21:27 +01001264 EXPECT_TRUE(channel->SetVideoSend(kSsrc, &options, &frame_forwarder));
sprangf24a0642017-02-28 13:23:26 -08001265 // Change back to regular video content, update encoder. Also change
1266 // a non |is_screencast| option just to verify it doesn't affect recreation.
Niels Möller805a27e2019-01-21 12:21:27 +01001267 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001268 ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(3));
Niels Möllere3cf3d02018-06-13 11:52:16 +02001269 EXPECT_EQ(webrtc::VideoCodecMode::kRealtimeVideo,
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001270 encoder_factory_->encoders().back()->GetCodecSettings().mode);
sprangf24a0642017-02-28 13:23:26 -08001271
1272 // Remove stream previously added to free the external encoder instance.
1273 EXPECT_TRUE(channel->RemoveSendStream(kSsrc));
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001274 EXPECT_EQ(0u, encoder_factory_->encoders().size());
sprangf24a0642017-02-28 13:23:26 -08001275}
1276
Mirko Bonadei6a489f22019-04-09 15:11:12 +02001277class WebRtcVideoChannelBaseTest : public ::testing::Test {
Niels Möller6557d0c2018-04-11 15:18:34 +02001278 protected:
1279 WebRtcVideoChannelBaseTest()
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02001280 : video_bitrate_allocator_factory_(
1281 webrtc::CreateBuiltinVideoBitrateAllocatorFactory()),
1282 engine_(webrtc::CreateBuiltinVideoEncoderFactory(),
1283 webrtc::CreateBuiltinVideoDecoderFactory()) {}
Niels Möller6557d0c2018-04-11 15:18:34 +02001284
1285 virtual void SetUp() {
Jonas Oreland49ac5952018-09-26 16:04:32 +02001286 // One testcase calls SetUp in a loop, only create call_ once.
1287 if (!call_) {
1288 call_.reset(webrtc::Call::Create(webrtc::Call::Config(&event_log_)));
1289 }
Niels Möller6557d0c2018-04-11 15:18:34 +02001290 cricket::MediaConfig media_config;
1291 // Disabling cpu overuse detection actually disables quality scaling too; it
1292 // implies DegradationPreference kMaintainResolution. Automatic scaling
1293 // needs to be disabled, otherwise, tests which check the size of received
1294 // frames become flaky.
1295 media_config.video.enable_cpu_adaptation = false;
Sebastian Jansson84848f22018-11-16 10:40:36 +01001296 channel_.reset(
1297 static_cast<cricket::WebRtcVideoChannel*>(engine_.CreateMediaChannel(
1298 call_.get(), media_config, cricket::VideoOptions(),
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02001299 webrtc::CryptoOptions(), video_bitrate_allocator_factory_.get())));
Niels Möller6557d0c2018-04-11 15:18:34 +02001300 channel_->OnReadyToSend(true);
1301 EXPECT_TRUE(channel_.get() != NULL);
1302 network_interface_.SetDestination(channel_.get());
Anton Sukhanov4f08faa2019-05-21 11:12:57 -07001303 channel_->SetInterface(&network_interface_, webrtc::MediaTransportConfig());
Niels Möller6557d0c2018-04-11 15:18:34 +02001304 cricket::VideoRecvParameters parameters;
1305 parameters.codecs = engine_.codecs();
1306 channel_->SetRecvParameters(parameters);
1307 EXPECT_TRUE(channel_->AddSendStream(DefaultSendStreamParams()));
Niels Möller805a27e2019-01-21 12:21:27 +01001308 frame_forwarder_ = absl::make_unique<webrtc::test::FrameForwarder>();
1309 frame_source_ = absl::make_unique<cricket::FakeFrameSource>(
1310 640, 480, rtc::kNumMicrosecsPerSec / kFramerate);
1311 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, nullptr, frame_forwarder_.get()));
Niels Möller6557d0c2018-04-11 15:18:34 +02001312 }
1313
1314 // Utility method to setup an additional stream to send and receive video.
1315 // Used to test send and recv between two streams.
1316 void SetUpSecondStream() {
1317 SetUpSecondStreamWithNoRecv();
1318 // Setup recv for second stream.
1319 EXPECT_TRUE(channel_->AddRecvStream(
1320 cricket::StreamParams::CreateLegacy(kSsrc + 2)));
1321 // Make the second renderer available for use by a new stream.
1322 EXPECT_TRUE(channel_->SetSink(kSsrc + 2, &renderer2_));
1323 }
1324 // Setup an additional stream just to send video. Defer add recv stream.
1325 // This is required if you want to test unsignalled recv of video rtp packets.
1326 void SetUpSecondStreamWithNoRecv() {
1327 // SetUp() already added kSsrc make sure duplicate SSRCs cant be added.
Yves Gerey665174f2018-06-19 15:03:05 +02001328 EXPECT_TRUE(
1329 channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
Niels Möller6557d0c2018-04-11 15:18:34 +02001330 EXPECT_TRUE(channel_->SetSink(kSsrc, &renderer_));
Yves Gerey665174f2018-06-19 15:03:05 +02001331 EXPECT_FALSE(
1332 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
Niels Möller6557d0c2018-04-11 15:18:34 +02001333 EXPECT_TRUE(channel_->AddSendStream(
1334 cricket::StreamParams::CreateLegacy(kSsrc + 2)));
1335 // We dont add recv for the second stream.
1336
1337 // Setup the receive and renderer for second stream after send.
Niels Möller805a27e2019-01-21 12:21:27 +01001338 frame_forwarder_2_ = absl::make_unique<webrtc::test::FrameForwarder>();
Yves Gerey665174f2018-06-19 15:03:05 +02001339 EXPECT_TRUE(
Niels Möller805a27e2019-01-21 12:21:27 +01001340 channel_->SetVideoSend(kSsrc + 2, nullptr, frame_forwarder_2_.get()));
Niels Möller6557d0c2018-04-11 15:18:34 +02001341 }
Yves Gerey665174f2018-06-19 15:03:05 +02001342 virtual void TearDown() { channel_.reset(); }
1343 bool SetDefaultCodec() { return SetOneCodec(DefaultCodec()); }
Niels Möller6557d0c2018-04-11 15:18:34 +02001344
1345 bool SetOneCodec(const cricket::VideoCodec& codec) {
Niels Möller805a27e2019-01-21 12:21:27 +01001346 frame_source_ = absl::make_unique<cricket::FakeFrameSource>(
1347 kVideoWidth, kVideoHeight, rtc::kNumMicrosecsPerSec / kFramerate);
Niels Möller6557d0c2018-04-11 15:18:34 +02001348
1349 bool sending = channel_->sending();
1350 bool success = SetSend(false);
1351 if (success) {
1352 cricket::VideoSendParameters parameters;
1353 parameters.codecs.push_back(codec);
1354 success = channel_->SetSendParameters(parameters);
1355 }
1356 if (success) {
1357 success = SetSend(sending);
1358 }
1359 return success;
1360 }
Yves Gerey665174f2018-06-19 15:03:05 +02001361 bool SetSend(bool send) { return channel_->SetSend(send); }
Niels Möller805a27e2019-01-21 12:21:27 +01001362 void SendFrame() {
1363 if (frame_forwarder_2_) {
1364 frame_forwarder_2_->IncomingCapturedFrame(frame_source_->GetFrame());
Niels Möller6557d0c2018-04-11 15:18:34 +02001365 }
Niels Möller805a27e2019-01-21 12:21:27 +01001366 frame_forwarder_->IncomingCapturedFrame(frame_source_->GetFrame());
Niels Möller6557d0c2018-04-11 15:18:34 +02001367 }
1368 bool WaitAndSendFrame(int wait_ms) {
1369 bool ret = rtc::Thread::Current()->ProcessMessages(wait_ms);
Niels Möller805a27e2019-01-21 12:21:27 +01001370 SendFrame();
Niels Möller6557d0c2018-04-11 15:18:34 +02001371 return ret;
1372 }
Yves Gerey665174f2018-06-19 15:03:05 +02001373 int NumRtpBytes() { return network_interface_.NumRtpBytes(); }
Niels Möller6557d0c2018-04-11 15:18:34 +02001374 int NumRtpBytes(uint32_t ssrc) {
1375 return network_interface_.NumRtpBytes(ssrc);
1376 }
Yves Gerey665174f2018-06-19 15:03:05 +02001377 int NumRtpPackets() { return network_interface_.NumRtpPackets(); }
Niels Möller6557d0c2018-04-11 15:18:34 +02001378 int NumRtpPackets(uint32_t ssrc) {
1379 return network_interface_.NumRtpPackets(ssrc);
1380 }
Yves Gerey665174f2018-06-19 15:03:05 +02001381 int NumSentSsrcs() { return network_interface_.NumSentSsrcs(); }
Niels Möller6557d0c2018-04-11 15:18:34 +02001382 const rtc::CopyOnWriteBuffer* GetRtpPacket(int index) {
1383 return network_interface_.GetRtpPacket(index);
1384 }
1385 static int GetPayloadType(const rtc::CopyOnWriteBuffer* p) {
Åsa Persson23cd45a2018-07-03 10:40:40 +02001386 webrtc::RTPHeader header;
1387 EXPECT_TRUE(ParseRtpPacket(p, &header));
1388 return header.payloadType;
Niels Möller6557d0c2018-04-11 15:18:34 +02001389 }
Åsa Persson23cd45a2018-07-03 10:40:40 +02001390
Niels Möller6557d0c2018-04-11 15:18:34 +02001391 static bool ParseRtpPacket(const rtc::CopyOnWriteBuffer* p,
Åsa Persson23cd45a2018-07-03 10:40:40 +02001392 webrtc::RTPHeader* header) {
1393 std::unique_ptr<webrtc::RtpHeaderParser> parser(
1394 webrtc::RtpHeaderParser::Create());
1395 return parser->Parse(p->cdata(), p->size(), header);
Niels Möller6557d0c2018-04-11 15:18:34 +02001396 }
1397
1398 // Tests that we can send and receive frames.
1399 void SendAndReceive(const cricket::VideoCodec& codec) {
1400 EXPECT_TRUE(SetOneCodec(codec));
1401 EXPECT_TRUE(SetSend(true));
1402 EXPECT_TRUE(channel_->SetSink(kDefaultReceiveSsrc, &renderer_));
1403 EXPECT_EQ(0, renderer_.num_rendered_frames());
Niels Möller805a27e2019-01-21 12:21:27 +01001404 SendFrame();
Niels Möller6557d0c2018-04-11 15:18:34 +02001405 EXPECT_FRAME_WAIT(1, kVideoWidth, kVideoHeight, kTimeout);
1406 std::unique_ptr<const rtc::CopyOnWriteBuffer> p(GetRtpPacket(0));
1407 EXPECT_EQ(codec.id, GetPayloadType(p.get()));
1408 }
1409
1410 void SendReceiveManyAndGetStats(const cricket::VideoCodec& codec,
Yves Gerey665174f2018-06-19 15:03:05 +02001411 int duration_sec,
1412 int fps) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001413 EXPECT_TRUE(SetOneCodec(codec));
1414 EXPECT_TRUE(SetSend(true));
1415 EXPECT_TRUE(channel_->SetSink(kDefaultReceiveSsrc, &renderer_));
1416 EXPECT_EQ(0, renderer_.num_rendered_frames());
1417 for (int i = 0; i < duration_sec; ++i) {
1418 for (int frame = 1; frame <= fps; ++frame) {
1419 EXPECT_TRUE(WaitAndSendFrame(1000 / fps));
1420 EXPECT_FRAME_WAIT(frame + i * fps, kVideoWidth, kVideoHeight, kTimeout);
1421 }
1422 }
1423 std::unique_ptr<const rtc::CopyOnWriteBuffer> p(GetRtpPacket(0));
1424 EXPECT_EQ(codec.id, GetPayloadType(p.get()));
1425 }
1426
Niels Möller6557d0c2018-04-11 15:18:34 +02001427 cricket::VideoSenderInfo GetSenderStats(size_t i) {
1428 cricket::VideoMediaInfo info;
1429 EXPECT_TRUE(channel_->GetStats(&info));
1430 return info.senders[i];
1431 }
1432
1433 cricket::VideoReceiverInfo GetReceiverStats(size_t i) {
1434 cricket::VideoMediaInfo info;
1435 EXPECT_TRUE(channel_->GetStats(&info));
1436 return info.receivers[i];
1437 }
1438
1439 // Two streams one channel tests.
1440
1441 // Tests that we can send and receive frames.
1442 void TwoStreamsSendAndReceive(const cricket::VideoCodec& codec) {
1443 SetUpSecondStream();
1444 // Test sending and receiving on first stream.
1445 SendAndReceive(codec);
1446 // Test sending and receiving on second stream.
1447 EXPECT_EQ_WAIT(1, renderer2_.num_rendered_frames(), kTimeout);
1448 EXPECT_GT(NumRtpPackets(), 0);
1449 EXPECT_EQ(1, renderer2_.num_rendered_frames());
1450 }
1451
1452 cricket::VideoCodec GetEngineCodec(const std::string& name) {
1453 for (const cricket::VideoCodec& engine_codec : engine_.codecs()) {
Niels Möller039743e2018-10-23 10:07:25 +02001454 if (absl::EqualsIgnoreCase(name, engine_codec.name))
Niels Möller6557d0c2018-04-11 15:18:34 +02001455 return engine_codec;
1456 }
1457 // This point should never be reached.
1458 ADD_FAILURE() << "Unrecognized codec name: " << name;
1459 return cricket::VideoCodec();
1460 }
1461
1462 cricket::VideoCodec DefaultCodec() { return GetEngineCodec("VP8"); }
1463
1464 cricket::StreamParams DefaultSendStreamParams() {
1465 return cricket::StreamParams::CreateLegacy(kSsrc);
1466 }
1467
1468 webrtc::RtcEventLogNullImpl event_log_;
Jonas Oreland49ac5952018-09-26 16:04:32 +02001469 std::unique_ptr<webrtc::Call> call_;
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02001470 std::unique_ptr<webrtc::VideoBitrateAllocatorFactory>
1471 video_bitrate_allocator_factory_;
Niels Möller6557d0c2018-04-11 15:18:34 +02001472 WebRtcVideoEngine engine_;
Niels Möller805a27e2019-01-21 12:21:27 +01001473
1474 std::unique_ptr<cricket::FakeFrameSource> frame_source_;
1475 std::unique_ptr<webrtc::test::FrameForwarder> frame_forwarder_;
1476 std::unique_ptr<webrtc::test::FrameForwarder> frame_forwarder_2_;
1477
Niels Möller6557d0c2018-04-11 15:18:34 +02001478 std::unique_ptr<WebRtcVideoChannel> channel_;
1479 cricket::FakeNetworkInterface network_interface_;
1480 cricket::FakeVideoRenderer renderer_;
1481
1482 // Used by test cases where 2 streams are run on the same channel.
1483 cricket::FakeVideoRenderer renderer2_;
1484};
1485
1486// Test that SetSend works.
srtee0c2eea2017-12-15 17:44:33 +01001487TEST_F(WebRtcVideoChannelBaseTest, SetSend) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001488 EXPECT_FALSE(channel_->sending());
Niels Möller805a27e2019-01-21 12:21:27 +01001489 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, nullptr, frame_forwarder_.get()));
Niels Möller6557d0c2018-04-11 15:18:34 +02001490 EXPECT_TRUE(SetOneCodec(DefaultCodec()));
1491 EXPECT_FALSE(channel_->sending());
1492 EXPECT_TRUE(SetSend(true));
1493 EXPECT_TRUE(channel_->sending());
Niels Möller805a27e2019-01-21 12:21:27 +01001494 SendFrame();
Niels Möller6557d0c2018-04-11 15:18:34 +02001495 EXPECT_TRUE_WAIT(NumRtpPackets() > 0, kTimeout);
1496 EXPECT_TRUE(SetSend(false));
1497 EXPECT_FALSE(channel_->sending());
srtee0c2eea2017-12-15 17:44:33 +01001498}
Niels Möller6557d0c2018-04-11 15:18:34 +02001499
1500// Test that SetSend fails without codecs being set.
srtee0c2eea2017-12-15 17:44:33 +01001501TEST_F(WebRtcVideoChannelBaseTest, SetSendWithoutCodecs) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001502 EXPECT_FALSE(channel_->sending());
1503 EXPECT_FALSE(SetSend(true));
1504 EXPECT_FALSE(channel_->sending());
srtee0c2eea2017-12-15 17:44:33 +01001505}
Niels Möller6557d0c2018-04-11 15:18:34 +02001506
1507// Test that we properly set the send and recv buffer sizes by the time
1508// SetSend is called.
srtee0c2eea2017-12-15 17:44:33 +01001509TEST_F(WebRtcVideoChannelBaseTest, SetSendSetsTransportBufferSizes) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001510 EXPECT_TRUE(SetOneCodec(DefaultCodec()));
1511 EXPECT_TRUE(SetSend(true));
1512 EXPECT_EQ(64 * 1024, network_interface_.sendbuf_size());
Johannes Krond38a2b82018-10-23 11:31:19 +02001513 EXPECT_EQ(256 * 1024, network_interface_.recvbuf_size());
Erik Språng820ebd02018-08-20 17:14:25 +02001514}
1515
Johannes Kron5a0665b2019-04-08 10:35:50 +02001516// Test that we properly set the send and recv buffer sizes when overriding
1517// via field trials.
1518TEST_F(WebRtcVideoChannelBaseTest, OverridesRecvBufferSize) {
1519 // Set field trial to override the default recv buffer size, and then re-run
1520 // setup where the interface is created and configured.
1521 const int kCustomRecvBufferSize = 123456;
1522 webrtc::test::ScopedFieldTrials field_trial(
1523 "WebRTC-IncreasedReceivebuffers/123456/");
1524 SetUp();
1525
1526 EXPECT_TRUE(SetOneCodec(DefaultCodec()));
1527 EXPECT_TRUE(SetSend(true));
1528 EXPECT_EQ(64 * 1024, network_interface_.sendbuf_size());
1529 EXPECT_EQ(kCustomRecvBufferSize, network_interface_.recvbuf_size());
1530}
1531
1532// Test that we properly set the send and recv buffer sizes when overriding
1533// via field trials with suffix.
1534TEST_F(WebRtcVideoChannelBaseTest, OverridesRecvBufferSizeWithSuffix) {
1535 // Set field trial to override the default recv buffer size, and then re-run
1536 // setup where the interface is created and configured.
1537 const int kCustomRecvBufferSize = 123456;
1538 webrtc::test::ScopedFieldTrials field_trial(
1539 "WebRTC-IncreasedReceivebuffers/123456_Dogfood/");
1540 SetUp();
1541
1542 EXPECT_TRUE(SetOneCodec(DefaultCodec()));
1543 EXPECT_TRUE(SetSend(true));
1544 EXPECT_EQ(64 * 1024, network_interface_.sendbuf_size());
1545 EXPECT_EQ(kCustomRecvBufferSize, network_interface_.recvbuf_size());
1546}
1547
1548// Test that we properly set the send and recv buffer sizes when overriding
1549// via field trials that don't make any sense.
1550TEST_F(WebRtcVideoChannelBaseTest, InvalidRecvBufferSize) {
1551 // Set bogus field trial values to override the default recv buffer size, and
1552 // then re-run setup where the interface is created and configured. The
1553 // default value should still be used.
1554
1555 for (std::string group : {" ", "NotANumber", "-1", "0"}) {
1556 std::string field_trial_string = "WebRTC-IncreasedReceivebuffers/";
1557 field_trial_string += group;
1558 field_trial_string += "/";
1559 webrtc::test::ScopedFieldTrials field_trial(field_trial_string);
1560 SetUp();
1561
1562 EXPECT_TRUE(SetOneCodec(DefaultCodec()));
1563 EXPECT_TRUE(SetSend(true));
1564 EXPECT_EQ(64 * 1024, network_interface_.sendbuf_size());
1565 EXPECT_EQ(256 * 1024, network_interface_.recvbuf_size());
1566 }
1567}
1568
Niels Möller6557d0c2018-04-11 15:18:34 +02001569// Test that stats work properly for a 1-1 call.
srtee0c2eea2017-12-15 17:44:33 +01001570TEST_F(WebRtcVideoChannelBaseTest, GetStats) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001571 const int kDurationSec = 3;
1572 const int kFps = 10;
1573 SendReceiveManyAndGetStats(DefaultCodec(), kDurationSec, kFps);
1574
1575 cricket::VideoMediaInfo info;
1576 EXPECT_TRUE(channel_->GetStats(&info));
1577
1578 ASSERT_EQ(1U, info.senders.size());
1579 // TODO(whyuan): bytes_sent and bytes_rcvd are different. Are both payload?
1580 // For webrtc, bytes_sent does not include the RTP header length.
1581 EXPECT_GT(info.senders[0].bytes_sent, 0);
1582 EXPECT_EQ(NumRtpPackets(), info.senders[0].packets_sent);
1583 EXPECT_EQ(0.0, info.senders[0].fraction_lost);
1584 ASSERT_TRUE(info.senders[0].codec_payload_type);
1585 EXPECT_EQ(DefaultCodec().id, *info.senders[0].codec_payload_type);
1586 EXPECT_EQ(0, info.senders[0].firs_rcvd);
1587 EXPECT_EQ(0, info.senders[0].plis_rcvd);
1588 EXPECT_EQ(0, info.senders[0].nacks_rcvd);
1589 EXPECT_EQ(kVideoWidth, info.senders[0].send_frame_width);
1590 EXPECT_EQ(kVideoHeight, info.senders[0].send_frame_height);
1591 EXPECT_GT(info.senders[0].framerate_input, 0);
1592 EXPECT_GT(info.senders[0].framerate_sent, 0);
1593
1594 EXPECT_EQ(1U, info.send_codecs.count(DefaultCodec().id));
1595 EXPECT_EQ(DefaultCodec().ToCodecParameters(),
1596 info.send_codecs[DefaultCodec().id]);
1597
1598 ASSERT_EQ(1U, info.receivers.size());
1599 EXPECT_EQ(1U, info.senders[0].ssrcs().size());
1600 EXPECT_EQ(1U, info.receivers[0].ssrcs().size());
1601 EXPECT_EQ(info.senders[0].ssrcs()[0], info.receivers[0].ssrcs()[0]);
1602 ASSERT_TRUE(info.receivers[0].codec_payload_type);
1603 EXPECT_EQ(DefaultCodec().id, *info.receivers[0].codec_payload_type);
1604 EXPECT_EQ(NumRtpBytes(), info.receivers[0].bytes_rcvd);
1605 EXPECT_EQ(NumRtpPackets(), info.receivers[0].packets_rcvd);
1606 EXPECT_EQ(0.0, info.receivers[0].fraction_lost);
1607 EXPECT_EQ(0, info.receivers[0].packets_lost);
1608 // TODO(asapersson): Not set for webrtc. Handle missing stats.
1609 // EXPECT_EQ(0, info.receivers[0].packets_concealed);
1610 EXPECT_EQ(0, info.receivers[0].firs_sent);
1611 EXPECT_EQ(0, info.receivers[0].plis_sent);
1612 EXPECT_EQ(0, info.receivers[0].nacks_sent);
1613 EXPECT_EQ(kVideoWidth, info.receivers[0].frame_width);
1614 EXPECT_EQ(kVideoHeight, info.receivers[0].frame_height);
1615 EXPECT_GT(info.receivers[0].framerate_rcvd, 0);
1616 EXPECT_GT(info.receivers[0].framerate_decoded, 0);
1617 EXPECT_GT(info.receivers[0].framerate_output, 0);
1618
1619 EXPECT_EQ(1U, info.receive_codecs.count(DefaultCodec().id));
1620 EXPECT_EQ(DefaultCodec().ToCodecParameters(),
1621 info.receive_codecs[DefaultCodec().id]);
srtee0c2eea2017-12-15 17:44:33 +01001622}
Niels Möller6557d0c2018-04-11 15:18:34 +02001623
1624// Test that stats work properly for a conf call with multiple recv streams.
srtee0c2eea2017-12-15 17:44:33 +01001625TEST_F(WebRtcVideoChannelBaseTest, GetStatsMultipleRecvStreams) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001626 cricket::FakeVideoRenderer renderer1, renderer2;
1627 EXPECT_TRUE(SetOneCodec(DefaultCodec()));
1628 cricket::VideoSendParameters parameters;
1629 parameters.codecs.push_back(DefaultCodec());
1630 parameters.conference_mode = true;
1631 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1632 EXPECT_TRUE(SetSend(true));
Yves Gerey665174f2018-06-19 15:03:05 +02001633 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
1634 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
Niels Möller6557d0c2018-04-11 15:18:34 +02001635 EXPECT_TRUE(channel_->SetSink(1, &renderer1));
1636 EXPECT_TRUE(channel_->SetSink(2, &renderer2));
1637 EXPECT_EQ(0, renderer1.num_rendered_frames());
1638 EXPECT_EQ(0, renderer2.num_rendered_frames());
1639 std::vector<uint32_t> ssrcs;
1640 ssrcs.push_back(1);
1641 ssrcs.push_back(2);
1642 network_interface_.SetConferenceMode(true, ssrcs);
Niels Möller805a27e2019-01-21 12:21:27 +01001643 SendFrame();
Niels Möller6557d0c2018-04-11 15:18:34 +02001644 EXPECT_FRAME_ON_RENDERER_WAIT(renderer1, 1, kVideoWidth, kVideoHeight,
1645 kTimeout);
1646 EXPECT_FRAME_ON_RENDERER_WAIT(renderer2, 1, kVideoWidth, kVideoHeight,
1647 kTimeout);
1648
1649 EXPECT_TRUE(channel_->SetSend(false));
1650
1651 cricket::VideoMediaInfo info;
1652 EXPECT_TRUE(channel_->GetStats(&info));
1653 ASSERT_EQ(1U, info.senders.size());
1654 // TODO(whyuan): bytes_sent and bytes_rcvd are different. Are both payload?
1655 // For webrtc, bytes_sent does not include the RTP header length.
1656 EXPECT_GT(GetSenderStats(0).bytes_sent, 0);
1657 EXPECT_EQ_WAIT(NumRtpPackets(), GetSenderStats(0).packets_sent, kTimeout);
1658 EXPECT_EQ(kVideoWidth, GetSenderStats(0).send_frame_width);
1659 EXPECT_EQ(kVideoHeight, GetSenderStats(0).send_frame_height);
1660
1661 ASSERT_EQ(2U, info.receivers.size());
1662 for (size_t i = 0; i < info.receivers.size(); ++i) {
1663 EXPECT_EQ(1U, GetReceiverStats(i).ssrcs().size());
1664 EXPECT_EQ(i + 1, GetReceiverStats(i).ssrcs()[0]);
1665 EXPECT_EQ_WAIT(NumRtpBytes(), GetReceiverStats(i).bytes_rcvd, kTimeout);
Yves Gerey665174f2018-06-19 15:03:05 +02001666 EXPECT_EQ_WAIT(NumRtpPackets(), GetReceiverStats(i).packets_rcvd, kTimeout);
Niels Möller6557d0c2018-04-11 15:18:34 +02001667 EXPECT_EQ_WAIT(kVideoWidth, GetReceiverStats(i).frame_width, kTimeout);
1668 EXPECT_EQ_WAIT(kVideoHeight, GetReceiverStats(i).frame_height, kTimeout);
1669 }
srtee0c2eea2017-12-15 17:44:33 +01001670}
Niels Möller6557d0c2018-04-11 15:18:34 +02001671
1672// Test that stats work properly for a conf call with multiple send streams.
srtee0c2eea2017-12-15 17:44:33 +01001673TEST_F(WebRtcVideoChannelBaseTest, GetStatsMultipleSendStreams) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001674 // Normal setup; note that we set the SSRC explicitly to ensure that
1675 // it will come first in the senders map.
1676 EXPECT_TRUE(SetOneCodec(DefaultCodec()));
1677 cricket::VideoSendParameters parameters;
1678 parameters.codecs.push_back(DefaultCodec());
1679 parameters.conference_mode = true;
1680 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Yves Gerey665174f2018-06-19 15:03:05 +02001681 EXPECT_TRUE(
1682 channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
Niels Möller6557d0c2018-04-11 15:18:34 +02001683 EXPECT_TRUE(channel_->SetSink(kSsrc, &renderer_));
1684 EXPECT_TRUE(SetSend(true));
Niels Möller805a27e2019-01-21 12:21:27 +01001685 SendFrame();
Niels Möller6557d0c2018-04-11 15:18:34 +02001686 EXPECT_TRUE_WAIT(NumRtpPackets() > 0, kTimeout);
1687 EXPECT_FRAME_WAIT(1, kVideoWidth, kVideoHeight, kTimeout);
1688
1689 // Add an additional capturer, and hook up a renderer to receive it.
1690 cricket::FakeVideoRenderer renderer2;
Niels Möller805a27e2019-01-21 12:21:27 +01001691 webrtc::test::FrameForwarder frame_forwarder;
Niels Möller6557d0c2018-04-11 15:18:34 +02001692 const int kTestWidth = 160;
1693 const int kTestHeight = 120;
Niels Möller805a27e2019-01-21 12:21:27 +01001694 cricket::FakeFrameSource frame_source(kTestWidth, kTestHeight,
1695 rtc::kNumMicrosecsPerSec / 5);
Yves Gerey665174f2018-06-19 15:03:05 +02001696 EXPECT_TRUE(
1697 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(5678)));
Niels Möller805a27e2019-01-21 12:21:27 +01001698 EXPECT_TRUE(channel_->SetVideoSend(5678, nullptr, &frame_forwarder));
Yves Gerey665174f2018-06-19 15:03:05 +02001699 EXPECT_TRUE(
1700 channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(5678)));
Niels Möller6557d0c2018-04-11 15:18:34 +02001701 EXPECT_TRUE(channel_->SetSink(5678, &renderer2));
Niels Möller805a27e2019-01-21 12:21:27 +01001702 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
Yves Gerey665174f2018-06-19 15:03:05 +02001703 EXPECT_FRAME_ON_RENDERER_WAIT(renderer2, 1, kTestWidth, kTestHeight,
1704 kTimeout);
Niels Möller6557d0c2018-04-11 15:18:34 +02001705
1706 // Get stats, and make sure they are correct for two senders. We wait until
1707 // the number of expected packets have been sent to avoid races where we
1708 // check stats before it has been updated.
1709 cricket::VideoMediaInfo info;
1710 for (uint32_t i = 0; i < kTimeout; ++i) {
1711 rtc::Thread::Current()->ProcessMessages(1);
1712 EXPECT_TRUE(channel_->GetStats(&info));
1713 ASSERT_EQ(2U, info.senders.size());
1714 if (info.senders[0].packets_sent + info.senders[1].packets_sent ==
1715 NumRtpPackets()) {
1716 // Stats have been updated for both sent frames, expectations can be
1717 // checked now.
1718 break;
1719 }
1720 }
1721 EXPECT_EQ(NumRtpPackets(),
1722 info.senders[0].packets_sent + info.senders[1].packets_sent)
1723 << "Timed out while waiting for packet counts for all sent packets.";
1724 EXPECT_EQ(1U, info.senders[0].ssrcs().size());
1725 EXPECT_EQ(1234U, info.senders[0].ssrcs()[0]);
1726 EXPECT_EQ(kVideoWidth, info.senders[0].send_frame_width);
1727 EXPECT_EQ(kVideoHeight, info.senders[0].send_frame_height);
1728 EXPECT_EQ(1U, info.senders[1].ssrcs().size());
1729 EXPECT_EQ(5678U, info.senders[1].ssrcs()[0]);
1730 EXPECT_EQ(kTestWidth, info.senders[1].send_frame_width);
1731 EXPECT_EQ(kTestHeight, info.senders[1].send_frame_height);
1732 // The capturer must be unregistered here as it runs out of it's scope next.
1733 channel_->SetVideoSend(5678, nullptr, nullptr);
srtee0c2eea2017-12-15 17:44:33 +01001734}
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +00001735
Niels Möller6557d0c2018-04-11 15:18:34 +02001736// Test that we can set the bandwidth.
srtee0c2eea2017-12-15 17:44:33 +01001737TEST_F(WebRtcVideoChannelBaseTest, SetSendBandwidth) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001738 cricket::VideoSendParameters parameters;
1739 parameters.codecs.push_back(DefaultCodec());
1740 parameters.max_bandwidth_bps = -1; // <= 0 means unlimited.
1741 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1742 parameters.max_bandwidth_bps = 128 * 1024;
1743 EXPECT_TRUE(channel_->SetSendParameters(parameters));
srtee0c2eea2017-12-15 17:44:33 +01001744}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001745
Niels Möller6557d0c2018-04-11 15:18:34 +02001746// Test that we can set the SSRC for the default send source.
srtee0c2eea2017-12-15 17:44:33 +01001747TEST_F(WebRtcVideoChannelBaseTest, SetSendSsrc) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001748 EXPECT_TRUE(SetDefaultCodec());
1749 EXPECT_TRUE(SetSend(true));
Niels Möller805a27e2019-01-21 12:21:27 +01001750 SendFrame();
Niels Möller6557d0c2018-04-11 15:18:34 +02001751 EXPECT_TRUE_WAIT(NumRtpPackets() > 0, kTimeout);
Åsa Persson23cd45a2018-07-03 10:40:40 +02001752 webrtc::RTPHeader header;
Niels Möller6557d0c2018-04-11 15:18:34 +02001753 std::unique_ptr<const rtc::CopyOnWriteBuffer> p(GetRtpPacket(0));
Åsa Persson23cd45a2018-07-03 10:40:40 +02001754 EXPECT_TRUE(ParseRtpPacket(p.get(), &header));
1755 EXPECT_EQ(kSsrc, header.ssrc);
1756
Niels Möller6557d0c2018-04-11 15:18:34 +02001757 // Packets are being paced out, so these can mismatch between the first and
1758 // second call to NumRtpPackets until pending packets are paced out.
Åsa Persson23cd45a2018-07-03 10:40:40 +02001759 EXPECT_EQ_WAIT(NumRtpPackets(), NumRtpPackets(header.ssrc), kTimeout);
1760 EXPECT_EQ_WAIT(NumRtpBytes(), NumRtpBytes(header.ssrc), kTimeout);
Niels Möller6557d0c2018-04-11 15:18:34 +02001761 EXPECT_EQ(1, NumSentSsrcs());
1762 EXPECT_EQ(0, NumRtpPackets(kSsrc - 1));
1763 EXPECT_EQ(0, NumRtpBytes(kSsrc - 1));
srtee0c2eea2017-12-15 17:44:33 +01001764}
Niels Möller6557d0c2018-04-11 15:18:34 +02001765
1766// Test that we can set the SSRC even after codecs are set.
srtee0c2eea2017-12-15 17:44:33 +01001767TEST_F(WebRtcVideoChannelBaseTest, SetSendSsrcAfterSetCodecs) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001768 // Remove stream added in Setup.
1769 EXPECT_TRUE(channel_->RemoveSendStream(kSsrc));
1770 EXPECT_TRUE(SetDefaultCodec());
Niels Möller6557d0c2018-04-11 15:18:34 +02001771 EXPECT_TRUE(
Yves Gerey665174f2018-06-19 15:03:05 +02001772 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(999)));
Niels Möller805a27e2019-01-21 12:21:27 +01001773 EXPECT_TRUE(channel_->SetVideoSend(999u, nullptr, frame_forwarder_.get()));
Niels Möller6557d0c2018-04-11 15:18:34 +02001774 EXPECT_TRUE(SetSend(true));
1775 EXPECT_TRUE(WaitAndSendFrame(0));
1776 EXPECT_TRUE_WAIT(NumRtpPackets() > 0, kTimeout);
Åsa Persson23cd45a2018-07-03 10:40:40 +02001777 webrtc::RTPHeader header;
Niels Möller6557d0c2018-04-11 15:18:34 +02001778 std::unique_ptr<const rtc::CopyOnWriteBuffer> p(GetRtpPacket(0));
Åsa Persson23cd45a2018-07-03 10:40:40 +02001779 EXPECT_TRUE(ParseRtpPacket(p.get(), &header));
1780 EXPECT_EQ(999u, header.ssrc);
Niels Möller6557d0c2018-04-11 15:18:34 +02001781 // Packets are being paced out, so these can mismatch between the first and
1782 // second call to NumRtpPackets until pending packets are paced out.
Åsa Persson23cd45a2018-07-03 10:40:40 +02001783 EXPECT_EQ_WAIT(NumRtpPackets(), NumRtpPackets(header.ssrc), kTimeout);
1784 EXPECT_EQ_WAIT(NumRtpBytes(), NumRtpBytes(header.ssrc), kTimeout);
Niels Möller6557d0c2018-04-11 15:18:34 +02001785 EXPECT_EQ(1, NumSentSsrcs());
1786 EXPECT_EQ(0, NumRtpPackets(kSsrc));
1787 EXPECT_EQ(0, NumRtpBytes(kSsrc));
srtee0c2eea2017-12-15 17:44:33 +01001788}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001789
Niels Möller6557d0c2018-04-11 15:18:34 +02001790// Test that we can set the default video renderer before and after
1791// media is received.
srtee0c2eea2017-12-15 17:44:33 +01001792TEST_F(WebRtcVideoChannelBaseTest, SetSink) {
Yves Gerey665174f2018-06-19 15:03:05 +02001793 uint8_t data1[] = {0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
1794 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
Niels Möller6557d0c2018-04-11 15:18:34 +02001795
1796 rtc::CopyOnWriteBuffer packet1(data1, sizeof(data1));
1797 rtc::SetBE32(packet1.data() + 8, kSsrc);
1798 channel_->SetSink(kDefaultReceiveSsrc, NULL);
1799 EXPECT_TRUE(SetDefaultCodec());
1800 EXPECT_TRUE(SetSend(true));
1801 EXPECT_EQ(0, renderer_.num_rendered_frames());
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07001802 channel_->OnPacketReceived(packet1, /* packet_time_us */ -1);
Niels Möller6557d0c2018-04-11 15:18:34 +02001803 EXPECT_TRUE(channel_->SetSink(kDefaultReceiveSsrc, &renderer_));
Niels Möller805a27e2019-01-21 12:21:27 +01001804 SendFrame();
Niels Möller6557d0c2018-04-11 15:18:34 +02001805 EXPECT_FRAME_WAIT(1, kVideoWidth, kVideoHeight, kTimeout);
srtee0c2eea2017-12-15 17:44:33 +01001806}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001807
Niels Möller6557d0c2018-04-11 15:18:34 +02001808// Tests setting up and configuring a send stream.
srtee0c2eea2017-12-15 17:44:33 +01001809TEST_F(WebRtcVideoChannelBaseTest, AddRemoveSendStreams) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001810 EXPECT_TRUE(SetOneCodec(DefaultCodec()));
1811 EXPECT_TRUE(SetSend(true));
1812 EXPECT_TRUE(channel_->SetSink(kDefaultReceiveSsrc, &renderer_));
Niels Möller805a27e2019-01-21 12:21:27 +01001813 SendFrame();
Niels Möller6557d0c2018-04-11 15:18:34 +02001814 EXPECT_FRAME_WAIT(1, kVideoWidth, kVideoHeight, kTimeout);
1815 EXPECT_GT(NumRtpPackets(), 0);
Åsa Persson23cd45a2018-07-03 10:40:40 +02001816 webrtc::RTPHeader header;
Niels Möller6557d0c2018-04-11 15:18:34 +02001817 size_t last_packet = NumRtpPackets() - 1;
Yves Gerey665174f2018-06-19 15:03:05 +02001818 std::unique_ptr<const rtc::CopyOnWriteBuffer> p(
1819 GetRtpPacket(static_cast<int>(last_packet)));
Åsa Persson23cd45a2018-07-03 10:40:40 +02001820 EXPECT_TRUE(ParseRtpPacket(p.get(), &header));
1821 EXPECT_EQ(kSsrc, header.ssrc);
Niels Möller6557d0c2018-04-11 15:18:34 +02001822
1823 // Remove the send stream that was added during Setup.
1824 EXPECT_TRUE(channel_->RemoveSendStream(kSsrc));
1825 int rtp_packets = NumRtpPackets();
1826
Niels Möller6557d0c2018-04-11 15:18:34 +02001827 EXPECT_TRUE(
Yves Gerey665174f2018-06-19 15:03:05 +02001828 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(789u)));
Niels Möller805a27e2019-01-21 12:21:27 +01001829 EXPECT_TRUE(channel_->SetVideoSend(789u, nullptr, frame_forwarder_.get()));
Niels Möller6557d0c2018-04-11 15:18:34 +02001830 EXPECT_EQ(rtp_packets, NumRtpPackets());
1831 // Wait 30ms to guarantee the engine does not drop the frame.
1832 EXPECT_TRUE(WaitAndSendFrame(30));
1833 EXPECT_TRUE_WAIT(NumRtpPackets() > rtp_packets, kTimeout);
1834
1835 last_packet = NumRtpPackets() - 1;
1836 p.reset(GetRtpPacket(static_cast<int>(last_packet)));
Åsa Persson23cd45a2018-07-03 10:40:40 +02001837 EXPECT_TRUE(ParseRtpPacket(p.get(), &header));
1838 EXPECT_EQ(789u, header.ssrc);
srtee0c2eea2017-12-15 17:44:33 +01001839}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001840
Niels Möller6557d0c2018-04-11 15:18:34 +02001841// Tests the behavior of incoming streams in a conference scenario.
srtee0c2eea2017-12-15 17:44:33 +01001842TEST_F(WebRtcVideoChannelBaseTest, SimulateConference) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001843 cricket::FakeVideoRenderer renderer1, renderer2;
1844 EXPECT_TRUE(SetDefaultCodec());
1845 cricket::VideoSendParameters parameters;
1846 parameters.codecs.push_back(DefaultCodec());
1847 parameters.conference_mode = true;
1848 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1849 EXPECT_TRUE(SetSend(true));
Yves Gerey665174f2018-06-19 15:03:05 +02001850 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
1851 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
Niels Möller6557d0c2018-04-11 15:18:34 +02001852 EXPECT_TRUE(channel_->SetSink(1, &renderer1));
1853 EXPECT_TRUE(channel_->SetSink(2, &renderer2));
1854 EXPECT_EQ(0, renderer1.num_rendered_frames());
1855 EXPECT_EQ(0, renderer2.num_rendered_frames());
1856 std::vector<uint32_t> ssrcs;
1857 ssrcs.push_back(1);
1858 ssrcs.push_back(2);
1859 network_interface_.SetConferenceMode(true, ssrcs);
Niels Möller805a27e2019-01-21 12:21:27 +01001860 SendFrame();
Niels Möller6557d0c2018-04-11 15:18:34 +02001861 EXPECT_FRAME_ON_RENDERER_WAIT(renderer1, 1, kVideoWidth, kVideoHeight,
1862 kTimeout);
1863 EXPECT_FRAME_ON_RENDERER_WAIT(renderer2, 1, kVideoWidth, kVideoHeight,
1864 kTimeout);
1865
1866 std::unique_ptr<const rtc::CopyOnWriteBuffer> p(GetRtpPacket(0));
1867 EXPECT_EQ(DefaultCodec().id, GetPayloadType(p.get()));
1868 EXPECT_EQ(kVideoWidth, renderer1.width());
1869 EXPECT_EQ(kVideoHeight, renderer1.height());
1870 EXPECT_EQ(kVideoWidth, renderer2.width());
1871 EXPECT_EQ(kVideoHeight, renderer2.height());
1872 EXPECT_TRUE(channel_->RemoveRecvStream(2));
1873 EXPECT_TRUE(channel_->RemoveRecvStream(1));
srtee0c2eea2017-12-15 17:44:33 +01001874}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001875
Niels Möller6557d0c2018-04-11 15:18:34 +02001876// Tests that we can add and remove capturers and frames are sent out properly
srtee0c2eea2017-12-15 17:44:33 +01001877TEST_F(WebRtcVideoChannelBaseTest, DISABLED_AddRemoveCapturer) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001878 using cricket::VideoCodec;
1879 using cricket::VideoOptions;
1880 using cricket::VideoFormat;
1881 using cricket::FOURCC_I420;
1882
1883 VideoCodec codec = DefaultCodec();
1884 const int time_between_send_ms = VideoFormat::FpsToInterval(kFramerate);
1885 EXPECT_TRUE(SetOneCodec(codec));
1886 EXPECT_TRUE(SetSend(true));
1887 EXPECT_TRUE(channel_->SetSink(kDefaultReceiveSsrc, &renderer_));
1888 EXPECT_EQ(0, renderer_.num_rendered_frames());
Niels Möller805a27e2019-01-21 12:21:27 +01001889 SendFrame();
Niels Möller6557d0c2018-04-11 15:18:34 +02001890 EXPECT_FRAME_WAIT(1, kVideoWidth, kVideoHeight, kTimeout);
Niels Möller805a27e2019-01-21 12:21:27 +01001891
1892 webrtc::test::FrameForwarder frame_forwarder;
1893 cricket::FakeFrameSource frame_source(480, 360, rtc::kNumMicrosecsPerSec / 30,
1894 rtc::kNumMicrosecsPerSec / 30);
Niels Möller6557d0c2018-04-11 15:18:34 +02001895
1896 // TODO(nisse): This testcase fails if we don't configure
1897 // screencast. It's unclear why, I see nothing obvious in this
1898 // test which is related to screencast logic.
1899 VideoOptions video_options;
1900 video_options.is_screencast = true;
1901 channel_->SetVideoSend(kSsrc, &video_options, nullptr);
1902
Niels Möller6557d0c2018-04-11 15:18:34 +02001903 int captured_frames = 1;
1904 for (int iterations = 0; iterations < 2; ++iterations) {
Niels Möller805a27e2019-01-21 12:21:27 +01001905 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, nullptr, &frame_forwarder));
Niels Möller6557d0c2018-04-11 15:18:34 +02001906 rtc::Thread::Current()->ProcessMessages(time_between_send_ms);
Niels Möller805a27e2019-01-21 12:21:27 +01001907 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
1908
Niels Möller6557d0c2018-04-11 15:18:34 +02001909 ++captured_frames;
1910 // Wait until frame of right size is captured.
1911 EXPECT_TRUE_WAIT(renderer_.num_rendered_frames() >= captured_frames &&
Niels Möller805a27e2019-01-21 12:21:27 +01001912 480 == renderer_.width() &&
1913 360 == renderer_.height() && !renderer_.black_frame(),
Yves Gerey665174f2018-06-19 15:03:05 +02001914 kTimeout);
Niels Möller6557d0c2018-04-11 15:18:34 +02001915 EXPECT_GE(renderer_.num_rendered_frames(), captured_frames);
Niels Möller805a27e2019-01-21 12:21:27 +01001916 EXPECT_EQ(480, renderer_.width());
1917 EXPECT_EQ(360, renderer_.height());
Niels Möller6557d0c2018-04-11 15:18:34 +02001918 captured_frames = renderer_.num_rendered_frames() + 1;
1919 EXPECT_FALSE(renderer_.black_frame());
1920 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, nullptr, nullptr));
1921 // Make sure a black frame is generated within the specified timeout.
1922 // The black frame should be the resolution of the previous frame to
1923 // prevent expensive encoder reconfigurations.
1924 EXPECT_TRUE_WAIT(renderer_.num_rendered_frames() >= captured_frames &&
Niels Möller805a27e2019-01-21 12:21:27 +01001925 480 == renderer_.width() &&
1926 360 == renderer_.height() && renderer_.black_frame(),
Yves Gerey665174f2018-06-19 15:03:05 +02001927 kTimeout);
Niels Möller6557d0c2018-04-11 15:18:34 +02001928 EXPECT_GE(renderer_.num_rendered_frames(), captured_frames);
Niels Möller805a27e2019-01-21 12:21:27 +01001929 EXPECT_EQ(480, renderer_.width());
1930 EXPECT_EQ(360, renderer_.height());
Niels Möller6557d0c2018-04-11 15:18:34 +02001931 EXPECT_TRUE(renderer_.black_frame());
1932
1933 // The black frame has the same timestamp as the next frame since it's
1934 // timestamp is set to the last frame's timestamp + interval. WebRTC will
1935 // not render a frame with the same timestamp so capture another frame
1936 // with the frame capturer to increment the next frame's timestamp.
Niels Möller805a27e2019-01-21 12:21:27 +01001937 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
Niels Möller6557d0c2018-04-11 15:18:34 +02001938 }
srtee0c2eea2017-12-15 17:44:33 +01001939}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001940
Niels Möller6557d0c2018-04-11 15:18:34 +02001941// Tests that if SetVideoSend is called with a NULL capturer after the
1942// capturer was already removed, the application doesn't crash (and no black
1943// frame is sent).
srtee0c2eea2017-12-15 17:44:33 +01001944TEST_F(WebRtcVideoChannelBaseTest, RemoveCapturerWithoutAdd) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001945 EXPECT_TRUE(SetOneCodec(DefaultCodec()));
1946 EXPECT_TRUE(SetSend(true));
1947 EXPECT_TRUE(channel_->SetSink(kDefaultReceiveSsrc, &renderer_));
1948 EXPECT_EQ(0, renderer_.num_rendered_frames());
Niels Möller805a27e2019-01-21 12:21:27 +01001949 SendFrame();
Niels Möller6557d0c2018-04-11 15:18:34 +02001950 EXPECT_FRAME_WAIT(1, kVideoWidth, kVideoHeight, kTimeout);
1951 // Wait for one frame so they don't get dropped because we send frames too
1952 // tightly.
1953 rtc::Thread::Current()->ProcessMessages(30);
1954 // Remove the capturer.
1955 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, nullptr, nullptr));
1956
1957 // No capturer was added, so this SetVideoSend shouldn't do anything.
1958 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, nullptr, nullptr));
1959 rtc::Thread::Current()->ProcessMessages(300);
1960 // Verify no more frames were sent.
1961 EXPECT_EQ(1, renderer_.num_rendered_frames());
srtee0c2eea2017-12-15 17:44:33 +01001962}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001963
Niels Möller6557d0c2018-04-11 15:18:34 +02001964// Tests that we can add and remove capturer as unique sources.
srtee0c2eea2017-12-15 17:44:33 +01001965TEST_F(WebRtcVideoChannelBaseTest, AddRemoveCapturerMultipleSources) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001966 // WebRTC implementation will drop frames if pushed to quickly. Wait the
1967 // interval time to avoid that.
1968 // WebRTC implementation will drop frames if pushed to quickly. Wait the
1969 // interval time to avoid that.
1970 // Set up the stream associated with the engine.
Yves Gerey665174f2018-06-19 15:03:05 +02001971 EXPECT_TRUE(
1972 channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
Niels Möller6557d0c2018-04-11 15:18:34 +02001973 EXPECT_TRUE(channel_->SetSink(kSsrc, &renderer_));
1974 cricket::VideoFormat capture_format(
1975 kVideoWidth, kVideoHeight,
1976 cricket::VideoFormat::FpsToInterval(kFramerate), cricket::FOURCC_I420);
1977 // Set up additional stream 1.
1978 cricket::FakeVideoRenderer renderer1;
1979 EXPECT_FALSE(channel_->SetSink(1, &renderer1));
Yves Gerey665174f2018-06-19 15:03:05 +02001980 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
Niels Möller6557d0c2018-04-11 15:18:34 +02001981 EXPECT_TRUE(channel_->SetSink(1, &renderer1));
Yves Gerey665174f2018-06-19 15:03:05 +02001982 EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(1)));
Niels Möller805a27e2019-01-21 12:21:27 +01001983
1984 webrtc::test::FrameForwarder frame_forwarder1;
1985 cricket::FakeFrameSource frame_source(kVideoWidth, kVideoHeight,
1986 rtc::kNumMicrosecsPerSec / kFramerate);
1987
Niels Möller6557d0c2018-04-11 15:18:34 +02001988 // Set up additional stream 2.
1989 cricket::FakeVideoRenderer renderer2;
1990 EXPECT_FALSE(channel_->SetSink(2, &renderer2));
Yves Gerey665174f2018-06-19 15:03:05 +02001991 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
Niels Möller6557d0c2018-04-11 15:18:34 +02001992 EXPECT_TRUE(channel_->SetSink(2, &renderer2));
Yves Gerey665174f2018-06-19 15:03:05 +02001993 EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
Niels Möller805a27e2019-01-21 12:21:27 +01001994 webrtc::test::FrameForwarder frame_forwarder2;
1995
Niels Möller6557d0c2018-04-11 15:18:34 +02001996 // State for all the streams.
1997 EXPECT_TRUE(SetOneCodec(DefaultCodec()));
1998 // A limitation in the lmi implementation requires that SetVideoSend() is
1999 // called after SetOneCodec().
2000 // TODO(hellner): this seems like an unnecessary constraint, fix it.
Niels Möller805a27e2019-01-21 12:21:27 +01002001 EXPECT_TRUE(channel_->SetVideoSend(1, nullptr, &frame_forwarder1));
2002 EXPECT_TRUE(channel_->SetVideoSend(2, nullptr, &frame_forwarder2));
Niels Möller6557d0c2018-04-11 15:18:34 +02002003 EXPECT_TRUE(SetSend(true));
2004 // Test capturer associated with engine.
2005 const int kTestWidth = 160;
2006 const int kTestHeight = 120;
Niels Möller805a27e2019-01-21 12:21:27 +01002007 frame_forwarder1.IncomingCapturedFrame(frame_source.GetFrame(
2008 kTestWidth, kTestHeight, webrtc::VideoRotation::kVideoRotation_0,
2009 rtc::kNumMicrosecsPerSec / kFramerate));
Yves Gerey665174f2018-06-19 15:03:05 +02002010 EXPECT_FRAME_ON_RENDERER_WAIT(renderer1, 1, kTestWidth, kTestHeight,
2011 kTimeout);
Niels Möller6557d0c2018-04-11 15:18:34 +02002012 // Capture a frame with additional capturer2, frames should be received
Niels Möller805a27e2019-01-21 12:21:27 +01002013 frame_forwarder2.IncomingCapturedFrame(frame_source.GetFrame(
2014 kTestWidth, kTestHeight, webrtc::VideoRotation::kVideoRotation_0,
2015 rtc::kNumMicrosecsPerSec / kFramerate));
Yves Gerey665174f2018-06-19 15:03:05 +02002016 EXPECT_FRAME_ON_RENDERER_WAIT(renderer2, 1, kTestWidth, kTestHeight,
2017 kTimeout);
Niels Möller6557d0c2018-04-11 15:18:34 +02002018 // Successfully remove the capturer.
2019 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, nullptr, nullptr));
2020 // The capturers must be unregistered here as it runs out of it's scope
2021 // next.
2022 EXPECT_TRUE(channel_->SetVideoSend(1, nullptr, nullptr));
2023 EXPECT_TRUE(channel_->SetVideoSend(2, nullptr, nullptr));
srtee0c2eea2017-12-15 17:44:33 +01002024}
Niels Möller6557d0c2018-04-11 15:18:34 +02002025
2026// Tests empty StreamParams is rejected.
srtee0c2eea2017-12-15 17:44:33 +01002027TEST_F(WebRtcVideoChannelBaseTest, RejectEmptyStreamParams) {
Niels Möller6557d0c2018-04-11 15:18:34 +02002028 // Remove the send stream that was added during Setup.
2029 EXPECT_TRUE(channel_->RemoveSendStream(kSsrc));
2030
2031 cricket::StreamParams empty;
2032 EXPECT_FALSE(channel_->AddSendStream(empty));
Yves Gerey665174f2018-06-19 15:03:05 +02002033 EXPECT_TRUE(
2034 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(789u)));
srtee0c2eea2017-12-15 17:44:33 +01002035}
Niels Möller6557d0c2018-04-11 15:18:34 +02002036
2037// Test that multiple send streams can be created and deleted properly.
srtee0c2eea2017-12-15 17:44:33 +01002038TEST_F(WebRtcVideoChannelBaseTest, MultipleSendStreams) {
Niels Möller6557d0c2018-04-11 15:18:34 +02002039 // Remove stream added in Setup. I.e. remove stream corresponding to default
2040 // channel.
2041 EXPECT_TRUE(channel_->RemoveSendStream(kSsrc));
Yves Gerey665174f2018-06-19 15:03:05 +02002042 const unsigned int kSsrcsSize = sizeof(kSsrcs4) / sizeof(kSsrcs4[0]);
Niels Möller6557d0c2018-04-11 15:18:34 +02002043 for (unsigned int i = 0; i < kSsrcsSize; ++i) {
2044 EXPECT_TRUE(channel_->AddSendStream(
2045 cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
2046 }
2047 // Delete one of the non default channel streams, let the destructor delete
2048 // the remaining ones.
2049 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcs4[kSsrcsSize - 1]));
2050 // Stream should already be deleted.
2051 EXPECT_FALSE(channel_->RemoveSendStream(kSsrcs4[kSsrcsSize - 1]));
srtee0c2eea2017-12-15 17:44:33 +01002052}
pbos@webrtc.orgc4175b92014-09-03 15:25:49 +00002053
eladalonf1841382017-06-12 01:16:46 -07002054TEST_F(WebRtcVideoChannelBaseTest, SendAndReceiveVp8Vga) {
magjed509e4fe2016-11-18 01:34:11 -08002055 SendAndReceive(GetEngineCodec("VP8"));
pbos@webrtc.org9359cb32014-07-23 15:44:48 +00002056}
2057
eladalonf1841382017-06-12 01:16:46 -07002058TEST_F(WebRtcVideoChannelBaseTest, SendAndReceiveVp8Qvga) {
magjed509e4fe2016-11-18 01:34:11 -08002059 SendAndReceive(GetEngineCodec("VP8"));
pbos@webrtc.org9359cb32014-07-23 15:44:48 +00002060}
2061
eladalonf1841382017-06-12 01:16:46 -07002062TEST_F(WebRtcVideoChannelBaseTest, SendAndReceiveVp8SvcQqvga) {
magjed509e4fe2016-11-18 01:34:11 -08002063 SendAndReceive(GetEngineCodec("VP8"));
pbos@webrtc.org9359cb32014-07-23 15:44:48 +00002064}
2065
eladalonf1841382017-06-12 01:16:46 -07002066TEST_F(WebRtcVideoChannelBaseTest, TwoStreamsSendAndReceive) {
Peter Boströmd1f584b2016-04-20 16:31:53 +02002067 // Set a high bitrate to not be downscaled by VP8 due to low initial start
2068 // bitrates. This currently happens at <250k, and two streams sharing 300k
2069 // initially will use QVGA instead of VGA.
2070 // TODO(pbos): Set up the quality scaler so that both senders reliably start
2071 // at QVGA, then verify that instead.
magjed509e4fe2016-11-18 01:34:11 -08002072 cricket::VideoCodec codec = GetEngineCodec("VP8");
Peter Boströmd1f584b2016-04-20 16:31:53 +02002073 codec.params[kCodecParamStartBitrate] = "1000000";
Niels Möller6557d0c2018-04-11 15:18:34 +02002074 TwoStreamsSendAndReceive(codec);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002075}
2076
eladalonf1841382017-06-12 01:16:46 -07002077class WebRtcVideoChannelTest : public WebRtcVideoEngineTest {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002078 public:
eladalonf1841382017-06-12 01:16:46 -07002079 WebRtcVideoChannelTest() : WebRtcVideoChannelTest("") {}
2080 explicit WebRtcVideoChannelTest(const char* field_trials)
Niels Möller805a27e2019-01-21 12:21:27 +01002081 : WebRtcVideoEngineTest(field_trials),
2082 frame_source_(1280, 720, rtc::kNumMicrosecsPerSec / 30),
2083 last_ssrc_(0) {}
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002084 void SetUp() override {
Anders Carlsson5f2bb622018-05-14 09:48:06 +02002085 encoder_factory_->AddSupportedVideoCodecType("VP8");
2086 encoder_factory_->AddSupportedVideoCodecType("VP9");
2087#if defined(WEBRTC_USE_H264)
2088 encoder_factory_->AddSupportedVideoCodecType("H264");
2089#endif
2090
Sebastian Jansson8f83b422018-02-21 13:07:13 +01002091 fake_call_.reset(new FakeCall());
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02002092 channel_.reset(engine_.CreateMediaChannel(
2093 fake_call_.get(), GetMediaConfig(), VideoOptions(),
2094 webrtc::CryptoOptions(), video_bitrate_allocator_factory_.get()));
Sergey Ulanove2b15012016-11-22 16:08:30 -08002095 channel_->OnReadyToSend(true);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002096 last_ssrc_ = 123;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002097 send_parameters_.codecs = engine_.codecs();
2098 recv_parameters_.codecs = engine_.codecs();
2099 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002100 }
2101
2102 protected:
2103 FakeVideoSendStream* AddSendStream() {
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002104 return AddSendStream(StreamParams::CreateLegacy(++last_ssrc_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002105 }
2106
2107 FakeVideoSendStream* AddSendStream(const StreamParams& sp) {
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002108 size_t num_streams = fake_call_->GetVideoSendStreams().size();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002109 EXPECT_TRUE(channel_->AddSendStream(sp));
2110 std::vector<FakeVideoSendStream*> streams =
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002111 fake_call_->GetVideoSendStreams();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002112 EXPECT_EQ(num_streams + 1, streams.size());
2113 return streams[streams.size() - 1];
2114 }
2115
2116 std::vector<FakeVideoSendStream*> GetFakeSendStreams() {
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002117 return fake_call_->GetVideoSendStreams();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002118 }
2119
2120 FakeVideoReceiveStream* AddRecvStream() {
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002121 return AddRecvStream(StreamParams::CreateLegacy(++last_ssrc_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002122 }
2123
2124 FakeVideoReceiveStream* AddRecvStream(const StreamParams& sp) {
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002125 size_t num_streams = fake_call_->GetVideoReceiveStreams().size();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002126 EXPECT_TRUE(channel_->AddRecvStream(sp));
2127 std::vector<FakeVideoReceiveStream*> streams =
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002128 fake_call_->GetVideoReceiveStreams();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002129 EXPECT_EQ(num_streams + 1, streams.size());
2130 return streams[streams.size() - 1];
2131 }
2132
pbos@webrtc.org00873182014-11-25 14:03:34 +00002133 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps,
2134 int expected_min_bitrate_bps,
2135 const char* start_bitrate_kbps,
2136 int expected_start_bitrate_bps,
2137 const char* max_bitrate_kbps,
2138 int expected_max_bitrate_bps) {
Sebastian Jansson8f83b422018-02-21 13:07:13 +01002139 ExpectSetBitrateParameters(expected_min_bitrate_bps,
2140 expected_start_bitrate_bps,
2141 expected_max_bitrate_bps);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002142 auto& codecs = send_parameters_.codecs;
2143 codecs.clear();
magjed509e4fe2016-11-18 01:34:11 -08002144 codecs.push_back(GetEngineCodec("VP8"));
pbos@webrtc.org00873182014-11-25 14:03:34 +00002145 codecs[0].params[kCodecParamMinBitrate] = min_bitrate_kbps;
2146 codecs[0].params[kCodecParamStartBitrate] = start_bitrate_kbps;
2147 codecs[0].params[kCodecParamMaxBitrate] = max_bitrate_kbps;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002148 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Sebastian Jansson8f83b422018-02-21 13:07:13 +01002149 }
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002150
Sebastian Jansson8f83b422018-02-21 13:07:13 +01002151 void ExpectSetBitrateParameters(int min_bitrate_bps,
2152 int start_bitrate_bps,
2153 int max_bitrate_bps) {
2154 EXPECT_CALL(
2155 *fake_call_->GetMockTransportControllerSend(),
2156 SetSdpBitrateParameters(AllOf(
2157 Field(&BitrateConstraints::min_bitrate_bps, min_bitrate_bps),
2158 Field(&BitrateConstraints::start_bitrate_bps, start_bitrate_bps),
2159 Field(&BitrateConstraints::max_bitrate_bps, max_bitrate_bps))));
2160 }
2161
2162 void ExpectSetMaxBitrate(int max_bitrate_bps) {
2163 EXPECT_CALL(*fake_call_->GetMockTransportControllerSend(),
2164 SetSdpBitrateParameters(Field(
2165 &BitrateConstraints::max_bitrate_bps, max_bitrate_bps)));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002166 }
2167
Johannes Kron9190b822018-10-29 11:22:05 +01002168 void TestExtmapAllowMixedCaller(bool extmap_allow_mixed) {
2169 // For a caller, the answer will be applied in set remote description
2170 // where SetSendParameters() is called.
2171 EXPECT_TRUE(
2172 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
2173 send_parameters_.extmap_allow_mixed = extmap_allow_mixed;
2174 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2175 const webrtc::VideoSendStream::Config& config =
2176 fake_call_->GetVideoSendStreams()[0]->GetConfig();
2177 EXPECT_EQ(extmap_allow_mixed, config.rtp.extmap_allow_mixed);
2178 }
2179
2180 void TestExtmapAllowMixedCallee(bool extmap_allow_mixed) {
2181 // For a callee, the answer will be applied in set local description
2182 // where SetExtmapAllowMixed() and AddSendStream() are called.
2183 channel_->SetExtmapAllowMixed(extmap_allow_mixed);
2184 EXPECT_TRUE(
2185 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
2186 const webrtc::VideoSendStream::Config& config =
2187 fake_call_->GetVideoSendStreams()[0]->GetConfig();
2188 EXPECT_EQ(extmap_allow_mixed, config.rtp.extmap_allow_mixed);
2189 }
2190
isheriff6f8d6862016-05-26 11:24:55 -07002191 void TestSetSendRtpHeaderExtensions(const std::string& ext_uri) {
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002192 // Enable extension.
2193 const int id = 1;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002194 cricket::VideoSendParameters parameters = send_parameters_;
isheriff6f8d6862016-05-26 11:24:55 -07002195 parameters.extensions.push_back(RtpExtension(ext_uri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002196 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002197 FakeVideoSendStream* send_stream =
2198 AddSendStream(cricket::StreamParams::CreateLegacy(123));
2199
2200 // Verify the send extension id.
2201 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
2202 EXPECT_EQ(id, send_stream->GetConfig().rtp.extensions[0].id);
isheriff6f8d6862016-05-26 11:24:55 -07002203 EXPECT_EQ(ext_uri, send_stream->GetConfig().rtp.extensions[0].uri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002204 // Verify call with same set of extensions returns true.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002205 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002206 // Verify that SetSendRtpHeaderExtensions doesn't implicitly add them for
2207 // receivers.
2208 EXPECT_TRUE(AddRecvStream(cricket::StreamParams::CreateLegacy(123))
2209 ->GetConfig()
2210 .rtp.extensions.empty());
2211
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00002212 // Verify that existing RTP header extensions can be removed.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002213 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Fredrik Solenberg709ed672015-09-15 12:26:33 +02002214 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
2215 send_stream = fake_call_->GetVideoSendStreams()[0];
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00002216 EXPECT_TRUE(send_stream->GetConfig().rtp.extensions.empty());
2217
2218 // Verify that adding receive RTP header extensions adds them for existing
2219 // streams.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002220 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Fredrik Solenberg709ed672015-09-15 12:26:33 +02002221 send_stream = fake_call_->GetVideoSendStreams()[0];
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00002222 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
2223 EXPECT_EQ(id, send_stream->GetConfig().rtp.extensions[0].id);
isheriff6f8d6862016-05-26 11:24:55 -07002224 EXPECT_EQ(ext_uri, send_stream->GetConfig().rtp.extensions[0].uri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002225 }
2226
isheriff6f8d6862016-05-26 11:24:55 -07002227 void TestSetRecvRtpHeaderExtensions(const std::string& ext_uri) {
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002228 // Enable extension.
2229 const int id = 1;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002230 cricket::VideoRecvParameters parameters = recv_parameters_;
isheriff6f8d6862016-05-26 11:24:55 -07002231 parameters.extensions.push_back(RtpExtension(ext_uri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002232 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002233
2234 FakeVideoReceiveStream* recv_stream =
2235 AddRecvStream(cricket::StreamParams::CreateLegacy(123));
2236
2237 // Verify the recv extension id.
2238 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.extensions.size());
2239 EXPECT_EQ(id, recv_stream->GetConfig().rtp.extensions[0].id);
isheriff6f8d6862016-05-26 11:24:55 -07002240 EXPECT_EQ(ext_uri, recv_stream->GetConfig().rtp.extensions[0].uri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002241 // Verify call with same set of extensions returns true.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002242 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00002243
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002244 // Verify that SetRecvRtpHeaderExtensions doesn't implicitly add them for
2245 // senders.
2246 EXPECT_TRUE(AddSendStream(cricket::StreamParams::CreateLegacy(123))
2247 ->GetConfig()
2248 .rtp.extensions.empty());
2249
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00002250 // Verify that existing RTP header extensions can be removed.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002251 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
Fredrik Solenberg709ed672015-09-15 12:26:33 +02002252 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
2253 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00002254 EXPECT_TRUE(recv_stream->GetConfig().rtp.extensions.empty());
2255
2256 // Verify that adding receive RTP header extensions adds them for existing
2257 // streams.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002258 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
Fredrik Solenberg709ed672015-09-15 12:26:33 +02002259 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00002260 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.extensions.size());
2261 EXPECT_EQ(id, recv_stream->GetConfig().rtp.extensions[0].id);
isheriff6f8d6862016-05-26 11:24:55 -07002262 EXPECT_EQ(ext_uri, recv_stream->GetConfig().rtp.extensions[0].uri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002263 }
2264
Stefan Holmerbbaf3632015-10-29 18:53:23 +01002265 void TestExtensionFilter(const std::vector<std::string>& extensions,
2266 const std::string& expected_extension) {
2267 cricket::VideoSendParameters parameters = send_parameters_;
2268 int expected_id = -1;
2269 int id = 1;
2270 for (const std::string& extension : extensions) {
2271 if (extension == expected_extension)
2272 expected_id = id;
isheriff6f8d6862016-05-26 11:24:55 -07002273 parameters.extensions.push_back(RtpExtension(extension, id++));
Stefan Holmerbbaf3632015-10-29 18:53:23 +01002274 }
2275 EXPECT_TRUE(channel_->SetSendParameters(parameters));
2276 FakeVideoSendStream* send_stream =
2277 AddSendStream(cricket::StreamParams::CreateLegacy(123));
2278
2279 // Verify that only one of them has been set, and that it is the one with
2280 // highest priority (transport sequence number).
2281 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
2282 EXPECT_EQ(expected_id, send_stream->GetConfig().rtp.extensions[0].id);
2283 EXPECT_EQ(expected_extension,
isheriff6f8d6862016-05-26 11:24:55 -07002284 send_stream->GetConfig().rtp.extensions[0].uri);
Stefan Holmerbbaf3632015-10-29 18:53:23 +01002285 }
2286
asapersson3c81a1a2017-06-14 05:52:21 -07002287 void TestDegradationPreference(bool resolution_scaling_enabled,
2288 bool fps_scaling_enabled);
2289
Erik Språngefbde372015-04-29 16:21:28 +02002290 void TestCpuAdaptation(bool enable_overuse, bool is_screenshare);
Peter Boström3548dd22015-05-22 18:48:36 +02002291 void TestReceiverLocalSsrcConfiguration(bool receiver_first);
magjed509e4fe2016-11-18 01:34:11 -08002292 void TestReceiveUnsignaledSsrcPacket(uint8_t payload_type,
2293 bool expect_created_receive_stream);
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002294
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002295 FakeVideoSendStream* SetDenoisingOption(
nisse05103312016-03-16 02:22:50 -07002296 uint32_t ssrc,
Niels Möller805a27e2019-01-21 12:21:27 +01002297 webrtc::test::FrameForwarder* frame_forwarder,
nisse0db023a2016-03-01 04:29:59 -08002298 bool enabled) {
nisse05103312016-03-16 02:22:50 -07002299 cricket::VideoOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002300 options.video_noise_reduction = enabled;
Niels Möller805a27e2019-01-21 12:21:27 +01002301 EXPECT_TRUE(channel_->SetVideoSend(ssrc, &options, frame_forwarder));
nisse0db023a2016-03-01 04:29:59 -08002302 // Options only take effect on the next frame.
Niels Möller805a27e2019-01-21 12:21:27 +01002303 frame_forwarder->IncomingCapturedFrame(frame_source_.GetFrame());
nisse0db023a2016-03-01 04:29:59 -08002304
Erik Språng143cec12015-04-28 10:01:41 +02002305 return fake_call_->GetVideoSendStreams().back();
2306 }
2307
Peter Boström2feafdb2015-09-09 14:32:14 +02002308 FakeVideoSendStream* SetUpSimulcast(bool enabled, bool with_rtx) {
2309 const int kRtxSsrcOffset = 0xDEADBEEF;
Erik Språng143cec12015-04-28 10:01:41 +02002310 last_ssrc_ += 3;
Peter Boström2feafdb2015-09-09 14:32:14 +02002311 std::vector<uint32_t> ssrcs;
2312 std::vector<uint32_t> rtx_ssrcs;
2313 uint32_t num_streams = enabled ? 3 : 1;
2314 for (uint32_t i = 0; i < num_streams; ++i) {
2315 uint32_t ssrc = last_ssrc_ + i;
2316 ssrcs.push_back(ssrc);
2317 if (with_rtx) {
2318 rtx_ssrcs.push_back(ssrc + kRtxSsrcOffset);
2319 }
Erik Språng143cec12015-04-28 10:01:41 +02002320 }
Peter Boström2feafdb2015-09-09 14:32:14 +02002321 if (with_rtx) {
2322 return AddSendStream(
2323 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
2324 }
2325 return AddSendStream(CreateSimStreamParams("cname", ssrcs));
Erik Språng143cec12015-04-28 10:01:41 +02002326 }
2327
perkjfa10b552016-10-02 23:45:26 -07002328 int GetMaxEncoderBitrate() {
skvladdc1c62c2016-03-16 19:07:43 -07002329 std::vector<FakeVideoSendStream*> streams =
2330 fake_call_->GetVideoSendStreams();
perkjfa10b552016-10-02 23:45:26 -07002331 EXPECT_EQ(1u, streams.size());
skvladdc1c62c2016-03-16 19:07:43 -07002332 FakeVideoSendStream* stream = streams[streams.size() - 1];
Mirko Bonadeif859e552018-05-30 15:31:29 +02002333 EXPECT_EQ(1u, stream->GetEncoderConfig().number_of_streams);
perkjfa10b552016-10-02 23:45:26 -07002334 return stream->GetVideoStreams()[0].max_bitrate_bps;
skvladdc1c62c2016-03-16 19:07:43 -07002335 }
2336
perkjfa10b552016-10-02 23:45:26 -07002337 void SetAndExpectMaxBitrate(int global_max,
skvladdc1c62c2016-03-16 19:07:43 -07002338 int stream_max,
2339 int expected_encoder_bitrate) {
2340 VideoSendParameters limited_send_params = send_parameters_;
2341 limited_send_params.max_bandwidth_bps = global_max;
2342 EXPECT_TRUE(channel_->SetSendParameters(limited_send_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07002343 webrtc::RtpParameters parameters =
2344 channel_->GetRtpSendParameters(last_ssrc_);
skvladdc1c62c2016-03-16 19:07:43 -07002345 EXPECT_EQ(1UL, parameters.encodings.size());
Oskar Sundbom78807582017-11-16 11:09:55 +01002346 parameters.encodings[0].max_bitrate_bps = stream_max;
Zach Steinba37b4b2018-01-23 15:02:36 -08002347 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
skvladdc1c62c2016-03-16 19:07:43 -07002348 // Read back the parameteres and verify they have the correct value
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07002349 parameters = channel_->GetRtpSendParameters(last_ssrc_);
skvladdc1c62c2016-03-16 19:07:43 -07002350 EXPECT_EQ(1UL, parameters.encodings.size());
Oskar Sundbom78807582017-11-16 11:09:55 +01002351 EXPECT_EQ(stream_max, parameters.encodings[0].max_bitrate_bps);
skvladdc1c62c2016-03-16 19:07:43 -07002352 // Verify that the new value propagated down to the encoder
perkjfa10b552016-10-02 23:45:26 -07002353 EXPECT_EQ(expected_encoder_bitrate, GetMaxEncoderBitrate());
skvladdc1c62c2016-03-16 19:07:43 -07002354 }
2355
Åsa Persson55659812018-06-18 17:51:32 +02002356 // Values from kSimulcastConfigs in simulcast.cc.
2357 const std::vector<webrtc::VideoStream> GetSimulcastBitrates720p() const {
2358 std::vector<webrtc::VideoStream> layers(3);
2359 layers[0].min_bitrate_bps = 30000;
2360 layers[0].target_bitrate_bps = 150000;
2361 layers[0].max_bitrate_bps = 200000;
2362 layers[1].min_bitrate_bps = 150000;
2363 layers[1].target_bitrate_bps = 500000;
2364 layers[1].max_bitrate_bps = 700000;
2365 layers[2].min_bitrate_bps = 600000;
2366 layers[2].target_bitrate_bps = 2500000;
2367 layers[2].max_bitrate_bps = 2500000;
2368 return layers;
2369 }
2370
Niels Möller805a27e2019-01-21 12:21:27 +01002371 cricket::FakeFrameSource frame_source_;
kwiberg686a8ef2016-02-26 03:00:35 -08002372 std::unique_ptr<FakeCall> fake_call_;
2373 std::unique_ptr<VideoMediaChannel> channel_;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002374 cricket::VideoSendParameters send_parameters_;
2375 cricket::VideoRecvParameters recv_parameters_;
Peter Boström0c4e06b2015-10-07 12:23:21 +02002376 uint32_t last_ssrc_;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002377};
2378
eladalonf1841382017-06-12 01:16:46 -07002379TEST_F(WebRtcVideoChannelTest, SetsSyncGroupFromSyncLabel) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02002380 const uint32_t kVideoSsrc = 123;
pbos8fc7fa72015-07-15 08:02:58 -07002381 const std::string kSyncLabel = "AvSyncLabel";
2382
2383 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kVideoSsrc);
Seth Hampson845e8782018-03-02 11:34:10 -08002384 sp.set_stream_ids({kSyncLabel});
pbos8fc7fa72015-07-15 08:02:58 -07002385 EXPECT_TRUE(channel_->AddRecvStream(sp));
2386
Mirko Bonadeif859e552018-05-30 15:31:29 +02002387 EXPECT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
pbos8fc7fa72015-07-15 08:02:58 -07002388 EXPECT_EQ(kSyncLabel,
2389 fake_call_->GetVideoReceiveStreams()[0]->GetConfig().sync_group)
2390 << "SyncGroup should be set based on sync_label";
2391}
2392
eladalonf1841382017-06-12 01:16:46 -07002393TEST_F(WebRtcVideoChannelTest, RecvStreamWithSimAndRtx) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002394 cricket::VideoSendParameters parameters;
2395 parameters.codecs = engine_.codecs();
2396 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002397 EXPECT_TRUE(channel_->SetSend(true));
nisse4b4dc862016-02-17 05:25:36 -08002398 parameters.conference_mode = true;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002399 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002400
2401 // Send side.
Peter Boström0c4e06b2015-10-07 12:23:21 +02002402 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
2403 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002404 FakeVideoSendStream* send_stream = AddSendStream(
2405 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
2406
2407 ASSERT_EQ(rtx_ssrcs.size(), send_stream->GetConfig().rtp.rtx.ssrcs.size());
2408 for (size_t i = 0; i < rtx_ssrcs.size(); ++i)
2409 EXPECT_EQ(rtx_ssrcs[i], send_stream->GetConfig().rtp.rtx.ssrcs[i]);
2410
2411 // Receiver side.
2412 FakeVideoReceiveStream* recv_stream = AddRecvStream(
2413 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
nisse26e3abb2017-08-25 04:44:25 -07002414 EXPECT_FALSE(
2415 recv_stream->GetConfig().rtp.rtx_associated_payload_types.empty());
nisseca5706d2017-09-11 02:32:16 -07002416 EXPECT_TRUE(VerifyRtxReceiveAssociations(recv_stream->GetConfig()))
Peter Boströmd8b01092016-05-12 16:44:36 +02002417 << "RTX should be mapped for all decoders/payload types.";
nisseca5706d2017-09-11 02:32:16 -07002418 EXPECT_TRUE(HasRtxReceiveAssociation(recv_stream->GetConfig(),
Yves Gerey665174f2018-06-19 15:03:05 +02002419 GetEngineCodec("red").id))
nisseca5706d2017-09-11 02:32:16 -07002420 << "RTX should be mapped for the RED payload type";
2421
brandtr14742122017-01-27 04:53:07 -08002422 EXPECT_EQ(rtx_ssrcs[0], recv_stream->GetConfig().rtp.rtx_ssrc);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002423}
2424
eladalonf1841382017-06-12 01:16:46 -07002425TEST_F(WebRtcVideoChannelTest, RecvStreamWithRtx) {
pbos@webrtc.orge322a172014-06-13 11:47:28 +00002426 // Setup one channel with an associated RTX stream.
2427 cricket::StreamParams params =
2428 cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
2429 params.AddFidSsrc(kSsrcs1[0], kRtxSsrcs1[0]);
2430 FakeVideoReceiveStream* recv_stream = AddRecvStream(params);
brandtr14742122017-01-27 04:53:07 -08002431 EXPECT_EQ(kRtxSsrcs1[0], recv_stream->GetConfig().rtp.rtx_ssrc);
nisseca5706d2017-09-11 02:32:16 -07002432
2433 EXPECT_TRUE(VerifyRtxReceiveAssociations(recv_stream->GetConfig()))
2434 << "RTX should be mapped for all decoders/payload types.";
2435 EXPECT_TRUE(HasRtxReceiveAssociation(recv_stream->GetConfig(),
Yves Gerey665174f2018-06-19 15:03:05 +02002436 GetEngineCodec("red").id))
nisseca5706d2017-09-11 02:32:16 -07002437 << "RTX should be mapped for the RED payload type";
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002438}
2439
eladalonf1841382017-06-12 01:16:46 -07002440TEST_F(WebRtcVideoChannelTest, RecvStreamNoRtx) {
pbos@webrtc.orge322a172014-06-13 11:47:28 +00002441 // Setup one channel without an associated RTX stream.
2442 cricket::StreamParams params =
2443 cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
2444 FakeVideoReceiveStream* recv_stream = AddRecvStream(params);
brandtr14742122017-01-27 04:53:07 -08002445 ASSERT_EQ(0U, recv_stream->GetConfig().rtp.rtx_ssrc);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002446}
2447
Johannes Kron9190b822018-10-29 11:22:05 +01002448// Test propagation of extmap allow mixed setting.
2449TEST_F(WebRtcVideoChannelTest, SetExtmapAllowMixedAsCaller) {
2450 TestExtmapAllowMixedCaller(/*extmap_allow_mixed=*/true);
2451}
2452TEST_F(WebRtcVideoChannelTest, SetExtmapAllowMixedDisabledAsCaller) {
2453 TestExtmapAllowMixedCaller(/*extmap_allow_mixed=*/false);
2454}
2455TEST_F(WebRtcVideoChannelTest, SetExtmapAllowMixedAsCallee) {
2456 TestExtmapAllowMixedCallee(/*extmap_allow_mixed=*/true);
2457}
2458TEST_F(WebRtcVideoChannelTest, SetExtmapAllowMixedDisabledAsCallee) {
2459 TestExtmapAllowMixedCallee(/*extmap_allow_mixed=*/false);
2460}
2461
eladalonf1841382017-06-12 01:16:46 -07002462TEST_F(WebRtcVideoChannelTest, NoHeaderExtesionsByDefault) {
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002463 FakeVideoSendStream* send_stream =
2464 AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcs1[0]));
2465 ASSERT_TRUE(send_stream->GetConfig().rtp.extensions.empty());
2466
2467 FakeVideoReceiveStream* recv_stream =
2468 AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrcs1[0]));
2469 ASSERT_TRUE(recv_stream->GetConfig().rtp.extensions.empty());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002470}
2471
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002472// Test support for RTP timestamp offset header extension.
eladalonf1841382017-06-12 01:16:46 -07002473TEST_F(WebRtcVideoChannelTest, SendRtpTimestampOffsetHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002474 TestSetSendRtpHeaderExtensions(RtpExtension::kTimestampOffsetUri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002475}
isheriff6f8d6862016-05-26 11:24:55 -07002476
eladalonf1841382017-06-12 01:16:46 -07002477TEST_F(WebRtcVideoChannelTest, RecvRtpTimestampOffsetHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002478 TestSetRecvRtpHeaderExtensions(RtpExtension::kTimestampOffsetUri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002479}
2480
2481// Test support for absolute send time header extension.
eladalonf1841382017-06-12 01:16:46 -07002482TEST_F(WebRtcVideoChannelTest, SendAbsoluteSendTimeHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002483 TestSetSendRtpHeaderExtensions(RtpExtension::kAbsSendTimeUri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002484}
isheriff6f8d6862016-05-26 11:24:55 -07002485
eladalonf1841382017-06-12 01:16:46 -07002486TEST_F(WebRtcVideoChannelTest, RecvAbsoluteSendTimeHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002487 TestSetRecvRtpHeaderExtensions(RtpExtension::kAbsSendTimeUri);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002488}
2489
eladalonf1841382017-06-12 01:16:46 -07002490TEST_F(WebRtcVideoChannelTest, FiltersExtensionsPicksTransportSeqNum) {
Stefan Holmerbbaf3632015-10-29 18:53:23 +01002491 // Enable three redundant extensions.
2492 std::vector<std::string> extensions;
isheriff6f8d6862016-05-26 11:24:55 -07002493 extensions.push_back(RtpExtension::kAbsSendTimeUri);
2494 extensions.push_back(RtpExtension::kTimestampOffsetUri);
2495 extensions.push_back(RtpExtension::kTransportSequenceNumberUri);
2496 TestExtensionFilter(extensions, RtpExtension::kTransportSequenceNumberUri);
Stefan Holmerbbaf3632015-10-29 18:53:23 +01002497}
2498
eladalonf1841382017-06-12 01:16:46 -07002499TEST_F(WebRtcVideoChannelTest, FiltersExtensionsPicksAbsSendTime) {
Stefan Holmerbbaf3632015-10-29 18:53:23 +01002500 // Enable two redundant extensions.
2501 std::vector<std::string> extensions;
isheriff6f8d6862016-05-26 11:24:55 -07002502 extensions.push_back(RtpExtension::kAbsSendTimeUri);
2503 extensions.push_back(RtpExtension::kTimestampOffsetUri);
2504 TestExtensionFilter(extensions, RtpExtension::kAbsSendTimeUri);
Stefan Holmerbbaf3632015-10-29 18:53:23 +01002505}
2506
stefanc1aeaf02015-10-15 07:26:07 -07002507// Test support for transport sequence number header extension.
eladalonf1841382017-06-12 01:16:46 -07002508TEST_F(WebRtcVideoChannelTest, SendTransportSequenceNumberHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002509 TestSetSendRtpHeaderExtensions(RtpExtension::kTransportSequenceNumberUri);
stefanc1aeaf02015-10-15 07:26:07 -07002510}
eladalonf1841382017-06-12 01:16:46 -07002511TEST_F(WebRtcVideoChannelTest, RecvTransportSequenceNumberHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002512 TestSetRecvRtpHeaderExtensions(RtpExtension::kTransportSequenceNumberUri);
stefanc1aeaf02015-10-15 07:26:07 -07002513}
2514
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -07002515// Test support for video rotation header extension.
eladalonf1841382017-06-12 01:16:46 -07002516TEST_F(WebRtcVideoChannelTest, SendVideoRotationHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002517 TestSetSendRtpHeaderExtensions(RtpExtension::kVideoRotationUri);
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -07002518}
eladalonf1841382017-06-12 01:16:46 -07002519TEST_F(WebRtcVideoChannelTest, RecvVideoRotationHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002520 TestSetRecvRtpHeaderExtensions(RtpExtension::kVideoRotationUri);
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -07002521}
2522
eladalonf1841382017-06-12 01:16:46 -07002523TEST_F(WebRtcVideoChannelTest, IdenticalSendExtensionsDoesntRecreateStream) {
Stefan Holmerbbaf3632015-10-29 18:53:23 +01002524 const int kAbsSendTimeId = 1;
2525 const int kVideoRotationId = 2;
isheriff6f8d6862016-05-26 11:24:55 -07002526 send_parameters_.extensions.push_back(
2527 RtpExtension(RtpExtension::kAbsSendTimeUri, kAbsSendTimeId));
2528 send_parameters_.extensions.push_back(
2529 RtpExtension(RtpExtension::kVideoRotationUri, kVideoRotationId));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00002530
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002531 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00002532 FakeVideoSendStream* send_stream =
2533 AddSendStream(cricket::StreamParams::CreateLegacy(123));
2534
2535 EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());
Stefan Holmerbbaf3632015-10-29 18:53:23 +01002536 ASSERT_EQ(2u, send_stream->GetConfig().rtp.extensions.size());
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00002537
2538 // Setting the same extensions (even if in different order) shouldn't
2539 // reallocate the stream.
Steve Anton2c9ebef2019-01-28 17:27:58 -08002540 absl::c_reverse(send_parameters_.extensions);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002541 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00002542
2543 EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());
2544
2545 // Setting different extensions should recreate the stream.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002546 send_parameters_.extensions.resize(1);
2547 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00002548
2549 EXPECT_EQ(2, fake_call_->GetNumCreatedSendStreams());
2550}
2551
eladalonf1841382017-06-12 01:16:46 -07002552TEST_F(WebRtcVideoChannelTest, IdenticalRecvExtensionsDoesntRecreateStream) {
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00002553 const int kTOffsetId = 1;
2554 const int kAbsSendTimeId = 2;
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -07002555 const int kVideoRotationId = 3;
isheriff6f8d6862016-05-26 11:24:55 -07002556 recv_parameters_.extensions.push_back(
2557 RtpExtension(RtpExtension::kAbsSendTimeUri, kAbsSendTimeId));
2558 recv_parameters_.extensions.push_back(
2559 RtpExtension(RtpExtension::kTimestampOffsetUri, kTOffsetId));
2560 recv_parameters_.extensions.push_back(
2561 RtpExtension(RtpExtension::kVideoRotationUri, kVideoRotationId));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00002562
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002563 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
Peter Boström54be3e02015-05-25 15:04:24 +02002564 FakeVideoReceiveStream* recv_stream =
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00002565 AddRecvStream(cricket::StreamParams::CreateLegacy(123));
2566
2567 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
Peter Boström54be3e02015-05-25 15:04:24 +02002568 ASSERT_EQ(3u, recv_stream->GetConfig().rtp.extensions.size());
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00002569
2570 // Setting the same extensions (even if in different order) shouldn't
2571 // reallocate the stream.
Steve Anton2c9ebef2019-01-28 17:27:58 -08002572 absl::c_reverse(recv_parameters_.extensions);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002573 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00002574
2575 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
2576
2577 // Setting different extensions should recreate the stream.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002578 recv_parameters_.extensions.resize(1);
2579 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00002580
2581 EXPECT_EQ(2, fake_call_->GetNumCreatedReceiveStreams());
2582}
2583
eladalonf1841382017-06-12 01:16:46 -07002584TEST_F(WebRtcVideoChannelTest,
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002585 SetSendRtpHeaderExtensionsExcludeUnsupportedExtensions) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002586 const int kUnsupportedId = 1;
2587 const int kTOffsetId = 2;
2588
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002589 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002590 RtpExtension(kUnsupportedExtensionName, kUnsupportedId));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002591 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002592 RtpExtension(RtpExtension::kTimestampOffsetUri, kTOffsetId));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002593 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002594 FakeVideoSendStream* send_stream =
2595 AddSendStream(cricket::StreamParams::CreateLegacy(123));
2596
2597 // Only timestamp offset extension is set to send stream,
2598 // unsupported rtp extension is ignored.
2599 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
isheriff6f8d6862016-05-26 11:24:55 -07002600 EXPECT_STREQ(RtpExtension::kTimestampOffsetUri,
2601 send_stream->GetConfig().rtp.extensions[0].uri.c_str());
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002602}
2603
eladalonf1841382017-06-12 01:16:46 -07002604TEST_F(WebRtcVideoChannelTest,
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002605 SetRecvRtpHeaderExtensionsExcludeUnsupportedExtensions) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002606 const int kUnsupportedId = 1;
2607 const int kTOffsetId = 2;
2608
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002609 recv_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002610 RtpExtension(kUnsupportedExtensionName, kUnsupportedId));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002611 recv_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002612 RtpExtension(RtpExtension::kTimestampOffsetUri, kTOffsetId));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002613 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002614 FakeVideoReceiveStream* recv_stream =
2615 AddRecvStream(cricket::StreamParams::CreateLegacy(123));
2616
2617 // Only timestamp offset extension is set to receive stream,
2618 // unsupported rtp extension is ignored.
2619 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.extensions.size());
isheriff6f8d6862016-05-26 11:24:55 -07002620 EXPECT_STREQ(RtpExtension::kTimestampOffsetUri,
2621 recv_stream->GetConfig().rtp.extensions[0].uri.c_str());
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002622}
2623
eladalonf1841382017-06-12 01:16:46 -07002624TEST_F(WebRtcVideoChannelTest, SetSendRtpHeaderExtensionsRejectsIncorrectIds) {
Peter Boström23914fe2015-03-31 15:08:04 +02002625 const int kIncorrectIds[] = {-2, -1, 0, 15, 16};
pkasting@chromium.orge7a4a122015-01-28 21:36:55 +00002626 for (size_t i = 0; i < arraysize(kIncorrectIds); ++i) {
isheriff6f8d6862016-05-26 11:24:55 -07002627 send_parameters_.extensions.push_back(
2628 RtpExtension(RtpExtension::kTimestampOffsetUri, kIncorrectIds[i]));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002629 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_))
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002630 << "Bad extension id '" << kIncorrectIds[i] << "' accepted.";
2631 }
2632}
2633
eladalonf1841382017-06-12 01:16:46 -07002634TEST_F(WebRtcVideoChannelTest, SetRecvRtpHeaderExtensionsRejectsIncorrectIds) {
Peter Boström23914fe2015-03-31 15:08:04 +02002635 const int kIncorrectIds[] = {-2, -1, 0, 15, 16};
pkasting@chromium.orge7a4a122015-01-28 21:36:55 +00002636 for (size_t i = 0; i < arraysize(kIncorrectIds); ++i) {
isheriff6f8d6862016-05-26 11:24:55 -07002637 recv_parameters_.extensions.push_back(
2638 RtpExtension(RtpExtension::kTimestampOffsetUri, kIncorrectIds[i]));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002639 EXPECT_FALSE(channel_->SetRecvParameters(recv_parameters_))
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002640 << "Bad extension id '" << kIncorrectIds[i] << "' accepted.";
2641 }
2642}
2643
eladalonf1841382017-06-12 01:16:46 -07002644TEST_F(WebRtcVideoChannelTest, SetSendRtpHeaderExtensionsRejectsDuplicateIds) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002645 const int id = 1;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002646 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002647 RtpExtension(RtpExtension::kTimestampOffsetUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002648 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002649 RtpExtension(RtpExtension::kAbsSendTimeUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002650 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002651
2652 // Duplicate entries are also not supported.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002653 send_parameters_.extensions.clear();
2654 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002655 RtpExtension(RtpExtension::kTimestampOffsetUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002656 send_parameters_.extensions.push_back(send_parameters_.extensions.back());
2657 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002658}
2659
eladalonf1841382017-06-12 01:16:46 -07002660TEST_F(WebRtcVideoChannelTest, SetRecvRtpHeaderExtensionsRejectsDuplicateIds) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002661 const int id = 1;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002662 recv_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002663 RtpExtension(RtpExtension::kTimestampOffsetUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002664 recv_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002665 RtpExtension(RtpExtension::kAbsSendTimeUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002666 EXPECT_FALSE(channel_->SetRecvParameters(recv_parameters_));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002667
2668 // Duplicate entries are also not supported.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002669 recv_parameters_.extensions.clear();
2670 recv_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002671 RtpExtension(RtpExtension::kTimestampOffsetUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002672 recv_parameters_.extensions.push_back(recv_parameters_.extensions.back());
2673 EXPECT_FALSE(channel_->SetRecvParameters(recv_parameters_));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002674}
2675
eladalonf1841382017-06-12 01:16:46 -07002676TEST_F(WebRtcVideoChannelTest, AddRecvStreamOnlyUsesOneReceiveStream) {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002677 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002678 EXPECT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002679}
2680
eladalonf1841382017-06-12 01:16:46 -07002681TEST_F(WebRtcVideoChannelTest, RtcpIsCompoundByDefault) {
Peter Boströmd7da1202015-06-05 14:09:38 +02002682 FakeVideoReceiveStream* stream = AddRecvStream();
pbosda903ea2015-10-02 02:36:56 -07002683 EXPECT_EQ(webrtc::RtcpMode::kCompound, stream->GetConfig().rtp.rtcp_mode);
Peter Boströmd7da1202015-06-05 14:09:38 +02002684}
2685
eladalonf1841382017-06-12 01:16:46 -07002686TEST_F(WebRtcVideoChannelTest, RembIsEnabledByDefault) {
pbos@webrtc.org257e1302014-07-25 19:01:32 +00002687 FakeVideoReceiveStream* stream = AddRecvStream();
2688 EXPECT_TRUE(stream->GetConfig().rtp.remb);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002689}
2690
eladalonf1841382017-06-12 01:16:46 -07002691TEST_F(WebRtcVideoChannelTest, TransportCcIsEnabledByDefault) {
stefan43edf0f2015-11-20 18:05:48 -08002692 FakeVideoReceiveStream* stream = AddRecvStream();
2693 EXPECT_TRUE(stream->GetConfig().rtp.transport_cc);
2694}
2695
eladalonf1841382017-06-12 01:16:46 -07002696TEST_F(WebRtcVideoChannelTest, RembCanBeEnabledAndDisabled) {
pbos@webrtc.org257e1302014-07-25 19:01:32 +00002697 FakeVideoReceiveStream* stream = AddRecvStream();
2698 EXPECT_TRUE(stream->GetConfig().rtp.remb);
2699
Peter Boström126c03e2015-05-11 12:48:12 +02002700 // Verify that REMB is turned off when send(!) codecs without REMB are set.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002701 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002702 parameters.codecs.push_back(RemoveFeedbackParams(GetEngineCodec("VP8")));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002703 EXPECT_TRUE(parameters.codecs[0].feedback_params.params().empty());
2704 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002705 stream = fake_call_->GetVideoReceiveStreams()[0];
pbos@webrtc.org257e1302014-07-25 19:01:32 +00002706 EXPECT_FALSE(stream->GetConfig().rtp.remb);
2707
2708 // Verify that REMB is turned on when setting default codecs since the
2709 // default codecs have REMB enabled.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002710 parameters.codecs = engine_.codecs();
2711 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002712 stream = fake_call_->GetVideoReceiveStreams()[0];
pbos@webrtc.org257e1302014-07-25 19:01:32 +00002713 EXPECT_TRUE(stream->GetConfig().rtp.remb);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002714}
2715
eladalonf1841382017-06-12 01:16:46 -07002716TEST_F(WebRtcVideoChannelTest, TransportCcCanBeEnabledAndDisabled) {
stefan43edf0f2015-11-20 18:05:48 -08002717 FakeVideoReceiveStream* stream = AddRecvStream();
2718 EXPECT_TRUE(stream->GetConfig().rtp.transport_cc);
2719
2720 // Verify that transport cc feedback is turned off when send(!) codecs without
2721 // transport cc feedback are set.
2722 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002723 parameters.codecs.push_back(RemoveFeedbackParams(GetEngineCodec("VP8")));
stefan43edf0f2015-11-20 18:05:48 -08002724 EXPECT_TRUE(parameters.codecs[0].feedback_params.params().empty());
2725 EXPECT_TRUE(channel_->SetSendParameters(parameters));
2726 stream = fake_call_->GetVideoReceiveStreams()[0];
2727 EXPECT_FALSE(stream->GetConfig().rtp.transport_cc);
2728
2729 // Verify that transport cc feedback is turned on when setting default codecs
2730 // since the default codecs have transport cc feedback enabled.
2731 parameters.codecs = engine_.codecs();
2732 EXPECT_TRUE(channel_->SetSendParameters(parameters));
2733 stream = fake_call_->GetVideoReceiveStreams()[0];
2734 EXPECT_TRUE(stream->GetConfig().rtp.transport_cc);
2735}
2736
eladalonf1841382017-06-12 01:16:46 -07002737TEST_F(WebRtcVideoChannelTest, NackIsEnabledByDefault) {
Anders Carlsson5f2bb622018-05-14 09:48:06 +02002738 AssignDefaultCodec();
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +00002739 VerifyCodecHasDefaultFeedbackParams(default_codec_);
2740
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002741 cricket::VideoSendParameters parameters;
2742 parameters.codecs = engine_.codecs();
2743 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org19864742014-05-30 07:35:47 +00002744 EXPECT_TRUE(channel_->SetSend(true));
2745
2746 // Send side.
2747 FakeVideoSendStream* send_stream =
2748 AddSendStream(cricket::StreamParams::CreateLegacy(1));
2749 EXPECT_GT(send_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
2750
2751 // Receiver side.
2752 FakeVideoReceiveStream* recv_stream =
2753 AddRecvStream(cricket::StreamParams::CreateLegacy(1));
2754 EXPECT_GT(recv_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
2755
2756 // Nack history size should match between sender and receiver.
2757 EXPECT_EQ(send_stream->GetConfig().rtp.nack.rtp_history_ms,
2758 recv_stream->GetConfig().rtp.nack.rtp_history_ms);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002759}
2760
eladalonf1841382017-06-12 01:16:46 -07002761TEST_F(WebRtcVideoChannelTest, NackCanBeEnabledAndDisabled) {
Peter Boström67c9df72015-05-11 14:34:58 +02002762 FakeVideoSendStream* send_stream = AddSendStream();
Peter Boström3548dd22015-05-22 18:48:36 +02002763 FakeVideoReceiveStream* recv_stream = AddRecvStream();
Peter Boström67c9df72015-05-11 14:34:58 +02002764
2765 EXPECT_GT(recv_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
2766 EXPECT_GT(send_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
2767
2768 // Verify that NACK is turned off when send(!) codecs without NACK are set.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002769 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002770 parameters.codecs.push_back(RemoveFeedbackParams(GetEngineCodec("VP8")));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002771 EXPECT_TRUE(parameters.codecs[0].feedback_params.params().empty());
2772 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Peter Boström67c9df72015-05-11 14:34:58 +02002773 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
2774 EXPECT_EQ(0, recv_stream->GetConfig().rtp.nack.rtp_history_ms);
2775 send_stream = fake_call_->GetVideoSendStreams()[0];
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +00002776 EXPECT_EQ(0, send_stream->GetConfig().rtp.nack.rtp_history_ms);
2777
Peter Boström67c9df72015-05-11 14:34:58 +02002778 // Verify that NACK is turned on when setting default codecs since the
2779 // default codecs have NACK enabled.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002780 parameters.codecs = engine_.codecs();
2781 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Peter Boström67c9df72015-05-11 14:34:58 +02002782 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
2783 EXPECT_GT(recv_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
2784 send_stream = fake_call_->GetVideoSendStreams()[0];
2785 EXPECT_GT(send_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +00002786}
2787
Peter Boströme7ba0862016-03-12 00:02:28 +01002788// This test verifies that new frame sizes reconfigures encoders even though not
2789// (yet) sending. The purpose of this is to permit encoding as quickly as
2790// possible once we start sending. Likely the frames being input are from the
2791// same source that will be sent later, which just means that we're ready
2792// earlier.
eladalonf1841382017-06-12 01:16:46 -07002793TEST_F(WebRtcVideoChannelTest, ReconfiguresEncodersWhenNotSending) {
Peter Boströme7ba0862016-03-12 00:02:28 +01002794 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002795 parameters.codecs.push_back(GetEngineCodec("VP8"));
Peter Boströme7ba0862016-03-12 00:02:28 +01002796 ASSERT_TRUE(channel_->SetSendParameters(parameters));
2797 channel_->SetSend(false);
2798
2799 FakeVideoSendStream* stream = AddSendStream();
2800
perkjfa10b552016-10-02 23:45:26 -07002801 // No frames entered.
Peter Boströme7ba0862016-03-12 00:02:28 +01002802 std::vector<webrtc::VideoStream> streams = stream->GetVideoStreams();
Danil Chapovalov350531e2018-06-08 11:04:04 +00002803 EXPECT_EQ(0u, streams[0].width);
2804 EXPECT_EQ(0u, streams[0].height);
Peter Boströme7ba0862016-03-12 00:02:28 +01002805
Niels Möller805a27e2019-01-21 12:21:27 +01002806 webrtc::test::FrameForwarder frame_forwarder;
2807 cricket::FakeFrameSource frame_source(1280, 720,
2808 rtc::kNumMicrosecsPerSec / 30);
2809
2810 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));
2811 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
Peter Boströme7ba0862016-03-12 00:02:28 +01002812
2813 // Frame entered, should be reconfigured to new dimensions.
2814 streams = stream->GetVideoStreams();
Niels Möller805a27e2019-01-21 12:21:27 +01002815 EXPECT_EQ(rtc::checked_cast<size_t>(1280), streams[0].width);
2816 EXPECT_EQ(rtc::checked_cast<size_t>(720), streams[0].height);
Peter Boströme7ba0862016-03-12 00:02:28 +01002817
Niels Möllerff40b142018-04-09 08:49:14 +02002818 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
Peter Boströme7ba0862016-03-12 00:02:28 +01002819}
2820
eladalonf1841382017-06-12 01:16:46 -07002821TEST_F(WebRtcVideoChannelTest, UsesCorrectSettingsForScreencast) {
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00002822 static const int kScreenshareMinBitrateKbps = 800;
magjed509e4fe2016-11-18 01:34:11 -08002823 cricket::VideoCodec codec = GetEngineCodec("VP8");
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002824 cricket::VideoSendParameters parameters;
2825 parameters.codecs.push_back(codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002826 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00002827 AddSendStream();
2828
Niels Möller805a27e2019-01-21 12:21:27 +01002829 webrtc::test::FrameForwarder frame_forwarder;
2830 cricket::FakeFrameSource frame_source(1280, 720,
2831 rtc::kNumMicrosecsPerSec / 30);
nisse05103312016-03-16 02:22:50 -07002832 VideoOptions min_bitrate_options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002833 min_bitrate_options.screencast_min_bitrate_kbps = kScreenshareMinBitrateKbps;
Niels Möller805a27e2019-01-21 12:21:27 +01002834 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &min_bitrate_options,
2835 &frame_forwarder));
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00002836
2837 EXPECT_TRUE(channel_->SetSend(true));
2838
Niels Möller805a27e2019-01-21 12:21:27 +01002839 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00002840 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
2841 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
2842
2843 EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());
2844
2845 // Verify non-screencast settings.
perkj26091b12016-09-01 01:17:40 -07002846 webrtc::VideoEncoderConfig encoder_config =
2847 send_stream->GetEncoderConfig().Copy();
Erik Språng143cec12015-04-28 10:01:41 +02002848 EXPECT_EQ(webrtc::VideoEncoderConfig::ContentType::kRealtimeVideo,
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00002849 encoder_config.content_type);
perkjfa10b552016-10-02 23:45:26 -07002850 std::vector<webrtc::VideoStream> streams = send_stream->GetVideoStreams();
Niels Möller805a27e2019-01-21 12:21:27 +01002851 EXPECT_EQ(rtc::checked_cast<size_t>(1280), streams.front().width);
2852 EXPECT_EQ(rtc::checked_cast<size_t>(720), streams.front().height);
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00002853 EXPECT_EQ(0, encoder_config.min_transmit_bitrate_bps)
2854 << "Non-screenshare shouldn't use min-transmit bitrate.";
2855
Niels Möllerff40b142018-04-09 08:49:14 +02002856 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
perkjd533aec2017-01-13 05:57:25 -08002857 EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());
nisse05103312016-03-16 02:22:50 -07002858 VideoOptions screencast_options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002859 screencast_options.is_screencast = true;
Niels Möller805a27e2019-01-21 12:21:27 +01002860 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &screencast_options,
2861 &frame_forwarder));
2862 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
sprangf24a0642017-02-28 13:23:26 -08002863 // Send stream recreated after option change.
2864 ASSERT_EQ(2, fake_call_->GetNumCreatedSendStreams());
2865 send_stream = fake_call_->GetVideoSendStreams().front();
2866 EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00002867
2868 // Verify screencast settings.
perkj26091b12016-09-01 01:17:40 -07002869 encoder_config = send_stream->GetEncoderConfig().Copy();
Erik Språng143cec12015-04-28 10:01:41 +02002870 EXPECT_EQ(webrtc::VideoEncoderConfig::ContentType::kScreen,
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00002871 encoder_config.content_type);
2872 EXPECT_EQ(kScreenshareMinBitrateKbps * 1000,
2873 encoder_config.min_transmit_bitrate_bps);
2874
perkjfa10b552016-10-02 23:45:26 -07002875 streams = send_stream->GetVideoStreams();
Niels Möller805a27e2019-01-21 12:21:27 +01002876 EXPECT_EQ(rtc::checked_cast<size_t>(1280), streams.front().width);
2877 EXPECT_EQ(rtc::checked_cast<size_t>(720), streams.front().height);
Sergey Silkina796a7e2018-03-01 15:11:29 +01002878 EXPECT_FALSE(streams[0].num_temporal_layers.has_value());
Niels Möllerff40b142018-04-09 08:49:14 +02002879 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002880}
2881
eladalonf1841382017-06-12 01:16:46 -07002882TEST_F(WebRtcVideoChannelTest,
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002883 ConferenceModeScreencastConfiguresTemporalLayer) {
Rasmus Brandt195d1d72018-05-09 11:28:01 +02002884 static const int kConferenceScreencastTemporalBitrateBps = 200 * 1000;
nisse4b4dc862016-02-17 05:25:36 -08002885 send_parameters_.conference_mode = true;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002886 channel_->SetSendParameters(send_parameters_);
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002887
2888 AddSendStream();
nisse05103312016-03-16 02:22:50 -07002889 VideoOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002890 options.is_screencast = true;
Niels Möller805a27e2019-01-21 12:21:27 +01002891 webrtc::test::FrameForwarder frame_forwarder;
2892 cricket::FakeFrameSource frame_source(1280, 720,
2893 rtc::kNumMicrosecsPerSec / 30);
2894 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002895 EXPECT_TRUE(channel_->SetSend(true));
2896
Niels Möller805a27e2019-01-21 12:21:27 +01002897 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002898 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
2899 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
2900
perkj26091b12016-09-01 01:17:40 -07002901 webrtc::VideoEncoderConfig encoder_config =
2902 send_stream->GetEncoderConfig().Copy();
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002903
2904 // Verify screencast settings.
perkj26091b12016-09-01 01:17:40 -07002905 encoder_config = send_stream->GetEncoderConfig().Copy();
Erik Språng143cec12015-04-28 10:01:41 +02002906 EXPECT_EQ(webrtc::VideoEncoderConfig::ContentType::kScreen,
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002907 encoder_config.content_type);
perkjfa10b552016-10-02 23:45:26 -07002908
2909 std::vector<webrtc::VideoStream> streams = send_stream->GetVideoStreams();
2910 ASSERT_EQ(1u, streams.size());
Sergey Silkina796a7e2018-03-01 15:11:29 +01002911 ASSERT_EQ(2u, streams[0].num_temporal_layers);
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002912 EXPECT_EQ(kConferenceScreencastTemporalBitrateBps,
Sergey Silkina796a7e2018-03-01 15:11:29 +01002913 streams[0].target_bitrate_bps);
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00002914
Niels Möllerff40b142018-04-09 08:49:14 +02002915 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002916}
2917
eladalonf1841382017-06-12 01:16:46 -07002918TEST_F(WebRtcVideoChannelTest, SuspendBelowMinBitrateDisabledByDefault) {
pbos@webrtc.org5ff71ab2014-07-23 07:28:56 +00002919 FakeVideoSendStream* stream = AddSendStream();
2920 EXPECT_FALSE(stream->GetConfig().suspend_below_min_bitrate);
2921}
2922
eladalonf1841382017-06-12 01:16:46 -07002923TEST_F(WebRtcVideoChannelTest, SetMediaConfigSuspendBelowMinBitrate) {
kthelgason2bc68642017-02-07 07:02:22 -08002924 MediaConfig media_config = GetMediaConfig();
nisse0db023a2016-03-01 04:29:59 -08002925 media_config.video.suspend_below_min_bitrate = true;
2926
Sebastian Jansson84848f22018-11-16 10:40:36 +01002927 channel_.reset(engine_.CreateMediaChannel(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02002928 fake_call_.get(), media_config, VideoOptions(), webrtc::CryptoOptions(),
2929 video_bitrate_allocator_factory_.get()));
Sergey Ulanove2b15012016-11-22 16:08:30 -08002930 channel_->OnReadyToSend(true);
nisse0db023a2016-03-01 04:29:59 -08002931
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002932 channel_->SetSendParameters(send_parameters_);
pbos@webrtc.org5ff71ab2014-07-23 07:28:56 +00002933
2934 FakeVideoSendStream* stream = AddSendStream();
2935 EXPECT_TRUE(stream->GetConfig().suspend_below_min_bitrate);
2936
nisse0db023a2016-03-01 04:29:59 -08002937 media_config.video.suspend_below_min_bitrate = false;
Sebastian Jansson84848f22018-11-16 10:40:36 +01002938 channel_.reset(engine_.CreateMediaChannel(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02002939 fake_call_.get(), media_config, VideoOptions(), webrtc::CryptoOptions(),
2940 video_bitrate_allocator_factory_.get()));
Sergey Ulanove2b15012016-11-22 16:08:30 -08002941 channel_->OnReadyToSend(true);
nisse0db023a2016-03-01 04:29:59 -08002942
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002943 channel_->SetSendParameters(send_parameters_);
pbos@webrtc.org5ff71ab2014-07-23 07:28:56 +00002944
nisse0db023a2016-03-01 04:29:59 -08002945 stream = AddSendStream();
pbos@webrtc.org5ff71ab2014-07-23 07:28:56 +00002946 EXPECT_FALSE(stream->GetConfig().suspend_below_min_bitrate);
2947}
2948
eladalonf1841382017-06-12 01:16:46 -07002949TEST_F(WebRtcVideoChannelTest, Vp8DenoisingEnabledByDefault) {
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00002950 FakeVideoSendStream* stream = AddSendStream();
2951 webrtc::VideoCodecVP8 vp8_settings;
2952 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
2953 EXPECT_TRUE(vp8_settings.denoisingOn);
2954}
2955
eladalonf1841382017-06-12 01:16:46 -07002956TEST_F(WebRtcVideoChannelTest, VerifyVp8SpecificSettings) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002957 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002958 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002959 ASSERT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00002960
Peter Boström2feafdb2015-09-09 14:32:14 +02002961 // Single-stream settings should apply with RTX as well (verifies that we
2962 // check number of regular SSRCs and not StreamParams::ssrcs which contains
2963 // both RTX and regular SSRCs).
2964 FakeVideoSendStream* stream = SetUpSimulcast(false, true);
Erik Språng143cec12015-04-28 10:01:41 +02002965
Niels Möller805a27e2019-01-21 12:21:27 +01002966 webrtc::test::FrameForwarder frame_forwarder;
2967 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));
Erik Språng143cec12015-04-28 10:01:41 +02002968 channel_->SetSend(true);
2969
Niels Möller805a27e2019-01-21 12:21:27 +01002970 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Erik Språng143cec12015-04-28 10:01:41 +02002971
pbos4cba4eb2015-10-26 11:18:18 -07002972 webrtc::VideoCodecVP8 vp8_settings;
2973 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
2974 EXPECT_TRUE(vp8_settings.denoisingOn)
2975 << "VP8 denoising should be on by default.";
2976
Niels Möller805a27e2019-01-21 12:21:27 +01002977 stream = SetDenoisingOption(last_ssrc_, &frame_forwarder, false);
Erik Språng143cec12015-04-28 10:01:41 +02002978
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00002979 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
2980 EXPECT_FALSE(vp8_settings.denoisingOn);
Erik Språng143cec12015-04-28 10:01:41 +02002981 EXPECT_TRUE(vp8_settings.automaticResizeOn);
2982 EXPECT_TRUE(vp8_settings.frameDroppingOn);
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00002983
Niels Möller805a27e2019-01-21 12:21:27 +01002984 stream = SetDenoisingOption(last_ssrc_, &frame_forwarder, true);
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00002985
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00002986 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
2987 EXPECT_TRUE(vp8_settings.denoisingOn);
Erik Språng143cec12015-04-28 10:01:41 +02002988 EXPECT_TRUE(vp8_settings.automaticResizeOn);
2989 EXPECT_TRUE(vp8_settings.frameDroppingOn);
2990
Niels Möllerff40b142018-04-09 08:49:14 +02002991 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
Peter Boström2feafdb2015-09-09 14:32:14 +02002992 stream = SetUpSimulcast(true, false);
Niels Möller805a27e2019-01-21 12:21:27 +01002993 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));
Erik Språng143cec12015-04-28 10:01:41 +02002994 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01002995 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Erik Språng143cec12015-04-28 10:01:41 +02002996
Mirko Bonadeif859e552018-05-30 15:31:29 +02002997 EXPECT_EQ(3u, stream->GetVideoStreams().size());
Erik Språng143cec12015-04-28 10:01:41 +02002998 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
2999 // Autmatic resize off when using simulcast.
3000 EXPECT_FALSE(vp8_settings.automaticResizeOn);
3001 EXPECT_TRUE(vp8_settings.frameDroppingOn);
3002
3003 // In screen-share mode, denoising is forced off and simulcast disabled.
nisse05103312016-03-16 02:22:50 -07003004 VideoOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01003005 options.is_screencast = true;
Niels Möller805a27e2019-01-21 12:21:27 +01003006 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
Niels Möller60653ba2016-03-02 11:41:36 +01003007
Niels Möller805a27e2019-01-21 12:21:27 +01003008 stream = SetDenoisingOption(last_ssrc_, &frame_forwarder, false);
Erik Språng143cec12015-04-28 10:01:41 +02003009
Mirko Bonadeif859e552018-05-30 15:31:29 +02003010 EXPECT_EQ(1u, stream->GetVideoStreams().size());
Erik Språng143cec12015-04-28 10:01:41 +02003011 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
3012 EXPECT_FALSE(vp8_settings.denoisingOn);
3013 // Resizing and frame dropping always off for screen sharing.
3014 EXPECT_FALSE(vp8_settings.automaticResizeOn);
3015 EXPECT_FALSE(vp8_settings.frameDroppingOn);
3016
Niels Möller805a27e2019-01-21 12:21:27 +01003017 stream = SetDenoisingOption(last_ssrc_, &frame_forwarder, true);
Erik Språng143cec12015-04-28 10:01:41 +02003018
3019 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
3020 EXPECT_FALSE(vp8_settings.denoisingOn);
3021 EXPECT_FALSE(vp8_settings.automaticResizeOn);
3022 EXPECT_FALSE(vp8_settings.frameDroppingOn);
3023
Niels Möllerff40b142018-04-09 08:49:14 +02003024 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
Erik Språng143cec12015-04-28 10:01:41 +02003025}
3026
deadbeef119760a2016-04-04 11:43:27 -07003027// Test that setting the same options doesn't result in the encoder being
3028// reconfigured.
eladalonf1841382017-06-12 01:16:46 -07003029TEST_F(WebRtcVideoChannelTest, SetIdenticalOptionsDoesntReconfigureEncoder) {
deadbeef119760a2016-04-04 11:43:27 -07003030 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01003031 webrtc::test::FrameForwarder frame_forwarder;
deadbeef119760a2016-04-04 11:43:27 -07003032
perkjfa10b552016-10-02 23:45:26 -07003033 AddSendStream();
perkjfa10b552016-10-02 23:45:26 -07003034 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08003035 parameters.codecs.push_back(GetEngineCodec("VP8"));
perkjfa10b552016-10-02 23:45:26 -07003036 ASSERT_TRUE(channel_->SetSendParameters(parameters));
3037 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
3038
Niels Möller805a27e2019-01-21 12:21:27 +01003039 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
3040 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
3041 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
perkjfa10b552016-10-02 23:45:26 -07003042 // Expect 1 reconfigurations at this point from the initial configuration.
3043 EXPECT_EQ(1, send_stream->num_encoder_reconfigurations());
deadbeef119760a2016-04-04 11:43:27 -07003044
3045 // Set the options one more time and expect no additional reconfigurations.
Niels Möller805a27e2019-01-21 12:21:27 +01003046 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
perkjfa10b552016-10-02 23:45:26 -07003047 EXPECT_EQ(1, send_stream->num_encoder_reconfigurations());
3048
3049 // Change |options| and expect 2 reconfigurations.
Oskar Sundbom78807582017-11-16 11:09:55 +01003050 options.video_noise_reduction = true;
Niels Möller805a27e2019-01-21 12:21:27 +01003051 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
deadbeef119760a2016-04-04 11:43:27 -07003052 EXPECT_EQ(2, send_stream->num_encoder_reconfigurations());
3053
Niels Möllerff40b142018-04-09 08:49:14 +02003054 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
deadbeef119760a2016-04-04 11:43:27 -07003055}
3056
eladalonf1841382017-06-12 01:16:46 -07003057class Vp9SettingsTest : public WebRtcVideoChannelTest {
Erik Språng143cec12015-04-28 10:01:41 +02003058 public:
asaperssonc5dabdd2016-03-21 04:15:50 -07003059 Vp9SettingsTest() : Vp9SettingsTest("") {}
3060 explicit Vp9SettingsTest(const char* field_trials)
eladalonf1841382017-06-12 01:16:46 -07003061 : WebRtcVideoChannelTest(field_trials) {
Magnus Jedvert02e7a192017-09-23 17:21:32 +02003062 encoder_factory_->AddSupportedVideoCodecType("VP9");
Erik Språng143cec12015-04-28 10:01:41 +02003063 }
3064 virtual ~Vp9SettingsTest() {}
3065
3066 protected:
Erik Språng143cec12015-04-28 10:01:41 +02003067 void TearDown() override {
3068 // Remove references to encoder_factory_ since this will be destroyed
3069 // before channel_ and engine_.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003070 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
Erik Språng143cec12015-04-28 10:01:41 +02003071 }
Erik Språng143cec12015-04-28 10:01:41 +02003072};
3073
3074TEST_F(Vp9SettingsTest, VerifyVp9SpecificSettings) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003075 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08003076 parameters.codecs.push_back(GetEngineCodec("VP9"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003077 ASSERT_TRUE(channel_->SetSendParameters(parameters));
Erik Språng143cec12015-04-28 10:01:41 +02003078
Peter Boström2feafdb2015-09-09 14:32:14 +02003079 FakeVideoSendStream* stream = SetUpSimulcast(false, false);
Erik Språng143cec12015-04-28 10:01:41 +02003080
Niels Möller805a27e2019-01-21 12:21:27 +01003081 webrtc::test::FrameForwarder frame_forwarder;
3082 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));
Erik Språng143cec12015-04-28 10:01:41 +02003083 channel_->SetSend(true);
3084
Niels Möller805a27e2019-01-21 12:21:27 +01003085 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Erik Språng143cec12015-04-28 10:01:41 +02003086
pbos4cba4eb2015-10-26 11:18:18 -07003087 webrtc::VideoCodecVP9 vp9_settings;
3088 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
jianja5e8aa62017-03-27 10:09:00 -07003089 EXPECT_TRUE(vp9_settings.denoisingOn)
3090 << "VP9 denoising should be on by default.";
pbos4cba4eb2015-10-26 11:18:18 -07003091
Niels Möller805a27e2019-01-21 12:21:27 +01003092 stream = SetDenoisingOption(last_ssrc_, &frame_forwarder, false);
Erik Språng143cec12015-04-28 10:01:41 +02003093
Erik Språng143cec12015-04-28 10:01:41 +02003094 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
3095 EXPECT_FALSE(vp9_settings.denoisingOn);
3096 // Frame dropping always on for real time video.
3097 EXPECT_TRUE(vp9_settings.frameDroppingOn);
3098
Niels Möller805a27e2019-01-21 12:21:27 +01003099 stream = SetDenoisingOption(last_ssrc_, &frame_forwarder, true);
Erik Språng143cec12015-04-28 10:01:41 +02003100
3101 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
3102 EXPECT_TRUE(vp9_settings.denoisingOn);
3103 EXPECT_TRUE(vp9_settings.frameDroppingOn);
3104
3105 // In screen-share mode, denoising is forced off.
nisse05103312016-03-16 02:22:50 -07003106 VideoOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01003107 options.is_screencast = true;
Niels Möller805a27e2019-01-21 12:21:27 +01003108 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
perkj2d5f0912016-02-29 00:04:41 -08003109
Niels Möller805a27e2019-01-21 12:21:27 +01003110 stream = SetDenoisingOption(last_ssrc_, &frame_forwarder, false);
Erik Språng143cec12015-04-28 10:01:41 +02003111
3112 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
3113 EXPECT_FALSE(vp9_settings.denoisingOn);
Sergey Silkinbe71a1e2018-05-17 16:46:43 +02003114 // Frame dropping always on for screen sharing.
3115 EXPECT_TRUE(vp9_settings.frameDroppingOn);
Erik Språng143cec12015-04-28 10:01:41 +02003116
Niels Möller805a27e2019-01-21 12:21:27 +01003117 stream = SetDenoisingOption(last_ssrc_, &frame_forwarder, false);
Erik Språng143cec12015-04-28 10:01:41 +02003118
3119 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
3120 EXPECT_FALSE(vp9_settings.denoisingOn);
Sergey Silkinbe71a1e2018-05-17 16:46:43 +02003121 EXPECT_TRUE(vp9_settings.frameDroppingOn);
Erik Språng143cec12015-04-28 10:01:41 +02003122
Niels Möllerff40b142018-04-09 08:49:14 +02003123 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003124}
3125
Sergey Silkinf18072e2018-03-14 10:35:35 +01003126TEST_F(Vp9SettingsTest, MultipleSsrcsEnablesSvc) {
3127 cricket::VideoSendParameters parameters;
3128 parameters.codecs.push_back(GetEngineCodec("VP9"));
3129 ASSERT_TRUE(channel_->SetSendParameters(parameters));
3130
3131 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
3132
3133 FakeVideoSendStream* stream =
3134 AddSendStream(CreateSimStreamParams("cname", ssrcs));
3135
3136 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
Sergey Silkinf18072e2018-03-14 10:35:35 +01003137
Niels Möller805a27e2019-01-21 12:21:27 +01003138 webrtc::test::FrameForwarder frame_forwarder;
3139 EXPECT_TRUE(channel_->SetVideoSend(ssrcs[0], nullptr, &frame_forwarder));
Sergey Silkinf18072e2018-03-14 10:35:35 +01003140 channel_->SetSend(true);
3141
Niels Möller805a27e2019-01-21 12:21:27 +01003142 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Sergey Silkinf18072e2018-03-14 10:35:35 +01003143
3144 webrtc::VideoCodecVP9 vp9_settings;
3145 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
3146
3147 const size_t kNumSpatialLayers = ssrcs.size();
3148 const size_t kNumTemporalLayers = 3;
3149 EXPECT_EQ(vp9_settings.numberOfSpatialLayers, kNumSpatialLayers);
3150 EXPECT_EQ(vp9_settings.numberOfTemporalLayers, kNumTemporalLayers);
3151
Niels Möllerff40b142018-04-09 08:49:14 +02003152 EXPECT_TRUE(channel_->SetVideoSend(ssrcs[0], nullptr, nullptr));
Sergey Silkinf18072e2018-03-14 10:35:35 +01003153}
3154
Ilya Nikolaevskiy33d2a912019-04-02 11:05:03 +02003155TEST_F(Vp9SettingsTest, SvcModeCreatesSingleRtpStream) {
3156 cricket::VideoSendParameters parameters;
3157 parameters.codecs.push_back(GetEngineCodec("VP9"));
3158 ASSERT_TRUE(channel_->SetSendParameters(parameters));
3159
3160 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
3161
3162 FakeVideoSendStream* stream =
3163 AddSendStream(CreateSimStreamParams("cname", ssrcs));
3164
3165 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
3166
3167 // Despite 3 ssrcs provided, single layer is used.
3168 EXPECT_EQ(1u, config.rtp.ssrcs.size());
3169
3170 webrtc::test::FrameForwarder frame_forwarder;
3171 EXPECT_TRUE(channel_->SetVideoSend(ssrcs[0], nullptr, &frame_forwarder));
3172 channel_->SetSend(true);
3173
3174 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
3175
3176 webrtc::VideoCodecVP9 vp9_settings;
3177 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
3178
3179 const size_t kNumSpatialLayers = ssrcs.size();
3180 EXPECT_EQ(vp9_settings.numberOfSpatialLayers, kNumSpatialLayers);
3181
3182 EXPECT_TRUE(channel_->SetVideoSend(ssrcs[0], nullptr, nullptr));
3183}
3184
Sergey Silkin8b9b5f92018-12-10 09:28:53 +01003185TEST_F(Vp9SettingsTest, AllEncodingParametersCopied) {
3186 cricket::VideoSendParameters send_parameters;
3187 send_parameters.codecs.push_back(GetEngineCodec("VP9"));
3188 ASSERT_TRUE(channel_->SetSendParameters(send_parameters));
3189
3190 const size_t kNumSpatialLayers = 3;
3191 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
3192
3193 FakeVideoSendStream* stream =
3194 AddSendStream(CreateSimStreamParams("cname", ssrcs));
3195
3196 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(ssrcs[0]);
3197 ASSERT_EQ(kNumSpatialLayers, parameters.encodings.size());
3198 ASSERT_TRUE(parameters.encodings[0].active);
3199 ASSERT_TRUE(parameters.encodings[1].active);
3200 ASSERT_TRUE(parameters.encodings[2].active);
3201 // Invert value to verify copying.
3202 parameters.encodings[1].active = false;
3203 EXPECT_TRUE(channel_->SetRtpSendParameters(ssrcs[0], parameters).ok());
3204
3205 webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
3206
3207 // number_of_streams should be 1 since all spatial layers are sent on the
3208 // same SSRC. But encoding parameters of all layers is supposed to be copied
3209 // and stored in simulcast_layers[].
3210 EXPECT_EQ(1u, encoder_config.number_of_streams);
3211 EXPECT_EQ(encoder_config.simulcast_layers.size(), kNumSpatialLayers);
3212 EXPECT_TRUE(encoder_config.simulcast_layers[0].active);
3213 EXPECT_FALSE(encoder_config.simulcast_layers[1].active);
3214 EXPECT_TRUE(encoder_config.simulcast_layers[2].active);
3215}
3216
Sergey Silkincf267052019-04-09 11:40:09 +02003217class Vp9SettingsTestWithFieldTrial
3218 : public Vp9SettingsTest,
3219 public ::testing::WithParamInterface<
3220 ::testing::tuple<const char*, int, int, webrtc::InterLayerPredMode>> {
asaperssonc5dabdd2016-03-21 04:15:50 -07003221 protected:
Sergey Silkincf267052019-04-09 11:40:09 +02003222 Vp9SettingsTestWithFieldTrial()
3223 : Vp9SettingsTest(::testing::get<0>(GetParam())),
3224 num_spatial_layers_(::testing::get<1>(GetParam())),
3225 num_temporal_layers_(::testing::get<2>(GetParam())),
Sergey Silkin19da5ce2019-05-20 17:57:17 +02003226 inter_layer_pred_mode_(::testing::get<3>(GetParam())) {}
Sergey Silkincf267052019-04-09 11:40:09 +02003227
3228 void VerifySettings(int num_spatial_layers,
3229 int num_temporal_layers,
3230 webrtc::InterLayerPredMode interLayerPred) {
asaperssonc5dabdd2016-03-21 04:15:50 -07003231 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08003232 parameters.codecs.push_back(GetEngineCodec("VP9"));
asaperssonc5dabdd2016-03-21 04:15:50 -07003233 ASSERT_TRUE(channel_->SetSendParameters(parameters));
3234
3235 FakeVideoSendStream* stream = SetUpSimulcast(false, false);
3236
Niels Möller805a27e2019-01-21 12:21:27 +01003237 webrtc::test::FrameForwarder frame_forwarder;
3238 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));
asaperssonc5dabdd2016-03-21 04:15:50 -07003239 channel_->SetSend(true);
3240
Niels Möller805a27e2019-01-21 12:21:27 +01003241 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
asaperssonc5dabdd2016-03-21 04:15:50 -07003242
3243 webrtc::VideoCodecVP9 vp9_settings;
3244 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
3245 EXPECT_EQ(num_spatial_layers, vp9_settings.numberOfSpatialLayers);
3246 EXPECT_EQ(num_temporal_layers, vp9_settings.numberOfTemporalLayers);
Sergey Silkin19da5ce2019-05-20 17:57:17 +02003247 EXPECT_EQ(inter_layer_pred_mode_, vp9_settings.interLayerPred);
asaperssonc5dabdd2016-03-21 04:15:50 -07003248
Niels Möllerff40b142018-04-09 08:49:14 +02003249 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
asaperssonc5dabdd2016-03-21 04:15:50 -07003250 }
Sergey Silkincf267052019-04-09 11:40:09 +02003251
3252 const uint8_t num_spatial_layers_;
3253 const uint8_t num_temporal_layers_;
Sergey Silkin19da5ce2019-05-20 17:57:17 +02003254 const webrtc::InterLayerPredMode inter_layer_pred_mode_;
asaperssonc5dabdd2016-03-21 04:15:50 -07003255};
3256
Sergey Silkincf267052019-04-09 11:40:09 +02003257TEST_P(Vp9SettingsTestWithFieldTrial, VerifyCodecSettings) {
Sergey Silkin19da5ce2019-05-20 17:57:17 +02003258 VerifySettings(num_spatial_layers_, num_temporal_layers_,
3259 inter_layer_pred_mode_);
asaperssonc5dabdd2016-03-21 04:15:50 -07003260}
3261
Sergey Silkincf267052019-04-09 11:40:09 +02003262INSTANTIATE_TEST_SUITE_P(
3263 ,
3264 Vp9SettingsTestWithFieldTrial,
3265 ::testing::Values(
3266 std::make_tuple("", 1, 1, webrtc::InterLayerPredMode::kOnKeyPic),
3267 std::make_tuple("WebRTC-SupportVP9SVC/Default/",
3268 1,
3269 1,
3270 webrtc::InterLayerPredMode::kOnKeyPic),
3271 std::make_tuple("WebRTC-SupportVP9SVC/EnabledByFlag_2SL3TL/",
3272 2,
3273 3,
3274 webrtc::InterLayerPredMode::kOnKeyPic),
Sergey Silkin19da5ce2019-05-20 17:57:17 +02003275 std::make_tuple("WebRTC-Vp9InterLayerPred/Default/",
Sergey Silkincf267052019-04-09 11:40:09 +02003276 1,
3277 1,
Sergey Silkin19da5ce2019-05-20 17:57:17 +02003278 webrtc::InterLayerPredMode::kOnKeyPic),
3279 std::make_tuple("WebRTC-Vp9InterLayerPred/Disabled/",
Sergey Silkincf267052019-04-09 11:40:09 +02003280 1,
3281 1,
Sergey Silkin19da5ce2019-05-20 17:57:17 +02003282 webrtc::InterLayerPredMode::kOnKeyPic),
3283 std::make_tuple(
3284 "WebRTC-Vp9InterLayerPred/Enabled,inter_layer_pred_mode:off/",
3285 1,
3286 1,
3287 webrtc::InterLayerPredMode::kOff),
3288 std::make_tuple(
3289 "WebRTC-Vp9InterLayerPred/Enabled,inter_layer_pred_mode:on/",
3290 1,
3291 1,
3292 webrtc::InterLayerPredMode::kOn),
3293 std::make_tuple(
3294 "WebRTC-Vp9InterLayerPred/Enabled,inter_layer_pred_mode:onkeypic/",
3295 1,
3296 1,
3297 webrtc::InterLayerPredMode::kOnKeyPic)));
asaperssonc5dabdd2016-03-21 04:15:50 -07003298
Åsa Persson45bbc8a2017-11-13 10:16:47 +01003299TEST_F(WebRtcVideoChannelTest, VerifyMinBitrate) {
3300 std::vector<webrtc::VideoStream> streams = AddSendStream()->GetVideoStreams();
3301 ASSERT_EQ(1u, streams.size());
3302 EXPECT_EQ(cricket::kMinVideoBitrateBps, streams[0].min_bitrate_bps);
3303}
3304
3305TEST_F(WebRtcVideoChannelTest, VerifyMinBitrateWithForcedFallbackFieldTrial) {
Elad Alon040dc432019-05-22 15:40:02 +02003306 RTC_DCHECK(!override_field_trials_);
3307 override_field_trials_ = absl::make_unique<webrtc::test::ScopedFieldTrials>(
Åsa Persson45bbc8a2017-11-13 10:16:47 +01003308 "WebRTC-VP8-Forced-Fallback-Encoder-v2/Enabled-1,2,34567/");
3309 std::vector<webrtc::VideoStream> streams = AddSendStream()->GetVideoStreams();
3310 ASSERT_EQ(1u, streams.size());
3311 EXPECT_EQ(34567, streams[0].min_bitrate_bps);
3312}
3313
asapersson3c81a1a2017-06-14 05:52:21 -07003314TEST_F(WebRtcVideoChannelTest,
3315 BalancedDegradationPreferenceNotSupportedWithoutFieldtrial) {
Elad Alon040dc432019-05-22 15:40:02 +02003316 RTC_DCHECK(!override_field_trials_);
3317 override_field_trials_ = absl::make_unique<webrtc::test::ScopedFieldTrials>(
asapersson3c81a1a2017-06-14 05:52:21 -07003318 "WebRTC-Video-BalancedDegradation/Disabled/");
3319 const bool kResolutionScalingEnabled = true;
3320 const bool kFpsScalingEnabled = false;
3321 TestDegradationPreference(kResolutionScalingEnabled, kFpsScalingEnabled);
3322}
3323
3324TEST_F(WebRtcVideoChannelTest,
3325 BalancedDegradationPreferenceSupportedBehindFieldtrial) {
Elad Alon040dc432019-05-22 15:40:02 +02003326 RTC_DCHECK(!override_field_trials_);
3327 override_field_trials_ = absl::make_unique<webrtc::test::ScopedFieldTrials>(
asapersson3c81a1a2017-06-14 05:52:21 -07003328 "WebRTC-Video-BalancedDegradation/Enabled/");
3329 const bool kResolutionScalingEnabled = true;
3330 const bool kFpsScalingEnabled = true;
3331 TestDegradationPreference(kResolutionScalingEnabled, kFpsScalingEnabled);
3332}
3333
eladalonf1841382017-06-12 01:16:46 -07003334TEST_F(WebRtcVideoChannelTest, AdaptsOnOveruse) {
Erik Språngefbde372015-04-29 16:21:28 +02003335 TestCpuAdaptation(true, false);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003336}
3337
eladalonf1841382017-06-12 01:16:46 -07003338TEST_F(WebRtcVideoChannelTest, DoesNotAdaptOnOveruseWhenDisabled) {
Erik Språngefbde372015-04-29 16:21:28 +02003339 TestCpuAdaptation(false, false);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003340}
3341
Niels Möller3de32e62019-01-18 08:42:18 +01003342TEST_F(WebRtcVideoChannelTest, DoesNotAdaptWhenScreeensharing) {
3343 TestCpuAdaptation(false, true);
3344}
3345
eladalonf1841382017-06-12 01:16:46 -07003346TEST_F(WebRtcVideoChannelTest, DoesNotAdaptOnOveruseWhenScreensharing) {
Erik Språngefbde372015-04-29 16:21:28 +02003347 TestCpuAdaptation(true, true);
3348}
3349
eladalonf1841382017-06-12 01:16:46 -07003350TEST_F(WebRtcVideoChannelTest, PreviousAdaptationDoesNotApplyToScreenshare) {
magjed509e4fe2016-11-18 01:34:11 -08003351 cricket::VideoCodec codec = GetEngineCodec("VP8");
Per766ad3b2016-04-05 15:23:49 +02003352 cricket::VideoSendParameters parameters;
3353 parameters.codecs.push_back(codec);
3354
kthelgason2bc68642017-02-07 07:02:22 -08003355 MediaConfig media_config = GetMediaConfig();
Niels Möller1d7ecd22018-01-18 15:25:12 +01003356 media_config.video.enable_cpu_adaptation = true;
Sebastian Jansson84848f22018-11-16 10:40:36 +01003357 channel_.reset(engine_.CreateMediaChannel(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02003358 fake_call_.get(), media_config, VideoOptions(), webrtc::CryptoOptions(),
3359 video_bitrate_allocator_factory_.get()));
Sergey Ulanove2b15012016-11-22 16:08:30 -08003360 channel_->OnReadyToSend(true);
Per766ad3b2016-04-05 15:23:49 +02003361 ASSERT_TRUE(channel_->SetSendParameters(parameters));
3362
3363 AddSendStream();
Niels Möller805a27e2019-01-21 12:21:27 +01003364 webrtc::test::FrameForwarder frame_forwarder;
Per766ad3b2016-04-05 15:23:49 +02003365
Per766ad3b2016-04-05 15:23:49 +02003366 ASSERT_TRUE(channel_->SetSend(true));
3367 cricket::VideoOptions camera_options;
Oskar Sundbom78807582017-11-16 11:09:55 +01003368 camera_options.is_screencast = false;
Niels Möller805a27e2019-01-21 12:21:27 +01003369 channel_->SetVideoSend(last_ssrc_, &camera_options, &frame_forwarder);
Per766ad3b2016-04-05 15:23:49 +02003370
3371 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
3372 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
Per766ad3b2016-04-05 15:23:49 +02003373
Niels Möllerdcc70292019-01-15 16:32:38 +01003374 EXPECT_TRUE(send_stream->resolution_scaling_enabled());
3375 // Dont' expect anything on framerate_scaling_enabled, since the default is
3376 // transitioning from MAINTAIN_FRAMERATE to BALANCED.
Per766ad3b2016-04-05 15:23:49 +02003377
Niels Möllerdcc70292019-01-15 16:32:38 +01003378 // Switch to screen share. Expect no resolution scaling.
Per766ad3b2016-04-05 15:23:49 +02003379 cricket::VideoOptions screenshare_options;
Oskar Sundbom78807582017-11-16 11:09:55 +01003380 screenshare_options.is_screencast = true;
Niels Möller805a27e2019-01-21 12:21:27 +01003381 channel_->SetVideoSend(last_ssrc_, &screenshare_options, &frame_forwarder);
sprangf24a0642017-02-28 13:23:26 -08003382 ASSERT_EQ(2, fake_call_->GetNumCreatedSendStreams());
3383 send_stream = fake_call_->GetVideoSendStreams().front();
Niels Möllerdcc70292019-01-15 16:32:38 +01003384 EXPECT_FALSE(send_stream->resolution_scaling_enabled());
Per766ad3b2016-04-05 15:23:49 +02003385
Niels Möllerdcc70292019-01-15 16:32:38 +01003386 // Switch back to the normal capturer. Expect resolution scaling to be
3387 // reenabled.
Niels Möller805a27e2019-01-21 12:21:27 +01003388 channel_->SetVideoSend(last_ssrc_, &camera_options, &frame_forwarder);
3389 send_stream = fake_call_->GetVideoSendStreams().front();
sprangf24a0642017-02-28 13:23:26 -08003390 ASSERT_EQ(3, fake_call_->GetNumCreatedSendStreams());
3391 send_stream = fake_call_->GetVideoSendStreams().front();
Niels Möllerdcc70292019-01-15 16:32:38 +01003392 EXPECT_TRUE(send_stream->resolution_scaling_enabled());
Per766ad3b2016-04-05 15:23:49 +02003393
Niels Möllerff40b142018-04-09 08:49:14 +02003394 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
Per766ad3b2016-04-05 15:23:49 +02003395}
3396
asapersson3c81a1a2017-06-14 05:52:21 -07003397// TODO(asapersson): Remove this test when the balanced field trial is removed.
3398void WebRtcVideoChannelTest::TestDegradationPreference(
3399 bool resolution_scaling_enabled,
3400 bool fps_scaling_enabled) {
3401 cricket::VideoCodec codec = GetEngineCodec("VP8");
3402 cricket::VideoSendParameters parameters;
3403 parameters.codecs.push_back(codec);
3404
3405 MediaConfig media_config = GetMediaConfig();
Niels Möller1d7ecd22018-01-18 15:25:12 +01003406 media_config.video.enable_cpu_adaptation = true;
Sebastian Jansson84848f22018-11-16 10:40:36 +01003407 channel_.reset(engine_.CreateMediaChannel(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02003408 fake_call_.get(), media_config, VideoOptions(), webrtc::CryptoOptions(),
3409 video_bitrate_allocator_factory_.get()));
asapersson3c81a1a2017-06-14 05:52:21 -07003410 channel_->OnReadyToSend(true);
3411
3412 EXPECT_TRUE(channel_->SetSendParameters(parameters));
3413
3414 AddSendStream();
3415
Niels Möller805a27e2019-01-21 12:21:27 +01003416 webrtc::test::FrameForwarder frame_forwarder;
asapersson3c81a1a2017-06-14 05:52:21 -07003417 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01003418 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
asapersson3c81a1a2017-06-14 05:52:21 -07003419
3420 EXPECT_TRUE(channel_->SetSend(true));
3421
3422 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
3423 EXPECT_EQ(resolution_scaling_enabled,
3424 send_stream->resolution_scaling_enabled());
3425 EXPECT_EQ(fps_scaling_enabled, send_stream->framerate_scaling_enabled());
3426
Niels Möllerff40b142018-04-09 08:49:14 +02003427 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
asapersson3c81a1a2017-06-14 05:52:21 -07003428}
3429
eladalonf1841382017-06-12 01:16:46 -07003430void WebRtcVideoChannelTest::TestCpuAdaptation(bool enable_overuse,
3431 bool is_screenshare) {
magjed509e4fe2016-11-18 01:34:11 -08003432 cricket::VideoCodec codec = GetEngineCodec("VP8");
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003433 cricket::VideoSendParameters parameters;
3434 parameters.codecs.push_back(codec);
nisse51542be2016-02-12 02:27:06 -08003435
kthelgason2bc68642017-02-07 07:02:22 -08003436 MediaConfig media_config = GetMediaConfig();
3437 if (enable_overuse) {
Niels Möller1d7ecd22018-01-18 15:25:12 +01003438 media_config.video.enable_cpu_adaptation = true;
pbos@webrtc.org42684be2014-10-03 11:25:45 +00003439 }
Sebastian Jansson84848f22018-11-16 10:40:36 +01003440 channel_.reset(engine_.CreateMediaChannel(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02003441 fake_call_.get(), media_config, VideoOptions(), webrtc::CryptoOptions(),
3442 video_bitrate_allocator_factory_.get()));
Sergey Ulanove2b15012016-11-22 16:08:30 -08003443 channel_->OnReadyToSend(true);
nisse51542be2016-02-12 02:27:06 -08003444
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003445 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00003446
3447 AddSendStream();
3448
Niels Möller805a27e2019-01-21 12:21:27 +01003449 webrtc::test::FrameForwarder frame_forwarder;
nisse05103312016-03-16 02:22:50 -07003450 VideoOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01003451 options.is_screencast = is_screenshare;
Niels Möller805a27e2019-01-21 12:21:27 +01003452 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00003453
3454 EXPECT_TRUE(channel_->SetSend(true));
3455
solenberge5269742015-09-08 05:13:22 -07003456 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
perkj2d5f0912016-02-29 00:04:41 -08003457
sprangc5d62e22017-04-02 23:53:04 -07003458 if (!enable_overuse) {
perkj803d97f2016-11-01 11:45:46 -07003459 EXPECT_FALSE(send_stream->resolution_scaling_enabled());
sprangc5d62e22017-04-02 23:53:04 -07003460 EXPECT_FALSE(send_stream->framerate_scaling_enabled());
Niels Möller805a27e2019-01-21 12:21:27 +01003461 } else if (is_screenshare) {
sprangc5d62e22017-04-02 23:53:04 -07003462 EXPECT_FALSE(send_stream->resolution_scaling_enabled());
3463 EXPECT_TRUE(send_stream->framerate_scaling_enabled());
3464 } else {
3465 EXPECT_TRUE(send_stream->resolution_scaling_enabled());
3466 EXPECT_FALSE(send_stream->framerate_scaling_enabled());
3467 }
Niels Möllerff40b142018-04-09 08:49:14 +02003468 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003469}
3470
eladalonf1841382017-06-12 01:16:46 -07003471TEST_F(WebRtcVideoChannelTest, EstimatesNtpStartTimeCorrectly) {
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00003472 // Start at last timestamp to verify that wraparounds are estimated correctly.
3473 static const uint32_t kInitialTimestamp = 0xFFFFFFFFu;
3474 static const int64_t kInitialNtpTimeMs = 1247891230;
3475 static const int kFrameOffsetMs = 20;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003476 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003477
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00003478 FakeVideoReceiveStream* stream = AddRecvStream();
3479 cricket::FakeVideoRenderer renderer;
nisse08582ff2016-02-04 01:24:52 -08003480 EXPECT_TRUE(channel_->SetSink(last_ssrc_, &renderer));
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00003481
Artem Titov1ebfb6a2019-01-03 23:49:37 +01003482 webrtc::VideoFrame video_frame =
3483 webrtc::VideoFrame::Builder()
3484 .set_video_frame_buffer(CreateBlackFrameBuffer(4, 4))
3485 .set_timestamp_rtp(kInitialTimestamp)
3486 .set_timestamp_us(0)
3487 .set_rotation(webrtc::kVideoRotation_0)
3488 .build();
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00003489 // Initial NTP time is not available on the first frame, but should still be
3490 // able to be estimated.
nisseeb83a1a2016-03-21 01:27:56 -07003491 stream->InjectFrame(video_frame);
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00003492
3493 EXPECT_EQ(1, renderer.num_rendered_frames());
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00003494
3495 // This timestamp is kInitialTimestamp (-1) + kFrameOffsetMs * 90, which
3496 // triggers a constant-overflow warning, hence we're calculating it explicitly
3497 // here.
Sebastian Jansson40889f32019-04-17 12:11:20 +02003498 fake_clock_.AdvanceTime(webrtc::TimeDelta::ms(kFrameOffsetMs));
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00003499 video_frame.set_timestamp(kFrameOffsetMs * 90 - 1);
3500 video_frame.set_ntp_time_ms(kInitialNtpTimeMs + kFrameOffsetMs);
nisseeb83a1a2016-03-21 01:27:56 -07003501 stream->InjectFrame(video_frame);
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00003502
3503 EXPECT_EQ(2, renderer.num_rendered_frames());
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00003504
3505 // Verify that NTP time has been correctly deduced.
3506 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00003507 ASSERT_TRUE(channel_->GetStats(&info));
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00003508 ASSERT_EQ(1u, info.receivers.size());
3509 EXPECT_EQ(kInitialNtpTimeMs, info.receivers[0].capture_start_ntp_time_ms);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003510}
3511
eladalonf1841382017-06-12 01:16:46 -07003512TEST_F(WebRtcVideoChannelTest, SetDefaultSendCodecs) {
Anders Carlsson5f2bb622018-05-14 09:48:06 +02003513 AssignDefaultAptRtxTypes();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003514 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003515
3516 VideoCodec codec;
3517 EXPECT_TRUE(channel_->GetSendCodec(&codec));
pbos@webrtc.org9fbb7172014-06-13 09:34:13 +00003518 EXPECT_TRUE(codec.Matches(engine_.codecs()[0]));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003519
3520 // Using a RTX setup to verify that the default RTX payload type is good.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003521 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
3522 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003523 FakeVideoSendStream* stream = AddSendStream(
3524 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
perkj26091b12016-09-01 01:17:40 -07003525 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003526
3527 // Make sure NACK and FEC are enabled on the correct payload types.
3528 EXPECT_EQ(1000, config.rtp.nack.rtp_history_ms);
magjed509e4fe2016-11-18 01:34:11 -08003529 EXPECT_EQ(GetEngineCodec("ulpfec").id, config.rtp.ulpfec.ulpfec_payload_type);
3530 EXPECT_EQ(GetEngineCodec("red").id, config.rtp.ulpfec.red_payload_type);
pbos@webrtc.org269605c2014-06-26 08:49:03 +00003531
3532 EXPECT_EQ(1u, config.rtp.rtx.ssrcs.size());
3533 EXPECT_EQ(kRtxSsrcs1[0], config.rtp.rtx.ssrcs[0]);
Shao Changbine62202f2015-04-21 20:24:50 +08003534 VerifySendStreamHasRtxTypes(config, default_apt_rtx_types_);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003535 // TODO(juberti): Check RTCP, PLI, TMMBR.
3536}
3537
brandtr31bd2242017-05-19 05:47:46 -07003538// The following four tests ensures that FlexFEC is not activated by default
3539// when the field trials are not enabled.
3540// TODO(brandtr): Remove or update these tests when FlexFEC _is_ enabled by
3541// default.
Yves Gerey665174f2018-06-19 15:03:05 +02003542TEST_F(WebRtcVideoChannelTest, FlexfecSendCodecWithoutSsrcNotExposedByDefault) {
brandtr468da7c2016-11-22 02:16:47 -08003543 FakeVideoSendStream* stream = AddSendStream();
3544 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
3545
brandtr3d200bd2017-01-16 06:59:19 -08003546 EXPECT_EQ(-1, config.rtp.flexfec.payload_type);
brandtr31bd2242017-05-19 05:47:46 -07003547 EXPECT_EQ(0U, config.rtp.flexfec.ssrc);
3548 EXPECT_TRUE(config.rtp.flexfec.protected_media_ssrcs.empty());
brandtr468da7c2016-11-22 02:16:47 -08003549}
3550
eladalonf1841382017-06-12 01:16:46 -07003551TEST_F(WebRtcVideoChannelTest, FlexfecSendCodecWithSsrcNotExposedByDefault) {
brandtr468da7c2016-11-22 02:16:47 -08003552 FakeVideoSendStream* stream = AddSendStream(
3553 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
3554 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
3555
brandtr3d200bd2017-01-16 06:59:19 -08003556 EXPECT_EQ(-1, config.rtp.flexfec.payload_type);
brandtr31bd2242017-05-19 05:47:46 -07003557 EXPECT_EQ(0U, config.rtp.flexfec.ssrc);
3558 EXPECT_TRUE(config.rtp.flexfec.protected_media_ssrcs.empty());
3559}
3560
Yves Gerey665174f2018-06-19 15:03:05 +02003561TEST_F(WebRtcVideoChannelTest, FlexfecRecvCodecWithoutSsrcNotExposedByDefault) {
brandtr31bd2242017-05-19 05:47:46 -07003562 AddRecvStream();
3563
3564 const std::vector<FakeFlexfecReceiveStream*>& streams =
3565 fake_call_->GetFlexfecReceiveStreams();
3566 EXPECT_TRUE(streams.empty());
3567}
3568
eladalonf1841382017-06-12 01:16:46 -07003569TEST_F(WebRtcVideoChannelTest, FlexfecRecvCodecWithSsrcNotExposedByDefault) {
brandtr31bd2242017-05-19 05:47:46 -07003570 AddRecvStream(
3571 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
3572
3573 const std::vector<FakeFlexfecReceiveStream*>& streams =
3574 fake_call_->GetFlexfecReceiveStreams();
3575 EXPECT_TRUE(streams.empty());
brandtr468da7c2016-11-22 02:16:47 -08003576}
3577
3578// TODO(brandtr): When FlexFEC is no longer behind a field trial, merge all
3579// tests that use this test fixture into the corresponding "non-field trial"
3580// tests.
eladalonf1841382017-06-12 01:16:46 -07003581class WebRtcVideoChannelFlexfecRecvTest : public WebRtcVideoChannelTest {
brandtr468da7c2016-11-22 02:16:47 -08003582 public:
eladalonf1841382017-06-12 01:16:46 -07003583 WebRtcVideoChannelFlexfecRecvTest()
3584 : WebRtcVideoChannelTest("WebRTC-FlexFEC-03-Advertised/Enabled/") {}
brandtr468da7c2016-11-22 02:16:47 -08003585};
3586
eladalonf1841382017-06-12 01:16:46 -07003587TEST_F(WebRtcVideoChannelFlexfecRecvTest,
brandtr36e7d702017-01-13 07:15:54 -08003588 DefaultFlexfecCodecHasTransportCcAndRembFeedbackParam) {
3589 EXPECT_TRUE(cricket::HasTransportCc(GetEngineCodec("flexfec-03")));
3590 EXPECT_TRUE(cricket::HasRemb(GetEngineCodec("flexfec-03")));
3591}
3592
eladalonf1841382017-06-12 01:16:46 -07003593TEST_F(WebRtcVideoChannelFlexfecRecvTest, SetDefaultRecvCodecsWithoutSsrc) {
brandtr31bd2242017-05-19 05:47:46 -07003594 AddRecvStream();
3595
3596 const std::vector<FakeFlexfecReceiveStream*>& streams =
3597 fake_call_->GetFlexfecReceiveStreams();
3598 EXPECT_TRUE(streams.empty());
Rasmus Brandt60bb6fe2018-02-05 09:51:47 +01003599
3600 const std::vector<FakeVideoReceiveStream*>& video_streams =
3601 fake_call_->GetVideoReceiveStreams();
3602 ASSERT_EQ(1U, video_streams.size());
3603 const FakeVideoReceiveStream& video_stream = *video_streams.front();
3604 EXPECT_EQ(0, video_stream.GetNumAddedSecondarySinks());
3605 EXPECT_EQ(0, video_stream.GetNumRemovedSecondarySinks());
brandtr31bd2242017-05-19 05:47:46 -07003606}
3607
eladalonf1841382017-06-12 01:16:46 -07003608TEST_F(WebRtcVideoChannelFlexfecRecvTest, SetDefaultRecvCodecsWithSsrc) {
brandtr31bd2242017-05-19 05:47:46 -07003609 AddRecvStream(
3610 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
3611
3612 const std::vector<FakeFlexfecReceiveStream*>& streams =
3613 fake_call_->GetFlexfecReceiveStreams();
3614 ASSERT_EQ(1U, streams.size());
3615 const FakeFlexfecReceiveStream* stream = streams.front();
3616 const webrtc::FlexfecReceiveStream::Config& config = stream->GetConfig();
3617 EXPECT_EQ(GetEngineCodec("flexfec-03").id, config.payload_type);
3618 EXPECT_EQ(kFlexfecSsrc, config.remote_ssrc);
3619 ASSERT_EQ(1U, config.protected_media_ssrcs.size());
3620 EXPECT_EQ(kSsrcs1[0], config.protected_media_ssrcs[0]);
brandtr7cd28b92017-09-22 00:26:25 -07003621
3622 const std::vector<FakeVideoReceiveStream*>& video_streams =
3623 fake_call_->GetVideoReceiveStreams();
3624 ASSERT_EQ(1U, video_streams.size());
Rasmus Brandt60bb6fe2018-02-05 09:51:47 +01003625 const FakeVideoReceiveStream& video_stream = *video_streams.front();
3626 EXPECT_EQ(1, video_stream.GetNumAddedSecondarySinks());
brandtr7cd28b92017-09-22 00:26:25 -07003627 const webrtc::VideoReceiveStream::Config& video_config =
Rasmus Brandt60bb6fe2018-02-05 09:51:47 +01003628 video_stream.GetConfig();
brandtr7cd28b92017-09-22 00:26:25 -07003629 EXPECT_TRUE(video_config.rtp.protected_by_flexfec);
brandtr31bd2242017-05-19 05:47:46 -07003630}
3631
eladalonf1841382017-06-12 01:16:46 -07003632TEST_F(WebRtcVideoChannelFlexfecRecvTest,
brandtr11fb4722017-05-30 01:31:37 -07003633 EnablingFlexfecDoesNotRecreateVideoReceiveStream) {
3634 cricket::VideoRecvParameters recv_parameters;
3635 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
3636 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
3637
3638 AddRecvStream(
3639 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
3640 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
Rasmus Brandt60bb6fe2018-02-05 09:51:47 +01003641 const std::vector<FakeVideoReceiveStream*>& video_streams =
3642 fake_call_->GetVideoReceiveStreams();
3643 ASSERT_EQ(1U, video_streams.size());
3644 const FakeVideoReceiveStream& video_stream = *video_streams.front();
3645 EXPECT_EQ(0, video_stream.GetNumAddedSecondarySinks());
3646 EXPECT_EQ(0, video_stream.GetNumRemovedSecondarySinks());
brandtr11fb4722017-05-30 01:31:37 -07003647
3648 // Enable FlexFEC.
3649 recv_parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
3650 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
3651 EXPECT_EQ(2, fake_call_->GetNumCreatedReceiveStreams())
3652 << "Enabling FlexFEC should create FlexfecReceiveStream.";
3653 EXPECT_EQ(1U, fake_call_->GetVideoReceiveStreams().size())
3654 << "Enabling FlexFEC should not create VideoReceiveStream.";
3655 EXPECT_EQ(1U, fake_call_->GetFlexfecReceiveStreams().size())
3656 << "Enabling FlexFEC should create a single FlexfecReceiveStream.";
Rasmus Brandt60bb6fe2018-02-05 09:51:47 +01003657 EXPECT_EQ(1, video_stream.GetNumAddedSecondarySinks());
3658 EXPECT_EQ(0, video_stream.GetNumRemovedSecondarySinks());
brandtr11fb4722017-05-30 01:31:37 -07003659}
3660
eladalonf1841382017-06-12 01:16:46 -07003661TEST_F(WebRtcVideoChannelFlexfecRecvTest,
brandtr11fb4722017-05-30 01:31:37 -07003662 DisablingFlexfecDoesNotRecreateVideoReceiveStream) {
3663 cricket::VideoRecvParameters recv_parameters;
3664 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
3665 recv_parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
3666 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
3667
3668 AddRecvStream(
3669 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
3670 EXPECT_EQ(2, fake_call_->GetNumCreatedReceiveStreams());
brandtr11fb4722017-05-30 01:31:37 -07003671 EXPECT_EQ(1U, fake_call_->GetFlexfecReceiveStreams().size());
Rasmus Brandt60bb6fe2018-02-05 09:51:47 +01003672 const std::vector<FakeVideoReceiveStream*>& video_streams =
3673 fake_call_->GetVideoReceiveStreams();
3674 ASSERT_EQ(1U, video_streams.size());
3675 const FakeVideoReceiveStream& video_stream = *video_streams.front();
3676 EXPECT_EQ(1, video_stream.GetNumAddedSecondarySinks());
3677 EXPECT_EQ(0, video_stream.GetNumRemovedSecondarySinks());
brandtr11fb4722017-05-30 01:31:37 -07003678
3679 // Disable FlexFEC.
3680 recv_parameters.codecs.clear();
3681 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
3682 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
3683 EXPECT_EQ(2, fake_call_->GetNumCreatedReceiveStreams())
3684 << "Disabling FlexFEC should not recreate VideoReceiveStream.";
3685 EXPECT_EQ(1U, fake_call_->GetVideoReceiveStreams().size())
3686 << "Disabling FlexFEC should not destroy VideoReceiveStream.";
3687 EXPECT_TRUE(fake_call_->GetFlexfecReceiveStreams().empty())
3688 << "Disabling FlexFEC should destroy FlexfecReceiveStream.";
Rasmus Brandt60bb6fe2018-02-05 09:51:47 +01003689 EXPECT_EQ(1, video_stream.GetNumAddedSecondarySinks());
3690 EXPECT_EQ(1, video_stream.GetNumRemovedSecondarySinks());
brandtr11fb4722017-05-30 01:31:37 -07003691}
3692
brandtr31bd2242017-05-19 05:47:46 -07003693// TODO(brandtr): When FlexFEC is no longer behind a field trial, merge all
3694// tests that use this test fixture into the corresponding "non-field trial"
3695// tests.
eladalonf1841382017-06-12 01:16:46 -07003696class WebRtcVideoChannelFlexfecSendRecvTest : public WebRtcVideoChannelTest {
brandtr31bd2242017-05-19 05:47:46 -07003697 public:
eladalonf1841382017-06-12 01:16:46 -07003698 WebRtcVideoChannelFlexfecSendRecvTest()
3699 : WebRtcVideoChannelTest(
brandtr31bd2242017-05-19 05:47:46 -07003700 "WebRTC-FlexFEC-03-Advertised/Enabled/WebRTC-FlexFEC-03/Enabled/") {
3701 }
3702};
3703
Yves Gerey665174f2018-06-19 15:03:05 +02003704TEST_F(WebRtcVideoChannelFlexfecSendRecvTest, SetDefaultSendCodecsWithoutSsrc) {
brandtr468da7c2016-11-22 02:16:47 -08003705 FakeVideoSendStream* stream = AddSendStream();
3706 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
3707
brandtr3d200bd2017-01-16 06:59:19 -08003708 EXPECT_EQ(GetEngineCodec("flexfec-03").id, config.rtp.flexfec.payload_type);
3709 EXPECT_EQ(0U, config.rtp.flexfec.ssrc);
3710 EXPECT_TRUE(config.rtp.flexfec.protected_media_ssrcs.empty());
brandtr468da7c2016-11-22 02:16:47 -08003711}
3712
eladalonf1841382017-06-12 01:16:46 -07003713TEST_F(WebRtcVideoChannelFlexfecSendRecvTest, SetDefaultSendCodecsWithSsrc) {
brandtr468da7c2016-11-22 02:16:47 -08003714 FakeVideoSendStream* stream = AddSendStream(
3715 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
3716 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
3717
brandtr3d200bd2017-01-16 06:59:19 -08003718 EXPECT_EQ(GetEngineCodec("flexfec-03").id, config.rtp.flexfec.payload_type);
3719 EXPECT_EQ(kFlexfecSsrc, config.rtp.flexfec.ssrc);
3720 ASSERT_EQ(1U, config.rtp.flexfec.protected_media_ssrcs.size());
3721 EXPECT_EQ(kSsrcs1[0], config.rtp.flexfec.protected_media_ssrcs[0]);
brandtr468da7c2016-11-22 02:16:47 -08003722}
3723
eladalonf1841382017-06-12 01:16:46 -07003724TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithoutFec) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003725 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08003726 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003727 ASSERT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003728
3729 FakeVideoSendStream* stream = AddSendStream();
perkj26091b12016-09-01 01:17:40 -07003730 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003731
brandtrb5f2c3f2016-10-04 23:28:39 -07003732 EXPECT_EQ(-1, config.rtp.ulpfec.ulpfec_payload_type);
3733 EXPECT_EQ(-1, config.rtp.ulpfec.red_payload_type);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003734}
3735
eladalonf1841382017-06-12 01:16:46 -07003736TEST_F(WebRtcVideoChannelFlexfecSendRecvTest, SetSendCodecsWithoutFec) {
brandtr468da7c2016-11-22 02:16:47 -08003737 cricket::VideoSendParameters parameters;
3738 parameters.codecs.push_back(GetEngineCodec("VP8"));
3739 ASSERT_TRUE(channel_->SetSendParameters(parameters));
3740
3741 FakeVideoSendStream* stream = AddSendStream();
3742 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
3743
brandtr3d200bd2017-01-16 06:59:19 -08003744 EXPECT_EQ(-1, config.rtp.flexfec.payload_type);
brandtr468da7c2016-11-22 02:16:47 -08003745}
3746
eladalonf1841382017-06-12 01:16:46 -07003747TEST_F(WebRtcVideoChannelFlexfecRecvTest, SetRecvCodecsWithFec) {
brandtr9c3d4c42017-01-23 06:59:13 -08003748 AddRecvStream(
3749 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
brandtr9c3d4c42017-01-23 06:59:13 -08003750
3751 cricket::VideoRecvParameters recv_parameters;
3752 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
3753 recv_parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
3754 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
brandtr9d58d942017-02-03 04:43:41 -08003755
3756 const std::vector<FakeFlexfecReceiveStream*>& flexfec_streams =
3757 fake_call_->GetFlexfecReceiveStreams();
3758 ASSERT_EQ(1U, flexfec_streams.size());
3759 const FakeFlexfecReceiveStream* flexfec_stream = flexfec_streams.front();
3760 const webrtc::FlexfecReceiveStream::Config& flexfec_stream_config =
3761 flexfec_stream->GetConfig();
brandtr9c3d4c42017-01-23 06:59:13 -08003762 EXPECT_EQ(GetEngineCodec("flexfec-03").id,
brandtr9d58d942017-02-03 04:43:41 -08003763 flexfec_stream_config.payload_type);
3764 EXPECT_EQ(kFlexfecSsrc, flexfec_stream_config.remote_ssrc);
3765 ASSERT_EQ(1U, flexfec_stream_config.protected_media_ssrcs.size());
3766 EXPECT_EQ(kSsrcs1[0], flexfec_stream_config.protected_media_ssrcs[0]);
3767 const std::vector<FakeVideoReceiveStream*>& video_streams =
3768 fake_call_->GetVideoReceiveStreams();
3769 const FakeVideoReceiveStream* video_stream = video_streams.front();
3770 const webrtc::VideoReceiveStream::Config& video_stream_config =
3771 video_stream->GetConfig();
3772 EXPECT_EQ(video_stream_config.rtp.local_ssrc,
3773 flexfec_stream_config.local_ssrc);
3774 EXPECT_EQ(video_stream_config.rtp.rtcp_mode, flexfec_stream_config.rtcp_mode);
3775 EXPECT_EQ(video_stream_config.rtcp_send_transport,
3776 flexfec_stream_config.rtcp_send_transport);
3777 // TODO(brandtr): Update this EXPECT when we set |transport_cc| in a
3778 // spec-compliant way.
3779 EXPECT_EQ(video_stream_config.rtp.transport_cc,
3780 flexfec_stream_config.transport_cc);
3781 EXPECT_EQ(video_stream_config.rtp.rtcp_mode, flexfec_stream_config.rtcp_mode);
3782 EXPECT_EQ(video_stream_config.rtp.extensions,
3783 flexfec_stream_config.rtp_header_extensions);
brandtr9c3d4c42017-01-23 06:59:13 -08003784}
3785
brandtr31bd2242017-05-19 05:47:46 -07003786// We should not send FlexFEC, even if we advertise it, unless the right
3787// field trial is set.
3788// TODO(brandtr): Remove when FlexFEC is enabled by default.
eladalonf1841382017-06-12 01:16:46 -07003789TEST_F(WebRtcVideoChannelFlexfecRecvTest,
brandtr31bd2242017-05-19 05:47:46 -07003790 SetSendCodecsWithoutSsrcWithFecDoesNotEnableFec) {
3791 cricket::VideoSendParameters parameters;
3792 parameters.codecs.push_back(GetEngineCodec("VP8"));
3793 parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
3794 ASSERT_TRUE(channel_->SetSendParameters(parameters));
3795
3796 FakeVideoSendStream* stream = AddSendStream();
3797 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
3798
3799 EXPECT_EQ(-1, config.rtp.flexfec.payload_type);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003800 EXPECT_EQ(0u, config.rtp.flexfec.ssrc);
brandtr31bd2242017-05-19 05:47:46 -07003801 EXPECT_TRUE(config.rtp.flexfec.protected_media_ssrcs.empty());
3802}
3803
eladalonf1841382017-06-12 01:16:46 -07003804TEST_F(WebRtcVideoChannelFlexfecRecvTest,
brandtr31bd2242017-05-19 05:47:46 -07003805 SetSendCodecsWithSsrcWithFecDoesNotEnableFec) {
3806 cricket::VideoSendParameters parameters;
3807 parameters.codecs.push_back(GetEngineCodec("VP8"));
3808 parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
3809 ASSERT_TRUE(channel_->SetSendParameters(parameters));
3810
3811 FakeVideoSendStream* stream = AddSendStream(
3812 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
3813 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
3814
3815 EXPECT_EQ(-1, config.rtp.flexfec.payload_type);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003816 EXPECT_EQ(0u, config.rtp.flexfec.ssrc);
brandtr31bd2242017-05-19 05:47:46 -07003817 EXPECT_TRUE(config.rtp.flexfec.protected_media_ssrcs.empty());
3818}
3819
eladalonf1841382017-06-12 01:16:46 -07003820TEST_F(WebRtcVideoChannelTest,
pbos@webrtc.org269605c2014-06-26 08:49:03 +00003821 SetSendCodecRejectsRtxWithoutAssociatedPayloadType) {
magjed509e4fe2016-11-18 01:34:11 -08003822 const int kUnusedPayloadType = 127;
3823 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType));
3824
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003825 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08003826 cricket::VideoCodec rtx_codec(kUnusedPayloadType, "rtx");
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003827 parameters.codecs.push_back(rtx_codec);
3828 EXPECT_FALSE(channel_->SetSendParameters(parameters))
pbos@webrtc.org269605c2014-06-26 08:49:03 +00003829 << "RTX codec without associated payload type should be rejected.";
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003830}
3831
eladalonf1841382017-06-12 01:16:46 -07003832TEST_F(WebRtcVideoChannelTest,
pbos@webrtc.org269605c2014-06-26 08:49:03 +00003833 SetSendCodecRejectsRtxWithoutMatchingVideoCodec) {
magjed509e4fe2016-11-18 01:34:11 -08003834 const int kUnusedPayloadType1 = 126;
3835 const int kUnusedPayloadType2 = 127;
3836 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType1));
3837 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType2));
3838 {
3839 cricket::VideoCodec rtx_codec = cricket::VideoCodec::CreateRtxCodec(
3840 kUnusedPayloadType1, GetEngineCodec("VP8").id);
3841 cricket::VideoSendParameters parameters;
3842 parameters.codecs.push_back(GetEngineCodec("VP8"));
3843 parameters.codecs.push_back(rtx_codec);
3844 ASSERT_TRUE(channel_->SetSendParameters(parameters));
3845 }
3846 {
3847 cricket::VideoCodec rtx_codec = cricket::VideoCodec::CreateRtxCodec(
3848 kUnusedPayloadType1, kUnusedPayloadType2);
3849 cricket::VideoSendParameters parameters;
3850 parameters.codecs.push_back(GetEngineCodec("VP8"));
3851 parameters.codecs.push_back(rtx_codec);
3852 EXPECT_FALSE(channel_->SetSendParameters(parameters))
3853 << "RTX without matching video codec should be rejected.";
3854 }
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003855}
3856
eladalonf1841382017-06-12 01:16:46 -07003857TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithChangedRtxPayloadType) {
brandtr14742122017-01-27 04:53:07 -08003858 const int kUnusedPayloadType1 = 126;
3859 const int kUnusedPayloadType2 = 127;
3860 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType1));
3861 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType2));
3862
3863 // SSRCs for RTX.
3864 cricket::StreamParams params =
3865 cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
3866 params.AddFidSsrc(kSsrcs1[0], kRtxSsrcs1[0]);
3867 AddSendStream(params);
3868
3869 // Original payload type for RTX.
3870 cricket::VideoSendParameters parameters;
3871 parameters.codecs.push_back(GetEngineCodec("VP8"));
3872 cricket::VideoCodec rtx_codec(kUnusedPayloadType1, "rtx");
3873 rtx_codec.SetParam("apt", GetEngineCodec("VP8").id);
3874 parameters.codecs.push_back(rtx_codec);
3875 EXPECT_TRUE(channel_->SetSendParameters(parameters));
3876 ASSERT_EQ(1U, fake_call_->GetVideoSendStreams().size());
3877 const webrtc::VideoSendStream::Config& config_before =
3878 fake_call_->GetVideoSendStreams()[0]->GetConfig();
3879 EXPECT_EQ(kUnusedPayloadType1, config_before.rtp.rtx.payload_type);
3880 ASSERT_EQ(1U, config_before.rtp.rtx.ssrcs.size());
3881 EXPECT_EQ(kRtxSsrcs1[0], config_before.rtp.rtx.ssrcs[0]);
3882
3883 // Change payload type for RTX.
3884 parameters.codecs[1].id = kUnusedPayloadType2;
3885 EXPECT_TRUE(channel_->SetSendParameters(parameters));
3886 ASSERT_EQ(1U, fake_call_->GetVideoSendStreams().size());
3887 const webrtc::VideoSendStream::Config& config_after =
3888 fake_call_->GetVideoSendStreams()[0]->GetConfig();
3889 EXPECT_EQ(kUnusedPayloadType2, config_after.rtp.rtx.payload_type);
3890 ASSERT_EQ(1U, config_after.rtp.rtx.ssrcs.size());
3891 EXPECT_EQ(kRtxSsrcs1[0], config_after.rtp.rtx.ssrcs[0]);
3892}
3893
eladalonf1841382017-06-12 01:16:46 -07003894TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithoutFecDisablesFec) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003895 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08003896 parameters.codecs.push_back(GetEngineCodec("VP8"));
3897 parameters.codecs.push_back(GetEngineCodec("ulpfec"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003898 ASSERT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org269605c2014-06-26 08:49:03 +00003899
3900 FakeVideoSendStream* stream = AddSendStream();
perkj26091b12016-09-01 01:17:40 -07003901 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
pbos@webrtc.org269605c2014-06-26 08:49:03 +00003902
magjed509e4fe2016-11-18 01:34:11 -08003903 EXPECT_EQ(GetEngineCodec("ulpfec").id, config.rtp.ulpfec.ulpfec_payload_type);
pbos@webrtc.org269605c2014-06-26 08:49:03 +00003904
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003905 parameters.codecs.pop_back();
3906 ASSERT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00003907 stream = fake_call_->GetVideoSendStreams()[0];
brandtr468da7c2016-11-22 02:16:47 -08003908 ASSERT_TRUE(stream != nullptr);
perkj26091b12016-09-01 01:17:40 -07003909 config = stream->GetConfig().Copy();
brandtrb5f2c3f2016-10-04 23:28:39 -07003910 EXPECT_EQ(-1, config.rtp.ulpfec.ulpfec_payload_type)
brandtr468da7c2016-11-22 02:16:47 -08003911 << "SetSendCodec without ULPFEC should disable current ULPFEC.";
3912}
3913
eladalonf1841382017-06-12 01:16:46 -07003914TEST_F(WebRtcVideoChannelFlexfecSendRecvTest,
brandtr31bd2242017-05-19 05:47:46 -07003915 SetSendCodecsWithoutFecDisablesFec) {
brandtr468da7c2016-11-22 02:16:47 -08003916 cricket::VideoSendParameters parameters;
3917 parameters.codecs.push_back(GetEngineCodec("VP8"));
3918 parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
3919 ASSERT_TRUE(channel_->SetSendParameters(parameters));
3920
3921 FakeVideoSendStream* stream = AddSendStream(
3922 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
3923 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
3924
brandtr3d200bd2017-01-16 06:59:19 -08003925 EXPECT_EQ(GetEngineCodec("flexfec-03").id, config.rtp.flexfec.payload_type);
3926 EXPECT_EQ(kFlexfecSsrc, config.rtp.flexfec.ssrc);
brandtr468da7c2016-11-22 02:16:47 -08003927 ASSERT_EQ(1U, config.rtp.flexfec.protected_media_ssrcs.size());
3928 EXPECT_EQ(kSsrcs1[0], config.rtp.flexfec.protected_media_ssrcs[0]);
3929
3930 parameters.codecs.pop_back();
3931 ASSERT_TRUE(channel_->SetSendParameters(parameters));
3932 stream = fake_call_->GetVideoSendStreams()[0];
3933 ASSERT_TRUE(stream != nullptr);
3934 config = stream->GetConfig().Copy();
brandtr3d200bd2017-01-16 06:59:19 -08003935 EXPECT_EQ(-1, config.rtp.flexfec.payload_type)
brandtr468da7c2016-11-22 02:16:47 -08003936 << "SetSendCodec without FlexFEC should disable current FlexFEC.";
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003937}
3938
eladalonf1841382017-06-12 01:16:46 -07003939TEST_F(WebRtcVideoChannelTest, SetSendCodecsChangesExistingStreams) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003940 cricket::VideoSendParameters parameters;
perkj26752742016-10-24 01:21:16 -07003941 cricket::VideoCodec codec(100, "VP8");
3942 codec.SetParam(kCodecParamMaxQuantization, kDefaultQpMax);
3943 parameters.codecs.push_back(codec);
perkjfa10b552016-10-02 23:45:26 -07003944
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003945 ASSERT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org86196c42015-02-16 21:02:00 +00003946 channel_->SetSend(true);
pbos@webrtc.org38ce7d02014-07-16 08:01:38 +00003947
pbos@webrtc.org86196c42015-02-16 21:02:00 +00003948 FakeVideoSendStream* stream = AddSendStream();
Niels Möller805a27e2019-01-21 12:21:27 +01003949 webrtc::test::FrameForwarder frame_forwarder;
3950 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));
pbos@webrtc.org86196c42015-02-16 21:02:00 +00003951
3952 std::vector<webrtc::VideoStream> streams = stream->GetVideoStreams();
perkjfa10b552016-10-02 23:45:26 -07003953 EXPECT_EQ(kDefaultQpMax, streams[0].max_qp);
pbos@webrtc.org38ce7d02014-07-16 08:01:38 +00003954
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003955 parameters.codecs.clear();
perkj26752742016-10-24 01:21:16 -07003956 codec.SetParam(kCodecParamMaxQuantization, kDefaultQpMax + 1);
3957 parameters.codecs.push_back(codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003958 ASSERT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00003959 streams = fake_call_->GetVideoSendStreams()[0]->GetVideoStreams();
perkjfa10b552016-10-02 23:45:26 -07003960 EXPECT_EQ(kDefaultQpMax + 1, streams[0].max_qp);
Niels Möllerff40b142018-04-09 08:49:14 +02003961 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003962}
3963
eladalonf1841382017-06-12 01:16:46 -07003964TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithBitrates) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00003965 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
3966 200000);
3967}
3968
eladalonf1841382017-06-12 01:16:46 -07003969TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithHighMaxBitrate) {
pbos@webrtc.orga5f6fb52015-03-23 22:29:39 +00003970 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
3971 std::vector<webrtc::VideoStream> streams = AddSendStream()->GetVideoStreams();
3972 ASSERT_EQ(1u, streams.size());
3973 EXPECT_EQ(10000000, streams[0].max_bitrate_bps);
3974}
3975
eladalonf1841382017-06-12 01:16:46 -07003976TEST_F(WebRtcVideoChannelTest,
pbos@webrtc.org00873182014-11-25 14:03:34 +00003977 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
Sebastian Jansson8f83b422018-02-21 13:07:13 +01003978 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
pbos@webrtc.org00873182014-11-25 14:03:34 +00003979}
3980
eladalonf1841382017-06-12 01:16:46 -07003981TEST_F(WebRtcVideoChannelTest, SetSendCodecsCapsMinAndStartBitrate) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00003982 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003983}
3984
eladalonf1841382017-06-12 01:16:46 -07003985TEST_F(WebRtcVideoChannelTest, SetSendCodecsRejectsMaxLessThanMinBitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003986 send_parameters_.codecs[0].params[kCodecParamMinBitrate] = "300";
3987 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "200";
3988 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003989}
3990
Taylor Brandstetter58f2bd92016-04-26 17:15:23 -07003991// Test that when both the codec-specific bitrate params and max_bandwidth_bps
3992// are present in the same send parameters, the settings are combined correctly.
eladalonf1841382017-06-12 01:16:46 -07003993TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithBitratesAndMaxSendBandwidth) {
Taylor Brandstetter58f2bd92016-04-26 17:15:23 -07003994 send_parameters_.codecs[0].params[kCodecParamMinBitrate] = "100";
3995 send_parameters_.codecs[0].params[kCodecParamStartBitrate] = "200";
3996 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "300";
3997 send_parameters_.max_bandwidth_bps = 400000;
Taylor Brandstetter58f2bd92016-04-26 17:15:23 -07003998 // We expect max_bandwidth_bps to take priority, if set.
Sebastian Jansson8f83b422018-02-21 13:07:13 +01003999 ExpectSetBitrateParameters(100000, 200000, 400000);
4000 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
4001 // Since the codec isn't changing, start_bitrate_bps should be -1.
4002 ExpectSetBitrateParameters(100000, -1, 350000);
Taylor Brandstetter58f2bd92016-04-26 17:15:23 -07004003
4004 // Decrease max_bandwidth_bps.
4005 send_parameters_.max_bandwidth_bps = 350000;
4006 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Taylor Brandstetter58f2bd92016-04-26 17:15:23 -07004007
4008 // Now try again with the values flipped around.
4009 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "400";
4010 send_parameters_.max_bandwidth_bps = 300000;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01004011 ExpectSetBitrateParameters(100000, 200000, 300000);
Taylor Brandstetter58f2bd92016-04-26 17:15:23 -07004012 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Taylor Brandstetter58f2bd92016-04-26 17:15:23 -07004013
4014 // If we change the codec max, max_bandwidth_bps should still apply.
4015 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "350";
Sebastian Jansson8f83b422018-02-21 13:07:13 +01004016 ExpectSetBitrateParameters(100000, 200000, 300000);
Taylor Brandstetter58f2bd92016-04-26 17:15:23 -07004017 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Taylor Brandstetter58f2bd92016-04-26 17:15:23 -07004018}
4019
Piotr (Peter) Slatala946b9682019-03-18 10:25:02 -07004020// Test that when both the codec-specific bitrate params and max_bandwidth_bps
4021// are present in the same send parameters, the settings are combined correctly.
4022TEST_F(WebRtcVideoChannelTest,
4023 SetSendCodecsWithBitratesAndMaxSendBandwidthForMediaTransport) {
4024 // Same as SetSendCodecsWithBitratesAndMaxSendBandwidth but with Media
4025 // Transport.
4026 webrtc::MediaTransportSettings settings;
4027 settings.is_caller = true;
4028 webrtc::FakeMediaTransport fake_media_transport(settings);
4029 std::unique_ptr<cricket::FakeNetworkInterface> network_interface(
4030 new cricket::FakeNetworkInterface);
Anton Sukhanov4f08faa2019-05-21 11:12:57 -07004031 channel_->SetInterface(network_interface.get(),
4032 webrtc::MediaTransportConfig(&fake_media_transport));
Piotr (Peter) Slatala946b9682019-03-18 10:25:02 -07004033
4034 send_parameters_.codecs[0].params[kCodecParamMinBitrate] = "100";
4035 send_parameters_.codecs[0].params[kCodecParamStartBitrate] = "200";
4036 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "300";
4037 send_parameters_.max_bandwidth_bps = 400000;
4038 {
4039 // We expect max_bandwidth_bps to take priority, if set.
4040 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
4041 ASSERT_EQ(1u,
4042 fake_media_transport.target_rate_constraints_in_order().size());
4043 const webrtc::MediaTransportTargetRateConstraints& constraint =
4044 fake_media_transport.target_rate_constraints_in_order()[0];
4045 ASSERT_EQ(webrtc::DataRate::bps(100000), constraint.min_bitrate);
4046 ASSERT_EQ(webrtc::DataRate::bps(200000), constraint.starting_bitrate);
4047 ASSERT_EQ(webrtc::DataRate::bps(400000), constraint.max_bitrate);
4048 }
4049
4050 {
4051 // Decrease max_bandwidth_bps.
4052 send_parameters_.max_bandwidth_bps = 350000;
4053 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
4054 ASSERT_EQ(2u,
4055 fake_media_transport.target_rate_constraints_in_order().size());
4056 const webrtc::MediaTransportTargetRateConstraints& constraint =
4057 fake_media_transport.target_rate_constraints_in_order()[1];
4058
4059 // Since the codec isn't changing, start_bitrate_bps should be 0.
4060 ASSERT_EQ(webrtc::DataRate::bps(100000), constraint.min_bitrate);
4061 ASSERT_EQ(absl::nullopt, constraint.starting_bitrate);
4062 ASSERT_EQ(webrtc::DataRate::bps(350000), constraint.max_bitrate);
4063 }
4064
4065 {
4066 // Now try again with the values flipped around.
4067 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "400";
4068 send_parameters_.max_bandwidth_bps = 300000;
4069 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
4070 ASSERT_EQ(3u,
4071 fake_media_transport.target_rate_constraints_in_order().size());
4072 const webrtc::MediaTransportTargetRateConstraints& constraint =
4073 fake_media_transport.target_rate_constraints_in_order()[2];
4074
4075 ASSERT_EQ(webrtc::DataRate::bps(100000), constraint.min_bitrate);
4076 ASSERT_EQ(webrtc::DataRate::bps(200000), constraint.starting_bitrate);
4077 ASSERT_EQ(webrtc::DataRate::bps(300000), constraint.max_bitrate);
4078 }
4079
4080 {
4081 // Now try again with the values flipped around.
4082 // If we change the codec max, max_bandwidth_bps should still apply.
4083 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "350";
4084 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
4085 ASSERT_EQ(4u,
4086 fake_media_transport.target_rate_constraints_in_order().size());
4087 const webrtc::MediaTransportTargetRateConstraints& constraint =
4088 fake_media_transport.target_rate_constraints_in_order()[3];
4089
4090 ASSERT_EQ(webrtc::DataRate::bps(100000), constraint.min_bitrate);
4091 ASSERT_EQ(webrtc::DataRate::bps(200000), constraint.starting_bitrate);
4092 ASSERT_EQ(webrtc::DataRate::bps(300000), constraint.max_bitrate);
4093 }
4094}
4095
Yves Gerey665174f2018-06-19 15:03:05 +02004096TEST_F(WebRtcVideoChannelTest, SetMaxSendBandwidthShouldPreserveOtherBitrates) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00004097 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
4098 200000);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004099 send_parameters_.max_bandwidth_bps = 300000;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01004100 // Setting max bitrate should keep previous min bitrate.
4101 // Setting max bitrate should not reset start bitrate.
4102 ExpectSetBitrateParameters(100000, -1, 300000);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004103 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.org00873182014-11-25 14:03:34 +00004104}
4105
eladalonf1841382017-06-12 01:16:46 -07004106TEST_F(WebRtcVideoChannelTest, SetMaxSendBandwidthShouldBeRemovable) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004107 send_parameters_.max_bandwidth_bps = 300000;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01004108 ExpectSetMaxBitrate(300000);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004109 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos5c7760a2017-03-10 11:23:12 -08004110 // -1 means to disable max bitrate (set infinite).
4111 send_parameters_.max_bandwidth_bps = -1;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01004112 ExpectSetMaxBitrate(-1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004113 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004114}
4115
eladalonf1841382017-06-12 01:16:46 -07004116TEST_F(WebRtcVideoChannelTest, SetMaxSendBandwidthAndAddSendStream) {
perkjfa10b552016-10-02 23:45:26 -07004117 send_parameters_.max_bandwidth_bps = 99999;
4118 FakeVideoSendStream* stream = AddSendStream();
Sebastian Jansson8f83b422018-02-21 13:07:13 +01004119 ExpectSetMaxBitrate(send_parameters_.max_bandwidth_bps);
perkjfa10b552016-10-02 23:45:26 -07004120 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
perkjfa10b552016-10-02 23:45:26 -07004121 ASSERT_EQ(1u, stream->GetVideoStreams().size());
4122 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
4123 stream->GetVideoStreams()[0].max_bitrate_bps);
4124
4125 send_parameters_.max_bandwidth_bps = 77777;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01004126 ExpectSetMaxBitrate(send_parameters_.max_bandwidth_bps);
perkjfa10b552016-10-02 23:45:26 -07004127 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
4128 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
perkjfa10b552016-10-02 23:45:26 -07004129 stream->GetVideoStreams()[0].max_bitrate_bps);
4130}
4131
Seth Hampsonfeec91e2018-07-13 10:41:10 -07004132// Tests that when the codec specific max bitrate and VideoSendParameters
4133// max_bandwidth_bps are used, that it sets the VideoStream's max bitrate
4134// appropriately.
4135TEST_F(WebRtcVideoChannelTest,
4136 MaxBitratePrioritizesVideoSendParametersOverCodecMaxBitrate) {
4137 send_parameters_.codecs[0].params[kCodecParamMinBitrate] = "100";
4138 send_parameters_.codecs[0].params[kCodecParamStartBitrate] = "200";
4139 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "300";
4140 send_parameters_.max_bandwidth_bps = -1;
4141 AddSendStream();
4142 ExpectSetMaxBitrate(300000);
4143 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
4144
4145 std::vector<FakeVideoSendStream*> video_send_streams = GetFakeSendStreams();
4146 ASSERT_EQ(1u, video_send_streams.size());
4147 FakeVideoSendStream* video_send_stream = video_send_streams[0];
4148 ASSERT_EQ(1u, video_send_streams[0]->GetVideoStreams().size());
4149 // First the max bitrate is set based upon the codec param.
4150 EXPECT_EQ(300000,
4151 video_send_streams[0]->GetVideoStreams()[0].max_bitrate_bps);
4152
4153 // The VideoSendParameters max bitrate overrides the codec's.
4154 send_parameters_.max_bandwidth_bps = 500000;
4155 ExpectSetMaxBitrate(send_parameters_.max_bandwidth_bps);
4156 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
4157 ASSERT_EQ(1u, video_send_stream->GetVideoStreams().size());
4158 EXPECT_EQ(500000, video_send_stream->GetVideoStreams()[0].max_bitrate_bps);
4159}
4160
4161// Tests that when the codec specific max bitrate and RtpParameters
4162// max_bitrate_bps are used, that it sets the VideoStream's max bitrate
4163// appropriately.
4164TEST_F(WebRtcVideoChannelTest,
4165 MaxBitratePrioritizesRtpParametersOverCodecMaxBitrate) {
4166 send_parameters_.codecs[0].params[kCodecParamMinBitrate] = "100";
4167 send_parameters_.codecs[0].params[kCodecParamStartBitrate] = "200";
4168 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "300";
4169 send_parameters_.max_bandwidth_bps = -1;
4170 AddSendStream();
4171 ExpectSetMaxBitrate(300000);
4172 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
4173
4174 std::vector<FakeVideoSendStream*> video_send_streams = GetFakeSendStreams();
4175 ASSERT_EQ(1u, video_send_streams.size());
4176 FakeVideoSendStream* video_send_stream = video_send_streams[0];
4177 ASSERT_EQ(1u, video_send_stream->GetVideoStreams().size());
4178 // First the max bitrate is set based upon the codec param.
4179 EXPECT_EQ(300000, video_send_stream->GetVideoStreams()[0].max_bitrate_bps);
4180
4181 // The RtpParameter max bitrate overrides the codec's.
4182 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
4183 ASSERT_EQ(1u, parameters.encodings.size());
4184 parameters.encodings[0].max_bitrate_bps = 500000;
4185 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
4186 ASSERT_EQ(1u, video_send_stream->GetVideoStreams().size());
4187 EXPECT_EQ(parameters.encodings[0].max_bitrate_bps,
4188 video_send_stream->GetVideoStreams()[0].max_bitrate_bps);
4189}
4190
Åsa Persson55659812018-06-18 17:51:32 +02004191TEST_F(WebRtcVideoChannelTest,
4192 MaxBitrateIsMinimumOfMaxSendBandwidthAndMaxEncodingBitrate) {
4193 send_parameters_.max_bandwidth_bps = 99999;
4194 FakeVideoSendStream* stream = AddSendStream();
4195 ExpectSetMaxBitrate(send_parameters_.max_bandwidth_bps);
4196 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
4197 ASSERT_EQ(1u, stream->GetVideoStreams().size());
4198 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
4199 stream->GetVideoStreams()[0].max_bitrate_bps);
4200
4201 // Get and set the rtp encoding parameters.
4202 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
4203 EXPECT_EQ(1u, parameters.encodings.size());
4204
4205 parameters.encodings[0].max_bitrate_bps = 99999 - 1;
4206 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
4207 EXPECT_EQ(parameters.encodings[0].max_bitrate_bps,
4208 stream->GetVideoStreams()[0].max_bitrate_bps);
4209
4210 parameters.encodings[0].max_bitrate_bps = 99999 + 1;
4211 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
4212 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
4213 stream->GetVideoStreams()[0].max_bitrate_bps);
4214}
4215
eladalonf1841382017-06-12 01:16:46 -07004216TEST_F(WebRtcVideoChannelTest, SetMaxSendBitrateCanIncreaseSenderBitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004217 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004218 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004219 ASSERT_TRUE(channel_->SetSendParameters(parameters));
Peter Boströmdfd53fe2015-03-27 15:58:11 +01004220 channel_->SetSend(true);
4221
4222 FakeVideoSendStream* stream = AddSendStream();
4223
Niels Möller805a27e2019-01-21 12:21:27 +01004224 webrtc::test::FrameForwarder frame_forwarder;
4225 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));
Peter Boström3afc8c42016-01-27 16:45:21 +01004226
Peter Boströmdfd53fe2015-03-27 15:58:11 +01004227 std::vector<webrtc::VideoStream> streams = stream->GetVideoStreams();
4228 int initial_max_bitrate_bps = streams[0].max_bitrate_bps;
4229 EXPECT_GT(initial_max_bitrate_bps, 0);
4230
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004231 parameters.max_bandwidth_bps = initial_max_bitrate_bps * 2;
4232 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Peter Boström3afc8c42016-01-27 16:45:21 +01004233 // Insert a frame to update the encoder config.
Niels Möller805a27e2019-01-21 12:21:27 +01004234 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Peter Boströmdfd53fe2015-03-27 15:58:11 +01004235 streams = stream->GetVideoStreams();
4236 EXPECT_EQ(initial_max_bitrate_bps * 2, streams[0].max_bitrate_bps);
Niels Möllerff40b142018-04-09 08:49:14 +02004237 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
Peter Boströmdfd53fe2015-03-27 15:58:11 +01004238}
4239
eladalonf1841382017-06-12 01:16:46 -07004240TEST_F(WebRtcVideoChannelTest,
Peter Boströmdfd53fe2015-03-27 15:58:11 +01004241 SetMaxSendBitrateCanIncreaseSimulcastSenderBitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004242 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004243 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004244 ASSERT_TRUE(channel_->SetSendParameters(parameters));
Peter Boströmdfd53fe2015-03-27 15:58:11 +01004245 channel_->SetSend(true);
4246
4247 FakeVideoSendStream* stream = AddSendStream(
4248 cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kSsrcs3)));
4249
4250 // Send a frame to make sure this scales up to >1 stream (simulcast).
Niels Möller805a27e2019-01-21 12:21:27 +01004251 webrtc::test::FrameForwarder frame_forwarder;
4252 EXPECT_TRUE(channel_->SetVideoSend(kSsrcs3[0], nullptr, &frame_forwarder));
4253 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Peter Boströmdfd53fe2015-03-27 15:58:11 +01004254
4255 std::vector<webrtc::VideoStream> streams = stream->GetVideoStreams();
4256 ASSERT_GT(streams.size(), 1u)
4257 << "Without simulcast this test doesn't make sense.";
pbosbe16f792015-10-16 12:49:39 -07004258 int initial_max_bitrate_bps = GetTotalMaxBitrateBps(streams);
Peter Boströmdfd53fe2015-03-27 15:58:11 +01004259 EXPECT_GT(initial_max_bitrate_bps, 0);
4260
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004261 parameters.max_bandwidth_bps = initial_max_bitrate_bps * 2;
4262 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Peter Boström3afc8c42016-01-27 16:45:21 +01004263 // Insert a frame to update the encoder config.
Niels Möller805a27e2019-01-21 12:21:27 +01004264 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Peter Boströmdfd53fe2015-03-27 15:58:11 +01004265 streams = stream->GetVideoStreams();
pbosbe16f792015-10-16 12:49:39 -07004266 int increased_max_bitrate_bps = GetTotalMaxBitrateBps(streams);
Peter Boströmdfd53fe2015-03-27 15:58:11 +01004267 EXPECT_EQ(initial_max_bitrate_bps * 2, increased_max_bitrate_bps);
4268
Niels Möllerff40b142018-04-09 08:49:14 +02004269 EXPECT_TRUE(channel_->SetVideoSend(kSsrcs3[0], nullptr, nullptr));
Peter Boströmdfd53fe2015-03-27 15:58:11 +01004270}
4271
eladalonf1841382017-06-12 01:16:46 -07004272TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithMaxQuantization) {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004273 static const char* kMaxQuantization = "21";
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004274 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004275 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004276 parameters.codecs[0].params[kCodecParamMaxQuantization] = kMaxQuantization;
4277 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Mirko Bonadeif859e552018-05-30 15:31:29 +02004278 EXPECT_EQ(atoi(kMaxQuantization),
pbos@webrtc.org6ae48c62014-06-06 10:49:19 +00004279 AddSendStream()->GetVideoStreams().back().max_qp);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004280
4281 VideoCodec codec;
4282 EXPECT_TRUE(channel_->GetSendCodec(&codec));
4283 EXPECT_EQ(kMaxQuantization, codec.params[kCodecParamMaxQuantization]);
4284}
4285
eladalonf1841382017-06-12 01:16:46 -07004286TEST_F(WebRtcVideoChannelTest, SetSendCodecsRejectBadPayloadTypes) {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004287 // TODO(pbos): Should we only allow the dynamic range?
pkasting@chromium.orge7a4a122015-01-28 21:36:55 +00004288 static const int kIncorrectPayloads[] = {-2, -1, 128, 129};
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004289 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004290 parameters.codecs.push_back(GetEngineCodec("VP8"));
pkasting@chromium.orge7a4a122015-01-28 21:36:55 +00004291 for (size_t i = 0; i < arraysize(kIncorrectPayloads); ++i) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004292 parameters.codecs[0].id = kIncorrectPayloads[i];
4293 EXPECT_FALSE(channel_->SetSendParameters(parameters))
pkasting@chromium.orgd3245462015-02-23 21:28:22 +00004294 << "Bad payload type '" << kIncorrectPayloads[i] << "' accepted.";
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004295 }
4296}
4297
eladalonf1841382017-06-12 01:16:46 -07004298TEST_F(WebRtcVideoChannelTest, SetSendCodecsAcceptAllValidPayloadTypes) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004299 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004300 parameters.codecs.push_back(GetEngineCodec("VP8"));
magjedf823ede2016-11-12 09:53:04 -08004301 for (int payload_type = 96; payload_type <= 127; ++payload_type) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004302 parameters.codecs[0].id = payload_type;
4303 EXPECT_TRUE(channel_->SetSendParameters(parameters))
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004304 << "Payload type '" << payload_type << "' rejected.";
4305 }
4306}
4307
deadbeef67cf2c12016-04-13 10:07:16 -07004308// Test that setting the a different set of codecs but with an identical front
4309// codec doesn't result in the stream being recreated.
4310// This may happen when a subsequent negotiation includes fewer codecs, as a
4311// result of one of the codecs being rejected.
eladalonf1841382017-06-12 01:16:46 -07004312TEST_F(WebRtcVideoChannelTest,
deadbeef67cf2c12016-04-13 10:07:16 -07004313 SetSendCodecsIdenticalFirstCodecDoesntRecreateStream) {
4314 cricket::VideoSendParameters parameters1;
magjed509e4fe2016-11-18 01:34:11 -08004315 parameters1.codecs.push_back(GetEngineCodec("VP8"));
4316 parameters1.codecs.push_back(GetEngineCodec("VP9"));
deadbeef67cf2c12016-04-13 10:07:16 -07004317 EXPECT_TRUE(channel_->SetSendParameters(parameters1));
4318
4319 AddSendStream();
4320 EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());
4321
4322 cricket::VideoSendParameters parameters2;
magjed509e4fe2016-11-18 01:34:11 -08004323 parameters2.codecs.push_back(GetEngineCodec("VP8"));
deadbeef67cf2c12016-04-13 10:07:16 -07004324 EXPECT_TRUE(channel_->SetSendParameters(parameters2));
4325 EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());
4326}
4327
eladalonf1841382017-06-12 01:16:46 -07004328TEST_F(WebRtcVideoChannelTest, SetRecvCodecsWithOnlyVp8) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004329 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004330 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004331 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004332}
4333
pbos@webrtc.orge322a172014-06-13 11:47:28 +00004334// Test that we set our inbound RTX codecs properly.
eladalonf1841382017-06-12 01:16:46 -07004335TEST_F(WebRtcVideoChannelTest, SetRecvCodecsWithRtx) {
magjed509e4fe2016-11-18 01:34:11 -08004336 const int kUnusedPayloadType1 = 126;
4337 const int kUnusedPayloadType2 = 127;
4338 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType1));
4339 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType2));
4340
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004341 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004342 parameters.codecs.push_back(GetEngineCodec("VP8"));
4343 cricket::VideoCodec rtx_codec(kUnusedPayloadType1, "rtx");
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004344 parameters.codecs.push_back(rtx_codec);
4345 EXPECT_FALSE(channel_->SetRecvParameters(parameters))
pbos@webrtc.orge322a172014-06-13 11:47:28 +00004346 << "RTX codec without associated payload should be rejected.";
4347
magjed509e4fe2016-11-18 01:34:11 -08004348 parameters.codecs[1].SetParam("apt", kUnusedPayloadType2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004349 EXPECT_FALSE(channel_->SetRecvParameters(parameters))
pbos@webrtc.orge322a172014-06-13 11:47:28 +00004350 << "RTX codec with invalid associated payload type should be rejected.";
4351
magjed509e4fe2016-11-18 01:34:11 -08004352 parameters.codecs[1].SetParam("apt", GetEngineCodec("VP8").id);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004353 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orge322a172014-06-13 11:47:28 +00004354
magjed509e4fe2016-11-18 01:34:11 -08004355 cricket::VideoCodec rtx_codec2(kUnusedPayloadType2, "rtx");
pbos@webrtc.orge322a172014-06-13 11:47:28 +00004356 rtx_codec2.SetParam("apt", rtx_codec.id);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004357 parameters.codecs.push_back(rtx_codec2);
pbos@webrtc.orge322a172014-06-13 11:47:28 +00004358
Yves Gerey665174f2018-06-19 15:03:05 +02004359 EXPECT_FALSE(channel_->SetRecvParameters(parameters))
4360 << "RTX codec with another RTX as associated payload type should be "
4361 "rejected.";
pbos@webrtc.orge322a172014-06-13 11:47:28 +00004362}
4363
eladalonf1841382017-06-12 01:16:46 -07004364TEST_F(WebRtcVideoChannelTest, SetRecvCodecsWithChangedRtxPayloadType) {
brandtr14742122017-01-27 04:53:07 -08004365 const int kUnusedPayloadType1 = 126;
4366 const int kUnusedPayloadType2 = 127;
4367 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType1));
4368 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType2));
4369
4370 // SSRCs for RTX.
4371 cricket::StreamParams params =
4372 cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
4373 params.AddFidSsrc(kSsrcs1[0], kRtxSsrcs1[0]);
4374 AddRecvStream(params);
4375
4376 // Original payload type for RTX.
4377 cricket::VideoRecvParameters parameters;
4378 parameters.codecs.push_back(GetEngineCodec("VP8"));
4379 cricket::VideoCodec rtx_codec(kUnusedPayloadType1, "rtx");
4380 rtx_codec.SetParam("apt", GetEngineCodec("VP8").id);
4381 parameters.codecs.push_back(rtx_codec);
4382 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
4383 ASSERT_EQ(1U, fake_call_->GetVideoReceiveStreams().size());
4384 const webrtc::VideoReceiveStream::Config& config_before =
4385 fake_call_->GetVideoReceiveStreams()[0]->GetConfig();
nisse26e3abb2017-08-25 04:44:25 -07004386 EXPECT_EQ(1U, config_before.rtp.rtx_associated_payload_types.size());
4387 const int* payload_type_before = FindKeyByValue(
4388 config_before.rtp.rtx_associated_payload_types, GetEngineCodec("VP8").id);
4389 ASSERT_NE(payload_type_before, nullptr);
4390 EXPECT_EQ(kUnusedPayloadType1, *payload_type_before);
brandtr14742122017-01-27 04:53:07 -08004391 EXPECT_EQ(kRtxSsrcs1[0], config_before.rtp.rtx_ssrc);
4392
4393 // Change payload type for RTX.
4394 parameters.codecs[1].id = kUnusedPayloadType2;
4395 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
4396 ASSERT_EQ(1U, fake_call_->GetVideoReceiveStreams().size());
4397 const webrtc::VideoReceiveStream::Config& config_after =
4398 fake_call_->GetVideoReceiveStreams()[0]->GetConfig();
nisse26e3abb2017-08-25 04:44:25 -07004399 EXPECT_EQ(1U, config_after.rtp.rtx_associated_payload_types.size());
4400 const int* payload_type_after = FindKeyByValue(
4401 config_after.rtp.rtx_associated_payload_types, GetEngineCodec("VP8").id);
4402 ASSERT_NE(payload_type_after, nullptr);
4403 EXPECT_EQ(kUnusedPayloadType2, *payload_type_after);
brandtr14742122017-01-27 04:53:07 -08004404 EXPECT_EQ(kRtxSsrcs1[0], config_after.rtp.rtx_ssrc);
4405}
4406
eladalonf1841382017-06-12 01:16:46 -07004407TEST_F(WebRtcVideoChannelTest, SetRecvCodecsDifferentPayloadType) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004408 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004409 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004410 parameters.codecs[0].id = 99;
4411 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004412}
4413
eladalonf1841382017-06-12 01:16:46 -07004414TEST_F(WebRtcVideoChannelTest, SetRecvCodecsAcceptDefaultCodecs) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004415 cricket::VideoRecvParameters parameters;
4416 parameters.codecs = engine_.codecs();
4417 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgccbed3b2014-07-11 13:02:54 +00004418
4419 FakeVideoReceiveStream* stream = AddRecvStream();
Tommi733b5472016-06-10 17:58:01 +02004420 const webrtc::VideoReceiveStream::Config& config = stream->GetConfig();
Niels Möllercb7e1d22018-09-11 15:56:04 +02004421 EXPECT_EQ(engine_.codecs()[0].name, config.decoders[0].video_format.name);
pbos@webrtc.org776e6f22014-10-29 15:28:39 +00004422 EXPECT_EQ(engine_.codecs()[0].id, config.decoders[0].payload_type);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004423}
4424
eladalonf1841382017-06-12 01:16:46 -07004425TEST_F(WebRtcVideoChannelTest, SetRecvCodecsRejectUnsupportedCodec) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004426 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004427 parameters.codecs.push_back(GetEngineCodec("VP8"));
perkj26752742016-10-24 01:21:16 -07004428 parameters.codecs.push_back(VideoCodec(101, "WTF3"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004429 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004430}
4431
eladalonf1841382017-06-12 01:16:46 -07004432TEST_F(WebRtcVideoChannelTest, SetRecvCodecsAcceptsMultipleVideoCodecs) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004433 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004434 parameters.codecs.push_back(GetEngineCodec("VP8"));
4435 parameters.codecs.push_back(GetEngineCodec("VP9"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004436 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004437}
4438
eladalonf1841382017-06-12 01:16:46 -07004439TEST_F(WebRtcVideoChannelTest, SetRecvCodecsWithoutFecDisablesFec) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004440 cricket::VideoSendParameters send_parameters;
magjed509e4fe2016-11-18 01:34:11 -08004441 send_parameters.codecs.push_back(GetEngineCodec("VP8"));
4442 send_parameters.codecs.push_back(GetEngineCodec("red"));
4443 send_parameters.codecs.push_back(GetEngineCodec("ulpfec"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004444 ASSERT_TRUE(channel_->SetSendParameters(send_parameters));
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00004445
4446 FakeVideoReceiveStream* stream = AddRecvStream();
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00004447
magjed509e4fe2016-11-18 01:34:11 -08004448 EXPECT_EQ(GetEngineCodec("ulpfec").id,
nisse3b3622f2017-09-26 02:49:21 -07004449 stream->GetConfig().rtp.ulpfec_payload_type);
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00004450
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004451 cricket::VideoRecvParameters recv_parameters;
magjed509e4fe2016-11-18 01:34:11 -08004452 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004453 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00004454 stream = fake_call_->GetVideoReceiveStreams()[0];
brandtr468da7c2016-11-22 02:16:47 -08004455 ASSERT_TRUE(stream != nullptr);
nisse3b3622f2017-09-26 02:49:21 -07004456 EXPECT_EQ(-1, stream->GetConfig().rtp.ulpfec_payload_type)
brandtr468da7c2016-11-22 02:16:47 -08004457 << "SetSendCodec without ULPFEC should disable current ULPFEC.";
4458}
4459
eladalonf1841382017-06-12 01:16:46 -07004460TEST_F(WebRtcVideoChannelFlexfecRecvTest, SetRecvParamsWithoutFecDisablesFec) {
brandtr468da7c2016-11-22 02:16:47 -08004461 AddRecvStream(
4462 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
brandtr9c3d4c42017-01-23 06:59:13 -08004463 const std::vector<FakeFlexfecReceiveStream*>& streams =
brandtr468da7c2016-11-22 02:16:47 -08004464 fake_call_->GetFlexfecReceiveStreams();
4465
4466 ASSERT_EQ(1U, streams.size());
brandtr9c3d4c42017-01-23 06:59:13 -08004467 const FakeFlexfecReceiveStream* stream = streams.front();
4468 EXPECT_EQ(GetEngineCodec("flexfec-03").id, stream->GetConfig().payload_type);
4469 EXPECT_EQ(kFlexfecSsrc, stream->GetConfig().remote_ssrc);
4470 ASSERT_EQ(1U, stream->GetConfig().protected_media_ssrcs.size());
4471 EXPECT_EQ(kSsrcs1[0], stream->GetConfig().protected_media_ssrcs[0]);
brandtr468da7c2016-11-22 02:16:47 -08004472
4473 cricket::VideoRecvParameters recv_parameters;
4474 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
4475 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
4476 EXPECT_TRUE(streams.empty())
4477 << "SetSendCodec without FlexFEC should disable current FlexFEC.";
pbos@webrtc.org269605c2014-06-26 08:49:03 +00004478}
4479
eladalonf1841382017-06-12 01:16:46 -07004480TEST_F(WebRtcVideoChannelTest, SetSendParamsWithFecEnablesFec) {
Stefan Holmer2b1f6512016-05-17 16:33:30 +02004481 FakeVideoReceiveStream* stream = AddRecvStream();
magjed509e4fe2016-11-18 01:34:11 -08004482 EXPECT_EQ(GetEngineCodec("ulpfec").id,
nisse3b3622f2017-09-26 02:49:21 -07004483 stream->GetConfig().rtp.ulpfec_payload_type);
Stefan Holmer2b1f6512016-05-17 16:33:30 +02004484
4485 cricket::VideoRecvParameters recv_parameters;
magjed509e4fe2016-11-18 01:34:11 -08004486 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
4487 recv_parameters.codecs.push_back(GetEngineCodec("red"));
4488 recv_parameters.codecs.push_back(GetEngineCodec("ulpfec"));
Stefan Holmer2b1f6512016-05-17 16:33:30 +02004489 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
4490 stream = fake_call_->GetVideoReceiveStreams()[0];
brandtr468da7c2016-11-22 02:16:47 -08004491 ASSERT_TRUE(stream != nullptr);
magjed509e4fe2016-11-18 01:34:11 -08004492 EXPECT_EQ(GetEngineCodec("ulpfec").id,
nisse3b3622f2017-09-26 02:49:21 -07004493 stream->GetConfig().rtp.ulpfec_payload_type)
brandtr468da7c2016-11-22 02:16:47 -08004494 << "ULPFEC should be enabled on the receive stream.";
Stefan Holmer2b1f6512016-05-17 16:33:30 +02004495
4496 cricket::VideoSendParameters send_parameters;
magjed509e4fe2016-11-18 01:34:11 -08004497 send_parameters.codecs.push_back(GetEngineCodec("VP8"));
4498 send_parameters.codecs.push_back(GetEngineCodec("red"));
4499 send_parameters.codecs.push_back(GetEngineCodec("ulpfec"));
Stefan Holmer2b1f6512016-05-17 16:33:30 +02004500 ASSERT_TRUE(channel_->SetSendParameters(send_parameters));
4501 stream = fake_call_->GetVideoReceiveStreams()[0];
magjed509e4fe2016-11-18 01:34:11 -08004502 EXPECT_EQ(GetEngineCodec("ulpfec").id,
nisse3b3622f2017-09-26 02:49:21 -07004503 stream->GetConfig().rtp.ulpfec_payload_type)
brandtr468da7c2016-11-22 02:16:47 -08004504 << "ULPFEC should be enabled on the receive stream.";
4505}
4506
eladalonf1841382017-06-12 01:16:46 -07004507TEST_F(WebRtcVideoChannelFlexfecSendRecvTest,
brandtr31bd2242017-05-19 05:47:46 -07004508 SetSendRecvParamsWithFecEnablesFec) {
brandtr468da7c2016-11-22 02:16:47 -08004509 AddRecvStream(
4510 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
brandtr9c3d4c42017-01-23 06:59:13 -08004511 const std::vector<FakeFlexfecReceiveStream*>& streams =
brandtr468da7c2016-11-22 02:16:47 -08004512 fake_call_->GetFlexfecReceiveStreams();
4513
4514 cricket::VideoRecvParameters recv_parameters;
4515 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
4516 recv_parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
4517 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
4518 ASSERT_EQ(1U, streams.size());
brandtr9c3d4c42017-01-23 06:59:13 -08004519 const FakeFlexfecReceiveStream* stream_with_recv_params = streams.front();
brandtr468da7c2016-11-22 02:16:47 -08004520 EXPECT_EQ(GetEngineCodec("flexfec-03").id,
brandtr9c3d4c42017-01-23 06:59:13 -08004521 stream_with_recv_params->GetConfig().payload_type);
4522 EXPECT_EQ(kFlexfecSsrc, stream_with_recv_params->GetConfig().remote_ssrc);
brandtr468da7c2016-11-22 02:16:47 -08004523 EXPECT_EQ(1U,
brandtr9c3d4c42017-01-23 06:59:13 -08004524 stream_with_recv_params->GetConfig().protected_media_ssrcs.size());
brandtr468da7c2016-11-22 02:16:47 -08004525 EXPECT_EQ(kSsrcs1[0],
brandtr9c3d4c42017-01-23 06:59:13 -08004526 stream_with_recv_params->GetConfig().protected_media_ssrcs[0]);
brandtr468da7c2016-11-22 02:16:47 -08004527
4528 cricket::VideoSendParameters send_parameters;
4529 send_parameters.codecs.push_back(GetEngineCodec("VP8"));
4530 send_parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
4531 ASSERT_TRUE(channel_->SetSendParameters(send_parameters));
4532 ASSERT_EQ(1U, streams.size());
brandtr9c3d4c42017-01-23 06:59:13 -08004533 const FakeFlexfecReceiveStream* stream_with_send_params = streams.front();
brandtr468da7c2016-11-22 02:16:47 -08004534 EXPECT_EQ(GetEngineCodec("flexfec-03").id,
brandtr9c3d4c42017-01-23 06:59:13 -08004535 stream_with_send_params->GetConfig().payload_type);
4536 EXPECT_EQ(kFlexfecSsrc, stream_with_send_params->GetConfig().remote_ssrc);
brandtr468da7c2016-11-22 02:16:47 -08004537 EXPECT_EQ(1U,
brandtr9c3d4c42017-01-23 06:59:13 -08004538 stream_with_send_params->GetConfig().protected_media_ssrcs.size());
brandtr468da7c2016-11-22 02:16:47 -08004539 EXPECT_EQ(kSsrcs1[0],
brandtr9c3d4c42017-01-23 06:59:13 -08004540 stream_with_send_params->GetConfig().protected_media_ssrcs[0]);
Stefan Holmer2b1f6512016-05-17 16:33:30 +02004541}
4542
eladalonf1841382017-06-12 01:16:46 -07004543TEST_F(WebRtcVideoChannelTest, SetRecvCodecsRejectDuplicateFecPayloads) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004544 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004545 parameters.codecs.push_back(GetEngineCodec("VP8"));
4546 parameters.codecs.push_back(GetEngineCodec("red"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004547 parameters.codecs[1].id = parameters.codecs[0].id;
4548 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004549}
4550
eladalonf1841382017-06-12 01:16:46 -07004551TEST_F(WebRtcVideoChannelFlexfecRecvTest,
brandtr31bd2242017-05-19 05:47:46 -07004552 SetRecvCodecsRejectDuplicateFecPayloads) {
brandtr468da7c2016-11-22 02:16:47 -08004553 cricket::VideoRecvParameters parameters;
4554 parameters.codecs.push_back(GetEngineCodec("VP8"));
4555 parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
4556 parameters.codecs[1].id = parameters.codecs[0].id;
4557 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
4558}
4559
eladalonf1841382017-06-12 01:16:46 -07004560TEST_F(WebRtcVideoChannelTest, SetRecvCodecsRejectDuplicateCodecPayloads) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004561 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004562 parameters.codecs.push_back(GetEngineCodec("VP8"));
4563 parameters.codecs.push_back(GetEngineCodec("VP9"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004564 parameters.codecs[1].id = parameters.codecs[0].id;
4565 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004566}
4567
eladalonf1841382017-06-12 01:16:46 -07004568TEST_F(WebRtcVideoChannelTest,
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004569 SetRecvCodecsAcceptSameCodecOnMultiplePayloadTypes) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004570 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004571 parameters.codecs.push_back(GetEngineCodec("VP8"));
4572 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004573 parameters.codecs[1].id += 1;
4574 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004575}
4576
deadbeef67cf2c12016-04-13 10:07:16 -07004577// Test that setting the same codecs but with a different order
deadbeef874ca3a2015-08-20 17:19:20 -07004578// doesn't result in the stream being recreated.
eladalonf1841382017-06-12 01:16:46 -07004579TEST_F(WebRtcVideoChannelTest,
deadbeef67cf2c12016-04-13 10:07:16 -07004580 SetRecvCodecsDifferentOrderDoesntRecreateStream) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004581 cricket::VideoRecvParameters parameters1;
magjed509e4fe2016-11-18 01:34:11 -08004582 parameters1.codecs.push_back(GetEngineCodec("VP8"));
4583 parameters1.codecs.push_back(GetEngineCodec("red"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004584 EXPECT_TRUE(channel_->SetRecvParameters(parameters1));
deadbeef874ca3a2015-08-20 17:19:20 -07004585
4586 AddRecvStream(cricket::StreamParams::CreateLegacy(123));
4587 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
4588
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004589 cricket::VideoRecvParameters parameters2;
magjed509e4fe2016-11-18 01:34:11 -08004590 parameters2.codecs.push_back(GetEngineCodec("red"));
4591 parameters2.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004592 EXPECT_TRUE(channel_->SetRecvParameters(parameters2));
deadbeef874ca3a2015-08-20 17:19:20 -07004593 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
4594}
4595
eladalonf1841382017-06-12 01:16:46 -07004596TEST_F(WebRtcVideoChannelTest, SendStreamNotSendingByDefault) {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004597 EXPECT_FALSE(AddSendStream()->IsSending());
4598}
4599
eladalonf1841382017-06-12 01:16:46 -07004600TEST_F(WebRtcVideoChannelTest, ReceiveStreamReceivingByDefault) {
pbos@webrtc.org85f42942014-07-22 09:14:58 +00004601 EXPECT_TRUE(AddRecvStream()->IsReceiving());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004602}
4603
eladalonf1841382017-06-12 01:16:46 -07004604TEST_F(WebRtcVideoChannelTest, SetSend) {
pbos@webrtc.org5301b0f2014-07-17 08:51:46 +00004605 FakeVideoSendStream* stream = AddSendStream();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004606 EXPECT_FALSE(stream->IsSending());
4607
4608 // false->true
4609 EXPECT_TRUE(channel_->SetSend(true));
4610 EXPECT_TRUE(stream->IsSending());
4611 // true->true
4612 EXPECT_TRUE(channel_->SetSend(true));
4613 EXPECT_TRUE(stream->IsSending());
4614 // true->false
4615 EXPECT_TRUE(channel_->SetSend(false));
4616 EXPECT_FALSE(stream->IsSending());
4617 // false->false
4618 EXPECT_TRUE(channel_->SetSend(false));
4619 EXPECT_FALSE(stream->IsSending());
4620
4621 EXPECT_TRUE(channel_->SetSend(true));
4622 FakeVideoSendStream* new_stream = AddSendStream();
4623 EXPECT_TRUE(new_stream->IsSending())
4624 << "Send stream created after SetSend(true) not sending initially.";
4625}
4626
pbos@webrtc.orgd8198032014-11-10 14:41:43 +00004627// This test verifies DSCP settings are properly applied on video media channel.
eladalonf1841382017-06-12 01:16:46 -07004628TEST_F(WebRtcVideoChannelTest, TestSetDscpOptions) {
kwiberg686a8ef2016-02-26 03:00:35 -08004629 std::unique_ptr<cricket::FakeNetworkInterface> network_interface(
pbos@webrtc.orgd8198032014-11-10 14:41:43 +00004630 new cricket::FakeNetworkInterface);
nisse51542be2016-02-12 02:27:06 -08004631 MediaConfig config;
Tim Haloun6ca98362018-09-17 17:06:08 -07004632 std::unique_ptr<cricket::WebRtcVideoChannel> channel;
Tim Haloun648d28a2018-10-18 16:52:22 -07004633 webrtc::RtpParameters parameters;
nisse51542be2016-02-12 02:27:06 -08004634
Sebastian Jansson84848f22018-11-16 10:40:36 +01004635 channel.reset(
4636 static_cast<cricket::WebRtcVideoChannel*>(engine_.CreateMediaChannel(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02004637 call_.get(), config, VideoOptions(), webrtc::CryptoOptions(),
4638 video_bitrate_allocator_factory_.get())));
Anton Sukhanov4f08faa2019-05-21 11:12:57 -07004639 channel->SetInterface(network_interface.get(),
4640 webrtc::MediaTransportConfig());
nisse51542be2016-02-12 02:27:06 -08004641 // Default value when DSCP is disabled should be DSCP_DEFAULT.
pbos@webrtc.orgd8198032014-11-10 14:41:43 +00004642 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface->dscp());
nisse51542be2016-02-12 02:27:06 -08004643
Tim Haloun648d28a2018-10-18 16:52:22 -07004644 // Default value when DSCP is enabled is also DSCP_DEFAULT, until it is set
4645 // through rtp parameters.
nisse51542be2016-02-12 02:27:06 -08004646 config.enable_dscp = true;
Sebastian Jansson84848f22018-11-16 10:40:36 +01004647 channel.reset(
4648 static_cast<cricket::WebRtcVideoChannel*>(engine_.CreateMediaChannel(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02004649 call_.get(), config, VideoOptions(), webrtc::CryptoOptions(),
4650 video_bitrate_allocator_factory_.get())));
Anton Sukhanov4f08faa2019-05-21 11:12:57 -07004651 channel->SetInterface(network_interface.get(),
4652 webrtc::MediaTransportConfig());
Tim Haloun648d28a2018-10-18 16:52:22 -07004653 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface->dscp());
4654
4655 // Create a send stream to configure
4656 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(kSsrc)));
4657 parameters = channel->GetRtpSendParameters(kSsrc);
4658 ASSERT_FALSE(parameters.encodings.empty());
4659
4660 // Various priorities map to various dscp values.
4661 parameters.encodings[0].network_priority = 4.0;
4662 ASSERT_TRUE(channel->SetRtpSendParameters(kSsrc, parameters).ok());
nisse51542be2016-02-12 02:27:06 -08004663 EXPECT_EQ(rtc::DSCP_AF41, network_interface->dscp());
Tim Haloun648d28a2018-10-18 16:52:22 -07004664 parameters.encodings[0].network_priority = 0.5;
4665 ASSERT_TRUE(channel->SetRtpSendParameters(kSsrc, parameters).ok());
4666 EXPECT_EQ(rtc::DSCP_CS1, network_interface->dscp());
4667
4668 // A bad priority does not change the dscp value.
4669 parameters.encodings[0].network_priority = 0.0;
4670 ASSERT_FALSE(channel->SetRtpSendParameters(kSsrc, parameters).ok());
4671 EXPECT_EQ(rtc::DSCP_CS1, network_interface->dscp());
nisse51542be2016-02-12 02:27:06 -08004672
Tim Haloun6ca98362018-09-17 17:06:08 -07004673 // Packets should also self-identify their dscp in PacketOptions.
4674 const uint8_t kData[10] = {0};
4675 EXPECT_TRUE(static_cast<webrtc::Transport*>(channel.get())
4676 ->SendRtcp(kData, sizeof(kData)));
Tim Haloun648d28a2018-10-18 16:52:22 -07004677 EXPECT_EQ(rtc::DSCP_CS1, network_interface->options().dscp);
Tim Haloun6ca98362018-09-17 17:06:08 -07004678
nisse51542be2016-02-12 02:27:06 -08004679 // Verify that setting the option to false resets the
4680 // DiffServCodePoint.
4681 config.enable_dscp = false;
Sebastian Jansson84848f22018-11-16 10:40:36 +01004682 channel.reset(
4683 static_cast<cricket::WebRtcVideoChannel*>(engine_.CreateMediaChannel(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02004684 call_.get(), config, VideoOptions(), webrtc::CryptoOptions(),
4685 video_bitrate_allocator_factory_.get())));
Anton Sukhanov4f08faa2019-05-21 11:12:57 -07004686 channel->SetInterface(network_interface.get(),
4687 webrtc::MediaTransportConfig());
nisse51542be2016-02-12 02:27:06 -08004688 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface->dscp());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004689}
4690
deadbeef13871492015-12-09 12:37:51 -08004691// This test verifies that the RTCP reduced size mode is properly applied to
4692// send video streams.
eladalonf1841382017-06-12 01:16:46 -07004693TEST_F(WebRtcVideoChannelTest, TestSetSendRtcpReducedSize) {
deadbeef13871492015-12-09 12:37:51 -08004694 // Create stream, expecting that default mode is "compound".
4695 FakeVideoSendStream* stream1 = AddSendStream();
4696 EXPECT_EQ(webrtc::RtcpMode::kCompound, stream1->GetConfig().rtp.rtcp_mode);
Florent Castellidacec712018-05-24 16:24:21 +02004697 webrtc::RtpParameters rtp_parameters =
4698 channel_->GetRtpSendParameters(last_ssrc_);
4699 EXPECT_FALSE(rtp_parameters.rtcp.reduced_size);
deadbeef13871492015-12-09 12:37:51 -08004700
4701 // Now enable reduced size mode.
4702 send_parameters_.rtcp.reduced_size = true;
4703 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
4704 stream1 = fake_call_->GetVideoSendStreams()[0];
4705 EXPECT_EQ(webrtc::RtcpMode::kReducedSize, stream1->GetConfig().rtp.rtcp_mode);
Florent Castellidacec712018-05-24 16:24:21 +02004706 rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
4707 EXPECT_TRUE(rtp_parameters.rtcp.reduced_size);
deadbeef13871492015-12-09 12:37:51 -08004708
4709 // Create a new stream and ensure it picks up the reduced size mode.
4710 FakeVideoSendStream* stream2 = AddSendStream();
4711 EXPECT_EQ(webrtc::RtcpMode::kReducedSize, stream2->GetConfig().rtp.rtcp_mode);
4712}
4713
4714// This test verifies that the RTCP reduced size mode is properly applied to
4715// receive video streams.
eladalonf1841382017-06-12 01:16:46 -07004716TEST_F(WebRtcVideoChannelTest, TestSetRecvRtcpReducedSize) {
deadbeef13871492015-12-09 12:37:51 -08004717 // Create stream, expecting that default mode is "compound".
4718 FakeVideoReceiveStream* stream1 = AddRecvStream();
4719 EXPECT_EQ(webrtc::RtcpMode::kCompound, stream1->GetConfig().rtp.rtcp_mode);
4720
4721 // Now enable reduced size mode.
Taylor Brandstetter5f0b83b2016-03-18 15:02:07 -07004722 // TODO(deadbeef): Once "recv_parameters" becomes "receiver_parameters",
4723 // the reduced_size flag should come from that.
4724 send_parameters_.rtcp.reduced_size = true;
4725 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
deadbeef13871492015-12-09 12:37:51 -08004726 stream1 = fake_call_->GetVideoReceiveStreams()[0];
4727 EXPECT_EQ(webrtc::RtcpMode::kReducedSize, stream1->GetConfig().rtp.rtcp_mode);
4728
4729 // Create a new stream and ensure it picks up the reduced size mode.
4730 FakeVideoReceiveStream* stream2 = AddRecvStream();
4731 EXPECT_EQ(webrtc::RtcpMode::kReducedSize, stream2->GetConfig().rtp.rtcp_mode);
4732}
4733
eladalonf1841382017-06-12 01:16:46 -07004734TEST_F(WebRtcVideoChannelTest, OnReadyToSendSignalsNetworkState) {
skvlad7a43d252016-03-22 15:32:27 -07004735 EXPECT_EQ(webrtc::kNetworkUp,
4736 fake_call_->GetNetworkState(webrtc::MediaType::VIDEO));
4737 EXPECT_EQ(webrtc::kNetworkUp,
4738 fake_call_->GetNetworkState(webrtc::MediaType::AUDIO));
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00004739
4740 channel_->OnReadyToSend(false);
skvlad7a43d252016-03-22 15:32:27 -07004741 EXPECT_EQ(webrtc::kNetworkDown,
4742 fake_call_->GetNetworkState(webrtc::MediaType::VIDEO));
4743 EXPECT_EQ(webrtc::kNetworkUp,
4744 fake_call_->GetNetworkState(webrtc::MediaType::AUDIO));
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00004745
4746 channel_->OnReadyToSend(true);
skvlad7a43d252016-03-22 15:32:27 -07004747 EXPECT_EQ(webrtc::kNetworkUp,
4748 fake_call_->GetNetworkState(webrtc::MediaType::VIDEO));
4749 EXPECT_EQ(webrtc::kNetworkUp,
4750 fake_call_->GetNetworkState(webrtc::MediaType::AUDIO));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004751}
4752
eladalonf1841382017-06-12 01:16:46 -07004753TEST_F(WebRtcVideoChannelTest, GetStatsReportsSentCodecName) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004754 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004755 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004756 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Peter Boström74d9ed72015-03-26 16:28:31 +01004757
4758 AddSendStream();
4759
4760 cricket::VideoMediaInfo info;
4761 ASSERT_TRUE(channel_->GetStats(&info));
magjed509e4fe2016-11-18 01:34:11 -08004762 EXPECT_EQ("VP8", info.senders[0].codec_name);
Peter Boström74d9ed72015-03-26 16:28:31 +01004763}
4764
eladalonf1841382017-06-12 01:16:46 -07004765TEST_F(WebRtcVideoChannelTest, GetStatsReportsEncoderImplementationName) {
Peter Boströmb7d9a972015-12-18 16:01:11 +01004766 FakeVideoSendStream* stream = AddSendStream();
4767 webrtc::VideoSendStream::Stats stats;
4768 stats.encoder_implementation_name = "encoder_implementation_name";
4769 stream->SetStats(stats);
4770
4771 cricket::VideoMediaInfo info;
4772 ASSERT_TRUE(channel_->GetStats(&info));
4773 EXPECT_EQ(stats.encoder_implementation_name,
4774 info.senders[0].encoder_implementation_name);
4775}
4776
eladalonf1841382017-06-12 01:16:46 -07004777TEST_F(WebRtcVideoChannelTest, GetStatsReportsCpuOveruseMetrics) {
pbos@webrtc.org3e6e2712015-02-26 12:19:31 +00004778 FakeVideoSendStream* stream = AddSendStream();
4779 webrtc::VideoSendStream::Stats stats;
4780 stats.avg_encode_time_ms = 13;
4781 stats.encode_usage_percent = 42;
4782 stream->SetStats(stats);
4783
4784 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00004785 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org3e6e2712015-02-26 12:19:31 +00004786 EXPECT_EQ(stats.avg_encode_time_ms, info.senders[0].avg_encode_ms);
4787 EXPECT_EQ(stats.encode_usage_percent, info.senders[0].encode_usage_percent);
4788}
4789
eladalonf1841382017-06-12 01:16:46 -07004790TEST_F(WebRtcVideoChannelTest, GetStatsReportsFramesEncoded) {
sakal43536c32016-10-24 01:46:43 -07004791 FakeVideoSendStream* stream = AddSendStream();
4792 webrtc::VideoSendStream::Stats stats;
4793 stats.frames_encoded = 13;
4794 stream->SetStats(stats);
4795
4796 cricket::VideoMediaInfo info;
4797 ASSERT_TRUE(channel_->GetStats(&info));
4798 EXPECT_EQ(stats.frames_encoded, info.senders[0].frames_encoded);
4799}
4800
eladalonf1841382017-06-12 01:16:46 -07004801TEST_F(WebRtcVideoChannelTest, GetStatsReportsQpSum) {
sakal87da4042016-10-31 06:53:47 -07004802 FakeVideoSendStream* stream = AddSendStream();
4803 webrtc::VideoSendStream::Stats stats;
Oskar Sundbom78807582017-11-16 11:09:55 +01004804 stats.qp_sum = 13;
sakal87da4042016-10-31 06:53:47 -07004805 stream->SetStats(stats);
4806
4807 cricket::VideoMediaInfo info;
4808 ASSERT_TRUE(channel_->GetStats(&info));
4809 EXPECT_EQ(stats.qp_sum, info.senders[0].qp_sum);
4810}
4811
eladalonf1841382017-06-12 01:16:46 -07004812TEST_F(WebRtcVideoChannelTest, GetStatsReportsUpperResolution) {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00004813 FakeVideoSendStream* stream = AddSendStream();
4814 webrtc::VideoSendStream::Stats stats;
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00004815 stats.substreams[17].width = 123;
4816 stats.substreams[17].height = 40;
4817 stats.substreams[42].width = 80;
4818 stats.substreams[42].height = 31;
4819 stats.substreams[11].width = 20;
4820 stats.substreams[11].height = 90;
pbos@webrtc.org273a4142014-12-01 15:23:21 +00004821 stream->SetStats(stats);
4822
4823 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00004824 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org273a4142014-12-01 15:23:21 +00004825 ASSERT_EQ(1u, info.senders.size());
4826 EXPECT_EQ(123, info.senders[0].send_frame_width);
4827 EXPECT_EQ(90, info.senders[0].send_frame_height);
4828}
4829
eladalonf1841382017-06-12 01:16:46 -07004830TEST_F(WebRtcVideoChannelTest, GetStatsReportsCpuAdaptationStats) {
perkj803d97f2016-11-01 11:45:46 -07004831 FakeVideoSendStream* stream = AddSendStream();
4832 webrtc::VideoSendStream::Stats stats;
4833 stats.number_of_cpu_adapt_changes = 2;
4834 stats.cpu_limited_resolution = true;
4835 stream->SetStats(stats);
pbos@webrtc.org9a4410e2015-02-26 10:03:39 +00004836
pbos@webrtc.org9a4410e2015-02-26 10:03:39 +00004837 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00004838 EXPECT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org9a4410e2015-02-26 10:03:39 +00004839 ASSERT_EQ(1U, info.senders.size());
eladalonf1841382017-06-12 01:16:46 -07004840 EXPECT_EQ(WebRtcVideoChannel::ADAPTREASON_CPU, info.senders[0].adapt_reason);
perkj803d97f2016-11-01 11:45:46 -07004841 EXPECT_EQ(stats.number_of_cpu_adapt_changes, info.senders[0].adapt_changes);
pbos@webrtc.org9a4410e2015-02-26 10:03:39 +00004842}
4843
eladalonf1841382017-06-12 01:16:46 -07004844TEST_F(WebRtcVideoChannelTest, GetStatsReportsAdaptationAndBandwidthStats) {
perkj803d97f2016-11-01 11:45:46 -07004845 FakeVideoSendStream* stream = AddSendStream();
asapersson17821db2015-12-14 02:08:12 -08004846 webrtc::VideoSendStream::Stats stats;
perkj803d97f2016-11-01 11:45:46 -07004847 stats.number_of_cpu_adapt_changes = 2;
4848 stats.cpu_limited_resolution = true;
asapersson17821db2015-12-14 02:08:12 -08004849 stats.bw_limited_resolution = true;
perkj803d97f2016-11-01 11:45:46 -07004850 stream->SetStats(stats);
4851
4852 cricket::VideoMediaInfo info;
asapersson17821db2015-12-14 02:08:12 -08004853 EXPECT_TRUE(channel_->GetStats(&info));
4854 ASSERT_EQ(1U, info.senders.size());
eladalonf1841382017-06-12 01:16:46 -07004855 EXPECT_EQ(WebRtcVideoChannel::ADAPTREASON_CPU |
4856 WebRtcVideoChannel::ADAPTREASON_BANDWIDTH,
asapersson17821db2015-12-14 02:08:12 -08004857 info.senders[0].adapt_reason);
perkj803d97f2016-11-01 11:45:46 -07004858 EXPECT_EQ(stats.number_of_cpu_adapt_changes, info.senders[0].adapt_changes);
asapersson17821db2015-12-14 02:08:12 -08004859}
4860
eladalonf1841382017-06-12 01:16:46 -07004861TEST_F(WebRtcVideoChannelTest,
asapersson17821db2015-12-14 02:08:12 -08004862 GetStatsTranslatesBandwidthLimitedResolutionCorrectly) {
4863 FakeVideoSendStream* stream = AddSendStream();
4864 webrtc::VideoSendStream::Stats stats;
4865 stats.bw_limited_resolution = true;
4866 stream->SetStats(stats);
4867
4868 cricket::VideoMediaInfo info;
4869 EXPECT_TRUE(channel_->GetStats(&info));
4870 ASSERT_EQ(1U, info.senders.size());
eladalonf1841382017-06-12 01:16:46 -07004871 EXPECT_EQ(WebRtcVideoChannel::ADAPTREASON_BANDWIDTH,
asapersson17821db2015-12-14 02:08:12 -08004872 info.senders[0].adapt_reason);
4873}
4874
Yves Gerey665174f2018-06-19 15:03:05 +02004875TEST_F(WebRtcVideoChannelTest, GetStatsTranslatesSendRtcpPacketTypesCorrectly) {
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00004876 FakeVideoSendStream* stream = AddSendStream();
4877 webrtc::VideoSendStream::Stats stats;
4878 stats.substreams[17].rtcp_packet_type_counts.fir_packets = 2;
4879 stats.substreams[17].rtcp_packet_type_counts.nack_packets = 3;
4880 stats.substreams[17].rtcp_packet_type_counts.pli_packets = 4;
4881
4882 stats.substreams[42].rtcp_packet_type_counts.fir_packets = 5;
4883 stats.substreams[42].rtcp_packet_type_counts.nack_packets = 7;
4884 stats.substreams[42].rtcp_packet_type_counts.pli_packets = 9;
4885
4886 stream->SetStats(stats);
4887
4888 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00004889 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00004890 EXPECT_EQ(7, info.senders[0].firs_rcvd);
4891 EXPECT_EQ(10, info.senders[0].nacks_rcvd);
4892 EXPECT_EQ(13, info.senders[0].plis_rcvd);
4893}
4894
eladalonf1841382017-06-12 01:16:46 -07004895TEST_F(WebRtcVideoChannelTest,
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00004896 GetStatsTranslatesReceiveRtcpPacketTypesCorrectly) {
4897 FakeVideoReceiveStream* stream = AddRecvStream();
4898 webrtc::VideoReceiveStream::Stats stats;
4899 stats.rtcp_packet_type_counts.fir_packets = 2;
4900 stats.rtcp_packet_type_counts.nack_packets = 3;
4901 stats.rtcp_packet_type_counts.pli_packets = 4;
4902 stream->SetStats(stats);
4903
4904 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00004905 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00004906 EXPECT_EQ(stats.rtcp_packet_type_counts.fir_packets,
Mirko Bonadeif859e552018-05-30 15:31:29 +02004907 rtc::checked_cast<unsigned int>(info.receivers[0].firs_sent));
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00004908 EXPECT_EQ(stats.rtcp_packet_type_counts.nack_packets,
Mirko Bonadeif859e552018-05-30 15:31:29 +02004909 rtc::checked_cast<unsigned int>(info.receivers[0].nacks_sent));
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00004910 EXPECT_EQ(stats.rtcp_packet_type_counts.pli_packets,
Mirko Bonadeif859e552018-05-30 15:31:29 +02004911 rtc::checked_cast<unsigned int>(info.receivers[0].plis_sent));
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00004912}
4913
eladalonf1841382017-06-12 01:16:46 -07004914TEST_F(WebRtcVideoChannelTest, GetStatsTranslatesDecodeStatsCorrectly) {
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00004915 FakeVideoReceiveStream* stream = AddRecvStream();
4916 webrtc::VideoReceiveStream::Stats stats;
Peter Boströmb7d9a972015-12-18 16:01:11 +01004917 stats.decoder_implementation_name = "decoder_implementation_name";
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00004918 stats.decode_ms = 2;
4919 stats.max_decode_ms = 3;
4920 stats.current_delay_ms = 4;
4921 stats.target_delay_ms = 5;
4922 stats.jitter_buffer_ms = 6;
4923 stats.min_playout_delay_ms = 7;
4924 stats.render_delay_ms = 8;
asapersson26dd92b2016-08-30 00:45:45 -07004925 stats.width = 9;
4926 stats.height = 10;
hbos42f6d2f2017-01-20 03:56:50 -08004927 stats.frame_counts.key_frames = 11;
4928 stats.frame_counts.delta_frames = 12;
hbos50cfe1f2017-01-23 07:21:55 -08004929 stats.frames_rendered = 13;
4930 stats.frames_decoded = 14;
Oskar Sundbom78807582017-11-16 11:09:55 +01004931 stats.qp_sum = 15;
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00004932 stream->SetStats(stats);
4933
4934 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00004935 ASSERT_TRUE(channel_->GetStats(&info));
Peter Boströmb7d9a972015-12-18 16:01:11 +01004936 EXPECT_EQ(stats.decoder_implementation_name,
4937 info.receivers[0].decoder_implementation_name);
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00004938 EXPECT_EQ(stats.decode_ms, info.receivers[0].decode_ms);
4939 EXPECT_EQ(stats.max_decode_ms, info.receivers[0].max_decode_ms);
4940 EXPECT_EQ(stats.current_delay_ms, info.receivers[0].current_delay_ms);
4941 EXPECT_EQ(stats.target_delay_ms, info.receivers[0].target_delay_ms);
4942 EXPECT_EQ(stats.jitter_buffer_ms, info.receivers[0].jitter_buffer_ms);
4943 EXPECT_EQ(stats.min_playout_delay_ms, info.receivers[0].min_playout_delay_ms);
4944 EXPECT_EQ(stats.render_delay_ms, info.receivers[0].render_delay_ms);
asapersson26dd92b2016-08-30 00:45:45 -07004945 EXPECT_EQ(stats.width, info.receivers[0].frame_width);
4946 EXPECT_EQ(stats.height, info.receivers[0].frame_height);
Mirko Bonadeif859e552018-05-30 15:31:29 +02004947 EXPECT_EQ(rtc::checked_cast<unsigned int>(stats.frame_counts.key_frames +
4948 stats.frame_counts.delta_frames),
hbos42f6d2f2017-01-20 03:56:50 -08004949 info.receivers[0].frames_received);
hbos50cfe1f2017-01-23 07:21:55 -08004950 EXPECT_EQ(stats.frames_rendered, info.receivers[0].frames_rendered);
sakale5ba44e2016-10-26 07:09:24 -07004951 EXPECT_EQ(stats.frames_decoded, info.receivers[0].frames_decoded);
sakalcc452e12017-02-09 04:53:45 -08004952 EXPECT_EQ(stats.qp_sum, info.receivers[0].qp_sum);
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00004953}
4954
eladalonf1841382017-06-12 01:16:46 -07004955TEST_F(WebRtcVideoChannelTest, GetStatsTranslatesReceivePacketStatsCorrectly) {
Peter Boström393347f2015-04-22 14:52:45 +02004956 FakeVideoReceiveStream* stream = AddRecvStream();
4957 webrtc::VideoReceiveStream::Stats stats;
4958 stats.rtp_stats.transmitted.payload_bytes = 2;
4959 stats.rtp_stats.transmitted.header_bytes = 3;
4960 stats.rtp_stats.transmitted.padding_bytes = 4;
4961 stats.rtp_stats.transmitted.packets = 5;
srte186d9c32017-08-04 05:03:53 -07004962 stats.rtcp_stats.packets_lost = 6;
Peter Boström393347f2015-04-22 14:52:45 +02004963 stats.rtcp_stats.fraction_lost = 7;
4964 stream->SetStats(stats);
4965
4966 cricket::VideoMediaInfo info;
4967 ASSERT_TRUE(channel_->GetStats(&info));
4968 EXPECT_EQ(stats.rtp_stats.transmitted.payload_bytes +
4969 stats.rtp_stats.transmitted.header_bytes +
4970 stats.rtp_stats.transmitted.padding_bytes,
Mirko Bonadeif859e552018-05-30 15:31:29 +02004971 rtc::checked_cast<size_t>(info.receivers[0].bytes_rcvd));
Peter Boström393347f2015-04-22 14:52:45 +02004972 EXPECT_EQ(stats.rtp_stats.transmitted.packets,
Mirko Bonadeif859e552018-05-30 15:31:29 +02004973 rtc::checked_cast<unsigned int>(info.receivers[0].packets_rcvd));
srte186d9c32017-08-04 05:03:53 -07004974 EXPECT_EQ(stats.rtcp_stats.packets_lost, info.receivers[0].packets_lost);
Mirko Bonadeif859e552018-05-30 15:31:29 +02004975 EXPECT_EQ(rtc::checked_cast<float>(stats.rtcp_stats.fraction_lost) / (1 << 8),
Peter Boström393347f2015-04-22 14:52:45 +02004976 info.receivers[0].fraction_lost);
4977}
4978
eladalonf1841382017-06-12 01:16:46 -07004979TEST_F(WebRtcVideoChannelTest, TranslatesCallStatsCorrectly) {
pbos@webrtc.org2b19f062014-12-11 13:26:09 +00004980 AddSendStream();
4981 AddSendStream();
4982 webrtc::Call::Stats stats;
4983 stats.rtt_ms = 123;
4984 fake_call_->SetStats(stats);
4985
4986 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00004987 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org2b19f062014-12-11 13:26:09 +00004988 ASSERT_EQ(2u, info.senders.size());
4989 EXPECT_EQ(stats.rtt_ms, info.senders[0].rtt_ms);
4990 EXPECT_EQ(stats.rtt_ms, info.senders[1].rtt_ms);
4991}
4992
eladalonf1841382017-06-12 01:16:46 -07004993TEST_F(WebRtcVideoChannelTest, TranslatesSenderBitrateStatsCorrectly) {
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00004994 FakeVideoSendStream* stream = AddSendStream();
4995 webrtc::VideoSendStream::Stats stats;
pbos@webrtc.org891d4832015-02-26 13:15:22 +00004996 stats.target_media_bitrate_bps = 156;
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00004997 stats.media_bitrate_bps = 123;
4998 stats.substreams[17].total_bitrate_bps = 1;
4999 stats.substreams[17].retransmit_bitrate_bps = 2;
5000 stats.substreams[42].total_bitrate_bps = 3;
5001 stats.substreams[42].retransmit_bitrate_bps = 4;
5002 stream->SetStats(stats);
5003
5004 FakeVideoSendStream* stream2 = AddSendStream();
5005 webrtc::VideoSendStream::Stats stats2;
pbos@webrtc.org891d4832015-02-26 13:15:22 +00005006 stats2.target_media_bitrate_bps = 200;
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00005007 stats2.media_bitrate_bps = 321;
5008 stats2.substreams[13].total_bitrate_bps = 5;
5009 stats2.substreams[13].retransmit_bitrate_bps = 6;
5010 stats2.substreams[21].total_bitrate_bps = 7;
5011 stats2.substreams[21].retransmit_bitrate_bps = 8;
5012 stream2->SetStats(stats2);
5013
5014 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00005015 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00005016 ASSERT_EQ(2u, info.senders.size());
stefanf79ade12017-06-02 06:44:03 -07005017 BandwidthEstimationInfo bwe_info;
5018 channel_->FillBitrateInfo(&bwe_info);
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00005019 // Assuming stream and stream2 corresponds to senders[0] and [1] respectively
5020 // is OK as std::maps are sorted and AddSendStream() gives increasing SSRCs.
5021 EXPECT_EQ(stats.media_bitrate_bps, info.senders[0].nominal_bitrate);
5022 EXPECT_EQ(stats2.media_bitrate_bps, info.senders[1].nominal_bitrate);
pbos@webrtc.org891d4832015-02-26 13:15:22 +00005023 EXPECT_EQ(stats.target_media_bitrate_bps + stats2.target_media_bitrate_bps,
stefanf79ade12017-06-02 06:44:03 -07005024 bwe_info.target_enc_bitrate);
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00005025 EXPECT_EQ(stats.media_bitrate_bps + stats2.media_bitrate_bps,
stefanf79ade12017-06-02 06:44:03 -07005026 bwe_info.actual_enc_bitrate);
5027 EXPECT_EQ(1 + 3 + 5 + 7, bwe_info.transmit_bitrate)
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00005028 << "Bandwidth stats should take all streams into account.";
stefanf79ade12017-06-02 06:44:03 -07005029 EXPECT_EQ(2 + 4 + 6 + 8, bwe_info.retransmit_bitrate)
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00005030 << "Bandwidth stats should take all streams into account.";
5031}
5032
eladalonf1841382017-06-12 01:16:46 -07005033TEST_F(WebRtcVideoChannelTest, DefaultReceiveStreamReconfiguresToUseRtx) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02005034 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orga2a6fe62015-03-06 15:35:19 +00005035
Peter Boström0c4e06b2015-10-07 12:23:21 +02005036 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
5037 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
pbos@webrtc.orga2a6fe62015-03-06 15:35:19 +00005038
5039 ASSERT_EQ(0u, fake_call_->GetVideoReceiveStreams().size());
5040 const size_t kDataLength = 12;
5041 uint8_t data[kDataLength];
5042 memset(data, 0, sizeof(data));
5043 rtc::SetBE32(&data[8], ssrcs[0]);
jbaucheec21bd2016-03-20 06:15:43 -07005044 rtc::CopyOnWriteBuffer packet(data, kDataLength);
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07005045 channel_->OnPacketReceived(packet, /* packet_time_us */ -1);
pbos@webrtc.orga2a6fe62015-03-06 15:35:19 +00005046
5047 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size())
5048 << "No default receive stream created.";
5049 FakeVideoReceiveStream* recv_stream = fake_call_->GetVideoReceiveStreams()[0];
brandtr14742122017-01-27 04:53:07 -08005050 EXPECT_EQ(0u, recv_stream->GetConfig().rtp.rtx_ssrc)
pbos@webrtc.orga2a6fe62015-03-06 15:35:19 +00005051 << "Default receive stream should not have configured RTX";
5052
5053 EXPECT_TRUE(channel_->AddRecvStream(
5054 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs)));
5055 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size())
brandtr14742122017-01-27 04:53:07 -08005056 << "AddRecvStream should have reconfigured, not added a new receiver.";
pbos@webrtc.orga2a6fe62015-03-06 15:35:19 +00005057 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
nisse26e3abb2017-08-25 04:44:25 -07005058 EXPECT_FALSE(
5059 recv_stream->GetConfig().rtp.rtx_associated_payload_types.empty());
nisseca5706d2017-09-11 02:32:16 -07005060 EXPECT_TRUE(VerifyRtxReceiveAssociations(recv_stream->GetConfig()))
Peter Boströmd8b01092016-05-12 16:44:36 +02005061 << "RTX should be mapped for all decoders/payload types.";
nisseca5706d2017-09-11 02:32:16 -07005062 EXPECT_TRUE(HasRtxReceiveAssociation(recv_stream->GetConfig(),
Yves Gerey665174f2018-06-19 15:03:05 +02005063 GetEngineCodec("red").id))
nisseca5706d2017-09-11 02:32:16 -07005064 << "RTX should be mapped also for the RED payload type";
brandtr14742122017-01-27 04:53:07 -08005065 EXPECT_EQ(rtx_ssrcs[0], recv_stream->GetConfig().rtp.rtx_ssrc);
pbos@webrtc.orga2a6fe62015-03-06 15:35:19 +00005066}
5067
eladalonf1841382017-06-12 01:16:46 -07005068TEST_F(WebRtcVideoChannelTest, RejectsAddingStreamsWithMissingSsrcsForRtx) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02005069 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Peter Boströmd4362cd2015-03-25 14:17:23 +01005070
Peter Boström0c4e06b2015-10-07 12:23:21 +02005071 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
5072 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
Peter Boströmd4362cd2015-03-25 14:17:23 +01005073
5074 StreamParams sp =
5075 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs);
5076 sp.ssrcs = ssrcs; // Without RTXs, this is the important part.
5077
5078 EXPECT_FALSE(channel_->AddSendStream(sp));
5079 EXPECT_FALSE(channel_->AddRecvStream(sp));
5080}
5081
eladalonf1841382017-06-12 01:16:46 -07005082TEST_F(WebRtcVideoChannelTest, RejectsAddingStreamsWithOverlappingRtxSsrcs) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02005083 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Peter Boströmd6f4c252015-03-26 16:23:04 +01005084
Peter Boström0c4e06b2015-10-07 12:23:21 +02005085 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
5086 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
Peter Boströmd6f4c252015-03-26 16:23:04 +01005087
5088 StreamParams sp =
5089 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs);
5090
5091 EXPECT_TRUE(channel_->AddSendStream(sp));
5092 EXPECT_TRUE(channel_->AddRecvStream(sp));
5093
5094 // The RTX SSRC is already used in previous streams, using it should fail.
5095 sp = cricket::StreamParams::CreateLegacy(rtx_ssrcs[0]);
5096 EXPECT_FALSE(channel_->AddSendStream(sp));
5097 EXPECT_FALSE(channel_->AddRecvStream(sp));
5098
5099 // After removing the original stream this should be fine to add (makes sure
5100 // that RTX ssrcs are not forever taken).
5101 EXPECT_TRUE(channel_->RemoveSendStream(ssrcs[0]));
5102 EXPECT_TRUE(channel_->RemoveRecvStream(ssrcs[0]));
5103 EXPECT_TRUE(channel_->AddSendStream(sp));
5104 EXPECT_TRUE(channel_->AddRecvStream(sp));
5105}
5106
eladalonf1841382017-06-12 01:16:46 -07005107TEST_F(WebRtcVideoChannelTest,
Peter Boströmd6f4c252015-03-26 16:23:04 +01005108 RejectsAddingStreamsWithOverlappingSimulcastSsrcs) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02005109 static const uint32_t kFirstStreamSsrcs[] = {1, 2, 3};
5110 static const uint32_t kOverlappingStreamSsrcs[] = {4, 3, 5};
Fredrik Solenbergb071a192015-09-17 16:42:56 +02005111 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Peter Boströmd6f4c252015-03-26 16:23:04 +01005112
Peter Boströmd6f4c252015-03-26 16:23:04 +01005113 StreamParams sp =
5114 cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kFirstStreamSsrcs));
5115
5116 EXPECT_TRUE(channel_->AddSendStream(sp));
5117 EXPECT_TRUE(channel_->AddRecvStream(sp));
5118
5119 // One of the SSRCs is already used in previous streams, using it should fail.
5120 sp = cricket::CreateSimStreamParams("cname",
5121 MAKE_VECTOR(kOverlappingStreamSsrcs));
5122 EXPECT_FALSE(channel_->AddSendStream(sp));
5123 EXPECT_FALSE(channel_->AddRecvStream(sp));
5124
5125 // After removing the original stream this should be fine to add (makes sure
5126 // that RTX ssrcs are not forever taken).
Peter Boström3548dd22015-05-22 18:48:36 +02005127 EXPECT_TRUE(channel_->RemoveSendStream(kFirstStreamSsrcs[0]));
5128 EXPECT_TRUE(channel_->RemoveRecvStream(kFirstStreamSsrcs[0]));
Peter Boströmd6f4c252015-03-26 16:23:04 +01005129 EXPECT_TRUE(channel_->AddSendStream(sp));
5130 EXPECT_TRUE(channel_->AddRecvStream(sp));
5131}
5132
eladalonf1841382017-06-12 01:16:46 -07005133TEST_F(WebRtcVideoChannelTest, ReportsSsrcGroupsInStats) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02005134 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Peter Boström259bd202015-05-28 13:39:50 +02005135
5136 static const uint32_t kSenderSsrcs[] = {4, 7, 10};
5137 static const uint32_t kSenderRtxSsrcs[] = {5, 8, 11};
5138
5139 StreamParams sender_sp = cricket::CreateSimWithRtxStreamParams(
5140 "cname", MAKE_VECTOR(kSenderSsrcs), MAKE_VECTOR(kSenderRtxSsrcs));
5141
5142 EXPECT_TRUE(channel_->AddSendStream(sender_sp));
5143
5144 static const uint32_t kReceiverSsrcs[] = {3};
5145 static const uint32_t kReceiverRtxSsrcs[] = {2};
5146
5147 StreamParams receiver_sp = cricket::CreateSimWithRtxStreamParams(
5148 "cname", MAKE_VECTOR(kReceiverSsrcs), MAKE_VECTOR(kReceiverRtxSsrcs));
5149 EXPECT_TRUE(channel_->AddRecvStream(receiver_sp));
5150
5151 cricket::VideoMediaInfo info;
5152 ASSERT_TRUE(channel_->GetStats(&info));
5153
5154 ASSERT_EQ(1u, info.senders.size());
5155 ASSERT_EQ(1u, info.receivers.size());
5156
5157 EXPECT_NE(sender_sp.ssrc_groups, receiver_sp.ssrc_groups);
5158 EXPECT_EQ(sender_sp.ssrc_groups, info.senders[0].ssrc_groups);
5159 EXPECT_EQ(receiver_sp.ssrc_groups, info.receivers[0].ssrc_groups);
5160}
5161
eladalonf1841382017-06-12 01:16:46 -07005162TEST_F(WebRtcVideoChannelTest, MapsReceivedPayloadTypeToCodecName) {
pbosf42376c2015-08-28 07:35:32 -07005163 FakeVideoReceiveStream* stream = AddRecvStream();
5164 webrtc::VideoReceiveStream::Stats stats;
5165 cricket::VideoMediaInfo info;
5166
5167 // Report no codec name before receiving.
5168 stream->SetStats(stats);
5169 ASSERT_TRUE(channel_->GetStats(&info));
5170 EXPECT_STREQ("", info.receivers[0].codec_name.c_str());
5171
5172 // Report VP8 if we're receiving it.
magjed509e4fe2016-11-18 01:34:11 -08005173 stats.current_payload_type = GetEngineCodec("VP8").id;
pbosf42376c2015-08-28 07:35:32 -07005174 stream->SetStats(stats);
5175 ASSERT_TRUE(channel_->GetStats(&info));
5176 EXPECT_STREQ(kVp8CodecName, info.receivers[0].codec_name.c_str());
5177
5178 // Report no codec name for unknown playload types.
5179 stats.current_payload_type = 3;
5180 stream->SetStats(stats);
5181 ASSERT_TRUE(channel_->GetStats(&info));
5182 EXPECT_STREQ("", info.receivers[0].codec_name.c_str());
5183}
5184
Seth Hampson5897a6e2018-04-03 11:16:33 -07005185// Tests that when we add a stream without SSRCs, but contains a stream_id
5186// that it is stored and its stream id is later used when the first packet
5187// arrives to properly create a receive stream with a sync label.
5188TEST_F(WebRtcVideoChannelTest, RecvUnsignaledSsrcWithSignaledStreamId) {
5189 const char kSyncLabel[] = "sync_label";
5190 cricket::StreamParams unsignaled_stream;
5191 unsignaled_stream.set_stream_ids({kSyncLabel});
5192 ASSERT_TRUE(channel_->AddRecvStream(unsignaled_stream));
5193 // The stream shouldn't have been created at this point because it doesn't
5194 // have any SSRCs.
Mirko Bonadeif859e552018-05-30 15:31:29 +02005195 EXPECT_EQ(0u, fake_call_->GetVideoReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07005196
5197 // Create and deliver packet.
5198 const size_t kDataLength = 12;
5199 uint8_t data[kDataLength];
5200 memset(data, 0, sizeof(data));
5201 rtc::SetBE32(&data[8], kIncomingUnsignalledSsrc);
5202 rtc::CopyOnWriteBuffer packet(data, kDataLength);
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07005203 channel_->OnPacketReceived(packet, /* packet_time_us */ -1);
Seth Hampson5897a6e2018-04-03 11:16:33 -07005204
5205 // The stream should now be created with the appropriate sync label.
5206 EXPECT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
5207 EXPECT_EQ(kSyncLabel,
5208 fake_call_->GetVideoReceiveStreams()[0]->GetConfig().sync_group);
5209
5210 // Removing the unsignaled stream should clear the cache. This time when
5211 // a default video receive stream is created it won't have a sync_group.
5212 ASSERT_TRUE(channel_->RemoveRecvStream(0));
5213 ASSERT_TRUE(channel_->RemoveRecvStream(kIncomingUnsignalledSsrc));
5214 EXPECT_EQ(0u, fake_call_->GetVideoReceiveStreams().size());
5215
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07005216 channel_->OnPacketReceived(packet, /* packet_time_us */ -1);
Seth Hampson5897a6e2018-04-03 11:16:33 -07005217 EXPECT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
5218 EXPECT_TRUE(
5219 fake_call_->GetVideoReceiveStreams()[0]->GetConfig().sync_group.empty());
5220}
5221
Ruslan Burakov493a6502019-02-27 15:32:48 +01005222// Test BaseMinimumPlayoutDelayMs on receive streams.
5223TEST_F(WebRtcVideoChannelTest, BaseMinimumPlayoutDelayMs) {
5224 // Test that set won't work for non-existing receive streams.
5225 EXPECT_FALSE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrc + 2, 200));
5226 // Test that get won't work for non-existing receive streams.
5227 EXPECT_FALSE(channel_->GetBaseMinimumPlayoutDelayMs(kSsrc + 2));
5228
5229 EXPECT_TRUE(AddRecvStream());
5230 // Test that set works for the existing receive stream.
5231 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(last_ssrc_, 200));
5232 auto* recv_stream = fake_call_->GetVideoReceiveStream(last_ssrc_);
5233 EXPECT_TRUE(recv_stream);
5234 EXPECT_EQ(recv_stream->base_mininum_playout_delay_ms(), 200);
5235 EXPECT_EQ(channel_->GetBaseMinimumPlayoutDelayMs(last_ssrc_).value_or(0),
5236 200);
5237}
5238
5239// Test BaseMinimumPlayoutDelayMs on unsignaled receive streams.
5240TEST_F(WebRtcVideoChannelTest, BaseMinimumPlayoutDelayMsUnsignaledRecvStream) {
5241 absl::optional<int> delay_ms;
5242 const FakeVideoReceiveStream* recv_stream;
5243
5244 // Set default stream with SSRC 0
5245 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(0, 200));
5246 EXPECT_EQ(200, channel_->GetBaseMinimumPlayoutDelayMs(0).value_or(0));
5247
5248 // Spawn an unsignaled stream by sending a packet, it should inherit
5249 // default delay 200.
5250 const size_t kDataLength = 12;
5251 uint8_t data[kDataLength];
5252 memset(data, 0, sizeof(data));
5253 rtc::SetBE32(&data[8], kIncomingUnsignalledSsrc);
5254 rtc::CopyOnWriteBuffer packet(data, kDataLength);
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07005255 channel_->OnPacketReceived(packet, /* packet_time_us */ -1);
Ruslan Burakov493a6502019-02-27 15:32:48 +01005256
5257 recv_stream = fake_call_->GetVideoReceiveStream(kIncomingUnsignalledSsrc);
5258 EXPECT_EQ(recv_stream->base_mininum_playout_delay_ms(), 200);
5259 delay_ms = channel_->GetBaseMinimumPlayoutDelayMs(kIncomingUnsignalledSsrc);
5260 EXPECT_EQ(200, delay_ms.value_or(0));
5261
5262 // Check that now if we change delay for SSRC 0 it will change delay for the
5263 // default receiving stream as well.
5264 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(0, 300));
5265 EXPECT_EQ(300, channel_->GetBaseMinimumPlayoutDelayMs(0).value_or(0));
5266 delay_ms = channel_->GetBaseMinimumPlayoutDelayMs(kIncomingUnsignalledSsrc);
5267 EXPECT_EQ(300, delay_ms.value_or(0));
5268 recv_stream = fake_call_->GetVideoReceiveStream(kIncomingUnsignalledSsrc);
5269 EXPECT_EQ(recv_stream->base_mininum_playout_delay_ms(), 300);
5270}
5271
eladalonf1841382017-06-12 01:16:46 -07005272void WebRtcVideoChannelTest::TestReceiveUnsignaledSsrcPacket(
noahricd10a68e2015-07-10 11:27:55 -07005273 uint8_t payload_type,
5274 bool expect_created_receive_stream) {
magjed509e4fe2016-11-18 01:34:11 -08005275 // kRedRtxPayloadType must currently be unused.
5276 EXPECT_FALSE(FindCodecById(engine_.codecs(), kRedRtxPayloadType));
5277
noahricd10a68e2015-07-10 11:27:55 -07005278 // Add a RED RTX codec.
5279 VideoCodec red_rtx_codec =
magjed509e4fe2016-11-18 01:34:11 -08005280 VideoCodec::CreateRtxCodec(kRedRtxPayloadType, GetEngineCodec("red").id);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02005281 recv_parameters_.codecs.push_back(red_rtx_codec);
5282 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
noahricd10a68e2015-07-10 11:27:55 -07005283
5284 ASSERT_EQ(0u, fake_call_->GetVideoReceiveStreams().size());
5285 const size_t kDataLength = 12;
5286 uint8_t data[kDataLength];
5287 memset(data, 0, sizeof(data));
5288
5289 rtc::Set8(data, 1, payload_type);
5290 rtc::SetBE32(&data[8], kIncomingUnsignalledSsrc);
jbaucheec21bd2016-03-20 06:15:43 -07005291 rtc::CopyOnWriteBuffer packet(data, kDataLength);
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07005292 channel_->OnPacketReceived(packet, /* packet_time_us */ -1);
noahricd10a68e2015-07-10 11:27:55 -07005293
5294 if (expect_created_receive_stream) {
5295 EXPECT_EQ(1u, fake_call_->GetVideoReceiveStreams().size())
5296 << "Should have created a receive stream for payload type: "
5297 << payload_type;
5298 } else {
5299 EXPECT_EQ(0u, fake_call_->GetVideoReceiveStreams().size())
5300 << "Shouldn't have created a receive stream for payload type: "
5301 << payload_type;
5302 }
5303}
5304
Åsa Persson2c7149b2018-10-15 09:36:10 +02005305class WebRtcVideoChannelDiscardUnknownSsrcTest : public WebRtcVideoChannelTest {
5306 public:
5307 WebRtcVideoChannelDiscardUnknownSsrcTest()
5308 : WebRtcVideoChannelTest(
5309 "WebRTC-Video-DiscardPacketsWithUnknownSsrc/Enabled/") {}
5310};
5311
5312TEST_F(WebRtcVideoChannelDiscardUnknownSsrcTest, NoUnsignalledStreamCreated) {
5313 TestReceiveUnsignaledSsrcPacket(GetEngineCodec("VP8").id,
5314 false /* expect_created_receive_stream */);
5315}
5316
eladalonf1841382017-06-12 01:16:46 -07005317TEST_F(WebRtcVideoChannelTest, Vp8PacketCreatesUnsignalledStream) {
magjed509e4fe2016-11-18 01:34:11 -08005318 TestReceiveUnsignaledSsrcPacket(GetEngineCodec("VP8").id,
5319 true /* expect_created_receive_stream */);
noahricd10a68e2015-07-10 11:27:55 -07005320}
5321
eladalonf1841382017-06-12 01:16:46 -07005322TEST_F(WebRtcVideoChannelTest, Vp9PacketCreatesUnsignalledStream) {
magjed509e4fe2016-11-18 01:34:11 -08005323 TestReceiveUnsignaledSsrcPacket(GetEngineCodec("VP9").id,
5324 true /* expect_created_receive_stream */);
noahricd10a68e2015-07-10 11:27:55 -07005325}
5326
eladalonf1841382017-06-12 01:16:46 -07005327TEST_F(WebRtcVideoChannelTest, RtxPacketDoesntCreateUnsignalledStream) {
Anders Carlsson5f2bb622018-05-14 09:48:06 +02005328 AssignDefaultAptRtxTypes();
magjed509e4fe2016-11-18 01:34:11 -08005329 const cricket::VideoCodec vp8 = GetEngineCodec("VP8");
5330 const int rtx_vp8_payload_type = default_apt_rtx_types_[vp8.id];
5331 TestReceiveUnsignaledSsrcPacket(rtx_vp8_payload_type,
5332 false /* expect_created_receive_stream */);
noahricd10a68e2015-07-10 11:27:55 -07005333}
5334
eladalonf1841382017-06-12 01:16:46 -07005335TEST_F(WebRtcVideoChannelTest, UlpfecPacketDoesntCreateUnsignalledStream) {
magjed509e4fe2016-11-18 01:34:11 -08005336 TestReceiveUnsignaledSsrcPacket(GetEngineCodec("ulpfec").id,
5337 false /* expect_created_receive_stream */);
noahricd10a68e2015-07-10 11:27:55 -07005338}
5339
eladalonf1841382017-06-12 01:16:46 -07005340TEST_F(WebRtcVideoChannelFlexfecRecvTest,
brandtr468da7c2016-11-22 02:16:47 -08005341 FlexfecPacketDoesntCreateUnsignalledStream) {
5342 TestReceiveUnsignaledSsrcPacket(GetEngineCodec("flexfec-03").id,
5343 false /* expect_created_receive_stream */);
5344}
5345
eladalonf1841382017-06-12 01:16:46 -07005346TEST_F(WebRtcVideoChannelTest, RedRtxPacketDoesntCreateUnsignalledStream) {
magjed509e4fe2016-11-18 01:34:11 -08005347 TestReceiveUnsignaledSsrcPacket(kRedRtxPayloadType,
5348 false /* expect_created_receive_stream */);
noahricd10a68e2015-07-10 11:27:55 -07005349}
5350
mzanaty8a855d62017-02-17 15:46:43 -08005351// Test that receiving any unsignalled SSRC works even if it changes.
5352// The first unsignalled SSRC received will create a default receive stream.
5353// Any different unsignalled SSRC received will replace the default.
eladalonf1841382017-06-12 01:16:46 -07005354TEST_F(WebRtcVideoChannelTest, ReceiveDifferentUnsignaledSsrc) {
mzanaty8a855d62017-02-17 15:46:43 -08005355 // Allow receiving VP8, VP9, H264 (if enabled).
5356 cricket::VideoRecvParameters parameters;
5357 parameters.codecs.push_back(GetEngineCodec("VP8"));
5358 parameters.codecs.push_back(GetEngineCodec("VP9"));
5359
5360#if defined(WEBRTC_USE_H264)
5361 cricket::VideoCodec H264codec(126, "H264");
5362 parameters.codecs.push_back(H264codec);
5363#endif
5364
5365 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
5366 // No receive streams yet.
5367 ASSERT_EQ(0u, fake_call_->GetVideoReceiveStreams().size());
5368 cricket::FakeVideoRenderer renderer;
5369 EXPECT_TRUE(channel_->SetSink(kDefaultRecvSsrc, &renderer));
5370
5371 // Receive VP8 packet on first SSRC.
5372 uint8_t data[kMinRtpPacketLen];
5373 cricket::RtpHeader rtpHeader;
5374 rtpHeader.payload_type = GetEngineCodec("VP8").id;
5375 rtpHeader.seq_num = rtpHeader.timestamp = 0;
Yves Gerey665174f2018-06-19 15:03:05 +02005376 rtpHeader.ssrc = kIncomingUnsignalledSsrc + 1;
mzanaty8a855d62017-02-17 15:46:43 -08005377 cricket::SetRtpHeader(data, sizeof(data), rtpHeader);
5378 rtc::CopyOnWriteBuffer packet(data, sizeof(data));
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07005379 channel_->OnPacketReceived(packet, /* packet_time_us */ -1);
mzanaty8a855d62017-02-17 15:46:43 -08005380 // VP8 packet should create default receive stream.
5381 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02005382 FakeVideoReceiveStream* recv_stream = fake_call_->GetVideoReceiveStreams()[0];
mzanaty8a855d62017-02-17 15:46:43 -08005383 EXPECT_EQ(rtpHeader.ssrc, recv_stream->GetConfig().rtp.remote_ssrc);
5384 // Verify that the receive stream sinks to a renderer.
Artem Titov1ebfb6a2019-01-03 23:49:37 +01005385 webrtc::VideoFrame video_frame =
5386 webrtc::VideoFrame::Builder()
5387 .set_video_frame_buffer(CreateBlackFrameBuffer(4, 4))
5388 .set_timestamp_rtp(100)
5389 .set_timestamp_us(0)
5390 .set_rotation(webrtc::kVideoRotation_0)
5391 .build();
mzanaty8a855d62017-02-17 15:46:43 -08005392 recv_stream->InjectFrame(video_frame);
5393 EXPECT_EQ(1, renderer.num_rendered_frames());
5394
5395 // Receive VP9 packet on second SSRC.
5396 rtpHeader.payload_type = GetEngineCodec("VP9").id;
Yves Gerey665174f2018-06-19 15:03:05 +02005397 rtpHeader.ssrc = kIncomingUnsignalledSsrc + 2;
mzanaty8a855d62017-02-17 15:46:43 -08005398 cricket::SetRtpHeader(data, sizeof(data), rtpHeader);
5399 rtc::CopyOnWriteBuffer packet2(data, sizeof(data));
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07005400 channel_->OnPacketReceived(packet2, /* packet_time_us */ -1);
mzanaty8a855d62017-02-17 15:46:43 -08005401 // VP9 packet should replace the default receive SSRC.
5402 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
5403 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
5404 EXPECT_EQ(rtpHeader.ssrc, recv_stream->GetConfig().rtp.remote_ssrc);
5405 // Verify that the receive stream sinks to a renderer.
Artem Titov1ebfb6a2019-01-03 23:49:37 +01005406 webrtc::VideoFrame video_frame2 =
5407 webrtc::VideoFrame::Builder()
5408 .set_video_frame_buffer(CreateBlackFrameBuffer(4, 4))
5409 .set_timestamp_rtp(200)
5410 .set_timestamp_us(0)
5411 .set_rotation(webrtc::kVideoRotation_0)
5412 .build();
mzanaty8a855d62017-02-17 15:46:43 -08005413 recv_stream->InjectFrame(video_frame2);
5414 EXPECT_EQ(2, renderer.num_rendered_frames());
5415
5416#if defined(WEBRTC_USE_H264)
5417 // Receive H264 packet on third SSRC.
5418 rtpHeader.payload_type = 126;
Yves Gerey665174f2018-06-19 15:03:05 +02005419 rtpHeader.ssrc = kIncomingUnsignalledSsrc + 3;
mzanaty8a855d62017-02-17 15:46:43 -08005420 cricket::SetRtpHeader(data, sizeof(data), rtpHeader);
5421 rtc::CopyOnWriteBuffer packet3(data, sizeof(data));
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07005422 channel_->OnPacketReceived(packet3, /* packet_time_us */ -1);
mzanaty8a855d62017-02-17 15:46:43 -08005423 // H264 packet should replace the default receive SSRC.
5424 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
5425 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
5426 EXPECT_EQ(rtpHeader.ssrc, recv_stream->GetConfig().rtp.remote_ssrc);
5427 // Verify that the receive stream sinks to a renderer.
Artem Titov1ebfb6a2019-01-03 23:49:37 +01005428 webrtc::VideoFrame video_frame3 =
5429 webrtc::VideoFrame::Builder()
5430 .set_video_frame_buffer(CreateBlackFrameBuffer(4, 4))
5431 .set_timestamp_rtp(300)
5432 .set_timestamp_us(0)
5433 .set_rotation(webrtc::kVideoRotation_0)
5434 .build();
mzanaty8a855d62017-02-17 15:46:43 -08005435 recv_stream->InjectFrame(video_frame3);
5436 EXPECT_EQ(3, renderer.num_rendered_frames());
5437#endif
5438}
5439
brandtr0dc57ea2017-05-29 23:33:31 -07005440// This test verifies that when a new default stream is created for a new
5441// unsignaled SSRC, the new stream does not overwrite any old stream that had
5442// been the default receive stream before being properly signaled.
eladalonf1841382017-06-12 01:16:46 -07005443TEST_F(WebRtcVideoChannelTest,
brandtr0dc57ea2017-05-29 23:33:31 -07005444 NewUnsignaledStreamDoesNotDestroyPreviouslyUnsignaledStream) {
5445 cricket::VideoRecvParameters parameters;
5446 parameters.codecs.push_back(GetEngineCodec("VP8"));
5447 ASSERT_TRUE(channel_->SetRecvParameters(parameters));
5448
5449 // No streams signaled and no packets received, so we should not have any
5450 // stream objects created yet.
5451 EXPECT_EQ(0u, fake_call_->GetVideoReceiveStreams().size());
5452
5453 // Receive packet on an unsignaled SSRC.
5454 uint8_t data[kMinRtpPacketLen];
5455 cricket::RtpHeader rtp_header;
5456 rtp_header.payload_type = GetEngineCodec("VP8").id;
5457 rtp_header.seq_num = rtp_header.timestamp = 0;
5458 rtp_header.ssrc = kSsrcs3[0];
5459 cricket::SetRtpHeader(data, sizeof(data), rtp_header);
5460 rtc::CopyOnWriteBuffer packet(data, sizeof(data));
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07005461 channel_->OnPacketReceived(packet, /* packet_time_us */ -1);
brandtr0dc57ea2017-05-29 23:33:31 -07005462 // Default receive stream should be created.
5463 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
5464 FakeVideoReceiveStream* recv_stream0 =
5465 fake_call_->GetVideoReceiveStreams()[0];
5466 EXPECT_EQ(kSsrcs3[0], recv_stream0->GetConfig().rtp.remote_ssrc);
5467
5468 // Signal the SSRC.
5469 EXPECT_TRUE(
5470 channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrcs3[0])));
5471 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
5472 recv_stream0 = fake_call_->GetVideoReceiveStreams()[0];
5473 EXPECT_EQ(kSsrcs3[0], recv_stream0->GetConfig().rtp.remote_ssrc);
5474
5475 // Receive packet on a different unsignaled SSRC.
5476 rtp_header.ssrc = kSsrcs3[1];
5477 cricket::SetRtpHeader(data, sizeof(data), rtp_header);
5478 packet.SetData(data, sizeof(data));
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07005479 channel_->OnPacketReceived(packet, /* packet_time_us */ -1);
brandtr0dc57ea2017-05-29 23:33:31 -07005480 // New default receive stream should be created, but old stream should remain.
5481 ASSERT_EQ(2u, fake_call_->GetVideoReceiveStreams().size());
5482 EXPECT_EQ(recv_stream0, fake_call_->GetVideoReceiveStreams()[0]);
5483 FakeVideoReceiveStream* recv_stream1 =
5484 fake_call_->GetVideoReceiveStreams()[1];
5485 EXPECT_EQ(kSsrcs3[1], recv_stream1->GetConfig().rtp.remote_ssrc);
5486}
5487
Seth Hampson7c682e02018-05-04 16:28:15 -07005488TEST_F(WebRtcVideoChannelTest, CanSetMaxBitrateForExistingStream) {
skvladdc1c62c2016-03-16 19:07:43 -07005489 AddSendStream();
5490
Niels Möller805a27e2019-01-21 12:21:27 +01005491 webrtc::test::FrameForwarder frame_forwarder;
5492 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));
skvladdc1c62c2016-03-16 19:07:43 -07005493 EXPECT_TRUE(channel_->SetSend(true));
Niels Möller805a27e2019-01-21 12:21:27 +01005494 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
skvladdc1c62c2016-03-16 19:07:43 -07005495
perkjfa10b552016-10-02 23:45:26 -07005496 int default_encoder_bitrate = GetMaxEncoderBitrate();
brandtr468da7c2016-11-22 02:16:47 -08005497 EXPECT_GT(default_encoder_bitrate, 1000);
skvladdc1c62c2016-03-16 19:07:43 -07005498
5499 // TODO(skvlad): Resolve the inconsistency between the interpretation
5500 // of the global bitrate limit for audio and video:
5501 // - Audio: max_bandwidth_bps = 0 - fail the operation,
5502 // max_bandwidth_bps = -1 - remove the bandwidth limit
5503 // - Video: max_bandwidth_bps = 0 - remove the bandwidth limit,
pbos5c7760a2017-03-10 11:23:12 -08005504 // max_bandwidth_bps = -1 - remove the bandwidth limit
skvladdc1c62c2016-03-16 19:07:43 -07005505
perkjfa10b552016-10-02 23:45:26 -07005506 SetAndExpectMaxBitrate(1000, 0, 1000);
5507 SetAndExpectMaxBitrate(1000, 800, 800);
5508 SetAndExpectMaxBitrate(600, 800, 600);
5509 SetAndExpectMaxBitrate(0, 800, 800);
5510 SetAndExpectMaxBitrate(0, 0, default_encoder_bitrate);
skvladdc1c62c2016-03-16 19:07:43 -07005511
Niels Möllerff40b142018-04-09 08:49:14 +02005512 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
skvladdc1c62c2016-03-16 19:07:43 -07005513}
5514
eladalonf1841382017-06-12 01:16:46 -07005515TEST_F(WebRtcVideoChannelTest, CannotSetMaxBitrateForNonexistentStream) {
skvladdc1c62c2016-03-16 19:07:43 -07005516 webrtc::RtpParameters nonexistent_parameters =
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07005517 channel_->GetRtpSendParameters(last_ssrc_);
Mirko Bonadeif859e552018-05-30 15:31:29 +02005518 EXPECT_EQ(0u, nonexistent_parameters.encodings.size());
skvladdc1c62c2016-03-16 19:07:43 -07005519
5520 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07005521 EXPECT_FALSE(
Zach Steinba37b4b2018-01-23 15:02:36 -08005522 channel_->SetRtpSendParameters(last_ssrc_, nonexistent_parameters).ok());
skvladdc1c62c2016-03-16 19:07:43 -07005523}
5524
eladalonf1841382017-06-12 01:16:46 -07005525TEST_F(WebRtcVideoChannelTest,
Seth Hampson7c682e02018-05-04 16:28:15 -07005526 SetLowMaxBitrateOverwritesVideoStreamMinBitrate) {
Åsa Perssonbdee46d2018-06-25 11:28:06 +02005527 FakeVideoSendStream* stream = AddSendStream();
5528
Seth Hampson7c682e02018-05-04 16:28:15 -07005529 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
5530 EXPECT_EQ(1UL, parameters.encodings.size());
5531 EXPECT_FALSE(parameters.encodings[0].max_bitrate_bps.has_value());
5532 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
5533
5534 // Note that this is testing the behavior of the FakeVideoSendStream, which
5535 // also calls to CreateEncoderStreams to get the VideoStreams, so essentially
5536 // we are just testing the behavior of
5537 // EncoderStreamFactory::CreateEncoderStreams.
Åsa Perssonbdee46d2018-06-25 11:28:06 +02005538 ASSERT_EQ(1UL, stream->GetVideoStreams().size());
5539 EXPECT_EQ(kMinVideoBitrateBps, stream->GetVideoStreams()[0].min_bitrate_bps);
Seth Hampson7c682e02018-05-04 16:28:15 -07005540
5541 // Set a low max bitrate & check that VideoStream.min_bitrate_bps is limited
5542 // by this amount.
5543 parameters = channel_->GetRtpSendParameters(last_ssrc_);
5544 int low_max_bitrate_bps = kMinVideoBitrateBps - 1000;
5545 parameters.encodings[0].max_bitrate_bps = low_max_bitrate_bps;
5546 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
5547
Åsa Perssonbdee46d2018-06-25 11:28:06 +02005548 ASSERT_EQ(1UL, stream->GetVideoStreams().size());
5549 EXPECT_EQ(low_max_bitrate_bps, stream->GetVideoStreams()[0].min_bitrate_bps);
5550 EXPECT_EQ(low_max_bitrate_bps, stream->GetVideoStreams()[0].max_bitrate_bps);
5551}
5552
5553TEST_F(WebRtcVideoChannelTest,
5554 SetHighMinBitrateOverwritesVideoStreamMaxBitrate) {
5555 FakeVideoSendStream* stream = AddSendStream();
5556
5557 // Note that this is testing the behavior of the FakeVideoSendStream, which
5558 // also calls to CreateEncoderStreams to get the VideoStreams, so essentially
5559 // we are just testing the behavior of
5560 // EncoderStreamFactory::CreateEncoderStreams.
5561 ASSERT_EQ(1UL, stream->GetVideoStreams().size());
5562 int high_min_bitrate_bps = stream->GetVideoStreams()[0].max_bitrate_bps + 1;
5563
5564 // Set a high min bitrate and check that max_bitrate_bps is adjusted up.
5565 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
5566 EXPECT_EQ(1UL, parameters.encodings.size());
5567 parameters.encodings[0].min_bitrate_bps = high_min_bitrate_bps;
5568 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
5569
5570 ASSERT_EQ(1UL, stream->GetVideoStreams().size());
5571 EXPECT_EQ(high_min_bitrate_bps, stream->GetVideoStreams()[0].min_bitrate_bps);
5572 EXPECT_EQ(high_min_bitrate_bps, stream->GetVideoStreams()[0].max_bitrate_bps);
5573}
5574
5575TEST_F(WebRtcVideoChannelTest,
5576 SetMinBitrateAboveMaxBitrateLimitAdjustsMinBitrateDown) {
5577 send_parameters_.max_bandwidth_bps = 99999;
5578 FakeVideoSendStream* stream = AddSendStream();
5579 ExpectSetMaxBitrate(send_parameters_.max_bandwidth_bps);
5580 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
5581 ASSERT_EQ(1UL, stream->GetVideoStreams().size());
5582 EXPECT_EQ(kMinVideoBitrateBps, stream->GetVideoStreams()[0].min_bitrate_bps);
5583 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
5584 stream->GetVideoStreams()[0].max_bitrate_bps);
5585
5586 // Set min bitrate above global max bitrate and check that min_bitrate_bps is
5587 // adjusted down.
5588 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
5589 EXPECT_EQ(1UL, parameters.encodings.size());
5590 parameters.encodings[0].min_bitrate_bps = 99999 + 1;
5591 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
5592 ASSERT_EQ(1UL, stream->GetVideoStreams().size());
5593 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
5594 stream->GetVideoStreams()[0].min_bitrate_bps);
5595 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
5596 stream->GetVideoStreams()[0].max_bitrate_bps);
Seth Hampson7c682e02018-05-04 16:28:15 -07005597}
5598
Åsa Persson8c1bf952018-09-13 10:42:19 +02005599TEST_F(WebRtcVideoChannelTest, SetMaxFramerateOneStream) {
5600 FakeVideoSendStream* stream = AddSendStream();
5601
5602 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
5603 EXPECT_EQ(1UL, parameters.encodings.size());
5604 EXPECT_FALSE(parameters.encodings[0].max_framerate.has_value());
5605 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
5606
5607 // Note that this is testing the behavior of the FakeVideoSendStream, which
5608 // also calls to CreateEncoderStreams to get the VideoStreams, so essentially
5609 // we are just testing the behavior of
5610 // EncoderStreamFactory::CreateEncoderStreams.
5611 ASSERT_EQ(1UL, stream->GetVideoStreams().size());
5612 EXPECT_EQ(kDefaultVideoMaxFramerate,
5613 stream->GetVideoStreams()[0].max_framerate);
5614
5615 // Set max framerate and check that VideoStream.max_framerate is set.
5616 const int kNewMaxFramerate = kDefaultVideoMaxFramerate - 1;
5617 parameters = channel_->GetRtpSendParameters(last_ssrc_);
5618 parameters.encodings[0].max_framerate = kNewMaxFramerate;
5619 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
5620
5621 ASSERT_EQ(1UL, stream->GetVideoStreams().size());
5622 EXPECT_EQ(kNewMaxFramerate, stream->GetVideoStreams()[0].max_framerate);
5623}
5624
Åsa Persson23eba222018-10-02 14:47:06 +02005625TEST_F(WebRtcVideoChannelTest, SetNumTemporalLayersForSingleStream) {
5626 FakeVideoSendStream* stream = AddSendStream();
5627
5628 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
5629 EXPECT_EQ(1UL, parameters.encodings.size());
5630 EXPECT_FALSE(parameters.encodings[0].num_temporal_layers.has_value());
5631 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
5632
5633 // Note that this is testing the behavior of the FakeVideoSendStream, which
5634 // also calls to CreateEncoderStreams to get the VideoStreams, so essentially
5635 // we are just testing the behavior of
5636 // EncoderStreamFactory::CreateEncoderStreams.
5637 ASSERT_EQ(1UL, stream->GetVideoStreams().size());
5638 EXPECT_FALSE(stream->GetVideoStreams()[0].num_temporal_layers.has_value());
5639
5640 // Set temporal layers and check that VideoStream.num_temporal_layers is set.
5641 parameters = channel_->GetRtpSendParameters(last_ssrc_);
5642 parameters.encodings[0].num_temporal_layers = 2;
5643 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
5644
5645 ASSERT_EQ(1UL, stream->GetVideoStreams().size());
5646 EXPECT_EQ(2UL, stream->GetVideoStreams()[0].num_temporal_layers);
5647}
5648
Seth Hampson7c682e02018-05-04 16:28:15 -07005649TEST_F(WebRtcVideoChannelTest,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07005650 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvladdc1c62c2016-03-16 19:07:43 -07005651 AddSendStream();
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07005652 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
skvladdc1c62c2016-03-16 19:07:43 -07005653 // Two or more encodings should result in failure.
5654 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08005655 EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08005656 // Zero encodings should also fail.
5657 parameters.encodings.clear();
Zach Steinba37b4b2018-01-23 15:02:36 -08005658 EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08005659}
5660
Zach Stein3ca452b2018-01-18 10:01:24 -08005661TEST_F(WebRtcVideoChannelTest,
5662 CannotSetSimulcastRtpSendParametersWithIncorrectNumberOfEncodings) {
5663 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
5664 StreamParams sp = CreateSimStreamParams("cname", ssrcs);
5665 AddSendStream(sp);
5666
5667 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
5668
5669 // Additional encodings should result in failure.
5670 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08005671 EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
Zach Stein3ca452b2018-01-18 10:01:24 -08005672 // Zero encodings should also fail.
5673 parameters.encodings.clear();
Zach Steinba37b4b2018-01-23 15:02:36 -08005674 EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
Zach Stein3ca452b2018-01-18 10:01:24 -08005675}
5676
deadbeeffb2aced2017-01-06 23:05:37 -08005677// Changing the SSRC through RtpParameters is not allowed.
eladalonf1841382017-06-12 01:16:46 -07005678TEST_F(WebRtcVideoChannelTest, CannotSetSsrcInRtpSendParameters) {
deadbeeffb2aced2017-01-06 23:05:37 -08005679 AddSendStream();
5680 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
Oskar Sundbom78807582017-11-16 11:09:55 +01005681 parameters.encodings[0].ssrc = 0xdeadbeef;
Zach Steinba37b4b2018-01-23 15:02:36 -08005682 EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
skvladdc1c62c2016-03-16 19:07:43 -07005683}
5684
Seth Hampson24722b32017-12-22 09:36:42 -08005685// Tests that when RTCRtpEncodingParameters.bitrate_priority gets set to
5686// a value <= 0, setting the parameters returns false.
5687TEST_F(WebRtcVideoChannelTest, SetRtpSendParametersInvalidBitratePriority) {
5688 AddSendStream();
5689 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
5690 EXPECT_EQ(1UL, parameters.encodings.size());
5691 EXPECT_EQ(webrtc::kDefaultBitratePriority,
5692 parameters.encodings[0].bitrate_priority);
5693
5694 parameters.encodings[0].bitrate_priority = 0;
Zach Steinba37b4b2018-01-23 15:02:36 -08005695 EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08005696 parameters.encodings[0].bitrate_priority = -2;
Zach Steinba37b4b2018-01-23 15:02:36 -08005697 EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08005698}
5699
5700// Tests when the the RTCRtpEncodingParameters.bitrate_priority gets set
5701// properly on the VideoChannel and propogates down to the video encoder.
5702TEST_F(WebRtcVideoChannelTest, SetRtpSendParametersPriorityOneStream) {
5703 AddSendStream();
5704 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
5705 EXPECT_EQ(1UL, parameters.encodings.size());
5706 EXPECT_EQ(webrtc::kDefaultBitratePriority,
5707 parameters.encodings[0].bitrate_priority);
5708
5709 // Change the value and set it on the VideoChannel.
5710 double new_bitrate_priority = 2.0;
5711 parameters.encodings[0].bitrate_priority = new_bitrate_priority;
Zach Steinba37b4b2018-01-23 15:02:36 -08005712 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08005713
5714 // Verify that the encoding parameters bitrate_priority is set for the
5715 // VideoChannel.
5716 parameters = channel_->GetRtpSendParameters(last_ssrc_);
5717 EXPECT_EQ(1UL, parameters.encodings.size());
5718 EXPECT_EQ(new_bitrate_priority, parameters.encodings[0].bitrate_priority);
5719
5720 // Verify that the new value propagated down to the encoder.
5721 std::vector<FakeVideoSendStream*> video_send_streams =
5722 fake_call_->GetVideoSendStreams();
5723 EXPECT_EQ(1UL, video_send_streams.size());
5724 FakeVideoSendStream* video_send_stream = video_send_streams.front();
5725 // Check that the WebRtcVideoSendStream updated the VideoEncoderConfig
5726 // appropriately.
5727 EXPECT_EQ(new_bitrate_priority,
5728 video_send_stream->GetEncoderConfig().bitrate_priority);
5729 // Check that the vector of VideoStreams also was propagated correctly. Note
5730 // that this is testing the behavior of the FakeVideoSendStream, which mimics
5731 // the calls to CreateEncoderStreams to get the VideoStreams.
Danil Chapovalov00c71832018-06-15 15:58:38 +02005732 EXPECT_EQ(absl::optional<double>(new_bitrate_priority),
Seth Hampson24722b32017-12-22 09:36:42 -08005733 video_send_stream->GetVideoStreams()[0].bitrate_priority);
5734}
5735
5736// Tests that the RTCRtpEncodingParameters.bitrate_priority is set for the
5737// VideoChannel and the value propogates to the video encoder with all simulcast
5738// streams.
5739TEST_F(WebRtcVideoChannelTest, SetRtpSendParametersPrioritySimulcastStreams) {
5740 // Create the stream params with multiple ssrcs for simulcast.
Åsa Persson31cb8f92018-06-27 10:44:56 +02005741 const size_t kNumSimulcastStreams = 3;
Seth Hampson24722b32017-12-22 09:36:42 -08005742 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
5743 StreamParams stream_params = CreateSimStreamParams("cname", ssrcs);
5744 AddSendStream(stream_params);
5745 uint32_t primary_ssrc = stream_params.first_ssrc();
5746
Niels Möller805a27e2019-01-21 12:21:27 +01005747 // Using the FrameForwarder, we manually send a full size
Tommi85959932018-02-07 19:26:06 +01005748 // frame. This creates multiple VideoStreams for all simulcast layers when
5749 // reconfiguring, and allows us to test this behavior.
Niels Möller805a27e2019-01-21 12:21:27 +01005750 webrtc::test::FrameForwarder frame_forwarder;
Seth Hampson24722b32017-12-22 09:36:42 -08005751 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01005752 EXPECT_TRUE(channel_->SetVideoSend(primary_ssrc, &options, &frame_forwarder));
Seth Hampson24722b32017-12-22 09:36:42 -08005753 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01005754 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame(
5755 1920, 1080, webrtc::VideoRotation::kVideoRotation_0,
5756 rtc::kNumMicrosecsPerSec / 30));
5757
Seth Hampson24722b32017-12-22 09:36:42 -08005758 // Get and set the rtp encoding parameters.
5759 webrtc::RtpParameters parameters =
5760 channel_->GetRtpSendParameters(primary_ssrc);
Åsa Persson31cb8f92018-06-27 10:44:56 +02005761 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
Seth Hampson24722b32017-12-22 09:36:42 -08005762 EXPECT_EQ(webrtc::kDefaultBitratePriority,
5763 parameters.encodings[0].bitrate_priority);
5764 // Change the value and set it on the VideoChannel.
5765 double new_bitrate_priority = 2.0;
5766 parameters.encodings[0].bitrate_priority = new_bitrate_priority;
Zach Steinba37b4b2018-01-23 15:02:36 -08005767 EXPECT_TRUE(channel_->SetRtpSendParameters(primary_ssrc, parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08005768
5769 // Verify that the encoding parameters priority is set on the VideoChannel.
5770 parameters = channel_->GetRtpSendParameters(primary_ssrc);
Åsa Persson31cb8f92018-06-27 10:44:56 +02005771 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
Seth Hampson24722b32017-12-22 09:36:42 -08005772 EXPECT_EQ(new_bitrate_priority, parameters.encodings[0].bitrate_priority);
5773
5774 // Verify that the new value propagated down to the encoder.
5775 std::vector<FakeVideoSendStream*> video_send_streams =
5776 fake_call_->GetVideoSendStreams();
5777 EXPECT_EQ(1UL, video_send_streams.size());
5778 FakeVideoSendStream* video_send_stream = video_send_streams.front();
5779 // Check that the WebRtcVideoSendStream updated the VideoEncoderConfig
5780 // appropriately.
Åsa Persson31cb8f92018-06-27 10:44:56 +02005781 EXPECT_EQ(kNumSimulcastStreams,
Seth Hampson24722b32017-12-22 09:36:42 -08005782 video_send_stream->GetEncoderConfig().number_of_streams);
5783 EXPECT_EQ(new_bitrate_priority,
5784 video_send_stream->GetEncoderConfig().bitrate_priority);
5785 // Check that the vector of VideoStreams also propagated correctly. The
5786 // FakeVideoSendStream calls CreateEncoderStreams, and we are testing that
5787 // these are created appropriately for the simulcast case.
Åsa Persson31cb8f92018-06-27 10:44:56 +02005788 EXPECT_EQ(kNumSimulcastStreams, video_send_stream->GetVideoStreams().size());
Danil Chapovalov00c71832018-06-15 15:58:38 +02005789 EXPECT_EQ(absl::optional<double>(new_bitrate_priority),
Seth Hampson24722b32017-12-22 09:36:42 -08005790 video_send_stream->GetVideoStreams()[0].bitrate_priority);
5791 // Since we are only setting bitrate priority per-sender, the other
5792 // VideoStreams should have a bitrate priority of 0.
Danil Chapovalov00c71832018-06-15 15:58:38 +02005793 EXPECT_EQ(absl::nullopt,
Seth Hampson24722b32017-12-22 09:36:42 -08005794 video_send_stream->GetVideoStreams()[1].bitrate_priority);
Danil Chapovalov00c71832018-06-15 15:58:38 +02005795 EXPECT_EQ(absl::nullopt,
Seth Hampson24722b32017-12-22 09:36:42 -08005796 video_send_stream->GetVideoStreams()[2].bitrate_priority);
Niels Möllerff40b142018-04-09 08:49:14 +02005797 EXPECT_TRUE(channel_->SetVideoSend(primary_ssrc, nullptr, nullptr));
Seth Hampson24722b32017-12-22 09:36:42 -08005798}
5799
Tim Haloun648d28a2018-10-18 16:52:22 -07005800// RTCRtpEncodingParameters.network_priority must be one of a few values
5801// derived from the default priority, corresponding to very-low, low, medium,
5802// or high.
5803TEST_F(WebRtcVideoChannelTest, SetRtpSendParametersInvalidNetworkPriority) {
5804 AddSendStream();
5805 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
5806 EXPECT_EQ(1UL, parameters.encodings.size());
5807 EXPECT_EQ(webrtc::kDefaultBitratePriority,
5808 parameters.encodings[0].network_priority);
5809
5810 double good_values[] = {0.5, 1.0, 2.0, 4.0};
5811 double bad_values[] = {-1.0, 0.0, 0.49, 0.51, 1.1, 3.99, 4.1, 5.0};
5812 for (auto it : good_values) {
5813 parameters.encodings[0].network_priority = it;
5814 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
5815 }
5816 for (auto it : bad_values) {
5817 parameters.encodings[0].network_priority = it;
5818 EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
5819 }
5820}
5821
Florent Castellic1a0bcb2019-01-29 14:26:48 +01005822TEST_F(WebRtcVideoChannelTest,
5823 GetAndSetRtpSendParametersScaleResolutionDownByVP8) {
Rasmus Brandt9387b522019-02-05 14:23:26 +01005824 VideoSendParameters parameters;
5825 parameters.codecs.push_back(VideoCodec(kVp8CodecName));
Florent Castellic1a0bcb2019-01-29 14:26:48 +01005826 ASSERT_TRUE(channel_->SetSendParameters(parameters));
5827 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
5828
5829 webrtc::test::FrameForwarder frame_forwarder;
Rasmus Brandt9387b522019-02-05 14:23:26 +01005830 FakeFrameSource frame_source(1280, 720, rtc::kNumMicrosecsPerSec / 30);
Florent Castellic1a0bcb2019-01-29 14:26:48 +01005831
5832 VideoOptions options;
5833 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
5834 channel_->SetSend(true);
5835
5836 // Try layers in natural order (smallest to largest).
5837 {
5838 auto rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
5839 ASSERT_EQ(3u, rtp_parameters.encodings.size());
5840 rtp_parameters.encodings[0].scale_resolution_down_by = 4.0;
5841 rtp_parameters.encodings[1].scale_resolution_down_by = 2.0;
5842 rtp_parameters.encodings[2].scale_resolution_down_by = 1.0;
5843 auto result = channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
5844 ASSERT_TRUE(result.ok());
5845
5846 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
5847
5848 std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
5849 ASSERT_EQ(3u, video_streams.size());
5850 EXPECT_EQ(320u, video_streams[0].width);
5851 EXPECT_EQ(180u, video_streams[0].height);
5852 EXPECT_EQ(640u, video_streams[1].width);
5853 EXPECT_EQ(360u, video_streams[1].height);
5854 EXPECT_EQ(1280u, video_streams[2].width);
5855 EXPECT_EQ(720u, video_streams[2].height);
5856 }
5857
5858 // Try layers in reverse natural order (largest to smallest).
5859 {
5860 auto rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
5861 ASSERT_EQ(3u, rtp_parameters.encodings.size());
5862 rtp_parameters.encodings[0].scale_resolution_down_by = 1.0;
5863 rtp_parameters.encodings[1].scale_resolution_down_by = 2.0;
5864 rtp_parameters.encodings[2].scale_resolution_down_by = 4.0;
5865 auto result = channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
5866 ASSERT_TRUE(result.ok());
5867
5868 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
5869
5870 std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
5871 ASSERT_EQ(3u, video_streams.size());
5872 EXPECT_EQ(1280u, video_streams[0].width);
5873 EXPECT_EQ(720u, video_streams[0].height);
5874 EXPECT_EQ(640u, video_streams[1].width);
5875 EXPECT_EQ(360u, video_streams[1].height);
5876 EXPECT_EQ(320u, video_streams[2].width);
5877 EXPECT_EQ(180u, video_streams[2].height);
5878 }
5879
5880 // Try layers in mixed order.
5881 {
5882 auto rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
5883 ASSERT_EQ(3u, rtp_parameters.encodings.size());
5884 rtp_parameters.encodings[0].scale_resolution_down_by = 10.0;
5885 rtp_parameters.encodings[1].scale_resolution_down_by = 2.0;
5886 rtp_parameters.encodings[2].scale_resolution_down_by = 4.0;
5887 auto result = channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
5888 ASSERT_TRUE(result.ok());
5889
5890 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
5891
5892 std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
5893 ASSERT_EQ(3u, video_streams.size());
5894 EXPECT_EQ(128u, video_streams[0].width);
5895 EXPECT_EQ(72u, video_streams[0].height);
5896 EXPECT_EQ(640u, video_streams[1].width);
5897 EXPECT_EQ(360u, video_streams[1].height);
5898 EXPECT_EQ(320u, video_streams[2].width);
5899 EXPECT_EQ(180u, video_streams[2].height);
5900 }
5901
5902 // Try with a missing scale setting, defaults to 1.0 if any other is set.
5903 {
5904 auto rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
5905 ASSERT_EQ(3u, rtp_parameters.encodings.size());
5906 rtp_parameters.encodings[0].scale_resolution_down_by = 1.0;
5907 rtp_parameters.encodings[1].scale_resolution_down_by.reset();
5908 rtp_parameters.encodings[2].scale_resolution_down_by = 4.0;
5909 auto result = channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
5910 ASSERT_TRUE(result.ok());
5911
5912 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
5913
5914 std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
5915 ASSERT_EQ(3u, video_streams.size());
5916 EXPECT_EQ(1280u, video_streams[0].width);
5917 EXPECT_EQ(720u, video_streams[0].height);
5918 EXPECT_EQ(1280u, video_streams[1].width);
5919 EXPECT_EQ(720u, video_streams[1].height);
5920 EXPECT_EQ(320u, video_streams[2].width);
5921 EXPECT_EQ(180u, video_streams[2].height);
5922 }
5923
5924 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
5925}
5926
5927TEST_F(WebRtcVideoChannelTest,
Rasmus Brandt9387b522019-02-05 14:23:26 +01005928 GetAndSetRtpSendParametersScaleResolutionDownByVP8WithOddResolution) {
5929 // Ensure that the top layer has width and height divisible by 2^3,
5930 // so that the bottom layer has width and height divisible by 2.
5931 // TODO(bugs.webrtc.org/8785): Remove this field trial when we fully trust
5932 // the number of simulcast layers set by the app.
5933 webrtc::test::ScopedFieldTrials field_trial(
5934 "WebRTC-NormalizeSimulcastResolution/Enabled-3/");
5935
5936 // Set up WebRtcVideoChannel for 3-layer VP8 simulcast.
5937 VideoSendParameters parameters;
5938 parameters.codecs.push_back(VideoCodec(kVp8CodecName));
5939 ASSERT_TRUE(channel_->SetSendParameters(parameters));
5940 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
5941 webrtc::test::FrameForwarder frame_forwarder;
5942 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, /*options=*/nullptr,
5943 &frame_forwarder));
5944 channel_->SetSend(true);
5945
5946 // Set |scale_resolution_down_by|'s.
5947 auto rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
5948 ASSERT_EQ(rtp_parameters.encodings.size(), 3u);
5949 rtp_parameters.encodings[0].scale_resolution_down_by = 1.0;
5950 rtp_parameters.encodings[1].scale_resolution_down_by = 2.0;
5951 rtp_parameters.encodings[2].scale_resolution_down_by = 4.0;
5952 const auto result =
5953 channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
5954 ASSERT_TRUE(result.ok());
5955
5956 // Use a capture resolution whose width and height are not divisible by 2^3.
5957 // (See field trial set at the top of the test.)
5958 FakeFrameSource frame_source(2007, 1207, rtc::kNumMicrosecsPerSec / 30);
5959 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
5960
5961 // Ensure the scaling is correct.
5962 const auto video_streams = stream->GetVideoStreams();
5963 ASSERT_EQ(video_streams.size(), 3u);
5964 // Ensure that we round the capture resolution down for the top layer...
5965 EXPECT_EQ(video_streams[0].width, 2000u);
5966 EXPECT_EQ(video_streams[0].height, 1200u);
5967 EXPECT_EQ(video_streams[1].width, 1000u);
5968 EXPECT_EQ(video_streams[1].height, 600u);
5969 // ...and that the bottom layer has a width/height divisible by 2.
5970 EXPECT_EQ(video_streams[2].width, 500u);
5971 EXPECT_EQ(video_streams[2].height, 300u);
5972
5973 // Tear down.
5974 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
5975}
5976
5977TEST_F(WebRtcVideoChannelTest,
Florent Castellic1a0bcb2019-01-29 14:26:48 +01005978 GetAndSetRtpSendParametersScaleResolutionDownByH264) {
Rasmus Brandt9387b522019-02-05 14:23:26 +01005979 encoder_factory_->AddSupportedVideoCodecType(kH264CodecName);
5980 VideoSendParameters parameters;
5981 parameters.codecs.push_back(VideoCodec(kH264CodecName));
Florent Castellic1a0bcb2019-01-29 14:26:48 +01005982 ASSERT_TRUE(channel_->SetSendParameters(parameters));
5983 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
5984
5985 webrtc::test::FrameForwarder frame_forwarder;
Rasmus Brandt9387b522019-02-05 14:23:26 +01005986 FakeFrameSource frame_source(1280, 720, rtc::kNumMicrosecsPerSec / 30);
Florent Castellic1a0bcb2019-01-29 14:26:48 +01005987
5988 VideoOptions options;
5989 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
5990 channel_->SetSend(true);
5991
5992 // Try layers in natural order (smallest to largest).
5993 {
5994 auto rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
5995 ASSERT_EQ(3u, rtp_parameters.encodings.size());
5996 rtp_parameters.encodings[0].scale_resolution_down_by = 4.0;
5997 rtp_parameters.encodings[1].scale_resolution_down_by = 2.0;
5998 rtp_parameters.encodings[2].scale_resolution_down_by = 1.0;
5999 auto result = channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
6000 ASSERT_TRUE(result.ok());
6001
6002 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
6003
6004 std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
6005 ASSERT_EQ(3u, video_streams.size());
6006 EXPECT_EQ(320u, video_streams[0].width);
6007 EXPECT_EQ(180u, video_streams[0].height);
6008 EXPECT_EQ(640u, video_streams[1].width);
6009 EXPECT_EQ(360u, video_streams[1].height);
6010 EXPECT_EQ(1280u, video_streams[2].width);
6011 EXPECT_EQ(720u, video_streams[2].height);
6012 }
6013
6014 // Try layers in reverse natural order (largest to smallest).
6015 {
6016 auto rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
6017 ASSERT_EQ(3u, rtp_parameters.encodings.size());
6018 rtp_parameters.encodings[0].scale_resolution_down_by = 1.0;
6019 rtp_parameters.encodings[1].scale_resolution_down_by = 2.0;
6020 rtp_parameters.encodings[2].scale_resolution_down_by = 4.0;
6021 auto result = channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
6022 ASSERT_TRUE(result.ok());
6023
6024 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
6025
6026 std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
6027 ASSERT_EQ(3u, video_streams.size());
6028 EXPECT_EQ(1280u, video_streams[0].width);
6029 EXPECT_EQ(720u, video_streams[0].height);
6030 EXPECT_EQ(640u, video_streams[1].width);
6031 EXPECT_EQ(360u, video_streams[1].height);
6032 EXPECT_EQ(320u, video_streams[2].width);
6033 EXPECT_EQ(180u, video_streams[2].height);
6034 }
6035
6036 // Try layers in mixed order.
6037 {
6038 auto rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
6039 ASSERT_EQ(3u, rtp_parameters.encodings.size());
6040 rtp_parameters.encodings[0].scale_resolution_down_by = 10.0;
6041 rtp_parameters.encodings[1].scale_resolution_down_by = 2.0;
6042 rtp_parameters.encodings[2].scale_resolution_down_by = 4.0;
6043 auto result = channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
6044 ASSERT_TRUE(result.ok());
6045
6046 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
6047
6048 std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
6049 ASSERT_EQ(3u, video_streams.size());
6050 EXPECT_EQ(128u, video_streams[0].width);
6051 EXPECT_EQ(72u, video_streams[0].height);
6052 EXPECT_EQ(640u, video_streams[1].width);
6053 EXPECT_EQ(360u, video_streams[1].height);
6054 EXPECT_EQ(320u, video_streams[2].width);
6055 EXPECT_EQ(180u, video_streams[2].height);
6056 }
6057
6058 // Try with a missing scale setting, defaults to 1.0 if any other is set.
6059 {
6060 auto rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
6061 ASSERT_EQ(3u, rtp_parameters.encodings.size());
6062 rtp_parameters.encodings[0].scale_resolution_down_by = 1.0;
6063 rtp_parameters.encodings[1].scale_resolution_down_by.reset();
6064 rtp_parameters.encodings[2].scale_resolution_down_by = 4.0;
6065 auto result = channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
6066 ASSERT_TRUE(result.ok());
6067
6068 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
6069
6070 std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
6071 ASSERT_EQ(3u, video_streams.size());
6072 EXPECT_EQ(1280u, video_streams[0].width);
6073 EXPECT_EQ(720u, video_streams[0].height);
6074 EXPECT_EQ(1280u, video_streams[1].width);
6075 EXPECT_EQ(720u, video_streams[1].height);
6076 EXPECT_EQ(320u, video_streams[2].width);
6077 EXPECT_EQ(180u, video_streams[2].height);
6078 }
6079 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
6080}
6081
Rasmus Brandt9387b522019-02-05 14:23:26 +01006082TEST_F(WebRtcVideoChannelTest,
6083 GetAndSetRtpSendParametersScaleResolutionDownByH264WithOddResolution) {
6084 // Ensure that the top layer has width and height divisible by 2^3,
6085 // so that the bottom layer has width and height divisible by 2.
6086 // TODO(bugs.webrtc.org/8785): Remove this field trial when we fully trust
6087 // the number of simulcast layers set by the app.
6088 webrtc::test::ScopedFieldTrials field_trial(
6089 "WebRTC-NormalizeSimulcastResolution/Enabled-3/");
6090
6091 // Set up WebRtcVideoChannel for 3-layer H264 simulcast.
6092 encoder_factory_->AddSupportedVideoCodecType(kH264CodecName);
6093 VideoSendParameters parameters;
6094 parameters.codecs.push_back(VideoCodec(kH264CodecName));
6095 ASSERT_TRUE(channel_->SetSendParameters(parameters));
6096 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
6097 webrtc::test::FrameForwarder frame_forwarder;
6098 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, /*options=*/nullptr,
6099 &frame_forwarder));
6100 channel_->SetSend(true);
6101
6102 // Set |scale_resolution_down_by|'s.
6103 auto rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
6104 ASSERT_EQ(rtp_parameters.encodings.size(), 3u);
6105 rtp_parameters.encodings[0].scale_resolution_down_by = 1.0;
6106 rtp_parameters.encodings[1].scale_resolution_down_by = 2.0;
6107 rtp_parameters.encodings[2].scale_resolution_down_by = 4.0;
6108 const auto result =
6109 channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
6110 ASSERT_TRUE(result.ok());
6111
6112 // Use a capture resolution whose width and height are not divisible by 2^3.
6113 // (See field trial set at the top of the test.)
6114 FakeFrameSource frame_source(2007, 1207, rtc::kNumMicrosecsPerSec / 30);
6115 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
6116
6117 // Ensure the scaling is correct.
6118 const auto video_streams = stream->GetVideoStreams();
6119 ASSERT_EQ(video_streams.size(), 3u);
6120 // Ensure that we round the capture resolution down for the top layer...
6121 EXPECT_EQ(video_streams[0].width, 2000u);
6122 EXPECT_EQ(video_streams[0].height, 1200u);
6123 EXPECT_EQ(video_streams[1].width, 1000u);
6124 EXPECT_EQ(video_streams[1].height, 600u);
6125 // ...and that the bottom layer has a width/height divisible by 2.
6126 EXPECT_EQ(video_streams[2].width, 500u);
6127 EXPECT_EQ(video_streams[2].height, 300u);
6128
6129 // Tear down.
6130 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
6131}
6132
Åsa Persson8c1bf952018-09-13 10:42:19 +02006133TEST_F(WebRtcVideoChannelTest, GetAndSetRtpSendParametersMaxFramerate) {
6134 const size_t kNumSimulcastStreams = 3;
6135 SetUpSimulcast(true, false);
6136
6137 // Get and set the rtp encoding parameters.
6138 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6139 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6140 for (const auto& encoding : parameters.encodings) {
6141 EXPECT_FALSE(encoding.max_framerate);
6142 }
6143
6144 // Change the value and set it on the VideoChannel.
6145 parameters.encodings[0].max_framerate = 10;
6146 parameters.encodings[1].max_framerate = 20;
6147 parameters.encodings[2].max_framerate = 25;
6148 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6149
6150 // Verify that the bitrates are set on the VideoChannel.
6151 parameters = channel_->GetRtpSendParameters(last_ssrc_);
6152 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6153 EXPECT_EQ(10, parameters.encodings[0].max_framerate);
6154 EXPECT_EQ(20, parameters.encodings[1].max_framerate);
6155 EXPECT_EQ(25, parameters.encodings[2].max_framerate);
6156}
6157
Åsa Persson23eba222018-10-02 14:47:06 +02006158TEST_F(WebRtcVideoChannelTest,
6159 SetRtpSendParametersNumTemporalLayersFailsForInvalidRange) {
6160 const size_t kNumSimulcastStreams = 3;
6161 SetUpSimulcast(true, false);
6162
6163 // Get and set the rtp encoding parameters.
6164 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6165 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6166
6167 // Num temporal layers should be in the range [1, kMaxTemporalStreams].
6168 parameters.encodings[0].num_temporal_layers = 0;
6169 EXPECT_EQ(webrtc::RTCErrorType::INVALID_RANGE,
6170 channel_->SetRtpSendParameters(last_ssrc_, parameters).type());
6171 parameters.encodings[0].num_temporal_layers = webrtc::kMaxTemporalStreams + 1;
6172 EXPECT_EQ(webrtc::RTCErrorType::INVALID_RANGE,
6173 channel_->SetRtpSendParameters(last_ssrc_, parameters).type());
6174}
6175
6176TEST_F(WebRtcVideoChannelTest,
6177 SetRtpSendParametersNumTemporalLayersFailsForInvalidModification) {
6178 const size_t kNumSimulcastStreams = 3;
6179 SetUpSimulcast(true, false);
6180
6181 // Get and set the rtp encoding parameters.
6182 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6183 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6184
6185 // No/all layers should be set.
6186 parameters.encodings[0].num_temporal_layers = 1;
6187 EXPECT_EQ(webrtc::RTCErrorType::INVALID_MODIFICATION,
6188 channel_->SetRtpSendParameters(last_ssrc_, parameters).type());
6189
6190 // Different values not supported.
6191 parameters.encodings[0].num_temporal_layers = 1;
6192 parameters.encodings[1].num_temporal_layers = 2;
6193 parameters.encodings[2].num_temporal_layers = 2;
6194 EXPECT_EQ(webrtc::RTCErrorType::INVALID_MODIFICATION,
6195 channel_->SetRtpSendParameters(last_ssrc_, parameters).type());
6196}
6197
6198TEST_F(WebRtcVideoChannelTest, GetAndSetRtpSendParametersNumTemporalLayers) {
6199 const size_t kNumSimulcastStreams = 3;
6200 SetUpSimulcast(true, false);
6201
6202 // Get and set the rtp encoding parameters.
6203 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6204 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6205 for (const auto& encoding : parameters.encodings)
6206 EXPECT_FALSE(encoding.num_temporal_layers);
6207
6208 // Change the value and set it on the VideoChannel.
6209 parameters.encodings[0].num_temporal_layers = 3;
6210 parameters.encodings[1].num_temporal_layers = 3;
6211 parameters.encodings[2].num_temporal_layers = 3;
6212 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6213
6214 // Verify that the number of temporal layers are set on the VideoChannel.
6215 parameters = channel_->GetRtpSendParameters(last_ssrc_);
6216 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6217 EXPECT_EQ(3, parameters.encodings[0].num_temporal_layers);
6218 EXPECT_EQ(3, parameters.encodings[1].num_temporal_layers);
6219 EXPECT_EQ(3, parameters.encodings[2].num_temporal_layers);
6220}
6221
6222TEST_F(WebRtcVideoChannelTest, NumTemporalLayersPropagatedToEncoder) {
6223 const size_t kNumSimulcastStreams = 3;
6224 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
6225
6226 // Send a full size frame so all simulcast layers are used when reconfiguring.
Niels Möller805a27e2019-01-21 12:21:27 +01006227 webrtc::test::FrameForwarder frame_forwarder;
Åsa Persson23eba222018-10-02 14:47:06 +02006228 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01006229 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
Åsa Persson23eba222018-10-02 14:47:06 +02006230 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01006231 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Åsa Persson23eba222018-10-02 14:47:06 +02006232
6233 // Get and set the rtp encoding parameters.
6234 // Change the value and set it on the VideoChannel.
6235 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6236 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6237 parameters.encodings[0].num_temporal_layers = 2;
6238 parameters.encodings[1].num_temporal_layers = 2;
6239 parameters.encodings[2].num_temporal_layers = 2;
6240 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6241
6242 // Verify that the new value is propagated down to the encoder.
6243 // Check that WebRtcVideoSendStream updates VideoEncoderConfig correctly.
6244 EXPECT_EQ(2, stream->num_encoder_reconfigurations());
6245 webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
6246 EXPECT_EQ(kNumSimulcastStreams, encoder_config.number_of_streams);
6247 EXPECT_EQ(kNumSimulcastStreams, encoder_config.simulcast_layers.size());
6248 EXPECT_EQ(2UL, encoder_config.simulcast_layers[0].num_temporal_layers);
6249 EXPECT_EQ(2UL, encoder_config.simulcast_layers[1].num_temporal_layers);
6250 EXPECT_EQ(2UL, encoder_config.simulcast_layers[2].num_temporal_layers);
6251
6252 // FakeVideoSendStream calls CreateEncoderStreams, test that the vector of
6253 // VideoStreams are created appropriately for the simulcast case.
6254 EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
6255 EXPECT_EQ(2UL, stream->GetVideoStreams()[0].num_temporal_layers);
6256 EXPECT_EQ(2UL, stream->GetVideoStreams()[1].num_temporal_layers);
6257 EXPECT_EQ(2UL, stream->GetVideoStreams()[2].num_temporal_layers);
6258
6259 // No parameter changed, encoder should not be reconfigured.
6260 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6261 EXPECT_EQ(2, stream->num_encoder_reconfigurations());
6262
6263 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
6264}
6265
6266TEST_F(WebRtcVideoChannelTest,
6267 DefaultValuePropagatedToEncoderForUnsetNumTemporalLayers) {
6268 const size_t kDefaultNumTemporalLayers = 3;
6269 const size_t kNumSimulcastStreams = 3;
6270 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
6271
6272 // Send a full size frame so all simulcast layers are used when reconfiguring.
Niels Möller805a27e2019-01-21 12:21:27 +01006273 webrtc::test::FrameForwarder frame_forwarder;
Åsa Persson23eba222018-10-02 14:47:06 +02006274 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01006275 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
Åsa Persson23eba222018-10-02 14:47:06 +02006276 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01006277 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Åsa Persson23eba222018-10-02 14:47:06 +02006278
6279 // Change rtp encoding parameters, num_temporal_layers not changed.
6280 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6281 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6282 parameters.encodings[0].min_bitrate_bps = 33000;
6283 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6284
6285 // Verify that no value is propagated down to the encoder.
6286 webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
6287 EXPECT_EQ(kNumSimulcastStreams, encoder_config.number_of_streams);
6288 EXPECT_EQ(kNumSimulcastStreams, encoder_config.simulcast_layers.size());
6289 EXPECT_FALSE(encoder_config.simulcast_layers[0].num_temporal_layers);
6290 EXPECT_FALSE(encoder_config.simulcast_layers[1].num_temporal_layers);
6291 EXPECT_FALSE(encoder_config.simulcast_layers[2].num_temporal_layers);
6292
6293 // FakeVideoSendStream calls CreateEncoderStreams, test that the vector of
6294 // VideoStreams are created appropriately for the simulcast case.
6295 EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
6296 EXPECT_EQ(kDefaultNumTemporalLayers,
6297 stream->GetVideoStreams()[0].num_temporal_layers);
6298 EXPECT_EQ(kDefaultNumTemporalLayers,
6299 stream->GetVideoStreams()[1].num_temporal_layers);
6300 EXPECT_EQ(kDefaultNumTemporalLayers,
6301 stream->GetVideoStreams()[2].num_temporal_layers);
6302
6303 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
6304}
6305
Åsa Persson8c1bf952018-09-13 10:42:19 +02006306TEST_F(WebRtcVideoChannelTest, MaxSimulcastFrameratePropagatedToEncoder) {
6307 const size_t kNumSimulcastStreams = 3;
6308 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
6309
6310 // Send a full size frame so all simulcast layers are used when reconfiguring.
Niels Möller805a27e2019-01-21 12:21:27 +01006311 webrtc::test::FrameForwarder frame_forwarder;
Åsa Persson8c1bf952018-09-13 10:42:19 +02006312 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01006313 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
Åsa Persson8c1bf952018-09-13 10:42:19 +02006314 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01006315 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Åsa Persson8c1bf952018-09-13 10:42:19 +02006316
6317 // Get and set the rtp encoding parameters.
6318 // Change the value and set it on the VideoChannel.
6319 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6320 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6321 parameters.encodings[0].max_framerate = 15;
6322 parameters.encodings[1].max_framerate = 25;
6323 parameters.encodings[2].max_framerate = 20;
6324 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6325
6326 // Verify that the new value propagated down to the encoder.
6327 // Check that WebRtcVideoSendStream updates VideoEncoderConfig correctly.
6328 EXPECT_EQ(2, stream->num_encoder_reconfigurations());
6329 webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
6330 EXPECT_EQ(kNumSimulcastStreams, encoder_config.number_of_streams);
6331 EXPECT_EQ(kNumSimulcastStreams, encoder_config.simulcast_layers.size());
6332 EXPECT_EQ(15, encoder_config.simulcast_layers[0].max_framerate);
6333 EXPECT_EQ(25, encoder_config.simulcast_layers[1].max_framerate);
6334 EXPECT_EQ(20, encoder_config.simulcast_layers[2].max_framerate);
6335
6336 // FakeVideoSendStream calls CreateEncoderStreams, test that the vector of
6337 // VideoStreams are created appropriately for the simulcast case.
6338 // Currently the maximum |max_framerate| is used.
6339 EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
6340 EXPECT_EQ(25, stream->GetVideoStreams()[0].max_framerate);
6341 EXPECT_EQ(25, stream->GetVideoStreams()[1].max_framerate);
6342 EXPECT_EQ(25, stream->GetVideoStreams()[2].max_framerate);
6343
6344 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
6345}
6346
6347TEST_F(WebRtcVideoChannelTest,
6348 DefaultValuePropagatedToEncoderForUnsetFramerate) {
6349 const size_t kNumSimulcastStreams = 3;
6350 const std::vector<webrtc::VideoStream> kDefault = GetSimulcastBitrates720p();
6351 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
6352
6353 // Send a full size frame so all simulcast layers are used when reconfiguring.
Niels Möller805a27e2019-01-21 12:21:27 +01006354 webrtc::test::FrameForwarder frame_forwarder;
Åsa Persson8c1bf952018-09-13 10:42:19 +02006355 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01006356 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
Åsa Persson8c1bf952018-09-13 10:42:19 +02006357 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01006358 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Åsa Persson8c1bf952018-09-13 10:42:19 +02006359
6360 // Get and set the rtp encoding parameters.
6361 // Change the value and set it on the VideoChannel.
6362 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6363 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6364 parameters.encodings[0].max_framerate = 15;
6365 parameters.encodings[2].max_framerate = 20;
6366 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6367
6368 // Verify that the new value propagated down to the encoder.
6369 // Check that WebRtcVideoSendStream updates VideoEncoderConfig correctly.
6370 webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
6371 EXPECT_EQ(kNumSimulcastStreams, encoder_config.number_of_streams);
6372 EXPECT_EQ(kNumSimulcastStreams, encoder_config.simulcast_layers.size());
6373 EXPECT_EQ(15, encoder_config.simulcast_layers[0].max_framerate);
6374 EXPECT_EQ(-1, encoder_config.simulcast_layers[1].max_framerate);
6375 EXPECT_EQ(20, encoder_config.simulcast_layers[2].max_framerate);
6376
6377 // FakeVideoSendStream calls CreateEncoderStreams, test that the vector of
6378 // VideoStreams are created appropriately for the simulcast case.
6379 // The maximum |max_framerate| is used, kDefaultVideoMaxFramerate: 60.
6380 EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
6381 EXPECT_EQ(kDefaultVideoMaxFramerate,
6382 stream->GetVideoStreams()[0].max_framerate);
6383 EXPECT_EQ(kDefaultVideoMaxFramerate,
6384 stream->GetVideoStreams()[1].max_framerate);
6385 EXPECT_EQ(kDefaultVideoMaxFramerate,
6386 stream->GetVideoStreams()[2].max_framerate);
6387
6388 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
6389}
6390
Åsa Persson55659812018-06-18 17:51:32 +02006391TEST_F(WebRtcVideoChannelTest, GetAndSetRtpSendParametersMinAndMaxBitrate) {
6392 const size_t kNumSimulcastStreams = 3;
6393 SetUpSimulcast(true, false);
6394
6395 // Get and set the rtp encoding parameters.
6396 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6397 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6398 for (const auto& encoding : parameters.encodings) {
6399 EXPECT_FALSE(encoding.min_bitrate_bps);
6400 EXPECT_FALSE(encoding.max_bitrate_bps);
6401 }
6402
6403 // Change the value and set it on the VideoChannel.
6404 parameters.encodings[0].min_bitrate_bps = 100000;
6405 parameters.encodings[0].max_bitrate_bps = 200000;
6406 parameters.encodings[1].min_bitrate_bps = 300000;
6407 parameters.encodings[1].max_bitrate_bps = 400000;
6408 parameters.encodings[2].min_bitrate_bps = 500000;
6409 parameters.encodings[2].max_bitrate_bps = 600000;
6410 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6411
6412 // Verify that the bitrates are set on the VideoChannel.
6413 parameters = channel_->GetRtpSendParameters(last_ssrc_);
6414 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6415 EXPECT_EQ(100000, parameters.encodings[0].min_bitrate_bps);
6416 EXPECT_EQ(200000, parameters.encodings[0].max_bitrate_bps);
6417 EXPECT_EQ(300000, parameters.encodings[1].min_bitrate_bps);
6418 EXPECT_EQ(400000, parameters.encodings[1].max_bitrate_bps);
6419 EXPECT_EQ(500000, parameters.encodings[2].min_bitrate_bps);
6420 EXPECT_EQ(600000, parameters.encodings[2].max_bitrate_bps);
6421}
6422
6423TEST_F(WebRtcVideoChannelTest, SetRtpSendParametersFailsWithIncorrectBitrate) {
6424 const size_t kNumSimulcastStreams = 3;
6425 SetUpSimulcast(true, false);
6426
6427 // Get and set the rtp encoding parameters.
6428 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6429 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6430
6431 // Max bitrate lower than min bitrate should fail.
6432 parameters.encodings[2].min_bitrate_bps = 100000;
6433 parameters.encodings[2].max_bitrate_bps = 100000 - 1;
6434 EXPECT_EQ(webrtc::RTCErrorType::INVALID_RANGE,
6435 channel_->SetRtpSendParameters(last_ssrc_, parameters).type());
6436}
6437
6438// Test that min and max bitrate values set via RtpParameters are correctly
6439// propagated to the underlying encoder, and that the target is set to 3/4 of
6440// the maximum (3/4 was chosen because it's similar to the simulcast defaults
6441// that are used if no min/max are specified).
6442TEST_F(WebRtcVideoChannelTest, MinAndMaxSimulcastBitratePropagatedToEncoder) {
6443 const size_t kNumSimulcastStreams = 3;
6444 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
6445
6446 // Send a full size frame so all simulcast layers are used when reconfiguring.
Niels Möller805a27e2019-01-21 12:21:27 +01006447 webrtc::test::FrameForwarder frame_forwarder;
Åsa Persson55659812018-06-18 17:51:32 +02006448 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01006449 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
Åsa Persson55659812018-06-18 17:51:32 +02006450 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01006451 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Åsa Persson55659812018-06-18 17:51:32 +02006452
6453 // Get and set the rtp encoding parameters.
6454 // Change the value and set it on the VideoChannel.
6455 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6456 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6457 parameters.encodings[0].min_bitrate_bps = 100000;
6458 parameters.encodings[0].max_bitrate_bps = 200000;
6459 parameters.encodings[1].min_bitrate_bps = 300000;
6460 parameters.encodings[1].max_bitrate_bps = 400000;
6461 parameters.encodings[2].min_bitrate_bps = 500000;
6462 parameters.encodings[2].max_bitrate_bps = 600000;
6463 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6464
6465 // Verify that the new value propagated down to the encoder.
6466 // Check that WebRtcVideoSendStream updates VideoEncoderConfig correctly.
6467 EXPECT_EQ(2, stream->num_encoder_reconfigurations());
6468 webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
6469 EXPECT_EQ(kNumSimulcastStreams, encoder_config.number_of_streams);
6470 EXPECT_EQ(kNumSimulcastStreams, encoder_config.simulcast_layers.size());
6471 EXPECT_EQ(100000, encoder_config.simulcast_layers[0].min_bitrate_bps);
6472 EXPECT_EQ(200000, encoder_config.simulcast_layers[0].max_bitrate_bps);
6473 EXPECT_EQ(300000, encoder_config.simulcast_layers[1].min_bitrate_bps);
6474 EXPECT_EQ(400000, encoder_config.simulcast_layers[1].max_bitrate_bps);
6475 EXPECT_EQ(500000, encoder_config.simulcast_layers[2].min_bitrate_bps);
6476 EXPECT_EQ(600000, encoder_config.simulcast_layers[2].max_bitrate_bps);
6477
6478 // FakeVideoSendStream calls CreateEncoderStreams, test that the vector of
6479 // VideoStreams are created appropriately for the simulcast case.
6480 EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
6481 // Target bitrate: 200000 * 3 / 4 = 150000.
6482 EXPECT_EQ(100000, stream->GetVideoStreams()[0].min_bitrate_bps);
6483 EXPECT_EQ(150000, stream->GetVideoStreams()[0].target_bitrate_bps);
6484 EXPECT_EQ(200000, stream->GetVideoStreams()[0].max_bitrate_bps);
6485 // Target bitrate: 400000 * 3 / 4 = 300000.
6486 EXPECT_EQ(300000, stream->GetVideoStreams()[1].min_bitrate_bps);
6487 EXPECT_EQ(300000, stream->GetVideoStreams()[1].target_bitrate_bps);
6488 EXPECT_EQ(400000, stream->GetVideoStreams()[1].max_bitrate_bps);
6489 // Target bitrate: 600000 * 3 / 4 = 450000, less than min -> max.
6490 EXPECT_EQ(500000, stream->GetVideoStreams()[2].min_bitrate_bps);
6491 EXPECT_EQ(600000, stream->GetVideoStreams()[2].target_bitrate_bps);
6492 EXPECT_EQ(600000, stream->GetVideoStreams()[2].max_bitrate_bps);
6493
6494 // No parameter changed, encoder should not be reconfigured.
6495 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6496 EXPECT_EQ(2, stream->num_encoder_reconfigurations());
6497
6498 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
6499}
6500
6501// Test to only specify the min or max bitrate value for a layer via
6502// RtpParameters. The unspecified min/max and target value should be set to the
6503// simulcast default that is used if no min/max are specified.
6504TEST_F(WebRtcVideoChannelTest, MinOrMaxSimulcastBitratePropagatedToEncoder) {
6505 const size_t kNumSimulcastStreams = 3;
6506 const std::vector<webrtc::VideoStream> kDefault = GetSimulcastBitrates720p();
6507 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
6508
6509 // Send a full size frame so all simulcast layers are used when reconfiguring.
Niels Möller805a27e2019-01-21 12:21:27 +01006510 webrtc::test::FrameForwarder frame_forwarder;
Åsa Persson55659812018-06-18 17:51:32 +02006511 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01006512 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
Åsa Persson55659812018-06-18 17:51:32 +02006513 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01006514 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Åsa Persson55659812018-06-18 17:51:32 +02006515
6516 // Get and set the rtp encoding parameters.
6517 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6518 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6519
6520 // Change the value and set it on the VideoChannel.
6521 // Layer 0: only configure min bitrate.
6522 const int kMinBpsLayer0 = kDefault[0].min_bitrate_bps + 1;
6523 parameters.encodings[0].min_bitrate_bps = kMinBpsLayer0;
6524 // Layer 1: only configure max bitrate.
6525 const int kMaxBpsLayer1 = kDefault[1].max_bitrate_bps - 1;
6526 parameters.encodings[1].max_bitrate_bps = kMaxBpsLayer1;
6527 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6528
6529 // Verify that the new value propagated down to the encoder.
6530 // Check that WebRtcVideoSendStream updates VideoEncoderConfig correctly.
6531 webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
6532 EXPECT_EQ(kNumSimulcastStreams, encoder_config.number_of_streams);
6533 EXPECT_EQ(kNumSimulcastStreams, encoder_config.simulcast_layers.size());
6534 EXPECT_EQ(kMinBpsLayer0, encoder_config.simulcast_layers[0].min_bitrate_bps);
6535 EXPECT_EQ(-1, encoder_config.simulcast_layers[0].max_bitrate_bps);
6536 EXPECT_EQ(-1, encoder_config.simulcast_layers[1].min_bitrate_bps);
6537 EXPECT_EQ(kMaxBpsLayer1, encoder_config.simulcast_layers[1].max_bitrate_bps);
6538 EXPECT_EQ(-1, encoder_config.simulcast_layers[2].min_bitrate_bps);
6539 EXPECT_EQ(-1, encoder_config.simulcast_layers[2].max_bitrate_bps);
6540
6541 // FakeVideoSendStream calls CreateEncoderStreams, test that the vector of
6542 // VideoStreams are created appropriately for the simulcast case.
6543 EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
6544 // Layer 0: min configured bitrate should overwrite min default.
6545 EXPECT_EQ(kMinBpsLayer0, stream->GetVideoStreams()[0].min_bitrate_bps);
6546 EXPECT_EQ(kDefault[0].target_bitrate_bps,
6547 stream->GetVideoStreams()[0].target_bitrate_bps);
6548 EXPECT_EQ(kDefault[0].max_bitrate_bps,
6549 stream->GetVideoStreams()[0].max_bitrate_bps);
6550 // Layer 1: max configured bitrate should overwrite max default.
6551 EXPECT_EQ(kDefault[1].min_bitrate_bps,
6552 stream->GetVideoStreams()[1].min_bitrate_bps);
6553 EXPECT_EQ(kDefault[1].target_bitrate_bps,
6554 stream->GetVideoStreams()[1].target_bitrate_bps);
6555 EXPECT_EQ(kMaxBpsLayer1, stream->GetVideoStreams()[1].max_bitrate_bps);
6556 // Layer 2: min and max bitrate not configured, default expected.
6557 EXPECT_EQ(kDefault[2].min_bitrate_bps,
6558 stream->GetVideoStreams()[2].min_bitrate_bps);
6559 EXPECT_EQ(kDefault[2].target_bitrate_bps,
6560 stream->GetVideoStreams()[2].target_bitrate_bps);
6561 EXPECT_EQ(kDefault[2].max_bitrate_bps,
6562 stream->GetVideoStreams()[2].max_bitrate_bps);
6563
6564 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
6565}
6566
6567// Test that specifying the min (or max) bitrate value for a layer via
6568// RtpParameters above (or below) the simulcast default max (or min) adjusts the
6569// unspecified values accordingly.
6570TEST_F(WebRtcVideoChannelTest, SetMinAndMaxSimulcastBitrateAboveBelowDefault) {
6571 const size_t kNumSimulcastStreams = 3;
6572 const std::vector<webrtc::VideoStream> kDefault = GetSimulcastBitrates720p();
6573 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
6574
6575 // Send a full size frame so all simulcast layers are used when reconfiguring.
Niels Möller805a27e2019-01-21 12:21:27 +01006576 webrtc::test::FrameForwarder frame_forwarder;
Åsa Persson55659812018-06-18 17:51:32 +02006577 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01006578 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
Åsa Persson55659812018-06-18 17:51:32 +02006579 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01006580 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Åsa Persson55659812018-06-18 17:51:32 +02006581
6582 // Get and set the rtp encoding parameters.
6583 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6584 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6585
6586 // Change the value and set it on the VideoChannel.
6587 // For layer 0, set the min bitrate above the default max.
6588 const int kMinBpsLayer0 = kDefault[0].max_bitrate_bps + 1;
6589 parameters.encodings[0].min_bitrate_bps = kMinBpsLayer0;
6590 // For layer 1, set the max bitrate below the default min.
6591 const int kMaxBpsLayer1 = kDefault[1].min_bitrate_bps - 1;
6592 parameters.encodings[1].max_bitrate_bps = kMaxBpsLayer1;
6593 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6594
6595 // Verify that the new value propagated down to the encoder.
6596 // FakeVideoSendStream calls CreateEncoderStreams, test that the vector of
6597 // VideoStreams are created appropriately for the simulcast case.
6598 EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
6599 // Layer 0: Min bitrate above default max (target/max should be adjusted).
6600 EXPECT_EQ(kMinBpsLayer0, stream->GetVideoStreams()[0].min_bitrate_bps);
6601 EXPECT_EQ(kMinBpsLayer0, stream->GetVideoStreams()[0].target_bitrate_bps);
6602 EXPECT_EQ(kMinBpsLayer0, stream->GetVideoStreams()[0].max_bitrate_bps);
6603 // Layer 1: Max bitrate below default min (min/target should be adjusted).
6604 EXPECT_EQ(kMaxBpsLayer1, stream->GetVideoStreams()[1].min_bitrate_bps);
6605 EXPECT_EQ(kMaxBpsLayer1, stream->GetVideoStreams()[1].target_bitrate_bps);
6606 EXPECT_EQ(kMaxBpsLayer1, stream->GetVideoStreams()[1].max_bitrate_bps);
6607 // Layer 2: min and max bitrate not configured, default expected.
6608 EXPECT_EQ(kDefault[2].min_bitrate_bps,
6609 stream->GetVideoStreams()[2].min_bitrate_bps);
6610 EXPECT_EQ(kDefault[2].target_bitrate_bps,
6611 stream->GetVideoStreams()[2].target_bitrate_bps);
6612 EXPECT_EQ(kDefault[2].max_bitrate_bps,
6613 stream->GetVideoStreams()[2].max_bitrate_bps);
6614
6615 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
6616}
6617
6618TEST_F(WebRtcVideoChannelTest, BandwidthAboveTotalMaxBitrateGivenToMaxLayer) {
6619 const size_t kNumSimulcastStreams = 3;
6620 const std::vector<webrtc::VideoStream> kDefault = GetSimulcastBitrates720p();
6621 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
6622
6623 // Send a full size frame so all simulcast layers are used when reconfiguring.
Niels Möller805a27e2019-01-21 12:21:27 +01006624 webrtc::test::FrameForwarder frame_forwarder;
Åsa Persson55659812018-06-18 17:51:32 +02006625 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01006626 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
Åsa Persson55659812018-06-18 17:51:32 +02006627 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01006628 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Åsa Persson55659812018-06-18 17:51:32 +02006629
6630 // Set max bitrate for all but the highest layer.
6631 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6632 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6633 parameters.encodings[0].max_bitrate_bps = kDefault[0].max_bitrate_bps;
6634 parameters.encodings[1].max_bitrate_bps = kDefault[1].max_bitrate_bps;
6635 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6636
6637 // Set max bandwidth equal to total max bitrate.
6638 send_parameters_.max_bandwidth_bps =
6639 GetTotalMaxBitrateBps(stream->GetVideoStreams());
6640 ExpectSetMaxBitrate(send_parameters_.max_bandwidth_bps);
6641 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
6642
6643 // No bitrate above the total max to give to the highest layer.
6644 EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
6645 EXPECT_EQ(kDefault[2].max_bitrate_bps,
6646 stream->GetVideoStreams()[2].max_bitrate_bps);
6647
6648 // Set max bandwidth above the total max bitrate.
6649 send_parameters_.max_bandwidth_bps =
6650 GetTotalMaxBitrateBps(stream->GetVideoStreams()) + 1;
6651 ExpectSetMaxBitrate(send_parameters_.max_bandwidth_bps);
6652 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
6653
6654 // The highest layer has no max bitrate set -> the bitrate above the total
6655 // max should be given to the highest layer.
6656 EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
6657 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
6658 GetTotalMaxBitrateBps(stream->GetVideoStreams()));
6659 EXPECT_EQ(kDefault[2].max_bitrate_bps + 1,
6660 stream->GetVideoStreams()[2].max_bitrate_bps);
6661
6662 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
6663}
6664
6665TEST_F(WebRtcVideoChannelTest,
6666 BandwidthAboveTotalMaxBitrateNotGivenToMaxLayerIfMaxBitrateSet) {
6667 const size_t kNumSimulcastStreams = 3;
6668 const std::vector<webrtc::VideoStream> kDefault = GetSimulcastBitrates720p();
6669 EXPECT_EQ(kNumSimulcastStreams, kDefault.size());
6670 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
6671
6672 // Send a full size frame so all simulcast layers are used when reconfiguring.
Niels Möller805a27e2019-01-21 12:21:27 +01006673 webrtc::test::FrameForwarder frame_forwarder;
Åsa Persson55659812018-06-18 17:51:32 +02006674 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01006675 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
Åsa Persson55659812018-06-18 17:51:32 +02006676 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01006677 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Åsa Persson55659812018-06-18 17:51:32 +02006678
6679 // Set max bitrate for the highest layer.
6680 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6681 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6682 parameters.encodings[2].max_bitrate_bps = kDefault[2].max_bitrate_bps;
6683 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6684
6685 // Set max bandwidth above the total max bitrate.
6686 send_parameters_.max_bandwidth_bps =
6687 GetTotalMaxBitrateBps(stream->GetVideoStreams()) + 1;
6688 ExpectSetMaxBitrate(send_parameters_.max_bandwidth_bps);
6689 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
6690
6691 // The highest layer has the max bitrate set -> the bitrate above the total
6692 // max should not be given to the highest layer.
6693 EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
6694 EXPECT_EQ(*parameters.encodings[2].max_bitrate_bps,
6695 stream->GetVideoStreams()[2].max_bitrate_bps);
6696
6697 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
6698}
6699
Åsa Perssonbdee46d2018-06-25 11:28:06 +02006700// Test that min and max bitrate values set via RtpParameters are correctly
6701// propagated to the underlying encoder for a single stream.
6702TEST_F(WebRtcVideoChannelTest, MinAndMaxBitratePropagatedToEncoder) {
6703 FakeVideoSendStream* stream = AddSendStream();
6704 EXPECT_TRUE(channel_->SetSend(true));
6705 EXPECT_TRUE(stream->IsSending());
6706
6707 // Set min and max bitrate.
6708 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6709 EXPECT_EQ(1u, parameters.encodings.size());
6710 parameters.encodings[0].min_bitrate_bps = 80000;
6711 parameters.encodings[0].max_bitrate_bps = 150000;
6712 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6713
6714 // Check that WebRtcVideoSendStream updates VideoEncoderConfig correctly.
6715 webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
6716 EXPECT_EQ(1u, encoder_config.number_of_streams);
6717 EXPECT_EQ(1u, encoder_config.simulcast_layers.size());
6718 EXPECT_EQ(80000, encoder_config.simulcast_layers[0].min_bitrate_bps);
6719 EXPECT_EQ(150000, encoder_config.simulcast_layers[0].max_bitrate_bps);
6720
6721 // FakeVideoSendStream calls CreateEncoderStreams, test that the vector of
6722 // VideoStreams are created appropriately.
6723 EXPECT_EQ(1u, stream->GetVideoStreams().size());
6724 EXPECT_EQ(80000, stream->GetVideoStreams()[0].min_bitrate_bps);
6725 EXPECT_EQ(150000, stream->GetVideoStreams()[0].target_bitrate_bps);
6726 EXPECT_EQ(150000, stream->GetVideoStreams()[0].max_bitrate_bps);
6727}
6728
6729// Test the default min and max bitrate value are correctly propagated to the
6730// underlying encoder for a single stream (when the values are not set via
6731// RtpParameters).
6732TEST_F(WebRtcVideoChannelTest, DefaultMinAndMaxBitratePropagatedToEncoder) {
6733 FakeVideoSendStream* stream = AddSendStream();
6734 EXPECT_TRUE(channel_->SetSend(true));
6735 EXPECT_TRUE(stream->IsSending());
6736
6737 // Check that WebRtcVideoSendStream updates VideoEncoderConfig correctly.
6738 webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
6739 EXPECT_EQ(1u, encoder_config.number_of_streams);
6740 EXPECT_EQ(1u, encoder_config.simulcast_layers.size());
6741 EXPECT_EQ(-1, encoder_config.simulcast_layers[0].min_bitrate_bps);
6742 EXPECT_EQ(-1, encoder_config.simulcast_layers[0].max_bitrate_bps);
6743
6744 // FakeVideoSendStream calls CreateEncoderStreams, test that the vector of
6745 // VideoStreams are created appropriately.
6746 EXPECT_EQ(1u, stream->GetVideoStreams().size());
6747 EXPECT_EQ(cricket::kMinVideoBitrateBps,
6748 stream->GetVideoStreams()[0].min_bitrate_bps);
6749 EXPECT_GT(stream->GetVideoStreams()[0].max_bitrate_bps,
6750 stream->GetVideoStreams()[0].min_bitrate_bps);
6751 EXPECT_EQ(stream->GetVideoStreams()[0].max_bitrate_bps,
6752 stream->GetVideoStreams()[0].target_bitrate_bps);
6753}
6754
Taylor Brandstetter14b9d792016-09-07 17:16:54 -07006755// Test that a stream will not be sending if its encoding is made inactive
6756// through SetRtpSendParameters.
Seth Hampson8234ead2018-02-02 15:16:24 -08006757TEST_F(WebRtcVideoChannelTest, SetRtpSendParametersOneEncodingActive) {
deadbeefdbe2b872016-03-22 15:42:00 -07006758 FakeVideoSendStream* stream = AddSendStream();
6759 EXPECT_TRUE(channel_->SetSend(true));
6760 EXPECT_TRUE(stream->IsSending());
6761
6762 // Get current parameters and change "active" to false.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07006763 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
deadbeefdbe2b872016-03-22 15:42:00 -07006764 ASSERT_EQ(1u, parameters.encodings.size());
6765 ASSERT_TRUE(parameters.encodings[0].active);
6766 parameters.encodings[0].active = false;
Zach Steinba37b4b2018-01-23 15:02:36 -08006767 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
deadbeefdbe2b872016-03-22 15:42:00 -07006768 EXPECT_FALSE(stream->IsSending());
6769
6770 // Now change it back to active and verify we resume sending.
6771 parameters.encodings[0].active = true;
Zach Steinba37b4b2018-01-23 15:02:36 -08006772 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
deadbeefdbe2b872016-03-22 15:42:00 -07006773 EXPECT_TRUE(stream->IsSending());
6774}
6775
Seth Hampson8234ead2018-02-02 15:16:24 -08006776// Tests that when active is updated for any simulcast layer then the send
6777// stream's sending state will be updated and it will be reconfigured with the
6778// new appropriate active simulcast streams.
6779TEST_F(WebRtcVideoChannelTest, SetRtpSendParametersMultipleEncodingsActive) {
6780 // Create the stream params with multiple ssrcs for simulcast.
Åsa Persson31cb8f92018-06-27 10:44:56 +02006781 const size_t kNumSimulcastStreams = 3;
Seth Hampson8234ead2018-02-02 15:16:24 -08006782 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
6783 StreamParams stream_params = CreateSimStreamParams("cname", ssrcs);
6784 FakeVideoSendStream* fake_video_send_stream = AddSendStream(stream_params);
6785 uint32_t primary_ssrc = stream_params.first_ssrc();
6786
Niels Möller805a27e2019-01-21 12:21:27 +01006787 // Using the FrameForwarder, we manually send a full size
Tommi85959932018-02-07 19:26:06 +01006788 // frame. This allows us to test that ReconfigureEncoder is called
6789 // appropriately.
Niels Möller805a27e2019-01-21 12:21:27 +01006790 webrtc::test::FrameForwarder frame_forwarder;
Seth Hampson8234ead2018-02-02 15:16:24 -08006791 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01006792 EXPECT_TRUE(channel_->SetVideoSend(primary_ssrc, &options, &frame_forwarder));
Seth Hampson8234ead2018-02-02 15:16:24 -08006793 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01006794 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame(
6795 1920, 1080, webrtc::VideoRotation::kVideoRotation_0,
6796 rtc::kNumMicrosecsPerSec / 30));
Seth Hampson8234ead2018-02-02 15:16:24 -08006797
6798 // Check that all encodings are initially active.
6799 webrtc::RtpParameters parameters =
6800 channel_->GetRtpSendParameters(primary_ssrc);
Åsa Persson31cb8f92018-06-27 10:44:56 +02006801 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
Seth Hampson8234ead2018-02-02 15:16:24 -08006802 EXPECT_TRUE(parameters.encodings[0].active);
6803 EXPECT_TRUE(parameters.encodings[1].active);
6804 EXPECT_TRUE(parameters.encodings[2].active);
6805 EXPECT_TRUE(fake_video_send_stream->IsSending());
6806
6807 // Only turn on only the middle stream.
6808 parameters.encodings[0].active = false;
6809 parameters.encodings[1].active = true;
6810 parameters.encodings[2].active = false;
6811 EXPECT_TRUE(channel_->SetRtpSendParameters(primary_ssrc, parameters).ok());
6812 // Verify that the active fields are set on the VideoChannel.
6813 parameters = channel_->GetRtpSendParameters(primary_ssrc);
Åsa Persson31cb8f92018-06-27 10:44:56 +02006814 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
Seth Hampson8234ead2018-02-02 15:16:24 -08006815 EXPECT_FALSE(parameters.encodings[0].active);
6816 EXPECT_TRUE(parameters.encodings[1].active);
6817 EXPECT_FALSE(parameters.encodings[2].active);
6818 // Check that the VideoSendStream is updated appropriately. This means its
6819 // send state was updated and it was reconfigured.
6820 EXPECT_TRUE(fake_video_send_stream->IsSending());
6821 std::vector<webrtc::VideoStream> simulcast_streams =
6822 fake_video_send_stream->GetVideoStreams();
Åsa Persson31cb8f92018-06-27 10:44:56 +02006823 EXPECT_EQ(kNumSimulcastStreams, simulcast_streams.size());
Seth Hampson8234ead2018-02-02 15:16:24 -08006824 EXPECT_FALSE(simulcast_streams[0].active);
6825 EXPECT_TRUE(simulcast_streams[1].active);
6826 EXPECT_FALSE(simulcast_streams[2].active);
6827
6828 // Turn off all streams.
6829 parameters.encodings[0].active = false;
6830 parameters.encodings[1].active = false;
6831 parameters.encodings[2].active = false;
6832 EXPECT_TRUE(channel_->SetRtpSendParameters(primary_ssrc, parameters).ok());
6833 // Verify that the active fields are set on the VideoChannel.
6834 parameters = channel_->GetRtpSendParameters(primary_ssrc);
Åsa Persson31cb8f92018-06-27 10:44:56 +02006835 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
Seth Hampson8234ead2018-02-02 15:16:24 -08006836 EXPECT_FALSE(parameters.encodings[0].active);
6837 EXPECT_FALSE(parameters.encodings[1].active);
6838 EXPECT_FALSE(parameters.encodings[2].active);
6839 // Check that the VideoSendStream is off.
6840 EXPECT_FALSE(fake_video_send_stream->IsSending());
6841 simulcast_streams = fake_video_send_stream->GetVideoStreams();
Åsa Persson31cb8f92018-06-27 10:44:56 +02006842 EXPECT_EQ(kNumSimulcastStreams, simulcast_streams.size());
Seth Hampson8234ead2018-02-02 15:16:24 -08006843 EXPECT_FALSE(simulcast_streams[0].active);
6844 EXPECT_FALSE(simulcast_streams[1].active);
6845 EXPECT_FALSE(simulcast_streams[2].active);
6846
Niels Möllerff40b142018-04-09 08:49:14 +02006847 EXPECT_TRUE(channel_->SetVideoSend(primary_ssrc, nullptr, nullptr));
Seth Hampson8234ead2018-02-02 15:16:24 -08006848}
6849
Taylor Brandstetter14b9d792016-09-07 17:16:54 -07006850// Test that if a stream is reconfigured (due to a codec change or other
6851// change) while its encoding is still inactive, it doesn't start sending.
eladalonf1841382017-06-12 01:16:46 -07006852TEST_F(WebRtcVideoChannelTest,
Taylor Brandstetter14b9d792016-09-07 17:16:54 -07006853 InactiveStreamDoesntStartSendingWhenReconfigured) {
6854 // Set an initial codec list, which will be modified later.
6855 cricket::VideoSendParameters parameters1;
magjed509e4fe2016-11-18 01:34:11 -08006856 parameters1.codecs.push_back(GetEngineCodec("VP8"));
6857 parameters1.codecs.push_back(GetEngineCodec("VP9"));
Taylor Brandstetter14b9d792016-09-07 17:16:54 -07006858 EXPECT_TRUE(channel_->SetSendParameters(parameters1));
6859
6860 FakeVideoSendStream* stream = AddSendStream();
6861 EXPECT_TRUE(channel_->SetSend(true));
6862 EXPECT_TRUE(stream->IsSending());
6863
6864 // Get current parameters and change "active" to false.
6865 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6866 ASSERT_EQ(1u, parameters.encodings.size());
6867 ASSERT_TRUE(parameters.encodings[0].active);
6868 parameters.encodings[0].active = false;
6869 EXPECT_EQ(1u, GetFakeSendStreams().size());
6870 EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());
Zach Steinba37b4b2018-01-23 15:02:36 -08006871 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
Taylor Brandstetter14b9d792016-09-07 17:16:54 -07006872 EXPECT_FALSE(stream->IsSending());
6873
6874 // Reorder the codec list, causing the stream to be reconfigured.
6875 cricket::VideoSendParameters parameters2;
magjed509e4fe2016-11-18 01:34:11 -08006876 parameters2.codecs.push_back(GetEngineCodec("VP9"));
6877 parameters2.codecs.push_back(GetEngineCodec("VP8"));
Taylor Brandstetter14b9d792016-09-07 17:16:54 -07006878 EXPECT_TRUE(channel_->SetSendParameters(parameters2));
6879 auto new_streams = GetFakeSendStreams();
6880 // Assert that a new underlying stream was created due to the codec change.
6881 // Otherwise, this test isn't testing what it set out to test.
6882 EXPECT_EQ(1u, GetFakeSendStreams().size());
6883 EXPECT_EQ(2, fake_call_->GetNumCreatedSendStreams());
6884
6885 // Verify that we still are not sending anything, due to the inactive
6886 // encoding.
6887 EXPECT_FALSE(new_streams[0]->IsSending());
6888}
6889
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07006890// Test that GetRtpSendParameters returns the currently configured codecs.
eladalonf1841382017-06-12 01:16:46 -07006891TEST_F(WebRtcVideoChannelTest, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07006892 AddSendStream();
6893 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08006894 parameters.codecs.push_back(GetEngineCodec("VP8"));
6895 parameters.codecs.push_back(GetEngineCodec("VP9"));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07006896 EXPECT_TRUE(channel_->SetSendParameters(parameters));
6897
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07006898 webrtc::RtpParameters rtp_parameters =
6899 channel_->GetRtpSendParameters(last_ssrc_);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07006900 ASSERT_EQ(2u, rtp_parameters.codecs.size());
magjed509e4fe2016-11-18 01:34:11 -08006901 EXPECT_EQ(GetEngineCodec("VP8").ToCodecParameters(),
6902 rtp_parameters.codecs[0]);
6903 EXPECT_EQ(GetEngineCodec("VP9").ToCodecParameters(),
6904 rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07006905}
6906
Florent Castellidacec712018-05-24 16:24:21 +02006907// Test that GetRtpSendParameters returns the currently configured RTCP CNAME.
6908TEST_F(WebRtcVideoChannelTest, GetRtpSendParametersRtcpCname) {
6909 StreamParams params = StreamParams::CreateLegacy(kSsrc);
6910 params.cname = "rtcpcname";
6911 AddSendStream(params);
6912
6913 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrc);
6914 EXPECT_STREQ("rtcpcname", rtp_parameters.rtcp.cname.c_str());
6915}
6916
deadbeeffb2aced2017-01-06 23:05:37 -08006917// Test that RtpParameters for send stream has one encoding and it has
6918// the correct SSRC.
eladalonf1841382017-06-12 01:16:46 -07006919TEST_F(WebRtcVideoChannelTest, GetRtpSendParametersSsrc) {
deadbeeffb2aced2017-01-06 23:05:37 -08006920 AddSendStream();
6921
6922 webrtc::RtpParameters rtp_parameters =
6923 channel_->GetRtpSendParameters(last_ssrc_);
6924 ASSERT_EQ(1u, rtp_parameters.encodings.size());
Oskar Sundbom78807582017-11-16 11:09:55 +01006925 EXPECT_EQ(last_ssrc_, rtp_parameters.encodings[0].ssrc);
deadbeeffb2aced2017-01-06 23:05:37 -08006926}
6927
Florent Castelliabe301f2018-06-12 18:33:49 +02006928TEST_F(WebRtcVideoChannelTest, DetectRtpSendParameterHeaderExtensionsChange) {
6929 AddSendStream();
6930
6931 webrtc::RtpParameters rtp_parameters =
6932 channel_->GetRtpSendParameters(last_ssrc_);
6933 rtp_parameters.header_extensions.emplace_back();
6934
6935 EXPECT_NE(0u, rtp_parameters.header_extensions.size());
6936
6937 webrtc::RTCError result =
6938 channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
6939 EXPECT_EQ(webrtc::RTCErrorType::INVALID_MODIFICATION, result.type());
6940}
6941
Florent Castelli87b3c512018-07-18 16:00:28 +02006942TEST_F(WebRtcVideoChannelTest, GetRtpSendParametersDegradationPreference) {
6943 AddSendStream();
6944
Niels Möller805a27e2019-01-21 12:21:27 +01006945 webrtc::test::FrameForwarder frame_forwarder;
6946 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));
Florent Castelli87b3c512018-07-18 16:00:28 +02006947
6948 webrtc::RtpParameters rtp_parameters =
6949 channel_->GetRtpSendParameters(last_ssrc_);
6950 EXPECT_EQ(rtp_parameters.degradation_preference,
6951 webrtc::DegradationPreference::BALANCED);
6952 rtp_parameters.degradation_preference =
6953 webrtc::DegradationPreference::MAINTAIN_FRAMERATE;
6954
6955 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters).ok());
6956
6957 webrtc::RtpParameters updated_rtp_parameters =
6958 channel_->GetRtpSendParameters(last_ssrc_);
6959 EXPECT_EQ(updated_rtp_parameters.degradation_preference,
6960 webrtc::DegradationPreference::MAINTAIN_FRAMERATE);
6961
6962 // Remove the source since it will be destroyed before the channel
6963 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
6964}
6965
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07006966// Test that if we set/get parameters multiple times, we get the same results.
eladalonf1841382017-06-12 01:16:46 -07006967TEST_F(WebRtcVideoChannelTest, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07006968 AddSendStream();
6969 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08006970 parameters.codecs.push_back(GetEngineCodec("VP8"));
6971 parameters.codecs.push_back(GetEngineCodec("VP9"));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07006972 EXPECT_TRUE(channel_->SetSendParameters(parameters));
6973
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07006974 webrtc::RtpParameters initial_params =
6975 channel_->GetRtpSendParameters(last_ssrc_);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07006976
6977 // We should be able to set the params we just got.
Zach Steinba37b4b2018-01-23 15:02:36 -08006978 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, initial_params).ok());
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07006979
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07006980 // ... And this shouldn't change the params returned by GetRtpSendParameters.
6981 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(last_ssrc_));
6982}
6983
6984// Test that GetRtpReceiveParameters returns the currently configured codecs.
eladalonf1841382017-06-12 01:16:46 -07006985TEST_F(WebRtcVideoChannelTest, GetRtpReceiveParametersCodecs) {
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07006986 AddRecvStream();
6987 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08006988 parameters.codecs.push_back(GetEngineCodec("VP8"));
6989 parameters.codecs.push_back(GetEngineCodec("VP9"));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07006990 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
6991
6992 webrtc::RtpParameters rtp_parameters =
6993 channel_->GetRtpReceiveParameters(last_ssrc_);
6994 ASSERT_EQ(2u, rtp_parameters.codecs.size());
magjed509e4fe2016-11-18 01:34:11 -08006995 EXPECT_EQ(GetEngineCodec("VP8").ToCodecParameters(),
6996 rtp_parameters.codecs[0]);
6997 EXPECT_EQ(GetEngineCodec("VP9").ToCodecParameters(),
6998 rtp_parameters.codecs[1]);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07006999}
7000
johan073ece42016-08-26 02:59:47 -07007001#if defined(WEBRTC_USE_H264)
eladalonf1841382017-06-12 01:16:46 -07007002TEST_F(WebRtcVideoChannelTest, GetRtpReceiveFmtpSprop) {
johan073ece42016-08-26 02:59:47 -07007003#else
eladalonf1841382017-06-12 01:16:46 -07007004TEST_F(WebRtcVideoChannelTest, DISABLED_GetRtpReceiveFmtpSprop) {
johan073ece42016-08-26 02:59:47 -07007005#endif
johan3859c892016-08-05 09:19:25 -07007006 cricket::VideoRecvParameters parameters;
perkj26752742016-10-24 01:21:16 -07007007 cricket::VideoCodec kH264sprop1(101, "H264");
magjed5dfac562016-11-25 03:56:37 -08007008 kH264sprop1.SetParam(kH264FmtpSpropParameterSets, "uvw");
johan3859c892016-08-05 09:19:25 -07007009 parameters.codecs.push_back(kH264sprop1);
perkj26752742016-10-24 01:21:16 -07007010 cricket::VideoCodec kH264sprop2(102, "H264");
magjed5dfac562016-11-25 03:56:37 -08007011 kH264sprop2.SetParam(kH264FmtpSpropParameterSets, "xyz");
johan3859c892016-08-05 09:19:25 -07007012 parameters.codecs.push_back(kH264sprop2);
7013 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
7014
7015 FakeVideoReceiveStream* recv_stream = AddRecvStream();
7016 const webrtc::VideoReceiveStream::Config& cfg = recv_stream->GetConfig();
7017 webrtc::RtpParameters rtp_parameters =
7018 channel_->GetRtpReceiveParameters(last_ssrc_);
7019 ASSERT_EQ(2u, rtp_parameters.codecs.size());
7020 EXPECT_EQ(kH264sprop1.ToCodecParameters(), rtp_parameters.codecs[0]);
7021 ASSERT_EQ(2u, cfg.decoders.size());
7022 EXPECT_EQ(101, cfg.decoders[0].payload_type);
Niels Möllercb7e1d22018-09-11 15:56:04 +02007023 EXPECT_EQ("H264", cfg.decoders[0].video_format.name);
magjed5dfac562016-11-25 03:56:37 -08007024 const auto it0 =
Niels Möllercb7e1d22018-09-11 15:56:04 +02007025 cfg.decoders[0].video_format.parameters.find(kH264FmtpSpropParameterSets);
7026 ASSERT_TRUE(it0 != cfg.decoders[0].video_format.parameters.end());
magjed5dfac562016-11-25 03:56:37 -08007027 EXPECT_EQ("uvw", it0->second);
johan3859c892016-08-05 09:19:25 -07007028
7029 EXPECT_EQ(102, cfg.decoders[1].payload_type);
Niels Möllercb7e1d22018-09-11 15:56:04 +02007030 EXPECT_EQ("H264", cfg.decoders[1].video_format.name);
magjed5dfac562016-11-25 03:56:37 -08007031 const auto it1 =
Niels Möllercb7e1d22018-09-11 15:56:04 +02007032 cfg.decoders[1].video_format.parameters.find(kH264FmtpSpropParameterSets);
7033 ASSERT_TRUE(it1 != cfg.decoders[1].video_format.parameters.end());
magjed5dfac562016-11-25 03:56:37 -08007034 EXPECT_EQ("xyz", it1->second);
johan3859c892016-08-05 09:19:25 -07007035}
7036
sakal1fd95952016-06-22 00:46:15 -07007037// Test that RtpParameters for receive stream has one encoding and it has
7038// the correct SSRC.
eladalonf1841382017-06-12 01:16:46 -07007039TEST_F(WebRtcVideoChannelTest, GetRtpReceiveParametersSsrc) {
sakal1fd95952016-06-22 00:46:15 -07007040 AddRecvStream();
7041
7042 webrtc::RtpParameters rtp_parameters =
7043 channel_->GetRtpReceiveParameters(last_ssrc_);
7044 ASSERT_EQ(1u, rtp_parameters.encodings.size());
Oskar Sundbom78807582017-11-16 11:09:55 +01007045 EXPECT_EQ(last_ssrc_, rtp_parameters.encodings[0].ssrc);
sakal1fd95952016-06-22 00:46:15 -07007046}
7047
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07007048// Test that if we set/get parameters multiple times, we get the same results.
eladalonf1841382017-06-12 01:16:46 -07007049TEST_F(WebRtcVideoChannelTest, SetAndGetRtpReceiveParameters) {
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07007050 AddRecvStream();
7051 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08007052 parameters.codecs.push_back(GetEngineCodec("VP8"));
7053 parameters.codecs.push_back(GetEngineCodec("VP9"));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07007054 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
7055
7056 webrtc::RtpParameters initial_params =
7057 channel_->GetRtpReceiveParameters(last_ssrc_);
7058
7059 // We should be able to set the params we just got.
7060 EXPECT_TRUE(channel_->SetRtpReceiveParameters(last_ssrc_, initial_params));
7061
7062 // ... And this shouldn't change the params returned by
7063 // GetRtpReceiveParameters.
7064 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(last_ssrc_));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07007065}
7066
deadbeef3bc15102017-04-20 19:25:07 -07007067// Test that GetRtpReceiveParameters returns parameters correctly when SSRCs
7068// aren't signaled. It should always return an empty "RtpEncodingParameters",
7069// even after a packet is received and the unsignaled SSRC is known.
eladalonf1841382017-06-12 01:16:46 -07007070TEST_F(WebRtcVideoChannelTest, GetRtpReceiveParametersWithUnsignaledSsrc) {
deadbeef3bc15102017-04-20 19:25:07 -07007071 // Call necessary methods to configure receiving a default stream as
7072 // soon as it arrives.
7073 cricket::VideoRecvParameters parameters;
7074 parameters.codecs.push_back(GetEngineCodec("VP8"));
7075 parameters.codecs.push_back(GetEngineCodec("VP9"));
7076 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
7077
7078 // Call GetRtpReceiveParameters before configured to receive an unsignaled
7079 // stream. Should return nothing.
7080 EXPECT_EQ(webrtc::RtpParameters(), channel_->GetRtpReceiveParameters(0));
7081
7082 // Set a sink for an unsignaled stream.
7083 cricket::FakeVideoRenderer renderer;
7084 // Value of "0" means "unsignaled stream".
7085 EXPECT_TRUE(channel_->SetSink(0, &renderer));
7086
7087 // Call GetRtpReceiveParameters before the SSRC is known. Value of "0"
7088 // in this method means "unsignaled stream".
7089 webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(0);
7090 ASSERT_EQ(1u, rtp_parameters.encodings.size());
7091 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
7092
7093 // Receive VP8 packet.
7094 uint8_t data[kMinRtpPacketLen];
7095 cricket::RtpHeader rtpHeader;
7096 rtpHeader.payload_type = GetEngineCodec("VP8").id;
7097 rtpHeader.seq_num = rtpHeader.timestamp = 0;
7098 rtpHeader.ssrc = kIncomingUnsignalledSsrc;
7099 cricket::SetRtpHeader(data, sizeof(data), rtpHeader);
7100 rtc::CopyOnWriteBuffer packet(data, sizeof(data));
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07007101 channel_->OnPacketReceived(packet, /* packet_time_us */ -1);
deadbeef3bc15102017-04-20 19:25:07 -07007102
7103 // The |ssrc| member should still be unset.
7104 rtp_parameters = channel_->GetRtpReceiveParameters(0);
7105 ASSERT_EQ(1u, rtp_parameters.encodings.size());
7106 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
7107}
7108
eladalonf1841382017-06-12 01:16:46 -07007109void WebRtcVideoChannelTest::TestReceiverLocalSsrcConfiguration(
Peter Boström3548dd22015-05-22 18:48:36 +02007110 bool receiver_first) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02007111 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Peter Boström3548dd22015-05-22 18:48:36 +02007112
7113 const uint32_t kSenderSsrc = 0xC0FFEE;
Peter Boströmdfa28152015-10-21 17:21:10 +02007114 const uint32_t kSecondSenderSsrc = 0xBADCAFE;
Peter Boström3548dd22015-05-22 18:48:36 +02007115 const uint32_t kReceiverSsrc = 0x4711;
Peter Boströmdfa28152015-10-21 17:21:10 +02007116 const uint32_t kExpectedDefaultReceiverSsrc = 1;
Peter Boström3548dd22015-05-22 18:48:36 +02007117
7118 if (receiver_first) {
7119 AddRecvStream(StreamParams::CreateLegacy(kReceiverSsrc));
7120 std::vector<FakeVideoReceiveStream*> receive_streams =
7121 fake_call_->GetVideoReceiveStreams();
7122 ASSERT_EQ(1u, receive_streams.size());
Peter Boströmdfa28152015-10-21 17:21:10 +02007123 // Default local SSRC when we have no sender.
7124 EXPECT_EQ(kExpectedDefaultReceiverSsrc,
7125 receive_streams[0]->GetConfig().rtp.local_ssrc);
Peter Boström3548dd22015-05-22 18:48:36 +02007126 }
7127 AddSendStream(StreamParams::CreateLegacy(kSenderSsrc));
7128 if (!receiver_first)
7129 AddRecvStream(StreamParams::CreateLegacy(kReceiverSsrc));
7130 std::vector<FakeVideoReceiveStream*> receive_streams =
7131 fake_call_->GetVideoReceiveStreams();
7132 ASSERT_EQ(1u, receive_streams.size());
7133 EXPECT_EQ(kSenderSsrc, receive_streams[0]->GetConfig().rtp.local_ssrc);
Peter Boströmdfa28152015-10-21 17:21:10 +02007134
7135 // Removing first sender should fall back to another (in this case the second)
7136 // local send stream's SSRC.
7137 AddSendStream(StreamParams::CreateLegacy(kSecondSenderSsrc));
7138 ASSERT_TRUE(channel_->RemoveSendStream(kSenderSsrc));
Yves Gerey665174f2018-06-19 15:03:05 +02007139 receive_streams = fake_call_->GetVideoReceiveStreams();
Peter Boströmdfa28152015-10-21 17:21:10 +02007140 ASSERT_EQ(1u, receive_streams.size());
7141 EXPECT_EQ(kSecondSenderSsrc, receive_streams[0]->GetConfig().rtp.local_ssrc);
7142
7143 // Removing the last sender should fall back to default local SSRC.
7144 ASSERT_TRUE(channel_->RemoveSendStream(kSecondSenderSsrc));
Yves Gerey665174f2018-06-19 15:03:05 +02007145 receive_streams = fake_call_->GetVideoReceiveStreams();
Peter Boströmdfa28152015-10-21 17:21:10 +02007146 ASSERT_EQ(1u, receive_streams.size());
7147 EXPECT_EQ(kExpectedDefaultReceiverSsrc,
7148 receive_streams[0]->GetConfig().rtp.local_ssrc);
Peter Boström3548dd22015-05-22 18:48:36 +02007149}
7150
eladalonf1841382017-06-12 01:16:46 -07007151TEST_F(WebRtcVideoChannelTest, ConfiguresLocalSsrc) {
Peter Boström3548dd22015-05-22 18:48:36 +02007152 TestReceiverLocalSsrcConfiguration(false);
7153}
7154
eladalonf1841382017-06-12 01:16:46 -07007155TEST_F(WebRtcVideoChannelTest, ConfiguresLocalSsrcOnExistingReceivers) {
Peter Boström3548dd22015-05-22 18:48:36 +02007156 TestReceiverLocalSsrcConfiguration(true);
7157}
7158
Mirko Bonadei6a489f22019-04-09 15:11:12 +02007159class WebRtcVideoChannelSimulcastTest : public ::testing::Test {
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007160 public:
eladalonf1841382017-06-12 01:16:46 -07007161 WebRtcVideoChannelSimulcastTest()
Sebastian Jansson8f83b422018-02-21 13:07:13 +01007162 : fake_call_(),
Magnus Jedvert02e7a192017-09-23 17:21:32 +02007163 encoder_factory_(new cricket::FakeWebRtcVideoEncoderFactory),
7164 decoder_factory_(new cricket::FakeWebRtcVideoDecoderFactory),
Jiawei Ouc2ebe212018-11-08 10:02:56 -08007165 mock_rate_allocator_factory_(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02007166 absl::make_unique<webrtc::MockVideoBitrateAllocatorFactory>()),
Anders Carlsson67537952018-05-03 11:28:29 +02007167 engine_(std::unique_ptr<cricket::FakeWebRtcVideoEncoderFactory>(
Magnus Jedvert02e7a192017-09-23 17:21:32 +02007168 encoder_factory_),
Anders Carlsson67537952018-05-03 11:28:29 +02007169 std::unique_ptr<cricket::FakeWebRtcVideoDecoderFactory>(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02007170 decoder_factory_)),
magjed2475ae22017-09-12 04:42:15 -07007171 last_ssrc_(0) {}
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007172
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00007173 void SetUp() override {
Anders Carlsson5f2bb622018-05-14 09:48:06 +02007174 encoder_factory_->AddSupportedVideoCodecType("VP8");
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02007175 channel_.reset(engine_.CreateMediaChannel(
7176 &fake_call_, GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
7177 mock_rate_allocator_factory_.get()));
Sergey Ulanove2b15012016-11-22 16:08:30 -08007178 channel_->OnReadyToSend(true);
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007179 last_ssrc_ = 123;
7180 }
7181
7182 protected:
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007183 void VerifySimulcastSettings(const VideoCodec& codec,
perkj26752742016-10-24 01:21:16 -07007184 int capture_width,
7185 int capture_height,
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007186 size_t num_configured_streams,
sprang429600d2017-01-26 06:12:26 -08007187 size_t expected_num_streams,
7188 bool screenshare,
7189 bool conference_mode) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02007190 cricket::VideoSendParameters parameters;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02007191 parameters.codecs.push_back(codec);
sprang429600d2017-01-26 06:12:26 -08007192 parameters.conference_mode = conference_mode;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02007193 ASSERT_TRUE(channel_->SetSendParameters(parameters));
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007194
Peter Boström0c4e06b2015-10-07 12:23:21 +02007195 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
henrikg91d6ede2015-09-17 00:24:34 -07007196 RTC_DCHECK(num_configured_streams <= ssrcs.size());
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007197 ssrcs.resize(num_configured_streams);
7198
sprangf24a0642017-02-28 13:23:26 -08007199 AddSendStream(CreateSimStreamParams("cname", ssrcs));
pbos@webrtc.org86196c42015-02-16 21:02:00 +00007200 // Send a full-size frame to trigger a stream reconfiguration to use all
7201 // expected simulcast layers.
Niels Möller805a27e2019-01-21 12:21:27 +01007202 webrtc::test::FrameForwarder frame_forwarder;
7203 cricket::FakeFrameSource frame_source(capture_width, capture_height,
7204 rtc::kNumMicrosecsPerSec / 30);
7205
sprangf24a0642017-02-28 13:23:26 -08007206 VideoOptions options;
7207 if (screenshare)
Oskar Sundbom78807582017-11-16 11:09:55 +01007208 options.is_screencast = screenshare;
Niels Möller805a27e2019-01-21 12:21:27 +01007209 EXPECT_TRUE(
7210 channel_->SetVideoSend(ssrcs.front(), &options, &frame_forwarder));
sprangf24a0642017-02-28 13:23:26 -08007211 // Fetch the latest stream since SetVideoSend() may recreate it if the
7212 // screen content setting is changed.
7213 FakeVideoSendStream* stream = fake_call_.GetVideoSendStreams().front();
pbos@webrtc.org86196c42015-02-16 21:02:00 +00007214 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01007215 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007216
Zach Stein3ca452b2018-01-18 10:01:24 -08007217 auto rtp_parameters = channel_->GetRtpSendParameters(kSsrcs3[0]);
7218 EXPECT_EQ(num_configured_streams, rtp_parameters.encodings.size());
7219
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007220 std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
7221 ASSERT_EQ(expected_num_streams, video_streams.size());
Ilya Nikolaevskiy33d2a912019-04-02 11:05:03 +02007222 EXPECT_LE(expected_num_streams, stream->GetConfig().rtp.ssrcs.size());
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007223
sprang429600d2017-01-26 06:12:26 -08007224 std::vector<webrtc::VideoStream> expected_streams;
7225 if (conference_mode) {
7226 expected_streams = GetSimulcastConfig(
7227 num_configured_streams, capture_width, capture_height, 0,
Seth Hampson24722b32017-12-22 09:36:42 -08007228 webrtc::kDefaultBitratePriority, kDefaultQpMax,
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +02007229 kDefaultVideoMaxFramerate, screenshare, true);
sprang3ebabf12017-02-16 07:35:22 -08007230 if (screenshare) {
7231 for (const webrtc::VideoStream& stream : expected_streams) {
7232 // Never scale screen content.
Danil Chapovalov350531e2018-06-08 11:04:04 +00007233 EXPECT_EQ(stream.width, rtc::checked_cast<size_t>(capture_width));
7234 EXPECT_EQ(stream.height, rtc::checked_cast<size_t>(capture_height));
sprang3ebabf12017-02-16 07:35:22 -08007235 }
7236 }
sprang429600d2017-01-26 06:12:26 -08007237 } else {
7238 webrtc::VideoStream stream;
7239 stream.width = capture_width;
7240 stream.height = capture_height;
7241 stream.max_framerate = kDefaultVideoMaxFramerate;
Åsa Persson45bbc8a2017-11-13 10:16:47 +01007242 stream.min_bitrate_bps = cricket::kMinVideoBitrateBps;
sprang429600d2017-01-26 06:12:26 -08007243 stream.target_bitrate_bps = stream.max_bitrate_bps =
Åsa Perssonbdee46d2018-06-25 11:28:06 +02007244 GetMaxDefaultBitrateBps(capture_width, capture_height);
sprang429600d2017-01-26 06:12:26 -08007245 stream.max_qp = kDefaultQpMax;
7246 expected_streams.push_back(stream);
7247 }
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007248
7249 ASSERT_EQ(expected_streams.size(), video_streams.size());
7250
7251 size_t num_streams = video_streams.size();
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00007252 int total_max_bitrate_bps = 0;
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007253 for (size_t i = 0; i < num_streams; ++i) {
7254 EXPECT_EQ(expected_streams[i].width, video_streams[i].width);
7255 EXPECT_EQ(expected_streams[i].height, video_streams[i].height);
7256
7257 EXPECT_GT(video_streams[i].max_framerate, 0);
7258 EXPECT_EQ(expected_streams[i].max_framerate,
7259 video_streams[i].max_framerate);
7260
7261 EXPECT_GT(video_streams[i].min_bitrate_bps, 0);
7262 EXPECT_EQ(expected_streams[i].min_bitrate_bps,
7263 video_streams[i].min_bitrate_bps);
7264
7265 EXPECT_GT(video_streams[i].target_bitrate_bps, 0);
7266 EXPECT_EQ(expected_streams[i].target_bitrate_bps,
7267 video_streams[i].target_bitrate_bps);
7268
7269 EXPECT_GT(video_streams[i].max_bitrate_bps, 0);
7270 EXPECT_EQ(expected_streams[i].max_bitrate_bps,
7271 video_streams[i].max_bitrate_bps);
7272
7273 EXPECT_GT(video_streams[i].max_qp, 0);
7274 EXPECT_EQ(expected_streams[i].max_qp, video_streams[i].max_qp);
7275
Sergey Silkina796a7e2018-03-01 15:11:29 +01007276 EXPECT_EQ(conference_mode,
7277 expected_streams[i].num_temporal_layers.has_value());
7278
7279 if (conference_mode) {
7280 EXPECT_EQ(expected_streams[i].num_temporal_layers,
7281 video_streams[i].num_temporal_layers);
7282 }
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00007283
7284 if (i == num_streams - 1) {
7285 total_max_bitrate_bps += video_streams[i].max_bitrate_bps;
7286 } else {
7287 total_max_bitrate_bps += video_streams[i].target_bitrate_bps;
7288 }
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007289 }
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00007290
Niels Möllerff40b142018-04-09 08:49:14 +02007291 EXPECT_TRUE(channel_->SetVideoSend(ssrcs.front(), nullptr, nullptr));
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007292 }
7293
7294 FakeVideoSendStream* AddSendStream() {
7295 return AddSendStream(StreamParams::CreateLegacy(last_ssrc_++));
7296 }
7297
7298 FakeVideoSendStream* AddSendStream(const StreamParams& sp) {
Yves Gerey665174f2018-06-19 15:03:05 +02007299 size_t num_streams = fake_call_.GetVideoSendStreams().size();
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007300 EXPECT_TRUE(channel_->AddSendStream(sp));
7301 std::vector<FakeVideoSendStream*> streams =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02007302 fake_call_.GetVideoSendStreams();
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007303 EXPECT_EQ(num_streams + 1, streams.size());
7304 return streams[streams.size() - 1];
7305 }
7306
7307 std::vector<FakeVideoSendStream*> GetFakeSendStreams() {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02007308 return fake_call_.GetVideoSendStreams();
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007309 }
7310
7311 FakeVideoReceiveStream* AddRecvStream() {
7312 return AddRecvStream(StreamParams::CreateLegacy(last_ssrc_++));
7313 }
7314
7315 FakeVideoReceiveStream* AddRecvStream(const StreamParams& sp) {
Yves Gerey665174f2018-06-19 15:03:05 +02007316 size_t num_streams = fake_call_.GetVideoReceiveStreams().size();
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007317 EXPECT_TRUE(channel_->AddRecvStream(sp));
7318 std::vector<FakeVideoReceiveStream*> streams =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02007319 fake_call_.GetVideoReceiveStreams();
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007320 EXPECT_EQ(num_streams + 1, streams.size());
7321 return streams[streams.size() - 1];
7322 }
7323
skvlad11a9cbf2016-10-07 11:53:05 -07007324 webrtc::RtcEventLogNullImpl event_log_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +02007325 FakeCall fake_call_;
Magnus Jedvert02e7a192017-09-23 17:21:32 +02007326 cricket::FakeWebRtcVideoEncoderFactory* encoder_factory_;
7327 cricket::FakeWebRtcVideoDecoderFactory* decoder_factory_;
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02007328 std::unique_ptr<webrtc::MockVideoBitrateAllocatorFactory>
7329 mock_rate_allocator_factory_;
eladalonf1841382017-06-12 01:16:46 -07007330 WebRtcVideoEngine engine_;
kwiberg686a8ef2016-02-26 03:00:35 -08007331 std::unique_ptr<VideoMediaChannel> channel_;
Peter Boström0c4e06b2015-10-07 12:23:21 +02007332 uint32_t last_ssrc_;
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007333};
7334
eladalonf1841382017-06-12 01:16:46 -07007335TEST_F(WebRtcVideoChannelSimulcastTest, SetSendCodecsWith2SimulcastStreams) {
sprang429600d2017-01-26 06:12:26 -08007336 VerifySimulcastSettings(cricket::VideoCodec("VP8"), 640, 360, 2, 2, false,
7337 true);
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007338}
7339
eladalonf1841382017-06-12 01:16:46 -07007340TEST_F(WebRtcVideoChannelSimulcastTest, SetSendCodecsWith3SimulcastStreams) {
sprang429600d2017-01-26 06:12:26 -08007341 VerifySimulcastSettings(cricket::VideoCodec("VP8"), 1280, 720, 3, 3, false,
7342 true);
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007343}
7344
7345// Test that we normalize send codec format size in simulcast.
eladalonf1841382017-06-12 01:16:46 -07007346TEST_F(WebRtcVideoChannelSimulcastTest, SetSendCodecsWithOddSizeInSimulcast) {
sprang429600d2017-01-26 06:12:26 -08007347 VerifySimulcastSettings(cricket::VideoCodec("VP8"), 541, 271, 2, 2, false,
7348 true);
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007349}
sprang429600d2017-01-26 06:12:26 -08007350
Ilya Nikolaevskiy3df1d5d2018-08-22 09:26:51 +02007351TEST_F(WebRtcVideoChannelSimulcastTest, SetSendCodecsForScreenshare) {
Ilya Nikolaevskiy3df1d5d2018-08-22 09:26:51 +02007352 VerifySimulcastSettings(cricket::VideoCodec("VP8"), 1280, 720, 3, 1, true,
7353 false);
7354}
7355
Ilya Nikolaevskiy3df1d5d2018-08-22 09:26:51 +02007356TEST_F(WebRtcVideoChannelSimulcastTest,
7357 SetSendCodecsForConferenceModeScreenshare) {
Erik Språng72e52ee2018-11-29 11:41:53 +01007358 webrtc::test::ScopedFieldTrials field_trials(
7359 "WebRTC-SimulcastScreenshare/Disabled/");
Ilya Nikolaevskiy3df1d5d2018-08-22 09:26:51 +02007360 VerifySimulcastSettings(cricket::VideoCodec("VP8"), 1280, 720, 3, 1, true,
7361 true);
7362}
7363
eladalonf1841382017-06-12 01:16:46 -07007364TEST_F(WebRtcVideoChannelSimulcastTest, SetSendCodecsForSimulcastScreenshare) {
sprang429600d2017-01-26 06:12:26 -08007365 VerifySimulcastSettings(cricket::VideoCodec("VP8"), 1280, 720, 3, 2, true,
7366 true);
7367}
7368
eladalonf1841382017-06-12 01:16:46 -07007369TEST_F(WebRtcVideoChannelSimulcastTest,
sprangfe627f32017-03-29 08:24:59 -07007370 NoSimulcastScreenshareWithoutConference) {
sprangfe627f32017-03-29 08:24:59 -07007371 VerifySimulcastSettings(cricket::VideoCodec("VP8"), 1280, 720, 3, 1, true,
7372 false);
7373}
7374
Yves Gereyb6a89422018-10-08 10:08:32 +02007375class WebRtcVideoFakeClock {
Jonas Oreland49ac5952018-09-26 16:04:32 +02007376 public:
Yves Gereyb6a89422018-10-08 10:08:32 +02007377 WebRtcVideoFakeClock() {
Jonas Oreland49ac5952018-09-26 16:04:32 +02007378 fake_clock_.AdvanceTime(webrtc::TimeDelta::ms(1)); // avoid time=0
7379 }
7380 rtc::ScopedFakeClock fake_clock_;
7381};
7382
Yves Gereyb6a89422018-10-08 10:08:32 +02007383// The fake clock needs to be initialized before the call, and not
7384// destroyed until after all threads spawned by the test have been stopped.
7385// This mixin ensures that.
7386class WebRtcVideoChannelTestWithClock : public WebRtcVideoFakeClock,
7387 public WebRtcVideoChannelBaseTest {};
7388
Jonas Oreland49ac5952018-09-26 16:04:32 +02007389TEST_F(WebRtcVideoChannelTestWithClock, GetSources) {
7390 uint8_t data1[] = {0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
7391 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
7392
7393 EXPECT_EQ(0u, channel_->GetSources(kSsrc).size());
7394
7395 rtc::CopyOnWriteBuffer packet1(data1, sizeof(data1));
7396 rtc::SetBE32(packet1.data() + 8, kSsrc);
7397 channel_->SetSink(kDefaultReceiveSsrc, NULL);
7398 EXPECT_TRUE(SetDefaultCodec());
7399 EXPECT_TRUE(SetSend(true));
7400 EXPECT_EQ(0, renderer_.num_rendered_frames());
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07007401 channel_->OnPacketReceived(packet1, /*packet_time_us=*/-1);
Jonas Oreland49ac5952018-09-26 16:04:32 +02007402
7403 std::vector<webrtc::RtpSource> sources = channel_->GetSources(kSsrc);
7404 EXPECT_EQ(1u, sources.size());
7405 EXPECT_EQ(webrtc::RtpSourceType::SSRC, sources[0].source_type());
7406 int64_t timestamp1 = sources[0].timestamp_ms();
7407
7408 // a new packet.
7409 int64_t timeDeltaMs = 1;
7410 fake_clock_.AdvanceTime(webrtc::TimeDelta::ms(timeDeltaMs));
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07007411 channel_->OnPacketReceived(packet1, /*packet_time_us=*/-1);
Jonas Oreland49ac5952018-09-26 16:04:32 +02007412 int64_t timestamp2 = channel_->GetSources(kSsrc)[0].timestamp_ms();
7413 EXPECT_EQ(timestamp2, timestamp1 + timeDeltaMs);
7414
7415 // It only keeps 10s of history.
7416 fake_clock_.AdvanceTime(webrtc::TimeDelta::seconds(10));
7417 fake_clock_.AdvanceTime(webrtc::TimeDelta::ms(1));
7418 EXPECT_EQ(0u, channel_->GetSources(kSsrc).size());
7419}
7420
7421TEST_F(WebRtcVideoChannelTestWithClock, GetContributingSources) {
7422 uint8_t data1[] = {0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7423 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
7424
7425 uint32_t kCsrc = 4321u;
7426 EXPECT_EQ(0u, channel_->GetSources(kSsrc).size());
7427 EXPECT_EQ(0u, channel_->GetSources(kCsrc).size());
7428
7429 rtc::CopyOnWriteBuffer packet1(data1, sizeof(data1));
7430 rtc::SetBE32(packet1.data() + 8, kSsrc);
7431 rtc::SetBE32(packet1.data() + 12, kCsrc);
7432 channel_->SetSink(kDefaultReceiveSsrc, NULL);
7433 EXPECT_TRUE(SetDefaultCodec());
7434 EXPECT_TRUE(SetSend(true));
7435 EXPECT_EQ(0, renderer_.num_rendered_frames());
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07007436 channel_->OnPacketReceived(packet1, /*packet_time_us=*/-1);
Jonas Oreland49ac5952018-09-26 16:04:32 +02007437
7438 {
7439 ASSERT_EQ(2u, channel_->GetSources(kSsrc).size());
7440 EXPECT_EQ(0u, channel_->GetSources(kCsrc).size());
7441 std::vector<webrtc::RtpSource> sources = channel_->GetSources(kSsrc);
7442 EXPECT_EQ(sources[0].timestamp_ms(), sources[1].timestamp_ms());
7443 // 1 SSRC and 1 CSRC.
Steve Anton2c9ebef2019-01-28 17:27:58 -08007444 EXPECT_EQ(1, absl::c_count_if(sources, [](const webrtc::RtpSource& source) {
7445 return source.source_type() == webrtc::RtpSourceType::SSRC;
7446 }));
7447 EXPECT_EQ(1, absl::c_count_if(sources, [](const webrtc::RtpSource& source) {
7448 return source.source_type() == webrtc::RtpSourceType::CSRC;
7449 }));
Jonas Oreland49ac5952018-09-26 16:04:32 +02007450 }
7451 int64_t timestamp1 = channel_->GetSources(kSsrc)[0].timestamp_ms();
7452
7453 // a new packet with only ssrc (i.e no csrc).
7454 uint8_t data2[] = {0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
7455 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
7456 rtc::CopyOnWriteBuffer packet2(data2, sizeof(data2));
7457 rtc::SetBE32(packet2.data() + 8, kSsrc);
7458
7459 int64_t timeDeltaMs = 1;
7460 fake_clock_.AdvanceTime(webrtc::TimeDelta::ms(timeDeltaMs));
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07007461 channel_->OnPacketReceived(packet2, /*packet_time_us=*/-1);
Jonas Oreland49ac5952018-09-26 16:04:32 +02007462
7463 {
7464 ASSERT_EQ(2u, channel_->GetSources(kSsrc).size());
7465 EXPECT_EQ(0u, channel_->GetSources(kCsrc).size());
7466 std::vector<webrtc::RtpSource> sources = channel_->GetSources(kSsrc);
7467 EXPECT_NE(sources[0].timestamp_ms(), sources[1].timestamp_ms());
7468 // 1 SSRC and 1 CSRC.
Steve Anton2c9ebef2019-01-28 17:27:58 -08007469 EXPECT_EQ(1, absl::c_count_if(sources, [](const webrtc::RtpSource& source) {
7470 return source.source_type() == webrtc::RtpSourceType::SSRC;
7471 }));
7472 EXPECT_EQ(1, absl::c_count_if(sources, [](const webrtc::RtpSource& source) {
7473 return source.source_type() == webrtc::RtpSourceType::CSRC;
7474 }));
7475 auto ssrcSource =
7476 absl::c_find_if(sources, [](const webrtc::RtpSource& source) {
Jonas Oreland49ac5952018-09-26 16:04:32 +02007477 return source.source_type() == webrtc::RtpSourceType::SSRC;
7478 });
Steve Anton2c9ebef2019-01-28 17:27:58 -08007479 auto csrcSource =
7480 absl::c_find_if(sources, [](const webrtc::RtpSource& source) {
Jonas Oreland49ac5952018-09-26 16:04:32 +02007481 return source.source_type() == webrtc::RtpSourceType::CSRC;
7482 });
7483
7484 EXPECT_EQ(ssrcSource->timestamp_ms(), timestamp1 + timeDeltaMs);
7485 EXPECT_EQ(csrcSource->timestamp_ms(), timestamp1);
7486 }
7487
7488 // It only keeps 10s of history.
7489 fake_clock_.AdvanceTime(webrtc::TimeDelta::seconds(10));
7490
7491 {
7492 ASSERT_EQ(1u, channel_->GetSources(kSsrc).size());
7493 EXPECT_EQ(0u, channel_->GetSources(kCsrc).size());
7494 std::vector<webrtc::RtpSource> sources = channel_->GetSources(kSsrc);
Steve Anton2c9ebef2019-01-28 17:27:58 -08007495 EXPECT_EQ(1, absl::c_count_if(sources, [](const webrtc::RtpSource& source) {
7496 return source.source_type() == webrtc::RtpSourceType::SSRC;
7497 }));
7498 EXPECT_EQ(0, absl::c_count_if(sources, [](const webrtc::RtpSource& source) {
7499 return source.source_type() == webrtc::RtpSourceType::CSRC;
7500 }));
Jonas Oreland49ac5952018-09-26 16:04:32 +02007501 }
7502
7503 fake_clock_.AdvanceTime(webrtc::TimeDelta::ms(1));
7504 EXPECT_EQ(0u, channel_->GetSources(kSsrc).size());
7505 EXPECT_EQ(0u, channel_->GetSources(kCsrc).size());
7506}
7507
Amit Hilbuchb000b712019-02-25 10:22:14 -08007508TEST_F(WebRtcVideoChannelTest, SetsRidsOnSendStream) {
7509 StreamParams sp = CreateSimStreamParams("cname", {123, 456, 789});
7510
7511 std::vector<std::string> rids = {"f", "h", "q"};
7512 std::vector<cricket::RidDescription> rid_descriptions;
7513 for (const auto& rid : rids) {
7514 rid_descriptions.emplace_back(rid, cricket::RidDirection::kSend);
7515 }
7516 sp.set_rids(rid_descriptions);
7517
7518 ASSERT_TRUE(channel_->AddSendStream(sp));
7519 const auto& streams = fake_call_->GetVideoSendStreams();
7520 ASSERT_EQ(1u, streams.size());
7521 auto stream = streams[0];
7522 ASSERT_NE(stream, nullptr);
7523 const auto& config = stream->GetConfig();
7524 EXPECT_THAT(config.rtp.rids, ::testing::ElementsAreArray(rids));
7525}
7526
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00007527} // namespace cricket