blob: 395d38ac1a4edfac34cb66f633e799cbae0458fe [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
Jonas Olssona4d87372019-07-05 19:08:33 +020011#include "media/engine/webrtc_video_engine.h"
12
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000013#include <map>
kwiberg686a8ef2016-02-26 03:00:35 -080014#include <memory>
Elad Alon040dc432019-05-22 15:40:02 +020015#include <string>
Steve Antone78bcb92017-10-31 09:53:08 -070016#include <utility>
pbos@webrtc.org86f613d2014-06-10 08:53:05 +000017#include <vector>
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000018
Steve Anton2c9ebef2019-01-28 17:27:58 -080019#include "absl/algorithm/container.h"
Niels Möller805a27e2019-01-21 12:21:27 +010020#include "absl/memory/memory.h"
Niels Möller039743e2018-10-23 10:07:25 +020021#include "absl/strings/match.h"
Danil Chapovalov83bbe912019-08-07 12:24:53 +020022#include "api/rtc_event_log/rtc_event_log.h"
Steve Anton10542f22019-01-11 09:11:00 -080023#include "api/rtp_parameters.h"
Danil Chapovalov53d45ba2019-07-03 14:56:33 +020024#include "api/task_queue/default_task_queue_factory.h"
Jiawei Ouc2ebe212018-11-08 10:02:56 -080025#include "api/test/mock_video_bitrate_allocator.h"
26#include "api/test/mock_video_bitrate_allocator_factory.h"
Emircan Uysalerdbcac7f2017-10-30 23:10:12 -070027#include "api/test/mock_video_decoder_factory.h"
28#include "api/test/mock_video_encoder_factory.h"
Markus Handell32565f62019-12-04 10:58:17 +010029#include "api/test/video/function_video_decoder_factory.h"
Erik Språng014dd3c2019-11-28 13:44:25 +010030#include "api/transport/field_trial_based_config.h"
Niels Möller65f17ca2019-09-12 13:59:36 +020031#include "api/transport/media/media_transport_config.h"
Jonas Oreland49ac5952018-09-26 16:04:32 +020032#include "api/units/time_delta.h"
Jiawei Ouc2ebe212018-11-08 10:02:56 -080033#include "api/video/builtin_video_bitrate_allocator_factory.h"
Niels Möller805a27e2019-01-21 12:21:27 +010034#include "api/video/i420_buffer.h"
Åsa Persson23eba222018-10-02 14:47:06 +020035#include "api/video/video_bitrate_allocation.h"
Anders Carlsson5f2bb622018-05-14 09:48:06 +020036#include "api/video_codecs/builtin_video_decoder_factory.h"
37#include "api/video_codecs/builtin_video_encoder_factory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020038#include "api/video_codecs/sdp_video_format.h"
39#include "api/video_codecs/video_decoder_factory.h"
40#include "api/video_codecs/video_encoder.h"
41#include "api/video_codecs/video_encoder_factory.h"
42#include "call/flexfec_receive_stream.h"
43#include "common_video/h264/profile_level_id.h"
Niels Möller805a27e2019-01-21 12:21:27 +010044#include "media/base/fake_frame_source.h"
Steve Anton10542f22019-01-11 09:11:00 -080045#include "media/base/fake_network_interface.h"
Steve Anton10542f22019-01-11 09:11:00 -080046#include "media/base/fake_video_renderer.h"
47#include "media/base/media_constants.h"
48#include "media/base/rtp_utils.h"
49#include "media/base/test_utils.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020050#include "media/engine/constants.h"
Steve Anton10542f22019-01-11 09:11:00 -080051#include "media/engine/fake_webrtc_call.h"
52#include "media/engine/fake_webrtc_video_engine.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020053#include "media/engine/simulcast.h"
Steve Anton10542f22019-01-11 09:11:00 -080054#include "media/engine/webrtc_voice_engine.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020055#include "rtc_base/arraysize.h"
Elad Alon80f53b72019-10-11 16:19:43 +020056#include "rtc_base/experiments/min_video_bitrate_experiment.h"
Steve Anton10542f22019-01-11 09:11:00 -080057#include "rtc_base/fake_clock.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020058#include "rtc_base/gunit.h"
Yves Gerey665174f2018-06-19 15:03:05 +020059#include "rtc_base/numerics/safe_conversions.h"
Steve Antonf3802842019-01-24 19:07:40 -080060#include "rtc_base/time_utils.h"
Markus Handell32565f62019-12-04 10:58:17 +010061#include "test/fake_decoder.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020062#include "test/field_trial.h"
Artem Titov33f9d2b2019-12-05 15:59:00 +010063#include "test/frame_forwarder.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020064#include "test/gmock.h"
Tommi25eb47c2019-08-29 16:39:05 +020065#include "test/rtp_header_parser.h"
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000066
Markus Handell8bc88342020-03-16 10:42:01 +010067using ::testing::_;
philipeld9cc8c02019-09-16 14:53:40 +020068using ::testing::Contains;
Markus Handell8bc88342020-03-16 10:42:01 +010069using ::testing::Each;
70using ::testing::ElementsAreArray;
philipeld9cc8c02019-09-16 14:53:40 +020071using ::testing::Eq;
Mirko Bonadei6a489f22019-04-09 15:11:12 +020072using ::testing::Field;
Chen Xing90f3b892019-06-25 10:16:14 +020073using ::testing::IsEmpty;
philipeld9cc8c02019-09-16 14:53:40 +020074using ::testing::Pair;
Markus Handell8bc88342020-03-16 10:42:01 +010075using ::testing::Return;
Chen Xing90f3b892019-06-25 10:16:14 +020076using ::testing::SizeIs;
Markus Handell8bc88342020-03-16 10:42:01 +010077using ::testing::StrNe;
78using ::testing::Values;
Sebastian Jansson8f83b422018-02-21 13:07:13 +010079using webrtc::BitrateConstraints;
isheriff6f8d6862016-05-26 11:24:55 -070080using webrtc::RtpExtension;
81
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000082namespace {
buildbot@webrtc.orga8530772014-12-10 09:01:18 +000083static const int kDefaultQpMax = 56;
buildbot@webrtc.orga8530772014-12-10 09:01:18 +000084
noahricd10a68e2015-07-10 11:27:55 -070085static const uint8_t kRedRtxPayloadType = 125;
86
Niels Möller6557d0c2018-04-11 15:18:34 +020087static const uint32_t kTimeout = 5000U;
Niels Möller6557d0c2018-04-11 15:18:34 +020088static const uint32_t kSsrc = 1234u;
89static const uint32_t kSsrcs4[] = {1, 2, 3, 4};
90static const int kVideoWidth = 640;
91static const int kVideoHeight = 360;
92static const int kFramerate = 30;
93
Peter Boström0c4e06b2015-10-07 12:23:21 +020094static const uint32_t kSsrcs1[] = {1};
95static const uint32_t kSsrcs3[] = {1, 2, 3};
96static const uint32_t kRtxSsrcs1[] = {4};
brandtr468da7c2016-11-22 02:16:47 -080097static const uint32_t kFlexfecSsrc = 5;
Peter Boström0c4e06b2015-10-07 12:23:21 +020098static const uint32_t kIncomingUnsignalledSsrc = 0xC0FFEE;
mzanaty8a855d62017-02-17 15:46:43 -080099
Bjorn A Mellemda4f0932019-07-30 08:34:03 -0700100constexpr uint32_t kRtpHeaderSize = 12;
101
pbos@webrtc.org3c107582014-07-20 15:27:35 +0000102static const char kUnsupportedExtensionName[] =
103 "urn:ietf:params:rtp-hdrext:unsupported";
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +0000104
magjed509e4fe2016-11-18 01:34:11 -0800105cricket::VideoCodec RemoveFeedbackParams(cricket::VideoCodec&& codec) {
106 codec.feedback_params = cricket::FeedbackParams();
Mirko Bonadei29a8d102018-04-25 23:58:26 +0200107 return std::move(codec);
magjed509e4fe2016-11-18 01:34:11 -0800108}
109
Elad Alonfadb1812019-05-24 13:40:02 +0200110void VerifyCodecHasDefaultFeedbackParams(const cricket::VideoCodec& codec,
111 bool lntf_expected) {
112 EXPECT_EQ(lntf_expected,
113 codec.HasFeedbackParam(cricket::FeedbackParam(
114 cricket::kRtcpFbParamLntf, cricket::kParamValueEmpty)));
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +0000115 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
116 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty)));
117 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
118 cricket::kRtcpFbParamNack, cricket::kRtcpFbNackParamPli)));
119 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
120 cricket::kRtcpFbParamRemb, cricket::kParamValueEmpty)));
121 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
stefan43edf0f2015-11-20 18:05:48 -0800122 cricket::kRtcpFbParamTransportCc, cricket::kParamValueEmpty)));
123 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +0000124 cricket::kRtcpFbParamCcm, cricket::kRtcpFbCcmParamFir)));
125}
126
magjed725e4842016-11-16 00:48:13 -0800127// Return true if any codec in |codecs| is an RTX codec with associated payload
128// type |payload_type|.
129bool HasRtxCodec(const std::vector<cricket::VideoCodec>& codecs,
130 int payload_type) {
131 for (const cricket::VideoCodec& codec : codecs) {
132 int associated_payload_type;
Niels Möller039743e2018-10-23 10:07:25 +0200133 if (absl::EqualsIgnoreCase(codec.name.c_str(), "rtx") &&
magjed725e4842016-11-16 00:48:13 -0800134 codec.GetParam(cricket::kCodecParamAssociatedPayloadType,
135 &associated_payload_type) &&
136 associated_payload_type == payload_type) {
137 return true;
138 }
139 }
140 return false;
141}
142
nisseca5706d2017-09-11 02:32:16 -0700143// TODO(nisse): Duplicated in call.cc.
144const int* FindKeyByValue(const std::map<int, int>& m, int v) {
145 for (const auto& kv : m) {
146 if (kv.second == v)
147 return &kv.first;
148 }
149 return nullptr;
150}
151
Yves Gerey665174f2018-06-19 15:03:05 +0200152bool HasRtxReceiveAssociation(const webrtc::VideoReceiveStream::Config& config,
153 int payload_type) {
nisseca5706d2017-09-11 02:32:16 -0700154 return FindKeyByValue(config.rtp.rtx_associated_payload_types,
155 payload_type) != nullptr;
156}
157
158// Check that there's an Rtx payload type for each decoder.
159bool VerifyRtxReceiveAssociations(
160 const webrtc::VideoReceiveStream::Config& config) {
161 for (const auto& decoder : config.decoders) {
162 if (!HasRtxReceiveAssociation(config, decoder.payload_type))
163 return false;
164 }
165 return true;
166}
167
brandtrffc61182016-11-28 06:02:22 -0800168rtc::scoped_refptr<webrtc::VideoFrameBuffer> CreateBlackFrameBuffer(
nisse64ec8f82016-09-27 00:17:25 -0700169 int width,
170 int height) {
171 rtc::scoped_refptr<webrtc::I420Buffer> buffer =
172 webrtc::I420Buffer::Create(width, height);
nisseaf916892017-01-10 07:44:26 -0800173 webrtc::I420Buffer::SetBlack(buffer);
nisse64ec8f82016-09-27 00:17:25 -0700174 return buffer;
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +0000175}
176
Shao Changbine62202f2015-04-21 20:24:50 +0800177void VerifySendStreamHasRtxTypes(const webrtc::VideoSendStream::Config& config,
178 const std::map<int, int>& rtx_types) {
179 std::map<int, int>::const_iterator it;
Niels Möller259a4972018-04-05 15:36:51 +0200180 it = rtx_types.find(config.rtp.payload_type);
Shao Changbine62202f2015-04-21 20:24:50 +0800181 EXPECT_TRUE(it != rtx_types.end() &&
182 it->second == config.rtp.rtx.payload_type);
183
brandtrb5f2c3f2016-10-04 23:28:39 -0700184 if (config.rtp.ulpfec.red_rtx_payload_type != -1) {
185 it = rtx_types.find(config.rtp.ulpfec.red_payload_type);
Shao Changbine62202f2015-04-21 20:24:50 +0800186 EXPECT_TRUE(it != rtx_types.end() &&
brandtrb5f2c3f2016-10-04 23:28:39 -0700187 it->second == config.rtp.ulpfec.red_rtx_payload_type);
Shao Changbine62202f2015-04-21 20:24:50 +0800188 }
189}
kthelgason2bc68642017-02-07 07:02:22 -0800190
191cricket::MediaConfig GetMediaConfig() {
192 cricket::MediaConfig media_config;
Niels Möller1d7ecd22018-01-18 15:25:12 +0100193 media_config.video.enable_cpu_adaptation = false;
kthelgason2bc68642017-02-07 07:02:22 -0800194 return media_config;
195}
nisse26e3abb2017-08-25 04:44:25 -0700196
Åsa Perssonbdee46d2018-06-25 11:28:06 +0200197// Values from GetMaxDefaultVideoBitrateKbps in webrtcvideoengine.cc.
198int GetMaxDefaultBitrateBps(size_t width, size_t height) {
199 if (width * height <= 320 * 240) {
200 return 600000;
201 } else if (width * height <= 640 * 480) {
202 return 1700000;
203 } else if (width * height <= 960 * 540) {
204 return 2000000;
205 } else {
206 return 2500000;
207 }
208}
209
Niels Möller731a2c22018-07-30 15:08:07 +0200210class MockVideoSource : public rtc::VideoSourceInterface<webrtc::VideoFrame> {
211 public:
212 MOCK_METHOD2(AddOrUpdateSink,
213 void(rtc::VideoSinkInterface<webrtc::VideoFrame>* sink,
214 const rtc::VideoSinkWants& wants));
215 MOCK_METHOD1(RemoveSink,
216 void(rtc::VideoSinkInterface<webrtc::VideoFrame>* sink));
217};
218
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000219} // namespace
220
Yves Gerey665174f2018-06-19 15:03:05 +0200221#define EXPECT_FRAME_WAIT(c, w, h, t) \
Niels Möller6557d0c2018-04-11 15:18:34 +0200222 EXPECT_EQ_WAIT((c), renderer_.num_rendered_frames(), (t)); \
Yves Gerey665174f2018-06-19 15:03:05 +0200223 EXPECT_EQ((w), renderer_.width()); \
224 EXPECT_EQ((h), renderer_.height()); \
Niels Möller6557d0c2018-04-11 15:18:34 +0200225 EXPECT_EQ(0, renderer_.errors());
226
Yves Gerey665174f2018-06-19 15:03:05 +0200227#define EXPECT_FRAME_ON_RENDERER_WAIT(r, c, w, h, t) \
Niels Möller6557d0c2018-04-11 15:18:34 +0200228 EXPECT_EQ_WAIT((c), (r).num_rendered_frames(), (t)); \
Yves Gerey665174f2018-06-19 15:03:05 +0200229 EXPECT_EQ((w), (r).width()); \
230 EXPECT_EQ((h), (r).height()); \
Niels Möller6557d0c2018-04-11 15:18:34 +0200231 EXPECT_EQ(0, (r).errors());
232
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000233namespace cricket {
eladalonf1841382017-06-12 01:16:46 -0700234class WebRtcVideoEngineTest : public ::testing::Test {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000235 public:
eladalonf1841382017-06-12 01:16:46 -0700236 WebRtcVideoEngineTest() : WebRtcVideoEngineTest("") {}
Elad Alon040dc432019-05-22 15:40:02 +0200237 explicit WebRtcVideoEngineTest(const std::string& field_trials)
238 : override_field_trials_(
239 field_trials.empty()
240 ? nullptr
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200241 : std::make_unique<webrtc::test::ScopedFieldTrials>(
Elad Alon040dc432019-05-22 15:40:02 +0200242 field_trials)),
Danil Chapovalov53d45ba2019-07-03 14:56:33 +0200243 task_queue_factory_(webrtc::CreateDefaultTaskQueueFactory()),
244 call_(webrtc::Call::Create([&] {
245 webrtc::Call::Config call_config(&event_log_);
246 call_config.task_queue_factory = task_queue_factory_.get();
Erik Språng014dd3c2019-11-28 13:44:25 +0100247 call_config.trials = &field_trials_;
Danil Chapovalov53d45ba2019-07-03 14:56:33 +0200248 return call_config;
249 }())),
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200250 encoder_factory_(new cricket::FakeWebRtcVideoEncoderFactory),
251 decoder_factory_(new cricket::FakeWebRtcVideoDecoderFactory),
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +0200252 video_bitrate_allocator_factory_(
253 webrtc::CreateBuiltinVideoBitrateAllocatorFactory()),
Anders Carlsson67537952018-05-03 11:28:29 +0200254 engine_(std::unique_ptr<cricket::FakeWebRtcVideoEncoderFactory>(
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200255 encoder_factory_),
Anders Carlsson67537952018-05-03 11:28:29 +0200256 std::unique_ptr<cricket::FakeWebRtcVideoDecoderFactory>(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +0200257 decoder_factory_)) {
Ilya Nikolaevskiy9c38c472018-09-03 16:11:42 +0200258 // Ensure fake clock doesn't return 0, which will cause some initializations
259 // fail inside RTP senders.
Danil Chapovalov0c626af2020-02-10 11:16:00 +0100260 fake_clock_.AdvanceTime(webrtc::TimeDelta::Micros(1));
Ilya Nikolaevskiy9c38c472018-09-03 16:11:42 +0200261 }
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000262
263 protected:
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200264 void AssignDefaultAptRtxTypes();
265 void AssignDefaultCodec();
266
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +0100267 // Find the index of the codec in the engine with the given name. The codec
268 // must be present.
Oleh Prypina40f8242017-12-21 13:32:23 +0100269 size_t GetEngineCodecIndex(const std::string& name) const;
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +0100270
magjed509e4fe2016-11-18 01:34:11 -0800271 // Find the codec in the engine with the given name. The codec must be
272 // present.
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +0100273 cricket::VideoCodec GetEngineCodec(const std::string& name) const;
Johannes Kron3e983682020-03-29 22:17:00 +0200274 void AddSupportedVideoCodecType(const std::string& name);
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200275 VideoMediaChannel* SetSendParamsWithAllSupportedCodecs();
pbos@webrtc.orgfa553ef2014-10-20 11:07:07 +0000276
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200277 VideoMediaChannel* SetRecvParamsWithSupportedCodecs(
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000278 const std::vector<VideoCodec>& codecs);
279
Elad Alon157540a2019-02-08 23:37:52 +0100280 void ExpectRtpCapabilitySupport(const char* uri, bool supported) const;
Peter Boströme4499152016-02-05 11:13:28 +0100281
Ilya Nikolaevskiy9c38c472018-09-03 16:11:42 +0200282 // Has to be the first one, so it is initialized before the call or there is a
283 // race condition in the clock access.
284 rtc::ScopedFakeClock fake_clock_;
Elad Alon040dc432019-05-22 15:40:02 +0200285 std::unique_ptr<webrtc::test::ScopedFieldTrials> override_field_trials_;
Erik Språng014dd3c2019-11-28 13:44:25 +0100286 webrtc::FieldTrialBasedConfig field_trials_;
Danil Chapovalov83bbe912019-08-07 12:24:53 +0200287 webrtc::RtcEventLogNull event_log_;
Danil Chapovalov53d45ba2019-07-03 14:56:33 +0200288 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory_;
eladalonf1841382017-06-12 01:16:46 -0700289 // Used in WebRtcVideoEngineVoiceTest, but defined here so it's properly
pbos@webrtc.orgf1f0d9a2015-03-02 13:30:15 +0000290 // initialized when the constructor is called.
kwiberg686a8ef2016-02-26 03:00:35 -0800291 std::unique_ptr<webrtc::Call> call_;
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200292 cricket::FakeWebRtcVideoEncoderFactory* encoder_factory_;
293 cricket::FakeWebRtcVideoDecoderFactory* decoder_factory_;
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +0200294 std::unique_ptr<webrtc::VideoBitrateAllocatorFactory>
295 video_bitrate_allocator_factory_;
eladalonf1841382017-06-12 01:16:46 -0700296 WebRtcVideoEngine engine_;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000297 VideoCodec default_codec_;
Shao Changbine62202f2015-04-21 20:24:50 +0800298 std::map<int, int> default_apt_rtx_types_;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000299};
300
eladalonf1841382017-06-12 01:16:46 -0700301TEST_F(WebRtcVideoEngineTest, DefaultRtxCodecHasAssociatedPayloadTypeSet) {
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200302 encoder_factory_->AddSupportedVideoCodecType("VP8");
303 AssignDefaultCodec();
304
Johannes Kron3e983682020-03-29 22:17:00 +0200305 std::vector<VideoCodec> engine_codecs = engine_.send_codecs();
pbos@webrtc.orge322a172014-06-13 11:47:28 +0000306 for (size_t i = 0; i < engine_codecs.size(); ++i) {
307 if (engine_codecs[i].name != kRtxCodecName)
308 continue;
309 int associated_payload_type;
310 EXPECT_TRUE(engine_codecs[i].GetParam(kCodecParamAssociatedPayloadType,
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000311 &associated_payload_type));
pbos@webrtc.orge322a172014-06-13 11:47:28 +0000312 EXPECT_EQ(default_codec_.id, associated_payload_type);
313 return;
314 }
315 FAIL() << "No RTX codec found among default codecs.";
316}
317
eladalonf1841382017-06-12 01:16:46 -0700318TEST_F(WebRtcVideoEngineTest, SupportsTimestampOffsetHeaderExtension) {
Elad Alon157540a2019-02-08 23:37:52 +0100319 ExpectRtpCapabilitySupport(RtpExtension::kTimestampOffsetUri, true);
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000320}
321
eladalonf1841382017-06-12 01:16:46 -0700322TEST_F(WebRtcVideoEngineTest, SupportsAbsoluteSenderTimeHeaderExtension) {
Elad Alon157540a2019-02-08 23:37:52 +0100323 ExpectRtpCapabilitySupport(RtpExtension::kAbsSendTimeUri, true);
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000324}
325
eladalonf1841382017-06-12 01:16:46 -0700326TEST_F(WebRtcVideoEngineTest, SupportsTransportSequenceNumberHeaderExtension) {
Elad Alon157540a2019-02-08 23:37:52 +0100327 ExpectRtpCapabilitySupport(RtpExtension::kTransportSequenceNumberUri, true);
stefanc1aeaf02015-10-15 07:26:07 -0700328}
329
eladalonf1841382017-06-12 01:16:46 -0700330TEST_F(WebRtcVideoEngineTest, SupportsVideoRotationHeaderExtension) {
Elad Alon157540a2019-02-08 23:37:52 +0100331 ExpectRtpCapabilitySupport(RtpExtension::kVideoRotationUri, true);
332}
333
334TEST_F(WebRtcVideoEngineTest, SupportsPlayoutDelayHeaderExtension) {
335 ExpectRtpCapabilitySupport(RtpExtension::kPlayoutDelayUri, true);
336}
337
338TEST_F(WebRtcVideoEngineTest, SupportsVideoContentTypeHeaderExtension) {
339 ExpectRtpCapabilitySupport(RtpExtension::kVideoContentTypeUri, true);
340}
341
342TEST_F(WebRtcVideoEngineTest, SupportsVideoTimingHeaderExtension) {
343 ExpectRtpCapabilitySupport(RtpExtension::kVideoTimingUri, true);
344}
345
346TEST_F(WebRtcVideoEngineTest, SupportsFrameMarkingHeaderExtension) {
347 ExpectRtpCapabilitySupport(RtpExtension::kFrameMarkingUri, true);
Johannes Krond0b69a82018-12-03 14:18:53 +0100348}
349
350TEST_F(WebRtcVideoEngineTest, SupportsColorSpaceHeaderExtension) {
Elad Alon157540a2019-02-08 23:37:52 +0100351 ExpectRtpCapabilitySupport(RtpExtension::kColorSpaceUri, true);
352}
353
Elad Alonccb9b752019-02-19 13:01:31 +0100354TEST_F(WebRtcVideoEngineTest, AdvertiseGenericDescriptor00) {
355 ExpectRtpCapabilitySupport(RtpExtension::kGenericFrameDescriptorUri00, false);
356}
357
philipel1e054862018-10-08 16:13:53 +0200358class WebRtcVideoEngineTestWithGenericDescriptor
359 : public WebRtcVideoEngineTest {
360 public:
361 WebRtcVideoEngineTestWithGenericDescriptor()
362 : WebRtcVideoEngineTest("WebRTC-GenericDescriptorAdvertised/Enabled/") {}
363};
364
Elad Alonccb9b752019-02-19 13:01:31 +0100365TEST_F(WebRtcVideoEngineTestWithGenericDescriptor,
366 AdvertiseGenericDescriptor00) {
367 ExpectRtpCapabilitySupport(RtpExtension::kGenericFrameDescriptorUri00, true);
368}
369
eladalonf1841382017-06-12 01:16:46 -0700370TEST_F(WebRtcVideoEngineTest, CVOSetHeaderExtensionBeforeCapturer) {
Niels Möller731a2c22018-07-30 15:08:07 +0200371 // Allocate the source first to prevent early destruction before channel's
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700372 // dtor is called.
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200373 ::testing::NiceMock<MockVideoSource> video_source;
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700374
Johannes Kron3e983682020-03-29 22:17:00 +0200375 AddSupportedVideoCodecType("VP8");
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700376
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200377 std::unique_ptr<VideoMediaChannel> channel(
378 SetSendParamsWithAllSupportedCodecs());
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700379 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(kSsrc)));
380
381 // Add CVO extension.
382 const int id = 1;
magjed509e4fe2016-11-18 01:34:11 -0800383 cricket::VideoSendParameters parameters;
384 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200385 parameters.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -0700386 RtpExtension(RtpExtension::kVideoRotationUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200387 EXPECT_TRUE(channel->SetSendParameters(parameters));
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700388
Niels Möller731a2c22018-07-30 15:08:07 +0200389 EXPECT_CALL(
390 video_source,
Markus Handell8bc88342020-03-16 10:42:01 +0100391 AddOrUpdateSink(_, Field(&rtc::VideoSinkWants::rotation_applied, false)));
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700392 // Set capturer.
Niels Möller731a2c22018-07-30 15:08:07 +0200393 EXPECT_TRUE(channel->SetVideoSend(kSsrc, nullptr, &video_source));
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700394
395 // Verify capturer has turned off applying rotation.
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200396 ::testing::Mock::VerifyAndClear(&video_source);
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700397
398 // Verify removing header extension turns on applying rotation.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200399 parameters.extensions.clear();
Niels Möller731a2c22018-07-30 15:08:07 +0200400 EXPECT_CALL(
401 video_source,
Markus Handell8bc88342020-03-16 10:42:01 +0100402 AddOrUpdateSink(_, Field(&rtc::VideoSinkWants::rotation_applied, true)));
Niels Möller731a2c22018-07-30 15:08:07 +0200403
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200404 EXPECT_TRUE(channel->SetSendParameters(parameters));
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700405}
406
eladalonf1841382017-06-12 01:16:46 -0700407TEST_F(WebRtcVideoEngineTest, CVOSetHeaderExtensionBeforeAddSendStream) {
Niels Möller731a2c22018-07-30 15:08:07 +0200408 // Allocate the source first to prevent early destruction before channel's
perkj91e1c152016-03-02 05:34:00 -0800409 // dtor is called.
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200410 ::testing::NiceMock<MockVideoSource> video_source;
perkj91e1c152016-03-02 05:34:00 -0800411
Johannes Kron3e983682020-03-29 22:17:00 +0200412 AddSupportedVideoCodecType("VP8");
perkj91e1c152016-03-02 05:34:00 -0800413
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200414 std::unique_ptr<VideoMediaChannel> channel(
415 SetSendParamsWithAllSupportedCodecs());
perkj91e1c152016-03-02 05:34:00 -0800416 // Add CVO extension.
417 const int id = 1;
magjed509e4fe2016-11-18 01:34:11 -0800418 cricket::VideoSendParameters parameters;
419 parameters.codecs.push_back(GetEngineCodec("VP8"));
perkj91e1c152016-03-02 05:34:00 -0800420 parameters.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -0700421 RtpExtension(RtpExtension::kVideoRotationUri, id));
perkj91e1c152016-03-02 05:34:00 -0800422 EXPECT_TRUE(channel->SetSendParameters(parameters));
423 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(kSsrc)));
424
Niels Möller731a2c22018-07-30 15:08:07 +0200425 // Set source.
426 EXPECT_CALL(
427 video_source,
Markus Handell8bc88342020-03-16 10:42:01 +0100428 AddOrUpdateSink(_, Field(&rtc::VideoSinkWants::rotation_applied, false)));
Niels Möller731a2c22018-07-30 15:08:07 +0200429 EXPECT_TRUE(channel->SetVideoSend(kSsrc, nullptr, &video_source));
perkj91e1c152016-03-02 05:34:00 -0800430}
431
eladalonf1841382017-06-12 01:16:46 -0700432TEST_F(WebRtcVideoEngineTest, CVOSetHeaderExtensionAfterCapturer) {
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200433 ::testing::NiceMock<MockVideoSource> video_source;
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700434
Johannes Kron3e983682020-03-29 22:17:00 +0200435 AddSupportedVideoCodecType("VP8");
436 AddSupportedVideoCodecType("VP9");
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700437
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200438 std::unique_ptr<VideoMediaChannel> channel(
439 SetSendParamsWithAllSupportedCodecs());
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700440 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(kSsrc)));
441
442 // Set capturer.
Niels Möller731a2c22018-07-30 15:08:07 +0200443 EXPECT_CALL(
444 video_source,
Markus Handell8bc88342020-03-16 10:42:01 +0100445 AddOrUpdateSink(_, Field(&rtc::VideoSinkWants::rotation_applied, true)));
Niels Möller731a2c22018-07-30 15:08:07 +0200446 EXPECT_TRUE(channel->SetVideoSend(kSsrc, nullptr, &video_source));
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700447
perkjcaafdba2016-03-20 07:34:29 -0700448 // Verify capturer has turned on applying rotation.
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200449 ::testing::Mock::VerifyAndClear(&video_source);
perkjcaafdba2016-03-20 07:34:29 -0700450
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700451 // Add CVO extension.
452 const int id = 1;
magjed509e4fe2016-11-18 01:34:11 -0800453 cricket::VideoSendParameters parameters;
454 parameters.codecs.push_back(GetEngineCodec("VP8"));
455 parameters.codecs.push_back(GetEngineCodec("VP9"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200456 parameters.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -0700457 RtpExtension(RtpExtension::kVideoRotationUri, id));
perkjcaafdba2016-03-20 07:34:29 -0700458 // Also remove the first codec to trigger a codec change as well.
459 parameters.codecs.erase(parameters.codecs.begin());
Niels Möller731a2c22018-07-30 15:08:07 +0200460 EXPECT_CALL(
461 video_source,
Markus Handell8bc88342020-03-16 10:42:01 +0100462 AddOrUpdateSink(_, Field(&rtc::VideoSinkWants::rotation_applied, false)));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200463 EXPECT_TRUE(channel->SetSendParameters(parameters));
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700464
465 // Verify capturer has turned off applying rotation.
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200466 ::testing::Mock::VerifyAndClear(&video_source);
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700467
468 // Verify removing header extension turns on applying rotation.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200469 parameters.extensions.clear();
Niels Möller731a2c22018-07-30 15:08:07 +0200470 EXPECT_CALL(
471 video_source,
Markus Handell8bc88342020-03-16 10:42:01 +0100472 AddOrUpdateSink(_, Field(&rtc::VideoSinkWants::rotation_applied, true)));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200473 EXPECT_TRUE(channel->SetSendParameters(parameters));
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700474}
475
eladalonf1841382017-06-12 01:16:46 -0700476TEST_F(WebRtcVideoEngineTest, SetSendFailsBeforeSettingCodecs) {
Johannes Kron3e983682020-03-29 22:17:00 +0200477 AddSupportedVideoCodecType("VP8");
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200478
Sebastian Jansson84848f22018-11-16 10:40:36 +0100479 std::unique_ptr<VideoMediaChannel> channel(engine_.CreateMediaChannel(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +0200480 call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
481 video_bitrate_allocator_factory_.get()));
pbos@webrtc.org5301b0f2014-07-17 08:51:46 +0000482
483 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(123)));
484
485 EXPECT_FALSE(channel->SetSend(true))
486 << "Channel should not start without codecs.";
487 EXPECT_TRUE(channel->SetSend(false))
488 << "Channel should be stoppable even without set codecs.";
489}
490
eladalonf1841382017-06-12 01:16:46 -0700491TEST_F(WebRtcVideoEngineTest, GetStatsWithoutSendCodecsSetDoesNotCrash) {
Johannes Kron3e983682020-03-29 22:17:00 +0200492 AddSupportedVideoCodecType("VP8");
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200493
Sebastian Jansson84848f22018-11-16 10:40:36 +0100494 std::unique_ptr<VideoMediaChannel> channel(engine_.CreateMediaChannel(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +0200495 call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
496 video_bitrate_allocator_factory_.get()));
pbos@webrtc.orgc3d2bd22014-08-12 20:55:10 +0000497 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(123)));
498 VideoMediaInfo info;
499 channel->GetStats(&info);
500}
501
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200502TEST_F(WebRtcVideoEngineTest, UseFactoryForVp8WhenSupported) {
Johannes Kron3e983682020-03-29 22:17:00 +0200503 AddSupportedVideoCodecType("VP8");
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000504
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200505 std::unique_ptr<VideoMediaChannel> channel(
506 SetSendParamsWithAllSupportedCodecs());
Sergey Ulanove2b15012016-11-22 16:08:30 -0800507 channel->OnReadyToSend(true);
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000508
509 EXPECT_TRUE(
510 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200511 EXPECT_EQ(0, encoder_factory_->GetNumCreatedEncoders());
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000512 EXPECT_TRUE(channel->SetSend(true));
Niels Möllerd0f0f682019-01-14 09:09:53 +0100513 webrtc::test::FrameForwarder frame_forwarder;
514 cricket::FakeFrameSource frame_source(1280, 720,
515 rtc::kNumMicrosecsPerSec / 30);
516 EXPECT_TRUE(channel->SetVideoSend(kSsrc, nullptr, &frame_forwarder));
517 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
Per21d45d22016-10-30 21:37:57 +0100518 // Sending one frame will have allocate the encoder.
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200519 ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(1));
520 EXPECT_TRUE_WAIT(encoder_factory_->encoders()[0]->GetNumEncodedFrames() > 0,
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000521 kTimeout);
522
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200523 int num_created_encoders = encoder_factory_->GetNumCreatedEncoders();
Per21d45d22016-10-30 21:37:57 +0100524 EXPECT_EQ(num_created_encoders, 1);
pbos@webrtc.org86196c42015-02-16 21:02:00 +0000525
526 // Setting codecs of the same type should not reallocate any encoders
527 // (expecting a no-op).
magjed509e4fe2016-11-18 01:34:11 -0800528 cricket::VideoSendParameters parameters;
529 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200530 EXPECT_TRUE(channel->SetSendParameters(parameters));
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200531 EXPECT_EQ(num_created_encoders, encoder_factory_->GetNumCreatedEncoders());
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000532
533 // Remove stream previously added to free the external encoder instance.
534 EXPECT_TRUE(channel->RemoveSendStream(kSsrc));
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200535 EXPECT_EQ(0u, encoder_factory_->encoders().size());
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000536}
537
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200538// Test that when an encoder factory supports H264, we add an RTX
539// codec for it.
540// TODO(deadbeef): This test should be updated if/when we start
541// adding RTX codecs for unrecognized codec names.
542TEST_F(WebRtcVideoEngineTest, RtxCodecAddedForH264Codec) {
magjed725e4842016-11-16 00:48:13 -0800543 using webrtc::H264::kLevel1;
Jonas Olssona4d87372019-07-05 19:08:33 +0200544 using webrtc::H264::ProfileLevelId;
545 using webrtc::H264::ProfileLevelIdToString;
Anders Carlsson67537952018-05-03 11:28:29 +0200546 webrtc::SdpVideoFormat h264_constrained_baseline("H264");
547 h264_constrained_baseline.parameters[kH264FmtpProfileLevelId] =
magjed725e4842016-11-16 00:48:13 -0800548 *ProfileLevelIdToString(
549 ProfileLevelId(webrtc::H264::kProfileConstrainedBaseline, kLevel1));
Anders Carlsson67537952018-05-03 11:28:29 +0200550 webrtc::SdpVideoFormat h264_constrained_high("H264");
551 h264_constrained_high.parameters[kH264FmtpProfileLevelId] =
magjed725e4842016-11-16 00:48:13 -0800552 *ProfileLevelIdToString(
553 ProfileLevelId(webrtc::H264::kProfileConstrainedHigh, kLevel1));
Anders Carlsson67537952018-05-03 11:28:29 +0200554 webrtc::SdpVideoFormat h264_high("H264");
555 h264_high.parameters[kH264FmtpProfileLevelId] = *ProfileLevelIdToString(
magjed725e4842016-11-16 00:48:13 -0800556 ProfileLevelId(webrtc::H264::kProfileHigh, kLevel1));
557
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200558 encoder_factory_->AddSupportedVideoCodec(h264_constrained_baseline);
559 encoder_factory_->AddSupportedVideoCodec(h264_constrained_high);
560 encoder_factory_->AddSupportedVideoCodec(h264_high);
Taylor Brandstetter6c3e7882016-06-29 11:14:19 -0700561
magjed725e4842016-11-16 00:48:13 -0800562 // First figure out what payload types the test codecs got assigned.
Johannes Kron3e983682020-03-29 22:17:00 +0200563 const std::vector<cricket::VideoCodec> codecs = engine_.send_codecs();
magjed509e4fe2016-11-18 01:34:11 -0800564 // Now search for RTX codecs for them. Expect that they all have associated
565 // RTX codecs.
magjed725e4842016-11-16 00:48:13 -0800566 EXPECT_TRUE(HasRtxCodec(
Anders Carlsson67537952018-05-03 11:28:29 +0200567 codecs,
568 FindMatchingCodec(codecs, cricket::VideoCodec(h264_constrained_baseline))
569 ->id));
magjed725e4842016-11-16 00:48:13 -0800570 EXPECT_TRUE(HasRtxCodec(
Anders Carlsson67537952018-05-03 11:28:29 +0200571 codecs,
572 FindMatchingCodec(codecs, cricket::VideoCodec(h264_constrained_high))
573 ->id));
magjed509e4fe2016-11-18 01:34:11 -0800574 EXPECT_TRUE(HasRtxCodec(
Anders Carlsson67537952018-05-03 11:28:29 +0200575 codecs, FindMatchingCodec(codecs, cricket::VideoCodec(h264_high))->id));
Taylor Brandstetter6c3e7882016-06-29 11:14:19 -0700576}
577
Mirko Bonadei8ef57932018-11-16 14:38:03 +0100578#if defined(RTC_ENABLE_VP9)
eladalonf1841382017-06-12 01:16:46 -0700579TEST_F(WebRtcVideoEngineTest, CanConstructDecoderForVp9EncoderFactory) {
Johannes Kron3e983682020-03-29 22:17:00 +0200580 AddSupportedVideoCodecType("VP9");
Peter Boström53eda3d2015-03-27 15:53:18 +0100581
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200582 std::unique_ptr<VideoMediaChannel> channel(
583 SetSendParamsWithAllSupportedCodecs());
Peter Boström53eda3d2015-03-27 15:53:18 +0100584
585 EXPECT_TRUE(
586 channel->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
587}
Mirko Bonadei8ef57932018-11-16 14:38:03 +0100588#endif // defined(RTC_ENABLE_VP9)
Peter Boström53eda3d2015-03-27 15:53:18 +0100589
eladalonf1841382017-06-12 01:16:46 -0700590TEST_F(WebRtcVideoEngineTest, PropagatesInputFrameTimestamp) {
Johannes Kron3e983682020-03-29 22:17:00 +0200591 AddSupportedVideoCodecType("VP8");
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100592 FakeCall* fake_call = new FakeCall();
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200593 call_.reset(fake_call);
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200594 std::unique_ptr<VideoMediaChannel> channel(
595 SetSendParamsWithAllSupportedCodecs());
qiangchenc27d89f2015-07-16 10:27:16 -0700596
597 EXPECT_TRUE(
598 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
599
Niels Möllerd0f0f682019-01-14 09:09:53 +0100600 webrtc::test::FrameForwarder frame_forwarder;
601 cricket::FakeFrameSource frame_source(1280, 720,
602 rtc::kNumMicrosecsPerSec / 60);
603 EXPECT_TRUE(channel->SetVideoSend(kSsrc, nullptr, &frame_forwarder));
qiangchenc27d89f2015-07-16 10:27:16 -0700604 channel->SetSend(true);
605
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200606 FakeVideoSendStream* stream = fake_call->GetVideoSendStreams()[0];
qiangchenc27d89f2015-07-16 10:27:16 -0700607
Niels Möllerd0f0f682019-01-14 09:09:53 +0100608 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
pbos1cb121d2015-09-14 11:38:38 -0700609 int64_t last_timestamp = stream->GetLastTimestamp();
qiangchenc27d89f2015-07-16 10:27:16 -0700610 for (int i = 0; i < 10; i++) {
Niels Möllerd0f0f682019-01-14 09:09:53 +0100611 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
pbos1cb121d2015-09-14 11:38:38 -0700612 int64_t timestamp = stream->GetLastTimestamp();
qiangchenc27d89f2015-07-16 10:27:16 -0700613 int64_t interval = timestamp - last_timestamp;
614
615 // Precision changes from nanosecond to millisecond.
616 // Allow error to be no more than 1.
617 EXPECT_NEAR(cricket::VideoFormat::FpsToInterval(60) / 1E6, interval, 1);
618
619 last_timestamp = timestamp;
620 }
621
Niels Möllerd0f0f682019-01-14 09:09:53 +0100622 frame_forwarder.IncomingCapturedFrame(
623 frame_source.GetFrame(1280, 720, webrtc::VideoRotation::kVideoRotation_0,
624 rtc::kNumMicrosecsPerSec / 30));
qiangchenc27d89f2015-07-16 10:27:16 -0700625 last_timestamp = stream->GetLastTimestamp();
626 for (int i = 0; i < 10; i++) {
Niels Möllerd0f0f682019-01-14 09:09:53 +0100627 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame(
628 1280, 720, webrtc::VideoRotation::kVideoRotation_0,
629 rtc::kNumMicrosecsPerSec / 30));
pbos1cb121d2015-09-14 11:38:38 -0700630 int64_t timestamp = stream->GetLastTimestamp();
qiangchenc27d89f2015-07-16 10:27:16 -0700631 int64_t interval = timestamp - last_timestamp;
632
633 // Precision changes from nanosecond to millisecond.
634 // Allow error to be no more than 1.
635 EXPECT_NEAR(cricket::VideoFormat::FpsToInterval(30) / 1E6, interval, 1);
636
637 last_timestamp = timestamp;
638 }
639
640 // Remove stream previously added to free the external encoder instance.
641 EXPECT_TRUE(channel->RemoveSendStream(kSsrc));
642}
643
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200644void WebRtcVideoEngineTest::AssignDefaultAptRtxTypes() {
Johannes Kron3e983682020-03-29 22:17:00 +0200645 std::vector<VideoCodec> engine_codecs = engine_.send_codecs();
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200646 RTC_DCHECK(!engine_codecs.empty());
647 for (const cricket::VideoCodec& codec : engine_codecs) {
648 if (codec.name == "rtx") {
649 int associated_payload_type;
650 if (codec.GetParam(kCodecParamAssociatedPayloadType,
651 &associated_payload_type)) {
652 default_apt_rtx_types_[associated_payload_type] = codec.id;
653 }
654 }
655 }
656}
657
658void WebRtcVideoEngineTest::AssignDefaultCodec() {
Johannes Kron3e983682020-03-29 22:17:00 +0200659 std::vector<VideoCodec> engine_codecs = engine_.send_codecs();
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200660 RTC_DCHECK(!engine_codecs.empty());
661 bool codec_set = false;
662 for (const cricket::VideoCodec& codec : engine_codecs) {
663 if (!codec_set && codec.name != "rtx" && codec.name != "red" &&
664 codec.name != "ulpfec") {
665 default_codec_ = codec;
666 codec_set = true;
667 }
668 }
669
670 RTC_DCHECK(codec_set);
671}
672
Oleh Prypina40f8242017-12-21 13:32:23 +0100673size_t WebRtcVideoEngineTest::GetEngineCodecIndex(
674 const std::string& name) const {
Johannes Kron3e983682020-03-29 22:17:00 +0200675 const std::vector<cricket::VideoCodec> codecs = engine_.send_codecs();
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +0100676 for (size_t i = 0; i < codecs.size(); ++i) {
677 const cricket::VideoCodec engine_codec = codecs[i];
Niels Möller039743e2018-10-23 10:07:25 +0200678 if (!absl::EqualsIgnoreCase(name, engine_codec.name))
Magnus Jedvert8deb8182017-10-05 13:13:32 +0200679 continue;
680 // The tests only use H264 Constrained Baseline. Make sure we don't return
681 // an internal H264 codec from the engine with a different H264 profile.
Niels Möller039743e2018-10-23 10:07:25 +0200682 if (absl::EqualsIgnoreCase(name.c_str(), kH264CodecName)) {
Danil Chapovalov00c71832018-06-15 15:58:38 +0200683 const absl::optional<webrtc::H264::ProfileLevelId> profile_level_id =
Magnus Jedvert8deb8182017-10-05 13:13:32 +0200684 webrtc::H264::ParseSdpProfileLevelId(engine_codec.params);
685 if (profile_level_id->profile !=
686 webrtc::H264::kProfileConstrainedBaseline) {
687 continue;
688 }
689 }
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +0100690 return i;
magjed509e4fe2016-11-18 01:34:11 -0800691 }
692 // This point should never be reached.
693 ADD_FAILURE() << "Unrecognized codec name: " << name;
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +0100694 return -1;
695}
696
697cricket::VideoCodec WebRtcVideoEngineTest::GetEngineCodec(
698 const std::string& name) const {
Johannes Kron3e983682020-03-29 22:17:00 +0200699 return engine_.send_codecs()[GetEngineCodecIndex(name)];
700}
701
702void WebRtcVideoEngineTest::AddSupportedVideoCodecType(
703 const std::string& name) {
704 encoder_factory_->AddSupportedVideoCodecType(name);
705 decoder_factory_->AddSupportedVideoCodecType(name);
magjed509e4fe2016-11-18 01:34:11 -0800706}
707
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200708VideoMediaChannel*
709WebRtcVideoEngineTest::SetSendParamsWithAllSupportedCodecs() {
Sebastian Jansson84848f22018-11-16 10:40:36 +0100710 VideoMediaChannel* channel = engine_.CreateMediaChannel(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +0200711 call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
712 video_bitrate_allocator_factory_.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200713 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -0800714 // We need to look up the codec in the engine to get the correct payload type.
Anders Carlsson67537952018-05-03 11:28:29 +0200715 for (const webrtc::SdpVideoFormat& format :
716 encoder_factory_->GetSupportedFormats()) {
717 cricket::VideoCodec engine_codec = GetEngineCodec(format.name);
Steve Anton2c9ebef2019-01-28 17:27:58 -0800718 if (!absl::c_linear_search(parameters.codecs, engine_codec)) {
Anders Carlsson67537952018-05-03 11:28:29 +0200719 parameters.codecs.push_back(engine_codec);
720 }
721 }
magjed509e4fe2016-11-18 01:34:11 -0800722
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200723 EXPECT_TRUE(channel->SetSendParameters(parameters));
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000724
725 return channel;
726}
727
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200728VideoMediaChannel* WebRtcVideoEngineTest::SetRecvParamsWithSupportedCodecs(
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000729 const std::vector<VideoCodec>& codecs) {
Sebastian Jansson84848f22018-11-16 10:40:36 +0100730 VideoMediaChannel* channel = engine_.CreateMediaChannel(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +0200731 call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
732 video_bitrate_allocator_factory_.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200733 cricket::VideoRecvParameters parameters;
734 parameters.codecs = codecs;
735 EXPECT_TRUE(channel->SetRecvParameters(parameters));
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000736
737 return channel;
738}
739
Elad Alon157540a2019-02-08 23:37:52 +0100740void WebRtcVideoEngineTest::ExpectRtpCapabilitySupport(const char* uri,
741 bool supported) const {
Markus Handell0357b3e2020-03-16 13:40:51 +0100742 const std::vector<webrtc::RtpExtension> header_extensions =
743 GetDefaultEnabledRtpHeaderExtensions(engine_);
Elad Alon157540a2019-02-08 23:37:52 +0100744 if (supported) {
Markus Handell8bc88342020-03-16 10:42:01 +0100745 EXPECT_THAT(header_extensions, Contains(Field(&RtpExtension::uri, uri)));
Elad Alon157540a2019-02-08 23:37:52 +0100746 } else {
Markus Handell8bc88342020-03-16 10:42:01 +0100747 EXPECT_THAT(header_extensions, Each(Field(&RtpExtension::uri, StrNe(uri))));
Elad Alon157540a2019-02-08 23:37:52 +0100748 }
749}
750
eladalonf1841382017-06-12 01:16:46 -0700751TEST_F(WebRtcVideoEngineTest, UsesSimulcastAdapterForVp8Factories) {
Johannes Kron3e983682020-03-29 22:17:00 +0200752 AddSupportedVideoCodecType("VP8");
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000753
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200754 std::unique_ptr<VideoMediaChannel> channel(
755 SetSendParamsWithAllSupportedCodecs());
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000756
Peter Boström0c4e06b2015-10-07 12:23:21 +0200757 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000758
Yves Gerey665174f2018-06-19 15:03:05 +0200759 EXPECT_TRUE(channel->AddSendStream(CreateSimStreamParams("cname", ssrcs)));
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000760 EXPECT_TRUE(channel->SetSend(true));
761
Niels Möller805a27e2019-01-21 12:21:27 +0100762 webrtc::test::FrameForwarder frame_forwarder;
763 cricket::FakeFrameSource frame_source(1280, 720,
764 rtc::kNumMicrosecsPerSec / 60);
765 EXPECT_TRUE(channel->SetVideoSend(ssrcs.front(), nullptr, &frame_forwarder));
766 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
pbos@webrtc.org86196c42015-02-16 21:02:00 +0000767
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200768 ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(2));
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000769
770 // Verify that encoders are configured for simulcast through adapter
771 // (increasing resolution and only configured to send one stream each).
772 int prev_width = -1;
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200773 for (size_t i = 0; i < encoder_factory_->encoders().size(); ++i) {
774 ASSERT_TRUE(encoder_factory_->encoders()[i]->WaitForInitEncode());
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000775 webrtc::VideoCodec codec_settings =
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200776 encoder_factory_->encoders()[i]->GetCodecSettings();
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000777 EXPECT_EQ(0, codec_settings.numberOfSimulcastStreams);
778 EXPECT_GT(codec_settings.width, prev_width);
779 prev_width = codec_settings.width;
780 }
pbos@webrtc.org86196c42015-02-16 21:02:00 +0000781
Niels Möllerff40b142018-04-09 08:49:14 +0200782 EXPECT_TRUE(channel->SetVideoSend(ssrcs.front(), nullptr, nullptr));
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000783
784 channel.reset();
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200785 ASSERT_EQ(0u, encoder_factory_->encoders().size());
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000786}
787
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200788TEST_F(WebRtcVideoEngineTest, ChannelWithH264CanChangeToVp8) {
Johannes Kron3e983682020-03-29 22:17:00 +0200789 AddSupportedVideoCodecType("VP8");
790 AddSupportedVideoCodecType("H264");
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000791
Niels Möllerd0f0f682019-01-14 09:09:53 +0100792 // Frame source.
793 webrtc::test::FrameForwarder frame_forwarder;
794 cricket::FakeFrameSource frame_source(1280, 720,
795 rtc::kNumMicrosecsPerSec / 30);
Niels Möller4db138e2018-04-19 09:04:13 +0200796
Sebastian Jansson84848f22018-11-16 10:40:36 +0100797 std::unique_ptr<VideoMediaChannel> channel(engine_.CreateMediaChannel(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +0200798 call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
799 video_bitrate_allocator_factory_.get()));
Anders Carlsson67537952018-05-03 11:28:29 +0200800 cricket::VideoSendParameters parameters;
801 parameters.codecs.push_back(GetEngineCodec("H264"));
802 EXPECT_TRUE(channel->SetSendParameters(parameters));
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000803
804 EXPECT_TRUE(
805 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
Niels Möllerd0f0f682019-01-14 09:09:53 +0100806 EXPECT_TRUE(channel->SetVideoSend(kSsrc, nullptr, &frame_forwarder));
Niels Möller4db138e2018-04-19 09:04:13 +0200807 // Sending one frame will have allocate the encoder.
Niels Möllerd0f0f682019-01-14 09:09:53 +0100808 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
Niels Möller4db138e2018-04-19 09:04:13 +0200809
810 ASSERT_EQ_WAIT(1u, encoder_factory_->encoders().size(), kTimeout);
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000811
Anders Carlsson67537952018-05-03 11:28:29 +0200812 cricket::VideoSendParameters new_parameters;
813 new_parameters.codecs.push_back(GetEngineCodec("VP8"));
814 EXPECT_TRUE(channel->SetSendParameters(new_parameters));
Niels Möller4db138e2018-04-19 09:04:13 +0200815
816 // Sending one frame will switch encoder.
Niels Möllerd0f0f682019-01-14 09:09:53 +0100817 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
Niels Möller4db138e2018-04-19 09:04:13 +0200818
Anders Carlsson8a150d92018-05-14 12:40:04 +0200819 EXPECT_EQ_WAIT(1u, encoder_factory_->encoders().size(), kTimeout);
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000820}
821
eladalonf1841382017-06-12 01:16:46 -0700822TEST_F(WebRtcVideoEngineTest,
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000823 UsesSimulcastAdapterForVp8WithCombinedVP8AndH264Factory) {
Johannes Kron3e983682020-03-29 22:17:00 +0200824 AddSupportedVideoCodecType("VP8");
825 AddSupportedVideoCodecType("H264");
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000826
Sebastian Jansson84848f22018-11-16 10:40:36 +0100827 std::unique_ptr<VideoMediaChannel> channel(engine_.CreateMediaChannel(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +0200828 call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
829 video_bitrate_allocator_factory_.get()));
magjed509e4fe2016-11-18 01:34:11 -0800830 cricket::VideoSendParameters parameters;
831 parameters.codecs.push_back(GetEngineCodec("VP8"));
832 EXPECT_TRUE(channel->SetSendParameters(parameters));
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000833
Peter Boström0c4e06b2015-10-07 12:23:21 +0200834 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000835
Yves Gerey665174f2018-06-19 15:03:05 +0200836 EXPECT_TRUE(channel->AddSendStream(CreateSimStreamParams("cname", ssrcs)));
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000837 EXPECT_TRUE(channel->SetSend(true));
838
839 // Send a fake frame, or else the media engine will configure the simulcast
840 // encoder adapter at a low-enough size that it'll only create a single
841 // encoder layer.
Niels Möller805a27e2019-01-21 12:21:27 +0100842 webrtc::test::FrameForwarder frame_forwarder;
843 cricket::FakeFrameSource frame_source(1280, 720,
844 rtc::kNumMicrosecsPerSec / 30);
845 EXPECT_TRUE(channel->SetVideoSend(ssrcs.front(), nullptr, &frame_forwarder));
846 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000847
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200848 ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(2));
849 ASSERT_TRUE(encoder_factory_->encoders()[0]->WaitForInitEncode());
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000850 EXPECT_EQ(webrtc::kVideoCodecVP8,
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200851 encoder_factory_->encoders()[0]->GetCodecSettings().codecType);
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000852
853 channel.reset();
854 // Make sure DestroyVideoEncoder was called on the factory.
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200855 EXPECT_EQ(0u, encoder_factory_->encoders().size());
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000856}
857
eladalonf1841382017-06-12 01:16:46 -0700858TEST_F(WebRtcVideoEngineTest,
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000859 DestroysNonSimulcastEncoderFromCombinedVP8AndH264Factory) {
Johannes Kron3e983682020-03-29 22:17:00 +0200860 AddSupportedVideoCodecType("VP8");
861 AddSupportedVideoCodecType("H264");
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000862
Sebastian Jansson84848f22018-11-16 10:40:36 +0100863 std::unique_ptr<VideoMediaChannel> channel(engine_.CreateMediaChannel(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +0200864 call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
865 video_bitrate_allocator_factory_.get()));
magjed509e4fe2016-11-18 01:34:11 -0800866 cricket::VideoSendParameters parameters;
867 parameters.codecs.push_back(GetEngineCodec("H264"));
868 EXPECT_TRUE(channel->SetSendParameters(parameters));
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000869
870 EXPECT_TRUE(
871 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
Per21d45d22016-10-30 21:37:57 +0100872
873 // Send a frame of 720p. This should trigger a "real" encoder initialization.
Niels Möller805a27e2019-01-21 12:21:27 +0100874 webrtc::test::FrameForwarder frame_forwarder;
875 cricket::FakeFrameSource frame_source(1280, 720,
876 rtc::kNumMicrosecsPerSec / 30);
877 EXPECT_TRUE(channel->SetVideoSend(kSsrc, nullptr, &frame_forwarder));
878 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
Niels Möller4db138e2018-04-19 09:04:13 +0200879 ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(1));
880 ASSERT_EQ(1u, encoder_factory_->encoders().size());
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200881 ASSERT_TRUE(encoder_factory_->encoders()[0]->WaitForInitEncode());
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000882 EXPECT_EQ(webrtc::kVideoCodecH264,
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200883 encoder_factory_->encoders()[0]->GetCodecSettings().codecType);
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000884
885 channel.reset();
886 // Make sure DestroyVideoEncoder was called on the factory.
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200887 ASSERT_EQ(0u, encoder_factory_->encoders().size());
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000888}
889
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200890TEST_F(WebRtcVideoEngineTest, SimulcastEnabledForH264BehindFieldTrial) {
Elad Alon040dc432019-05-22 15:40:02 +0200891 RTC_DCHECK(!override_field_trials_);
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200892 override_field_trials_ = std::make_unique<webrtc::test::ScopedFieldTrials>(
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200893 "WebRTC-H264Simulcast/Enabled/");
Johannes Kron3e983682020-03-29 22:17:00 +0200894 AddSupportedVideoCodecType("H264");
noahricfdac5162015-08-27 01:59:29 -0700895
Sebastian Jansson84848f22018-11-16 10:40:36 +0100896 std::unique_ptr<VideoMediaChannel> channel(engine_.CreateMediaChannel(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +0200897 call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
898 video_bitrate_allocator_factory_.get()));
Anders Carlsson67537952018-05-03 11:28:29 +0200899 cricket::VideoSendParameters parameters;
900 parameters.codecs.push_back(GetEngineCodec("H264"));
901 EXPECT_TRUE(channel->SetSendParameters(parameters));
noahricfdac5162015-08-27 01:59:29 -0700902
Peter Boström0c4e06b2015-10-07 12:23:21 +0200903 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
noahricfdac5162015-08-27 01:59:29 -0700904 EXPECT_TRUE(
905 channel->AddSendStream(cricket::CreateSimStreamParams("cname", ssrcs)));
Peter Boströmce23bee2016-02-02 14:14:30 +0100906
907 // Send a frame of 720p. This should trigger a "real" encoder initialization.
Niels Möller805a27e2019-01-21 12:21:27 +0100908 webrtc::test::FrameForwarder frame_forwarder;
909 cricket::FakeFrameSource frame_source(1280, 720,
910 rtc::kNumMicrosecsPerSec / 30);
911 EXPECT_TRUE(channel->SetVideoSend(ssrcs[0], nullptr, &frame_forwarder));
912 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
Peter Boströmce23bee2016-02-02 14:14:30 +0100913
Niels Möller4db138e2018-04-19 09:04:13 +0200914 ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(1));
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200915 ASSERT_EQ(1u, encoder_factory_->encoders().size());
916 FakeWebRtcVideoEncoder* encoder = encoder_factory_->encoders()[0];
917 ASSERT_TRUE(encoder_factory_->encoders()[0]->WaitForInitEncode());
noahricfdac5162015-08-27 01:59:29 -0700918 EXPECT_EQ(webrtc::kVideoCodecH264, encoder->GetCodecSettings().codecType);
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200919 EXPECT_LT(1u, encoder->GetCodecSettings().numberOfSimulcastStreams);
Niels Möllerff40b142018-04-09 08:49:14 +0200920 EXPECT_TRUE(channel->SetVideoSend(ssrcs[0], nullptr, nullptr));
noahricfdac5162015-08-27 01:59:29 -0700921}
922
brandtrffc61182016-11-28 06:02:22 -0800923// Test that the FlexFEC field trial properly alters the output of
eladalonf1841382017-06-12 01:16:46 -0700924// WebRtcVideoEngine::codecs(), for an existing |engine_| object.
brandtrffc61182016-11-28 06:02:22 -0800925//
926// TODO(brandtr): Remove this test, when the FlexFEC field trial is gone.
eladalonf1841382017-06-12 01:16:46 -0700927TEST_F(WebRtcVideoEngineTest,
brandtrffc61182016-11-28 06:02:22 -0800928 Flexfec03SupportedAsInternalCodecBehindFieldTrial) {
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200929 encoder_factory_->AddSupportedVideoCodecType("VP8");
930
Steve Anton2c9ebef2019-01-28 17:27:58 -0800931 auto flexfec = Field("name", &VideoCodec::name, "flexfec-03");
brandtrffc61182016-11-28 06:02:22 -0800932
933 // FlexFEC is not active without field trial.
Johannes Kron3e983682020-03-29 22:17:00 +0200934 EXPECT_THAT(engine_.send_codecs(), Not(Contains(flexfec)));
brandtrffc61182016-11-28 06:02:22 -0800935
936 // FlexFEC is active with field trial.
Elad Alon040dc432019-05-22 15:40:02 +0200937 RTC_DCHECK(!override_field_trials_);
Mirko Bonadei317a1f02019-09-17 17:06:18 +0200938 override_field_trials_ = std::make_unique<webrtc::test::ScopedFieldTrials>(
brandtr340e3fd2017-02-28 15:43:10 -0800939 "WebRTC-FlexFEC-03-Advertised/Enabled/");
Johannes Kron3e983682020-03-29 22:17:00 +0200940 EXPECT_THAT(engine_.send_codecs(), Contains(flexfec));
brandtrffc61182016-11-28 06:02:22 -0800941}
942
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200943// Test that codecs are added in the order they are reported from the factory.
944TEST_F(WebRtcVideoEngineTest, ReportSupportedCodecs) {
945 encoder_factory_->AddSupportedVideoCodecType("VP8");
946 const char* kFakeCodecName = "FakeCodec";
947 encoder_factory_->AddSupportedVideoCodecType(kFakeCodecName);
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000948
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200949 // The last reported codec should appear after the first codec in the vector.
Oleh Prypina40f8242017-12-21 13:32:23 +0100950 const size_t vp8_index = GetEngineCodecIndex("VP8");
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200951 const size_t fake_codec_index = GetEngineCodecIndex(kFakeCodecName);
952 EXPECT_LT(vp8_index, fake_codec_index);
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000953}
954
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200955// Test that a codec that was added after the engine was initialized
brandtrffc61182016-11-28 06:02:22 -0800956// does show up in the codec list after it was added.
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200957TEST_F(WebRtcVideoEngineTest, ReportSupportedAddedCodec) {
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +0100958 const char* kFakeExternalCodecName1 = "FakeExternalCodec1";
959 const char* kFakeExternalCodecName2 = "FakeExternalCodec2";
Magnus Jedvert154ee1f2017-11-15 19:27:11 +0100960
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +0100961 // Set up external encoder factory with first codec, and initialize engine.
962 encoder_factory_->AddSupportedVideoCodecType(kFakeExternalCodecName1);
963
Johannes Kron3e983682020-03-29 22:17:00 +0200964 std::vector<cricket::VideoCodec> codecs_before(engine_.send_codecs());
brandtrffc61182016-11-28 06:02:22 -0800965
966 // Add second codec.
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +0100967 encoder_factory_->AddSupportedVideoCodecType(kFakeExternalCodecName2);
Johannes Kron3e983682020-03-29 22:17:00 +0200968 std::vector<cricket::VideoCodec> codecs_after(engine_.send_codecs());
Sami Kalliomäkie9a18b22018-07-13 10:28:21 +0200969 // The codec itself and RTX should have been added.
970 EXPECT_EQ(codecs_before.size() + 2, codecs_after.size());
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +0100971
972 // Check that both fake codecs are present and that the second fake codec
973 // appears after the first fake codec.
Oleh Prypina40f8242017-12-21 13:32:23 +0100974 const size_t fake_codec_index1 = GetEngineCodecIndex(kFakeExternalCodecName1);
975 const size_t fake_codec_index2 = GetEngineCodecIndex(kFakeExternalCodecName2);
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +0100976 EXPECT_LT(fake_codec_index1, fake_codec_index2);
brandtrffc61182016-11-28 06:02:22 -0800977}
978
Sami Kalliomäkie9a18b22018-07-13 10:28:21 +0200979TEST_F(WebRtcVideoEngineTest, ReportRtxForExternalCodec) {
980 const char* kFakeCodecName = "FakeCodec";
981 encoder_factory_->AddSupportedVideoCodecType(kFakeCodecName);
982
983 const size_t fake_codec_index = GetEngineCodecIndex(kFakeCodecName);
Johannes Kron3e983682020-03-29 22:17:00 +0200984 EXPECT_EQ("rtx", engine_.send_codecs().at(fake_codec_index + 1).name);
Sami Kalliomäkie9a18b22018-07-13 10:28:21 +0200985}
986
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200987TEST_F(WebRtcVideoEngineTest, RegisterDecodersIfSupported) {
Johannes Kron3e983682020-03-29 22:17:00 +0200988 AddSupportedVideoCodecType("VP8");
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200989 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -0800990 parameters.codecs.push_back(GetEngineCodec("VP8"));
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000991
kwiberg686a8ef2016-02-26 03:00:35 -0800992 std::unique_ptr<VideoMediaChannel> channel(
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200993 SetRecvParamsWithSupportedCodecs(parameters.codecs));
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000994
995 EXPECT_TRUE(
996 channel->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200997 ASSERT_EQ(1u, decoder_factory_->decoders().size());
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000998
999 // Setting codecs of the same type should not reallocate the decoder.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02001000 EXPECT_TRUE(channel->SetRecvParameters(parameters));
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001001 EXPECT_EQ(1, decoder_factory_->GetNumCreatedDecoders());
pbos@webrtc.org96a93252014-11-03 14:46:44 +00001002
1003 // Remove stream previously added to free the external decoder instance.
1004 EXPECT_TRUE(channel->RemoveRecvStream(kSsrc));
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001005 EXPECT_EQ(0u, decoder_factory_->decoders().size());
pbos@webrtc.org96a93252014-11-03 14:46:44 +00001006}
1007
Anders Carlsson5f2bb622018-05-14 09:48:06 +02001008// Verifies that we can set up decoders.
1009TEST_F(WebRtcVideoEngineTest, RegisterH264DecoderIfSupported) {
pbos@webrtc.org96a93252014-11-03 14:46:44 +00001010 // TODO(pbos): Do not assume that encoder/decoder support is symmetric. We
1011 // can't even query the WebRtcVideoDecoderFactory for supported codecs.
1012 // For now we add a FakeWebRtcVideoEncoderFactory to add H264 to supported
1013 // codecs.
Johannes Kron3e983682020-03-29 22:17:00 +02001014 AddSupportedVideoCodecType("H264");
pbos@webrtc.org96a93252014-11-03 14:46:44 +00001015 std::vector<cricket::VideoCodec> codecs;
magjed509e4fe2016-11-18 01:34:11 -08001016 codecs.push_back(GetEngineCodec("H264"));
pbos@webrtc.org96a93252014-11-03 14:46:44 +00001017
kwiberg686a8ef2016-02-26 03:00:35 -08001018 std::unique_ptr<VideoMediaChannel> channel(
Anders Carlsson5f2bb622018-05-14 09:48:06 +02001019 SetRecvParamsWithSupportedCodecs(codecs));
pbos@webrtc.org96a93252014-11-03 14:46:44 +00001020
1021 EXPECT_TRUE(
1022 channel->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001023 ASSERT_EQ(1u, decoder_factory_->decoders().size());
pbos@webrtc.org96a93252014-11-03 14:46:44 +00001024}
1025
Jonas Oreland49ac5952018-09-26 16:04:32 +02001026// Tests when GetSources is called with non-existing ssrc, it will return an
1027// empty list of RtpSource without crashing.
1028TEST_F(WebRtcVideoEngineTest, GetSourcesWithNonExistingSsrc) {
1029 // Setup an recv stream with |kSsrc|.
Johannes Kron3e983682020-03-29 22:17:00 +02001030 AddSupportedVideoCodecType("VP8");
Jonas Oreland49ac5952018-09-26 16:04:32 +02001031 cricket::VideoRecvParameters parameters;
1032 parameters.codecs.push_back(GetEngineCodec("VP8"));
1033 std::unique_ptr<VideoMediaChannel> channel(
1034 SetRecvParamsWithSupportedCodecs(parameters.codecs));
1035
1036 EXPECT_TRUE(
1037 channel->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
1038
1039 // Call GetSources with |kSsrc + 1| which doesn't exist.
1040 std::vector<webrtc::RtpSource> sources = channel->GetSources(kSsrc + 1);
1041 EXPECT_EQ(0u, sources.size());
1042}
1043
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001044TEST(WebRtcVideoEngineNewVideoCodecFactoryTest, NullFactories) {
1045 std::unique_ptr<webrtc::VideoEncoderFactory> encoder_factory;
1046 std::unique_ptr<webrtc::VideoDecoderFactory> decoder_factory;
1047 WebRtcVideoEngine engine(std::move(encoder_factory),
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02001048 std::move(decoder_factory));
Johannes Kron3e983682020-03-29 22:17:00 +02001049 EXPECT_EQ(0u, engine.send_codecs().size());
1050 EXPECT_EQ(0u, engine.recv_codecs().size());
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001051}
1052
1053TEST(WebRtcVideoEngineNewVideoCodecFactoryTest, EmptyFactories) {
1054 // |engine| take ownership of the factories.
Emircan Uysalerdbcac7f2017-10-30 23:10:12 -07001055 webrtc::MockVideoEncoderFactory* encoder_factory =
1056 new webrtc::MockVideoEncoderFactory();
1057 webrtc::MockVideoDecoderFactory* decoder_factory =
1058 new webrtc::MockVideoDecoderFactory();
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001059 WebRtcVideoEngine engine(
1060 (std::unique_ptr<webrtc::VideoEncoderFactory>(encoder_factory)),
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02001061 (std::unique_ptr<webrtc::VideoDecoderFactory>(decoder_factory)));
Johannes Kron3e983682020-03-29 22:17:00 +02001062 // TODO(kron): Change to Times(1) once send and receive codecs are changed
1063 // to be treated independently.
1064 EXPECT_CALL(*encoder_factory, GetSupportedFormats()).Times(1);
1065 EXPECT_EQ(0u, engine.send_codecs().size());
1066 EXPECT_EQ(0u, engine.recv_codecs().size());
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001067 EXPECT_CALL(*encoder_factory, Die());
1068 EXPECT_CALL(*decoder_factory, Die());
1069}
1070
1071// Test full behavior in the video engine when video codec factories of the new
1072// type are injected supporting the single codec Vp8. Check the returned codecs
1073// from the engine and that we will create a Vp8 encoder and decoder using the
1074// new factories.
1075TEST(WebRtcVideoEngineNewVideoCodecFactoryTest, Vp8) {
1076 // |engine| take ownership of the factories.
Emircan Uysalerdbcac7f2017-10-30 23:10:12 -07001077 webrtc::MockVideoEncoderFactory* encoder_factory =
1078 new webrtc::MockVideoEncoderFactory();
1079 webrtc::MockVideoDecoderFactory* decoder_factory =
1080 new webrtc::MockVideoDecoderFactory();
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02001081 std::unique_ptr<webrtc::MockVideoBitrateAllocatorFactory>
1082 rate_allocator_factory =
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001083 std::make_unique<webrtc::MockVideoBitrateAllocatorFactory>();
Jiawei Ouc2ebe212018-11-08 10:02:56 -08001084 EXPECT_CALL(*rate_allocator_factory,
1085 CreateVideoBitrateAllocatorProxy(Field(
1086 &webrtc::VideoCodec::codecType, webrtc::kVideoCodecVP8)))
Markus Handell8bc88342020-03-16 10:42:01 +01001087 .WillOnce(Return(new webrtc::MockVideoBitrateAllocator()));
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001088 WebRtcVideoEngine engine(
1089 (std::unique_ptr<webrtc::VideoEncoderFactory>(encoder_factory)),
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02001090 (std::unique_ptr<webrtc::VideoDecoderFactory>(decoder_factory)));
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001091 const webrtc::SdpVideoFormat vp8_format("VP8");
1092 const std::vector<webrtc::SdpVideoFormat> supported_formats = {vp8_format};
1093 EXPECT_CALL(*encoder_factory, GetSupportedFormats())
Markus Handell8bc88342020-03-16 10:42:01 +01001094 .WillRepeatedly(Return(supported_formats));
Johannes Kron3e983682020-03-29 22:17:00 +02001095 EXPECT_CALL(*decoder_factory, GetSupportedFormats())
1096 .WillRepeatedly(Return(supported_formats));
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001097
1098 // Verify the codecs from the engine.
Johannes Kron3e983682020-03-29 22:17:00 +02001099 const std::vector<VideoCodec> engine_codecs = engine.send_codecs();
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +01001100 // Verify default codecs has been added correctly.
1101 EXPECT_EQ(5u, engine_codecs.size());
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001102 EXPECT_EQ("VP8", engine_codecs.at(0).name);
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +01001103
1104 // RTX codec for VP8.
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001105 EXPECT_EQ("rtx", engine_codecs.at(1).name);
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +01001106 int vp8_associated_payload;
1107 EXPECT_TRUE(engine_codecs.at(1).GetParam(kCodecParamAssociatedPayloadType,
1108 &vp8_associated_payload));
1109 EXPECT_EQ(vp8_associated_payload, engine_codecs.at(0).id);
1110
1111 EXPECT_EQ(kRedCodecName, engine_codecs.at(2).name);
1112
1113 // RTX codec for RED.
1114 EXPECT_EQ("rtx", engine_codecs.at(3).name);
1115 int red_associated_payload;
1116 EXPECT_TRUE(engine_codecs.at(3).GetParam(kCodecParamAssociatedPayloadType,
1117 &red_associated_payload));
1118 EXPECT_EQ(red_associated_payload, engine_codecs.at(2).id);
1119
1120 EXPECT_EQ(kUlpfecCodecName, engine_codecs.at(4).name);
1121
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001122 int associated_payload_type;
1123 EXPECT_TRUE(engine_codecs.at(1).GetParam(
1124 cricket::kCodecParamAssociatedPayloadType, &associated_payload_type));
1125 EXPECT_EQ(engine_codecs.at(0).id, associated_payload_type);
1126 // Verify default parameters has been added to the VP8 codec.
Elad Alonfadb1812019-05-24 13:40:02 +02001127 VerifyCodecHasDefaultFeedbackParams(engine_codecs.at(0),
1128 /*lntf_expected=*/false);
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001129
1130 // Mock encoder creation. |engine| take ownership of the encoder.
Mirta Dvornicic1ec2a162018-12-10 09:47:34 +00001131 webrtc::VideoEncoderFactory::CodecInfo codec_info;
1132 codec_info.is_hardware_accelerated = false;
1133 codec_info.has_internal_source = false;
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001134 const webrtc::SdpVideoFormat format("VP8");
Mirta Dvornicic1ec2a162018-12-10 09:47:34 +00001135 EXPECT_CALL(*encoder_factory, QueryVideoEncoder(format))
Markus Handell8bc88342020-03-16 10:42:01 +01001136 .WillRepeatedly(Return(codec_info));
Anders Carlsson67537952018-05-03 11:28:29 +02001137 FakeWebRtcVideoEncoder* const encoder = new FakeWebRtcVideoEncoder(nullptr);
Niels Möllerc572ff32018-11-07 08:43:50 +01001138 rtc::Event encoder_created;
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001139 EXPECT_CALL(*encoder_factory, CreateVideoEncoderProxy(format))
Niels Möller4db138e2018-04-19 09:04:13 +02001140 .WillOnce(
1141 ::testing::DoAll(::testing::InvokeWithoutArgs(
1142 [&encoder_created]() { encoder_created.Set(); }),
Markus Handell8bc88342020-03-16 10:42:01 +01001143 Return(encoder)));
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001144
1145 // Mock decoder creation. |engine| take ownership of the decoder.
Anders Carlsson67537952018-05-03 11:28:29 +02001146 FakeWebRtcVideoDecoder* const decoder = new FakeWebRtcVideoDecoder(nullptr);
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001147 EXPECT_CALL(*decoder_factory, CreateVideoDecoderProxy(format))
Markus Handell8bc88342020-03-16 10:42:01 +01001148 .WillOnce(Return(decoder));
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001149
1150 // Create a call.
Danil Chapovalov83bbe912019-08-07 12:24:53 +02001151 webrtc::RtcEventLogNull event_log;
Danil Chapovalov53d45ba2019-07-03 14:56:33 +02001152 auto task_queue_factory = webrtc::CreateDefaultTaskQueueFactory();
1153 webrtc::Call::Config call_config(&event_log);
Erik Språng014dd3c2019-11-28 13:44:25 +01001154 webrtc::FieldTrialBasedConfig field_trials;
1155 call_config.trials = &field_trials;
Danil Chapovalov53d45ba2019-07-03 14:56:33 +02001156 call_config.task_queue_factory = task_queue_factory.get();
1157 const auto call = absl::WrapUnique(webrtc::Call::Create(call_config));
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001158
1159 // Create send channel.
1160 const int send_ssrc = 123;
Sebastian Jansson84848f22018-11-16 10:40:36 +01001161 std::unique_ptr<VideoMediaChannel> send_channel(engine.CreateMediaChannel(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02001162 call.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
1163 rate_allocator_factory.get()));
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001164 cricket::VideoSendParameters send_parameters;
1165 send_parameters.codecs.push_back(engine_codecs.at(0));
1166 EXPECT_TRUE(send_channel->SetSendParameters(send_parameters));
1167 send_channel->OnReadyToSend(true);
1168 EXPECT_TRUE(
1169 send_channel->AddSendStream(StreamParams::CreateLegacy(send_ssrc)));
1170 EXPECT_TRUE(send_channel->SetSend(true));
1171
Niels Möller4db138e2018-04-19 09:04:13 +02001172 // Set capturer.
Niels Möller805a27e2019-01-21 12:21:27 +01001173 webrtc::test::FrameForwarder frame_forwarder;
1174 cricket::FakeFrameSource frame_source(1280, 720,
1175 rtc::kNumMicrosecsPerSec / 30);
1176 EXPECT_TRUE(send_channel->SetVideoSend(send_ssrc, nullptr, &frame_forwarder));
Niels Möller4db138e2018-04-19 09:04:13 +02001177 // Sending one frame will allocate the encoder.
Niels Möller805a27e2019-01-21 12:21:27 +01001178 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
Niels Möller4db138e2018-04-19 09:04:13 +02001179 encoder_created.Wait(kTimeout);
1180
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001181 // Create recv channel.
1182 const int recv_ssrc = 321;
Sebastian Jansson84848f22018-11-16 10:40:36 +01001183 std::unique_ptr<VideoMediaChannel> recv_channel(engine.CreateMediaChannel(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02001184 call.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
1185 rate_allocator_factory.get()));
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001186 cricket::VideoRecvParameters recv_parameters;
1187 recv_parameters.codecs.push_back(engine_codecs.at(0));
1188 EXPECT_TRUE(recv_channel->SetRecvParameters(recv_parameters));
1189 EXPECT_TRUE(recv_channel->AddRecvStream(
1190 cricket::StreamParams::CreateLegacy(recv_ssrc)));
1191
1192 // Remove streams previously added to free the encoder and decoder instance.
1193 EXPECT_CALL(*encoder_factory, Die());
1194 EXPECT_CALL(*decoder_factory, Die());
Jiawei Ouc2ebe212018-11-08 10:02:56 -08001195 EXPECT_CALL(*rate_allocator_factory, Die());
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001196 EXPECT_TRUE(send_channel->RemoveSendStream(send_ssrc));
1197 EXPECT_TRUE(recv_channel->RemoveRecvStream(recv_ssrc));
1198}
1199
Magnus Jedvert7501b1c2017-11-09 13:43:42 +01001200// Test behavior when decoder factory fails to create a decoder (returns null).
1201TEST(WebRtcVideoEngineNewVideoCodecFactoryTest, NullDecoder) {
1202 // |engine| take ownership of the factories.
1203 webrtc::MockVideoEncoderFactory* encoder_factory =
Jiawei Ouc2ebe212018-11-08 10:02:56 -08001204 new webrtc::MockVideoEncoderFactory();
Magnus Jedvert7501b1c2017-11-09 13:43:42 +01001205 webrtc::MockVideoDecoderFactory* decoder_factory =
Jiawei Ouc2ebe212018-11-08 10:02:56 -08001206 new webrtc::MockVideoDecoderFactory();
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02001207 std::unique_ptr<webrtc::MockVideoBitrateAllocatorFactory>
1208 rate_allocator_factory =
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001209 std::make_unique<webrtc::MockVideoBitrateAllocatorFactory>();
Magnus Jedvert7501b1c2017-11-09 13:43:42 +01001210 WebRtcVideoEngine engine(
1211 (std::unique_ptr<webrtc::VideoEncoderFactory>(encoder_factory)),
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02001212 (std::unique_ptr<webrtc::VideoDecoderFactory>(decoder_factory)));
Magnus Jedvert7501b1c2017-11-09 13:43:42 +01001213 const webrtc::SdpVideoFormat vp8_format("VP8");
1214 const std::vector<webrtc::SdpVideoFormat> supported_formats = {vp8_format};
1215 EXPECT_CALL(*encoder_factory, GetSupportedFormats())
Markus Handell8bc88342020-03-16 10:42:01 +01001216 .WillRepeatedly(Return(supported_formats));
Magnus Jedvert7501b1c2017-11-09 13:43:42 +01001217
1218 // Decoder creation fails.
Markus Handell8bc88342020-03-16 10:42:01 +01001219 EXPECT_CALL(*decoder_factory, CreateVideoDecoderProxy(_))
1220 .WillOnce(Return(nullptr));
Magnus Jedvert7501b1c2017-11-09 13:43:42 +01001221
1222 // Create a call.
Danil Chapovalov83bbe912019-08-07 12:24:53 +02001223 webrtc::RtcEventLogNull event_log;
Danil Chapovalov53d45ba2019-07-03 14:56:33 +02001224 auto task_queue_factory = webrtc::CreateDefaultTaskQueueFactory();
1225 webrtc::Call::Config call_config(&event_log);
Erik Språng014dd3c2019-11-28 13:44:25 +01001226 webrtc::FieldTrialBasedConfig field_trials;
1227 call_config.trials = &field_trials;
Danil Chapovalov53d45ba2019-07-03 14:56:33 +02001228 call_config.task_queue_factory = task_queue_factory.get();
1229 const auto call = absl::WrapUnique(webrtc::Call::Create(call_config));
Magnus Jedvert7501b1c2017-11-09 13:43:42 +01001230
1231 // Create recv channel.
Johannes Kron3e983682020-03-29 22:17:00 +02001232 EXPECT_CALL(*decoder_factory, GetSupportedFormats())
1233 .WillRepeatedly(::testing::Return(supported_formats));
Magnus Jedvert7501b1c2017-11-09 13:43:42 +01001234 const int recv_ssrc = 321;
Sebastian Jansson84848f22018-11-16 10:40:36 +01001235 std::unique_ptr<VideoMediaChannel> recv_channel(engine.CreateMediaChannel(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02001236 call.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
1237 rate_allocator_factory.get()));
Magnus Jedvert7501b1c2017-11-09 13:43:42 +01001238 cricket::VideoRecvParameters recv_parameters;
Johannes Kron3e983682020-03-29 22:17:00 +02001239 recv_parameters.codecs.push_back(engine.recv_codecs().front());
Magnus Jedvert7501b1c2017-11-09 13:43:42 +01001240 EXPECT_TRUE(recv_channel->SetRecvParameters(recv_parameters));
1241 EXPECT_TRUE(recv_channel->AddRecvStream(
1242 cricket::StreamParams::CreateLegacy(recv_ssrc)));
1243
1244 // Remove streams previously added to free the encoder and decoder instance.
1245 EXPECT_TRUE(recv_channel->RemoveRecvStream(recv_ssrc));
1246}
1247
eladalonf1841382017-06-12 01:16:46 -07001248TEST_F(WebRtcVideoEngineTest, DISABLED_RecreatesEncoderOnContentTypeChange) {
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001249 encoder_factory_->AddSupportedVideoCodecType("VP8");
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001250 std::unique_ptr<FakeCall> fake_call(new FakeCall());
Anders Carlsson5f2bb622018-05-14 09:48:06 +02001251 std::unique_ptr<VideoMediaChannel> channel(
1252 SetSendParamsWithAllSupportedCodecs());
sprangf24a0642017-02-28 13:23:26 -08001253 ASSERT_TRUE(
1254 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
1255 cricket::VideoCodec codec = GetEngineCodec("VP8");
1256 cricket::VideoSendParameters parameters;
1257 parameters.codecs.push_back(codec);
1258 channel->OnReadyToSend(true);
1259 channel->SetSend(true);
1260 ASSERT_TRUE(channel->SetSendParameters(parameters));
1261
Niels Möller805a27e2019-01-21 12:21:27 +01001262 webrtc::test::FrameForwarder frame_forwarder;
1263 cricket::FakeFrameSource frame_source(1280, 720,
1264 rtc::kNumMicrosecsPerSec / 30);
sprangf24a0642017-02-28 13:23:26 -08001265 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01001266 EXPECT_TRUE(channel->SetVideoSend(kSsrc, &options, &frame_forwarder));
sprangf24a0642017-02-28 13:23:26 -08001267
Niels Möller805a27e2019-01-21 12:21:27 +01001268 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001269 ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(1));
Niels Möllere3cf3d02018-06-13 11:52:16 +02001270 EXPECT_EQ(webrtc::VideoCodecMode::kRealtimeVideo,
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001271 encoder_factory_->encoders().back()->GetCodecSettings().mode);
sprangf24a0642017-02-28 13:23:26 -08001272
Niels Möller805a27e2019-01-21 12:21:27 +01001273 EXPECT_TRUE(channel->SetVideoSend(kSsrc, &options, &frame_forwarder));
1274 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
sprangf24a0642017-02-28 13:23:26 -08001275 // No change in content type, keep current encoder.
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001276 EXPECT_EQ(1, encoder_factory_->GetNumCreatedEncoders());
sprangf24a0642017-02-28 13:23:26 -08001277
1278 options.is_screencast.emplace(true);
Niels Möller805a27e2019-01-21 12:21:27 +01001279 EXPECT_TRUE(channel->SetVideoSend(kSsrc, &options, &frame_forwarder));
1280 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
sprangf24a0642017-02-28 13:23:26 -08001281 // Change to screen content, recreate encoder. For the simulcast encoder
1282 // adapter case, this will result in two calls since InitEncode triggers a
1283 // a new instance.
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001284 ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(2));
Niels Möllere3cf3d02018-06-13 11:52:16 +02001285 EXPECT_EQ(webrtc::VideoCodecMode::kScreensharing,
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001286 encoder_factory_->encoders().back()->GetCodecSettings().mode);
sprangf24a0642017-02-28 13:23:26 -08001287
Niels Möller805a27e2019-01-21 12:21:27 +01001288 EXPECT_TRUE(channel->SetVideoSend(kSsrc, &options, &frame_forwarder));
1289 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
sprangf24a0642017-02-28 13:23:26 -08001290 // Still screen content, no need to update encoder.
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001291 EXPECT_EQ(2, encoder_factory_->GetNumCreatedEncoders());
sprangf24a0642017-02-28 13:23:26 -08001292
1293 options.is_screencast.emplace(false);
1294 options.video_noise_reduction.emplace(false);
Niels Möller805a27e2019-01-21 12:21:27 +01001295 EXPECT_TRUE(channel->SetVideoSend(kSsrc, &options, &frame_forwarder));
sprangf24a0642017-02-28 13:23:26 -08001296 // Change back to regular video content, update encoder. Also change
1297 // a non |is_screencast| option just to verify it doesn't affect recreation.
Niels Möller805a27e2019-01-21 12:21:27 +01001298 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001299 ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(3));
Niels Möllere3cf3d02018-06-13 11:52:16 +02001300 EXPECT_EQ(webrtc::VideoCodecMode::kRealtimeVideo,
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001301 encoder_factory_->encoders().back()->GetCodecSettings().mode);
sprangf24a0642017-02-28 13:23:26 -08001302
1303 // Remove stream previously added to free the external encoder instance.
1304 EXPECT_TRUE(channel->RemoveSendStream(kSsrc));
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001305 EXPECT_EQ(0u, encoder_factory_->encoders().size());
sprangf24a0642017-02-28 13:23:26 -08001306}
1307
Markus Handell32565f62019-12-04 10:58:17 +01001308class WebRtcVideoChannelEncodedFrameCallbackTest : public ::testing::Test {
1309 protected:
1310 webrtc::Call::Config GetCallConfig(
1311 webrtc::RtcEventLogNull* event_log,
1312 webrtc::TaskQueueFactory* task_queue_factory) {
1313 webrtc::Call::Config call_config(event_log);
1314 call_config.task_queue_factory = task_queue_factory;
1315 call_config.trials = &field_trials_;
1316 return call_config;
1317 }
1318
1319 WebRtcVideoChannelEncodedFrameCallbackTest()
1320 : task_queue_factory_(webrtc::CreateDefaultTaskQueueFactory()),
1321 call_(absl::WrapUnique(webrtc::Call::Create(
1322 GetCallConfig(&event_log_, task_queue_factory_.get())))),
1323 video_bitrate_allocator_factory_(
1324 webrtc::CreateBuiltinVideoBitrateAllocatorFactory()),
1325 engine_(
1326 webrtc::CreateBuiltinVideoEncoderFactory(),
Johannes Kron3e983682020-03-29 22:17:00 +02001327 std::make_unique<webrtc::test::FunctionVideoDecoderFactory>(
1328 []() { return std::make_unique<webrtc::test::FakeDecoder>(); },
1329 kSdpVideoFormats)),
Markus Handell32565f62019-12-04 10:58:17 +01001330 channel_(absl::WrapUnique(static_cast<cricket::WebRtcVideoChannel*>(
1331 engine_.CreateMediaChannel(
1332 call_.get(),
1333 cricket::MediaConfig(),
1334 cricket::VideoOptions(),
1335 webrtc::CryptoOptions(),
1336 video_bitrate_allocator_factory_.get())))) {
1337 network_interface_.SetDestination(channel_.get());
1338 channel_->SetInterface(&network_interface_, webrtc::MediaTransportConfig());
1339 cricket::VideoRecvParameters parameters;
Johannes Kron3e983682020-03-29 22:17:00 +02001340 parameters.codecs = engine_.recv_codecs();
Markus Handell32565f62019-12-04 10:58:17 +01001341 channel_->SetRecvParameters(parameters);
1342 }
1343
1344 void DeliverKeyFrame(uint32_t ssrc) {
1345 webrtc::RtpPacket packet;
1346 packet.SetMarker(true);
1347 packet.SetPayloadType(96); // VP8
1348 packet.SetSsrc(ssrc);
1349
1350 // VP8 Keyframe + 1 byte payload
1351 uint8_t* buf_ptr = packet.AllocatePayload(11);
1352 memset(buf_ptr, 0, 11); // Pass MSAN (don't care about bytes 1-9)
1353 buf_ptr[0] = 0x10; // Partition ID 0 + beginning of partition.
1354 call_->Receiver()->DeliverPacket(webrtc::MediaType::VIDEO, packet.Buffer(),
1355 /*packet_time_us=*/0);
1356 }
1357
1358 void DeliverKeyFrameAndWait(uint32_t ssrc) {
1359 DeliverKeyFrame(ssrc);
1360 EXPECT_EQ_WAIT(1, renderer_.num_rendered_frames(), kTimeout);
1361 EXPECT_EQ(0, renderer_.errors());
1362 }
1363
Johannes Kron3e983682020-03-29 22:17:00 +02001364 static const std::vector<webrtc::SdpVideoFormat> kSdpVideoFormats;
Markus Handell32565f62019-12-04 10:58:17 +01001365 webrtc::FieldTrialBasedConfig field_trials_;
1366 webrtc::RtcEventLogNull event_log_;
1367 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory_;
1368 std::unique_ptr<webrtc::Call> call_;
1369 std::unique_ptr<webrtc::VideoBitrateAllocatorFactory>
1370 video_bitrate_allocator_factory_;
1371 WebRtcVideoEngine engine_;
1372 std::unique_ptr<WebRtcVideoChannel> channel_;
1373 cricket::FakeNetworkInterface network_interface_;
1374 cricket::FakeVideoRenderer renderer_;
1375};
1376
Johannes Kron3e983682020-03-29 22:17:00 +02001377const std::vector<webrtc::SdpVideoFormat>
1378 WebRtcVideoChannelEncodedFrameCallbackTest::kSdpVideoFormats = {
1379 webrtc::SdpVideoFormat("VP8")};
1380
Markus Handell32565f62019-12-04 10:58:17 +01001381TEST_F(WebRtcVideoChannelEncodedFrameCallbackTest,
1382 SetEncodedFrameBufferFunction_DefaultStream) {
1383 testing::MockFunction<void(const webrtc::RecordableEncodedFrame&)> callback;
1384 EXPECT_CALL(callback, Call);
1385 EXPECT_TRUE(channel_->AddRecvStream(
1386 cricket::StreamParams::CreateLegacy(kSsrc), /*is_default_stream=*/true));
1387 channel_->SetRecordableEncodedFrameCallback(/*ssrc=*/0,
1388 callback.AsStdFunction());
1389 EXPECT_TRUE(channel_->SetSink(kSsrc, &renderer_));
1390 DeliverKeyFrame(kSsrc);
1391 EXPECT_EQ_WAIT(1, renderer_.num_rendered_frames(), kTimeout);
1392 EXPECT_EQ(0, renderer_.errors());
1393 channel_->RemoveRecvStream(kSsrc);
1394}
1395
1396TEST_F(WebRtcVideoChannelEncodedFrameCallbackTest,
1397 SetEncodedFrameBufferFunction_MatchSsrcWithDefaultStream) {
1398 testing::MockFunction<void(const webrtc::RecordableEncodedFrame&)> callback;
1399 EXPECT_CALL(callback, Call);
1400 EXPECT_TRUE(channel_->AddRecvStream(
1401 cricket::StreamParams::CreateLegacy(kSsrc), /*is_default_stream=*/true));
1402 EXPECT_TRUE(channel_->SetSink(kSsrc, &renderer_));
1403 channel_->SetRecordableEncodedFrameCallback(kSsrc, callback.AsStdFunction());
1404 DeliverKeyFrame(kSsrc);
1405 EXPECT_EQ_WAIT(1, renderer_.num_rendered_frames(), kTimeout);
1406 EXPECT_EQ(0, renderer_.errors());
1407 channel_->RemoveRecvStream(kSsrc);
1408}
1409
1410TEST_F(WebRtcVideoChannelEncodedFrameCallbackTest,
1411 SetEncodedFrameBufferFunction_MatchSsrc) {
1412 testing::MockFunction<void(const webrtc::RecordableEncodedFrame&)> callback;
1413 EXPECT_CALL(callback, Call);
1414 EXPECT_TRUE(channel_->AddRecvStream(
1415 cricket::StreamParams::CreateLegacy(kSsrc), /*is_default_stream=*/false));
1416 EXPECT_TRUE(channel_->SetSink(kSsrc, &renderer_));
1417 channel_->SetRecordableEncodedFrameCallback(kSsrc, callback.AsStdFunction());
1418 DeliverKeyFrame(kSsrc);
1419 EXPECT_EQ_WAIT(1, renderer_.num_rendered_frames(), kTimeout);
1420 EXPECT_EQ(0, renderer_.errors());
1421 channel_->RemoveRecvStream(kSsrc);
1422}
1423
1424TEST_F(WebRtcVideoChannelEncodedFrameCallbackTest,
1425 SetEncodedFrameBufferFunction_MismatchSsrc) {
1426 testing::StrictMock<
1427 testing::MockFunction<void(const webrtc::RecordableEncodedFrame&)>>
1428 callback;
1429 EXPECT_TRUE(
1430 channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc + 1),
1431 /*is_default_stream=*/false));
1432 EXPECT_TRUE(channel_->SetSink(kSsrc + 1, &renderer_));
1433 channel_->SetRecordableEncodedFrameCallback(kSsrc, callback.AsStdFunction());
1434 DeliverKeyFrame(kSsrc); // Expected to not cause function to fire.
1435 DeliverKeyFrameAndWait(kSsrc + 1);
1436 channel_->RemoveRecvStream(kSsrc + 1);
1437}
1438
1439TEST_F(WebRtcVideoChannelEncodedFrameCallbackTest,
1440 SetEncodedFrameBufferFunction_MismatchSsrcWithDefaultStream) {
1441 testing::StrictMock<
1442 testing::MockFunction<void(const webrtc::RecordableEncodedFrame&)>>
1443 callback;
1444 EXPECT_TRUE(
1445 channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc + 1),
1446 /*is_default_stream=*/true));
1447 EXPECT_TRUE(channel_->SetSink(kSsrc + 1, &renderer_));
1448 channel_->SetRecordableEncodedFrameCallback(kSsrc, callback.AsStdFunction());
1449 DeliverKeyFrame(kSsrc); // Expected to not cause function to fire.
1450 DeliverKeyFrameAndWait(kSsrc + 1);
1451 channel_->RemoveRecvStream(kSsrc + 1);
1452}
1453
Mirko Bonadei6a489f22019-04-09 15:11:12 +02001454class WebRtcVideoChannelBaseTest : public ::testing::Test {
Niels Möller6557d0c2018-04-11 15:18:34 +02001455 protected:
1456 WebRtcVideoChannelBaseTest()
Danil Chapovalov53d45ba2019-07-03 14:56:33 +02001457 : task_queue_factory_(webrtc::CreateDefaultTaskQueueFactory()),
1458 video_bitrate_allocator_factory_(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02001459 webrtc::CreateBuiltinVideoBitrateAllocatorFactory()),
1460 engine_(webrtc::CreateBuiltinVideoEncoderFactory(),
1461 webrtc::CreateBuiltinVideoDecoderFactory()) {}
Niels Möller6557d0c2018-04-11 15:18:34 +02001462
1463 virtual void SetUp() {
Jonas Oreland49ac5952018-09-26 16:04:32 +02001464 // One testcase calls SetUp in a loop, only create call_ once.
1465 if (!call_) {
Danil Chapovalov53d45ba2019-07-03 14:56:33 +02001466 webrtc::Call::Config call_config(&event_log_);
1467 call_config.task_queue_factory = task_queue_factory_.get();
Erik Språng014dd3c2019-11-28 13:44:25 +01001468 call_config.trials = &field_trials_;
Danil Chapovalov53d45ba2019-07-03 14:56:33 +02001469 call_.reset(webrtc::Call::Create(call_config));
Jonas Oreland49ac5952018-09-26 16:04:32 +02001470 }
Niels Möller6557d0c2018-04-11 15:18:34 +02001471 cricket::MediaConfig media_config;
1472 // Disabling cpu overuse detection actually disables quality scaling too; it
1473 // implies DegradationPreference kMaintainResolution. Automatic scaling
1474 // needs to be disabled, otherwise, tests which check the size of received
1475 // frames become flaky.
1476 media_config.video.enable_cpu_adaptation = false;
Sebastian Jansson84848f22018-11-16 10:40:36 +01001477 channel_.reset(
1478 static_cast<cricket::WebRtcVideoChannel*>(engine_.CreateMediaChannel(
1479 call_.get(), media_config, cricket::VideoOptions(),
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02001480 webrtc::CryptoOptions(), video_bitrate_allocator_factory_.get())));
Niels Möller6557d0c2018-04-11 15:18:34 +02001481 channel_->OnReadyToSend(true);
1482 EXPECT_TRUE(channel_.get() != NULL);
1483 network_interface_.SetDestination(channel_.get());
Anton Sukhanov4f08faa2019-05-21 11:12:57 -07001484 channel_->SetInterface(&network_interface_, webrtc::MediaTransportConfig());
Niels Möller6557d0c2018-04-11 15:18:34 +02001485 cricket::VideoRecvParameters parameters;
Johannes Kron3e983682020-03-29 22:17:00 +02001486 parameters.codecs = engine_.send_codecs();
Niels Möller6557d0c2018-04-11 15:18:34 +02001487 channel_->SetRecvParameters(parameters);
1488 EXPECT_TRUE(channel_->AddSendStream(DefaultSendStreamParams()));
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001489 frame_forwarder_ = std::make_unique<webrtc::test::FrameForwarder>();
1490 frame_source_ = std::make_unique<cricket::FakeFrameSource>(
Niels Möller805a27e2019-01-21 12:21:27 +01001491 640, 480, rtc::kNumMicrosecsPerSec / kFramerate);
1492 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, nullptr, frame_forwarder_.get()));
Niels Möller6557d0c2018-04-11 15:18:34 +02001493 }
1494
1495 // Utility method to setup an additional stream to send and receive video.
1496 // Used to test send and recv between two streams.
1497 void SetUpSecondStream() {
1498 SetUpSecondStreamWithNoRecv();
1499 // Setup recv for second stream.
1500 EXPECT_TRUE(channel_->AddRecvStream(
1501 cricket::StreamParams::CreateLegacy(kSsrc + 2)));
1502 // Make the second renderer available for use by a new stream.
1503 EXPECT_TRUE(channel_->SetSink(kSsrc + 2, &renderer2_));
1504 }
1505 // Setup an additional stream just to send video. Defer add recv stream.
1506 // This is required if you want to test unsignalled recv of video rtp packets.
1507 void SetUpSecondStreamWithNoRecv() {
1508 // SetUp() already added kSsrc make sure duplicate SSRCs cant be added.
Yves Gerey665174f2018-06-19 15:03:05 +02001509 EXPECT_TRUE(
1510 channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
Niels Möller6557d0c2018-04-11 15:18:34 +02001511 EXPECT_TRUE(channel_->SetSink(kSsrc, &renderer_));
Yves Gerey665174f2018-06-19 15:03:05 +02001512 EXPECT_FALSE(
1513 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
Niels Möller6557d0c2018-04-11 15:18:34 +02001514 EXPECT_TRUE(channel_->AddSendStream(
1515 cricket::StreamParams::CreateLegacy(kSsrc + 2)));
1516 // We dont add recv for the second stream.
1517
1518 // Setup the receive and renderer for second stream after send.
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001519 frame_forwarder_2_ = std::make_unique<webrtc::test::FrameForwarder>();
Yves Gerey665174f2018-06-19 15:03:05 +02001520 EXPECT_TRUE(
Niels Möller805a27e2019-01-21 12:21:27 +01001521 channel_->SetVideoSend(kSsrc + 2, nullptr, frame_forwarder_2_.get()));
Niels Möller6557d0c2018-04-11 15:18:34 +02001522 }
Yves Gerey665174f2018-06-19 15:03:05 +02001523 virtual void TearDown() { channel_.reset(); }
1524 bool SetDefaultCodec() { return SetOneCodec(DefaultCodec()); }
Niels Möller6557d0c2018-04-11 15:18:34 +02001525
1526 bool SetOneCodec(const cricket::VideoCodec& codec) {
Mirko Bonadei317a1f02019-09-17 17:06:18 +02001527 frame_source_ = std::make_unique<cricket::FakeFrameSource>(
Niels Möller805a27e2019-01-21 12:21:27 +01001528 kVideoWidth, kVideoHeight, rtc::kNumMicrosecsPerSec / kFramerate);
Niels Möller6557d0c2018-04-11 15:18:34 +02001529
1530 bool sending = channel_->sending();
1531 bool success = SetSend(false);
1532 if (success) {
1533 cricket::VideoSendParameters parameters;
1534 parameters.codecs.push_back(codec);
1535 success = channel_->SetSendParameters(parameters);
1536 }
1537 if (success) {
1538 success = SetSend(sending);
1539 }
1540 return success;
1541 }
Yves Gerey665174f2018-06-19 15:03:05 +02001542 bool SetSend(bool send) { return channel_->SetSend(send); }
Niels Möller805a27e2019-01-21 12:21:27 +01001543 void SendFrame() {
1544 if (frame_forwarder_2_) {
1545 frame_forwarder_2_->IncomingCapturedFrame(frame_source_->GetFrame());
Niels Möller6557d0c2018-04-11 15:18:34 +02001546 }
Niels Möller805a27e2019-01-21 12:21:27 +01001547 frame_forwarder_->IncomingCapturedFrame(frame_source_->GetFrame());
Niels Möller6557d0c2018-04-11 15:18:34 +02001548 }
1549 bool WaitAndSendFrame(int wait_ms) {
1550 bool ret = rtc::Thread::Current()->ProcessMessages(wait_ms);
Niels Möller805a27e2019-01-21 12:21:27 +01001551 SendFrame();
Niels Möller6557d0c2018-04-11 15:18:34 +02001552 return ret;
1553 }
Yves Gerey665174f2018-06-19 15:03:05 +02001554 int NumRtpBytes() { return network_interface_.NumRtpBytes(); }
Niels Möller6557d0c2018-04-11 15:18:34 +02001555 int NumRtpBytes(uint32_t ssrc) {
1556 return network_interface_.NumRtpBytes(ssrc);
1557 }
Yves Gerey665174f2018-06-19 15:03:05 +02001558 int NumRtpPackets() { return network_interface_.NumRtpPackets(); }
Niels Möller6557d0c2018-04-11 15:18:34 +02001559 int NumRtpPackets(uint32_t ssrc) {
1560 return network_interface_.NumRtpPackets(ssrc);
1561 }
Yves Gerey665174f2018-06-19 15:03:05 +02001562 int NumSentSsrcs() { return network_interface_.NumSentSsrcs(); }
Niels Möller6557d0c2018-04-11 15:18:34 +02001563 const rtc::CopyOnWriteBuffer* GetRtpPacket(int index) {
1564 return network_interface_.GetRtpPacket(index);
1565 }
1566 static int GetPayloadType(const rtc::CopyOnWriteBuffer* p) {
Åsa Persson23cd45a2018-07-03 10:40:40 +02001567 webrtc::RTPHeader header;
1568 EXPECT_TRUE(ParseRtpPacket(p, &header));
1569 return header.payloadType;
Niels Möller6557d0c2018-04-11 15:18:34 +02001570 }
Åsa Persson23cd45a2018-07-03 10:40:40 +02001571
Niels Möller6557d0c2018-04-11 15:18:34 +02001572 static bool ParseRtpPacket(const rtc::CopyOnWriteBuffer* p,
Åsa Persson23cd45a2018-07-03 10:40:40 +02001573 webrtc::RTPHeader* header) {
1574 std::unique_ptr<webrtc::RtpHeaderParser> parser(
Tommi25eb47c2019-08-29 16:39:05 +02001575 webrtc::RtpHeaderParser::CreateForTest());
Åsa Persson23cd45a2018-07-03 10:40:40 +02001576 return parser->Parse(p->cdata(), p->size(), header);
Niels Möller6557d0c2018-04-11 15:18:34 +02001577 }
1578
1579 // Tests that we can send and receive frames.
1580 void SendAndReceive(const cricket::VideoCodec& codec) {
1581 EXPECT_TRUE(SetOneCodec(codec));
1582 EXPECT_TRUE(SetSend(true));
Saurav Das749f6602019-12-04 09:31:36 -08001583 channel_->SetDefaultSink(&renderer_);
Niels Möller6557d0c2018-04-11 15:18:34 +02001584 EXPECT_EQ(0, renderer_.num_rendered_frames());
Niels Möller805a27e2019-01-21 12:21:27 +01001585 SendFrame();
Niels Möller6557d0c2018-04-11 15:18:34 +02001586 EXPECT_FRAME_WAIT(1, kVideoWidth, kVideoHeight, kTimeout);
1587 std::unique_ptr<const rtc::CopyOnWriteBuffer> p(GetRtpPacket(0));
1588 EXPECT_EQ(codec.id, GetPayloadType(p.get()));
1589 }
1590
1591 void SendReceiveManyAndGetStats(const cricket::VideoCodec& codec,
Yves Gerey665174f2018-06-19 15:03:05 +02001592 int duration_sec,
1593 int fps) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001594 EXPECT_TRUE(SetOneCodec(codec));
1595 EXPECT_TRUE(SetSend(true));
Saurav Das749f6602019-12-04 09:31:36 -08001596 channel_->SetDefaultSink(&renderer_);
Niels Möller6557d0c2018-04-11 15:18:34 +02001597 EXPECT_EQ(0, renderer_.num_rendered_frames());
1598 for (int i = 0; i < duration_sec; ++i) {
1599 for (int frame = 1; frame <= fps; ++frame) {
1600 EXPECT_TRUE(WaitAndSendFrame(1000 / fps));
1601 EXPECT_FRAME_WAIT(frame + i * fps, kVideoWidth, kVideoHeight, kTimeout);
1602 }
1603 }
1604 std::unique_ptr<const rtc::CopyOnWriteBuffer> p(GetRtpPacket(0));
1605 EXPECT_EQ(codec.id, GetPayloadType(p.get()));
1606 }
1607
Niels Möller6557d0c2018-04-11 15:18:34 +02001608 cricket::VideoSenderInfo GetSenderStats(size_t i) {
1609 cricket::VideoMediaInfo info;
1610 EXPECT_TRUE(channel_->GetStats(&info));
1611 return info.senders[i];
1612 }
1613
1614 cricket::VideoReceiverInfo GetReceiverStats(size_t i) {
1615 cricket::VideoMediaInfo info;
1616 EXPECT_TRUE(channel_->GetStats(&info));
1617 return info.receivers[i];
1618 }
1619
1620 // Two streams one channel tests.
1621
1622 // Tests that we can send and receive frames.
1623 void TwoStreamsSendAndReceive(const cricket::VideoCodec& codec) {
1624 SetUpSecondStream();
1625 // Test sending and receiving on first stream.
1626 SendAndReceive(codec);
1627 // Test sending and receiving on second stream.
1628 EXPECT_EQ_WAIT(1, renderer2_.num_rendered_frames(), kTimeout);
1629 EXPECT_GT(NumRtpPackets(), 0);
1630 EXPECT_EQ(1, renderer2_.num_rendered_frames());
1631 }
1632
1633 cricket::VideoCodec GetEngineCodec(const std::string& name) {
Johannes Kron3e983682020-03-29 22:17:00 +02001634 for (const cricket::VideoCodec& engine_codec : engine_.send_codecs()) {
Niels Möller039743e2018-10-23 10:07:25 +02001635 if (absl::EqualsIgnoreCase(name, engine_codec.name))
Niels Möller6557d0c2018-04-11 15:18:34 +02001636 return engine_codec;
1637 }
1638 // This point should never be reached.
1639 ADD_FAILURE() << "Unrecognized codec name: " << name;
1640 return cricket::VideoCodec();
1641 }
1642
1643 cricket::VideoCodec DefaultCodec() { return GetEngineCodec("VP8"); }
1644
1645 cricket::StreamParams DefaultSendStreamParams() {
1646 return cricket::StreamParams::CreateLegacy(kSsrc);
1647 }
1648
Danil Chapovalov83bbe912019-08-07 12:24:53 +02001649 webrtc::RtcEventLogNull event_log_;
Erik Språng014dd3c2019-11-28 13:44:25 +01001650 webrtc::FieldTrialBasedConfig field_trials_;
Danil Chapovalov53d45ba2019-07-03 14:56:33 +02001651 std::unique_ptr<webrtc::TaskQueueFactory> task_queue_factory_;
Jonas Oreland49ac5952018-09-26 16:04:32 +02001652 std::unique_ptr<webrtc::Call> call_;
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02001653 std::unique_ptr<webrtc::VideoBitrateAllocatorFactory>
1654 video_bitrate_allocator_factory_;
Niels Möller6557d0c2018-04-11 15:18:34 +02001655 WebRtcVideoEngine engine_;
Niels Möller805a27e2019-01-21 12:21:27 +01001656
1657 std::unique_ptr<cricket::FakeFrameSource> frame_source_;
1658 std::unique_ptr<webrtc::test::FrameForwarder> frame_forwarder_;
1659 std::unique_ptr<webrtc::test::FrameForwarder> frame_forwarder_2_;
1660
Niels Möller6557d0c2018-04-11 15:18:34 +02001661 std::unique_ptr<WebRtcVideoChannel> channel_;
1662 cricket::FakeNetworkInterface network_interface_;
1663 cricket::FakeVideoRenderer renderer_;
1664
1665 // Used by test cases where 2 streams are run on the same channel.
1666 cricket::FakeVideoRenderer renderer2_;
1667};
1668
1669// Test that SetSend works.
srtee0c2eea2017-12-15 17:44:33 +01001670TEST_F(WebRtcVideoChannelBaseTest, SetSend) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001671 EXPECT_FALSE(channel_->sending());
Niels Möller805a27e2019-01-21 12:21:27 +01001672 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, nullptr, frame_forwarder_.get()));
Niels Möller6557d0c2018-04-11 15:18:34 +02001673 EXPECT_TRUE(SetOneCodec(DefaultCodec()));
1674 EXPECT_FALSE(channel_->sending());
1675 EXPECT_TRUE(SetSend(true));
1676 EXPECT_TRUE(channel_->sending());
Niels Möller805a27e2019-01-21 12:21:27 +01001677 SendFrame();
Niels Möller6557d0c2018-04-11 15:18:34 +02001678 EXPECT_TRUE_WAIT(NumRtpPackets() > 0, kTimeout);
1679 EXPECT_TRUE(SetSend(false));
1680 EXPECT_FALSE(channel_->sending());
srtee0c2eea2017-12-15 17:44:33 +01001681}
Niels Möller6557d0c2018-04-11 15:18:34 +02001682
1683// Test that SetSend fails without codecs being set.
srtee0c2eea2017-12-15 17:44:33 +01001684TEST_F(WebRtcVideoChannelBaseTest, SetSendWithoutCodecs) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001685 EXPECT_FALSE(channel_->sending());
1686 EXPECT_FALSE(SetSend(true));
1687 EXPECT_FALSE(channel_->sending());
srtee0c2eea2017-12-15 17:44:33 +01001688}
Niels Möller6557d0c2018-04-11 15:18:34 +02001689
1690// Test that we properly set the send and recv buffer sizes by the time
1691// SetSend is called.
srtee0c2eea2017-12-15 17:44:33 +01001692TEST_F(WebRtcVideoChannelBaseTest, SetSendSetsTransportBufferSizes) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001693 EXPECT_TRUE(SetOneCodec(DefaultCodec()));
1694 EXPECT_TRUE(SetSend(true));
1695 EXPECT_EQ(64 * 1024, network_interface_.sendbuf_size());
Johannes Krond38a2b82018-10-23 11:31:19 +02001696 EXPECT_EQ(256 * 1024, network_interface_.recvbuf_size());
Erik Språng820ebd02018-08-20 17:14:25 +02001697}
1698
Johannes Kron5a0665b2019-04-08 10:35:50 +02001699// Test that we properly set the send and recv buffer sizes when overriding
1700// via field trials.
1701TEST_F(WebRtcVideoChannelBaseTest, OverridesRecvBufferSize) {
1702 // Set field trial to override the default recv buffer size, and then re-run
1703 // setup where the interface is created and configured.
1704 const int kCustomRecvBufferSize = 123456;
1705 webrtc::test::ScopedFieldTrials field_trial(
1706 "WebRTC-IncreasedReceivebuffers/123456/");
1707 SetUp();
1708
1709 EXPECT_TRUE(SetOneCodec(DefaultCodec()));
1710 EXPECT_TRUE(SetSend(true));
1711 EXPECT_EQ(64 * 1024, network_interface_.sendbuf_size());
1712 EXPECT_EQ(kCustomRecvBufferSize, network_interface_.recvbuf_size());
1713}
1714
1715// Test that we properly set the send and recv buffer sizes when overriding
1716// via field trials with suffix.
1717TEST_F(WebRtcVideoChannelBaseTest, OverridesRecvBufferSizeWithSuffix) {
1718 // Set field trial to override the default recv buffer size, and then re-run
1719 // setup where the interface is created and configured.
1720 const int kCustomRecvBufferSize = 123456;
1721 webrtc::test::ScopedFieldTrials field_trial(
1722 "WebRTC-IncreasedReceivebuffers/123456_Dogfood/");
1723 SetUp();
1724
1725 EXPECT_TRUE(SetOneCodec(DefaultCodec()));
1726 EXPECT_TRUE(SetSend(true));
1727 EXPECT_EQ(64 * 1024, network_interface_.sendbuf_size());
1728 EXPECT_EQ(kCustomRecvBufferSize, network_interface_.recvbuf_size());
1729}
1730
1731// Test that we properly set the send and recv buffer sizes when overriding
1732// via field trials that don't make any sense.
1733TEST_F(WebRtcVideoChannelBaseTest, InvalidRecvBufferSize) {
1734 // Set bogus field trial values to override the default recv buffer size, and
1735 // then re-run setup where the interface is created and configured. The
1736 // default value should still be used.
1737
1738 for (std::string group : {" ", "NotANumber", "-1", "0"}) {
1739 std::string field_trial_string = "WebRTC-IncreasedReceivebuffers/";
1740 field_trial_string += group;
1741 field_trial_string += "/";
1742 webrtc::test::ScopedFieldTrials field_trial(field_trial_string);
1743 SetUp();
1744
1745 EXPECT_TRUE(SetOneCodec(DefaultCodec()));
1746 EXPECT_TRUE(SetSend(true));
1747 EXPECT_EQ(64 * 1024, network_interface_.sendbuf_size());
1748 EXPECT_EQ(256 * 1024, network_interface_.recvbuf_size());
1749 }
1750}
1751
Niels Möller6557d0c2018-04-11 15:18:34 +02001752// Test that stats work properly for a 1-1 call.
srtee0c2eea2017-12-15 17:44:33 +01001753TEST_F(WebRtcVideoChannelBaseTest, GetStats) {
Bjorn A Mellemda4f0932019-07-30 08:34:03 -07001754 SetUp();
1755
Niels Möller6557d0c2018-04-11 15:18:34 +02001756 const int kDurationSec = 3;
1757 const int kFps = 10;
1758 SendReceiveManyAndGetStats(DefaultCodec(), kDurationSec, kFps);
1759
1760 cricket::VideoMediaInfo info;
1761 EXPECT_TRUE(channel_->GetStats(&info));
1762
1763 ASSERT_EQ(1U, info.senders.size());
1764 // TODO(whyuan): bytes_sent and bytes_rcvd are different. Are both payload?
1765 // For webrtc, bytes_sent does not include the RTP header length.
Niels Möllerac0a4cb2019-10-09 15:01:33 +02001766 EXPECT_EQ(info.senders[0].payload_bytes_sent,
Bjorn A Mellemda4f0932019-07-30 08:34:03 -07001767 NumRtpBytes() - kRtpHeaderSize * NumRtpPackets());
Niels Möller6557d0c2018-04-11 15:18:34 +02001768 EXPECT_EQ(NumRtpPackets(), info.senders[0].packets_sent);
1769 EXPECT_EQ(0.0, info.senders[0].fraction_lost);
1770 ASSERT_TRUE(info.senders[0].codec_payload_type);
1771 EXPECT_EQ(DefaultCodec().id, *info.senders[0].codec_payload_type);
1772 EXPECT_EQ(0, info.senders[0].firs_rcvd);
1773 EXPECT_EQ(0, info.senders[0].plis_rcvd);
1774 EXPECT_EQ(0, info.senders[0].nacks_rcvd);
1775 EXPECT_EQ(kVideoWidth, info.senders[0].send_frame_width);
1776 EXPECT_EQ(kVideoHeight, info.senders[0].send_frame_height);
1777 EXPECT_GT(info.senders[0].framerate_input, 0);
1778 EXPECT_GT(info.senders[0].framerate_sent, 0);
1779
1780 EXPECT_EQ(1U, info.send_codecs.count(DefaultCodec().id));
1781 EXPECT_EQ(DefaultCodec().ToCodecParameters(),
1782 info.send_codecs[DefaultCodec().id]);
1783
1784 ASSERT_EQ(1U, info.receivers.size());
1785 EXPECT_EQ(1U, info.senders[0].ssrcs().size());
1786 EXPECT_EQ(1U, info.receivers[0].ssrcs().size());
1787 EXPECT_EQ(info.senders[0].ssrcs()[0], info.receivers[0].ssrcs()[0]);
1788 ASSERT_TRUE(info.receivers[0].codec_payload_type);
1789 EXPECT_EQ(DefaultCodec().id, *info.receivers[0].codec_payload_type);
Bjorn A Mellemda4f0932019-07-30 08:34:03 -07001790 EXPECT_EQ(NumRtpBytes() - kRtpHeaderSize * NumRtpPackets(),
Niels Möllerac0a4cb2019-10-09 15:01:33 +02001791 info.receivers[0].payload_bytes_rcvd);
Niels Möller6557d0c2018-04-11 15:18:34 +02001792 EXPECT_EQ(NumRtpPackets(), info.receivers[0].packets_rcvd);
Niels Möller6557d0c2018-04-11 15:18:34 +02001793 EXPECT_EQ(0, info.receivers[0].packets_lost);
1794 // TODO(asapersson): Not set for webrtc. Handle missing stats.
1795 // EXPECT_EQ(0, info.receivers[0].packets_concealed);
1796 EXPECT_EQ(0, info.receivers[0].firs_sent);
1797 EXPECT_EQ(0, info.receivers[0].plis_sent);
1798 EXPECT_EQ(0, info.receivers[0].nacks_sent);
1799 EXPECT_EQ(kVideoWidth, info.receivers[0].frame_width);
1800 EXPECT_EQ(kVideoHeight, info.receivers[0].frame_height);
1801 EXPECT_GT(info.receivers[0].framerate_rcvd, 0);
1802 EXPECT_GT(info.receivers[0].framerate_decoded, 0);
1803 EXPECT_GT(info.receivers[0].framerate_output, 0);
1804
1805 EXPECT_EQ(1U, info.receive_codecs.count(DefaultCodec().id));
1806 EXPECT_EQ(DefaultCodec().ToCodecParameters(),
1807 info.receive_codecs[DefaultCodec().id]);
srtee0c2eea2017-12-15 17:44:33 +01001808}
Niels Möller6557d0c2018-04-11 15:18:34 +02001809
1810// Test that stats work properly for a conf call with multiple recv streams.
srtee0c2eea2017-12-15 17:44:33 +01001811TEST_F(WebRtcVideoChannelBaseTest, GetStatsMultipleRecvStreams) {
Bjorn A Mellemda4f0932019-07-30 08:34:03 -07001812 SetUp();
1813
Niels Möller6557d0c2018-04-11 15:18:34 +02001814 cricket::FakeVideoRenderer renderer1, renderer2;
1815 EXPECT_TRUE(SetOneCodec(DefaultCodec()));
1816 cricket::VideoSendParameters parameters;
1817 parameters.codecs.push_back(DefaultCodec());
1818 parameters.conference_mode = true;
1819 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1820 EXPECT_TRUE(SetSend(true));
Yves Gerey665174f2018-06-19 15:03:05 +02001821 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
1822 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
Niels Möller6557d0c2018-04-11 15:18:34 +02001823 EXPECT_TRUE(channel_->SetSink(1, &renderer1));
1824 EXPECT_TRUE(channel_->SetSink(2, &renderer2));
1825 EXPECT_EQ(0, renderer1.num_rendered_frames());
1826 EXPECT_EQ(0, renderer2.num_rendered_frames());
1827 std::vector<uint32_t> ssrcs;
1828 ssrcs.push_back(1);
1829 ssrcs.push_back(2);
1830 network_interface_.SetConferenceMode(true, ssrcs);
Niels Möller805a27e2019-01-21 12:21:27 +01001831 SendFrame();
Niels Möller6557d0c2018-04-11 15:18:34 +02001832 EXPECT_FRAME_ON_RENDERER_WAIT(renderer1, 1, kVideoWidth, kVideoHeight,
1833 kTimeout);
1834 EXPECT_FRAME_ON_RENDERER_WAIT(renderer2, 1, kVideoWidth, kVideoHeight,
1835 kTimeout);
1836
1837 EXPECT_TRUE(channel_->SetSend(false));
1838
1839 cricket::VideoMediaInfo info;
1840 EXPECT_TRUE(channel_->GetStats(&info));
1841 ASSERT_EQ(1U, info.senders.size());
1842 // TODO(whyuan): bytes_sent and bytes_rcvd are different. Are both payload?
1843 // For webrtc, bytes_sent does not include the RTP header length.
Bjorn A Mellemda4f0932019-07-30 08:34:03 -07001844 EXPECT_EQ_WAIT(NumRtpBytes() - kRtpHeaderSize * NumRtpPackets(),
Niels Möllerac0a4cb2019-10-09 15:01:33 +02001845 GetSenderStats(0).payload_bytes_sent, kTimeout);
Niels Möller6557d0c2018-04-11 15:18:34 +02001846 EXPECT_EQ_WAIT(NumRtpPackets(), GetSenderStats(0).packets_sent, kTimeout);
1847 EXPECT_EQ(kVideoWidth, GetSenderStats(0).send_frame_width);
1848 EXPECT_EQ(kVideoHeight, GetSenderStats(0).send_frame_height);
1849
1850 ASSERT_EQ(2U, info.receivers.size());
1851 for (size_t i = 0; i < info.receivers.size(); ++i) {
1852 EXPECT_EQ(1U, GetReceiverStats(i).ssrcs().size());
1853 EXPECT_EQ(i + 1, GetReceiverStats(i).ssrcs()[0]);
Bjorn A Mellemda4f0932019-07-30 08:34:03 -07001854 EXPECT_EQ_WAIT(NumRtpBytes() - kRtpHeaderSize * NumRtpPackets(),
Niels Möllerac0a4cb2019-10-09 15:01:33 +02001855 GetReceiverStats(i).payload_bytes_rcvd, kTimeout);
Yves Gerey665174f2018-06-19 15:03:05 +02001856 EXPECT_EQ_WAIT(NumRtpPackets(), GetReceiverStats(i).packets_rcvd, kTimeout);
Niels Möller6557d0c2018-04-11 15:18:34 +02001857 EXPECT_EQ_WAIT(kVideoWidth, GetReceiverStats(i).frame_width, kTimeout);
1858 EXPECT_EQ_WAIT(kVideoHeight, GetReceiverStats(i).frame_height, kTimeout);
1859 }
srtee0c2eea2017-12-15 17:44:33 +01001860}
Niels Möller6557d0c2018-04-11 15:18:34 +02001861
1862// Test that stats work properly for a conf call with multiple send streams.
srtee0c2eea2017-12-15 17:44:33 +01001863TEST_F(WebRtcVideoChannelBaseTest, GetStatsMultipleSendStreams) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001864 // Normal setup; note that we set the SSRC explicitly to ensure that
1865 // it will come first in the senders map.
1866 EXPECT_TRUE(SetOneCodec(DefaultCodec()));
1867 cricket::VideoSendParameters parameters;
1868 parameters.codecs.push_back(DefaultCodec());
1869 parameters.conference_mode = true;
1870 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Yves Gerey665174f2018-06-19 15:03:05 +02001871 EXPECT_TRUE(
1872 channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
Niels Möller6557d0c2018-04-11 15:18:34 +02001873 EXPECT_TRUE(channel_->SetSink(kSsrc, &renderer_));
1874 EXPECT_TRUE(SetSend(true));
Niels Möller805a27e2019-01-21 12:21:27 +01001875 SendFrame();
Niels Möller6557d0c2018-04-11 15:18:34 +02001876 EXPECT_TRUE_WAIT(NumRtpPackets() > 0, kTimeout);
1877 EXPECT_FRAME_WAIT(1, kVideoWidth, kVideoHeight, kTimeout);
1878
1879 // Add an additional capturer, and hook up a renderer to receive it.
1880 cricket::FakeVideoRenderer renderer2;
Niels Möller805a27e2019-01-21 12:21:27 +01001881 webrtc::test::FrameForwarder frame_forwarder;
Niels Möller6557d0c2018-04-11 15:18:34 +02001882 const int kTestWidth = 160;
1883 const int kTestHeight = 120;
Niels Möller805a27e2019-01-21 12:21:27 +01001884 cricket::FakeFrameSource frame_source(kTestWidth, kTestHeight,
1885 rtc::kNumMicrosecsPerSec / 5);
Yves Gerey665174f2018-06-19 15:03:05 +02001886 EXPECT_TRUE(
1887 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(5678)));
Niels Möller805a27e2019-01-21 12:21:27 +01001888 EXPECT_TRUE(channel_->SetVideoSend(5678, nullptr, &frame_forwarder));
Yves Gerey665174f2018-06-19 15:03:05 +02001889 EXPECT_TRUE(
1890 channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(5678)));
Niels Möller6557d0c2018-04-11 15:18:34 +02001891 EXPECT_TRUE(channel_->SetSink(5678, &renderer2));
Niels Möller805a27e2019-01-21 12:21:27 +01001892 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
Yves Gerey665174f2018-06-19 15:03:05 +02001893 EXPECT_FRAME_ON_RENDERER_WAIT(renderer2, 1, kTestWidth, kTestHeight,
1894 kTimeout);
Niels Möller6557d0c2018-04-11 15:18:34 +02001895
1896 // Get stats, and make sure they are correct for two senders. We wait until
1897 // the number of expected packets have been sent to avoid races where we
1898 // check stats before it has been updated.
1899 cricket::VideoMediaInfo info;
1900 for (uint32_t i = 0; i < kTimeout; ++i) {
1901 rtc::Thread::Current()->ProcessMessages(1);
1902 EXPECT_TRUE(channel_->GetStats(&info));
1903 ASSERT_EQ(2U, info.senders.size());
1904 if (info.senders[0].packets_sent + info.senders[1].packets_sent ==
1905 NumRtpPackets()) {
1906 // Stats have been updated for both sent frames, expectations can be
1907 // checked now.
1908 break;
1909 }
1910 }
1911 EXPECT_EQ(NumRtpPackets(),
1912 info.senders[0].packets_sent + info.senders[1].packets_sent)
1913 << "Timed out while waiting for packet counts for all sent packets.";
1914 EXPECT_EQ(1U, info.senders[0].ssrcs().size());
1915 EXPECT_EQ(1234U, info.senders[0].ssrcs()[0]);
1916 EXPECT_EQ(kVideoWidth, info.senders[0].send_frame_width);
1917 EXPECT_EQ(kVideoHeight, info.senders[0].send_frame_height);
1918 EXPECT_EQ(1U, info.senders[1].ssrcs().size());
1919 EXPECT_EQ(5678U, info.senders[1].ssrcs()[0]);
1920 EXPECT_EQ(kTestWidth, info.senders[1].send_frame_width);
1921 EXPECT_EQ(kTestHeight, info.senders[1].send_frame_height);
1922 // The capturer must be unregistered here as it runs out of it's scope next.
1923 channel_->SetVideoSend(5678, nullptr, nullptr);
srtee0c2eea2017-12-15 17:44:33 +01001924}
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +00001925
Niels Möller6557d0c2018-04-11 15:18:34 +02001926// Test that we can set the bandwidth.
srtee0c2eea2017-12-15 17:44:33 +01001927TEST_F(WebRtcVideoChannelBaseTest, SetSendBandwidth) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001928 cricket::VideoSendParameters parameters;
1929 parameters.codecs.push_back(DefaultCodec());
1930 parameters.max_bandwidth_bps = -1; // <= 0 means unlimited.
1931 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1932 parameters.max_bandwidth_bps = 128 * 1024;
1933 EXPECT_TRUE(channel_->SetSendParameters(parameters));
srtee0c2eea2017-12-15 17:44:33 +01001934}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001935
Niels Möller6557d0c2018-04-11 15:18:34 +02001936// Test that we can set the SSRC for the default send source.
srtee0c2eea2017-12-15 17:44:33 +01001937TEST_F(WebRtcVideoChannelBaseTest, SetSendSsrc) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001938 EXPECT_TRUE(SetDefaultCodec());
1939 EXPECT_TRUE(SetSend(true));
Niels Möller805a27e2019-01-21 12:21:27 +01001940 SendFrame();
Niels Möller6557d0c2018-04-11 15:18:34 +02001941 EXPECT_TRUE_WAIT(NumRtpPackets() > 0, kTimeout);
Åsa Persson23cd45a2018-07-03 10:40:40 +02001942 webrtc::RTPHeader header;
Niels Möller6557d0c2018-04-11 15:18:34 +02001943 std::unique_ptr<const rtc::CopyOnWriteBuffer> p(GetRtpPacket(0));
Åsa Persson23cd45a2018-07-03 10:40:40 +02001944 EXPECT_TRUE(ParseRtpPacket(p.get(), &header));
1945 EXPECT_EQ(kSsrc, header.ssrc);
1946
Niels Möller6557d0c2018-04-11 15:18:34 +02001947 // Packets are being paced out, so these can mismatch between the first and
1948 // second call to NumRtpPackets until pending packets are paced out.
Åsa Persson23cd45a2018-07-03 10:40:40 +02001949 EXPECT_EQ_WAIT(NumRtpPackets(), NumRtpPackets(header.ssrc), kTimeout);
1950 EXPECT_EQ_WAIT(NumRtpBytes(), NumRtpBytes(header.ssrc), kTimeout);
Niels Möller6557d0c2018-04-11 15:18:34 +02001951 EXPECT_EQ(1, NumSentSsrcs());
1952 EXPECT_EQ(0, NumRtpPackets(kSsrc - 1));
1953 EXPECT_EQ(0, NumRtpBytes(kSsrc - 1));
srtee0c2eea2017-12-15 17:44:33 +01001954}
Niels Möller6557d0c2018-04-11 15:18:34 +02001955
1956// Test that we can set the SSRC even after codecs are set.
srtee0c2eea2017-12-15 17:44:33 +01001957TEST_F(WebRtcVideoChannelBaseTest, SetSendSsrcAfterSetCodecs) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001958 // Remove stream added in Setup.
1959 EXPECT_TRUE(channel_->RemoveSendStream(kSsrc));
1960 EXPECT_TRUE(SetDefaultCodec());
Niels Möller6557d0c2018-04-11 15:18:34 +02001961 EXPECT_TRUE(
Yves Gerey665174f2018-06-19 15:03:05 +02001962 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(999)));
Niels Möller805a27e2019-01-21 12:21:27 +01001963 EXPECT_TRUE(channel_->SetVideoSend(999u, nullptr, frame_forwarder_.get()));
Niels Möller6557d0c2018-04-11 15:18:34 +02001964 EXPECT_TRUE(SetSend(true));
1965 EXPECT_TRUE(WaitAndSendFrame(0));
1966 EXPECT_TRUE_WAIT(NumRtpPackets() > 0, kTimeout);
Åsa Persson23cd45a2018-07-03 10:40:40 +02001967 webrtc::RTPHeader header;
Niels Möller6557d0c2018-04-11 15:18:34 +02001968 std::unique_ptr<const rtc::CopyOnWriteBuffer> p(GetRtpPacket(0));
Åsa Persson23cd45a2018-07-03 10:40:40 +02001969 EXPECT_TRUE(ParseRtpPacket(p.get(), &header));
1970 EXPECT_EQ(999u, header.ssrc);
Niels Möller6557d0c2018-04-11 15:18:34 +02001971 // Packets are being paced out, so these can mismatch between the first and
1972 // second call to NumRtpPackets until pending packets are paced out.
Åsa Persson23cd45a2018-07-03 10:40:40 +02001973 EXPECT_EQ_WAIT(NumRtpPackets(), NumRtpPackets(header.ssrc), kTimeout);
1974 EXPECT_EQ_WAIT(NumRtpBytes(), NumRtpBytes(header.ssrc), kTimeout);
Niels Möller6557d0c2018-04-11 15:18:34 +02001975 EXPECT_EQ(1, NumSentSsrcs());
1976 EXPECT_EQ(0, NumRtpPackets(kSsrc));
1977 EXPECT_EQ(0, NumRtpBytes(kSsrc));
srtee0c2eea2017-12-15 17:44:33 +01001978}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001979
Niels Möller6557d0c2018-04-11 15:18:34 +02001980// Test that we can set the default video renderer before and after
1981// media is received.
srtee0c2eea2017-12-15 17:44:33 +01001982TEST_F(WebRtcVideoChannelBaseTest, SetSink) {
Yves Gerey665174f2018-06-19 15:03:05 +02001983 uint8_t data1[] = {0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
1984 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
Niels Möller6557d0c2018-04-11 15:18:34 +02001985
1986 rtc::CopyOnWriteBuffer packet1(data1, sizeof(data1));
1987 rtc::SetBE32(packet1.data() + 8, kSsrc);
Saurav Das749f6602019-12-04 09:31:36 -08001988 channel_->SetDefaultSink(NULL);
Niels Möller6557d0c2018-04-11 15:18:34 +02001989 EXPECT_TRUE(SetDefaultCodec());
1990 EXPECT_TRUE(SetSend(true));
1991 EXPECT_EQ(0, renderer_.num_rendered_frames());
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07001992 channel_->OnPacketReceived(packet1, /* packet_time_us */ -1);
Saurav Das749f6602019-12-04 09:31:36 -08001993 channel_->SetDefaultSink(&renderer_);
Niels Möller805a27e2019-01-21 12:21:27 +01001994 SendFrame();
Niels Möller6557d0c2018-04-11 15:18:34 +02001995 EXPECT_FRAME_WAIT(1, kVideoWidth, kVideoHeight, kTimeout);
srtee0c2eea2017-12-15 17:44:33 +01001996}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001997
Niels Möller6557d0c2018-04-11 15:18:34 +02001998// Tests setting up and configuring a send stream.
srtee0c2eea2017-12-15 17:44:33 +01001999TEST_F(WebRtcVideoChannelBaseTest, AddRemoveSendStreams) {
Niels Möller6557d0c2018-04-11 15:18:34 +02002000 EXPECT_TRUE(SetOneCodec(DefaultCodec()));
2001 EXPECT_TRUE(SetSend(true));
Saurav Das749f6602019-12-04 09:31:36 -08002002 channel_->SetDefaultSink(&renderer_);
Niels Möller805a27e2019-01-21 12:21:27 +01002003 SendFrame();
Niels Möller6557d0c2018-04-11 15:18:34 +02002004 EXPECT_FRAME_WAIT(1, kVideoWidth, kVideoHeight, kTimeout);
2005 EXPECT_GT(NumRtpPackets(), 0);
Åsa Persson23cd45a2018-07-03 10:40:40 +02002006 webrtc::RTPHeader header;
Niels Möller6557d0c2018-04-11 15:18:34 +02002007 size_t last_packet = NumRtpPackets() - 1;
Yves Gerey665174f2018-06-19 15:03:05 +02002008 std::unique_ptr<const rtc::CopyOnWriteBuffer> p(
2009 GetRtpPacket(static_cast<int>(last_packet)));
Åsa Persson23cd45a2018-07-03 10:40:40 +02002010 EXPECT_TRUE(ParseRtpPacket(p.get(), &header));
2011 EXPECT_EQ(kSsrc, header.ssrc);
Niels Möller6557d0c2018-04-11 15:18:34 +02002012
2013 // Remove the send stream that was added during Setup.
2014 EXPECT_TRUE(channel_->RemoveSendStream(kSsrc));
2015 int rtp_packets = NumRtpPackets();
2016
Niels Möller6557d0c2018-04-11 15:18:34 +02002017 EXPECT_TRUE(
Yves Gerey665174f2018-06-19 15:03:05 +02002018 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(789u)));
Niels Möller805a27e2019-01-21 12:21:27 +01002019 EXPECT_TRUE(channel_->SetVideoSend(789u, nullptr, frame_forwarder_.get()));
Niels Möller6557d0c2018-04-11 15:18:34 +02002020 EXPECT_EQ(rtp_packets, NumRtpPackets());
2021 // Wait 30ms to guarantee the engine does not drop the frame.
2022 EXPECT_TRUE(WaitAndSendFrame(30));
2023 EXPECT_TRUE_WAIT(NumRtpPackets() > rtp_packets, kTimeout);
2024
2025 last_packet = NumRtpPackets() - 1;
2026 p.reset(GetRtpPacket(static_cast<int>(last_packet)));
Åsa Persson23cd45a2018-07-03 10:40:40 +02002027 EXPECT_TRUE(ParseRtpPacket(p.get(), &header));
2028 EXPECT_EQ(789u, header.ssrc);
srtee0c2eea2017-12-15 17:44:33 +01002029}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002030
Niels Möller6557d0c2018-04-11 15:18:34 +02002031// Tests the behavior of incoming streams in a conference scenario.
srtee0c2eea2017-12-15 17:44:33 +01002032TEST_F(WebRtcVideoChannelBaseTest, SimulateConference) {
Niels Möller6557d0c2018-04-11 15:18:34 +02002033 cricket::FakeVideoRenderer renderer1, renderer2;
2034 EXPECT_TRUE(SetDefaultCodec());
2035 cricket::VideoSendParameters parameters;
2036 parameters.codecs.push_back(DefaultCodec());
2037 parameters.conference_mode = true;
2038 EXPECT_TRUE(channel_->SetSendParameters(parameters));
2039 EXPECT_TRUE(SetSend(true));
Yves Gerey665174f2018-06-19 15:03:05 +02002040 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
2041 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
Niels Möller6557d0c2018-04-11 15:18:34 +02002042 EXPECT_TRUE(channel_->SetSink(1, &renderer1));
2043 EXPECT_TRUE(channel_->SetSink(2, &renderer2));
2044 EXPECT_EQ(0, renderer1.num_rendered_frames());
2045 EXPECT_EQ(0, renderer2.num_rendered_frames());
2046 std::vector<uint32_t> ssrcs;
2047 ssrcs.push_back(1);
2048 ssrcs.push_back(2);
2049 network_interface_.SetConferenceMode(true, ssrcs);
Niels Möller805a27e2019-01-21 12:21:27 +01002050 SendFrame();
Niels Möller6557d0c2018-04-11 15:18:34 +02002051 EXPECT_FRAME_ON_RENDERER_WAIT(renderer1, 1, kVideoWidth, kVideoHeight,
2052 kTimeout);
2053 EXPECT_FRAME_ON_RENDERER_WAIT(renderer2, 1, kVideoWidth, kVideoHeight,
2054 kTimeout);
2055
2056 std::unique_ptr<const rtc::CopyOnWriteBuffer> p(GetRtpPacket(0));
2057 EXPECT_EQ(DefaultCodec().id, GetPayloadType(p.get()));
2058 EXPECT_EQ(kVideoWidth, renderer1.width());
2059 EXPECT_EQ(kVideoHeight, renderer1.height());
2060 EXPECT_EQ(kVideoWidth, renderer2.width());
2061 EXPECT_EQ(kVideoHeight, renderer2.height());
2062 EXPECT_TRUE(channel_->RemoveRecvStream(2));
2063 EXPECT_TRUE(channel_->RemoveRecvStream(1));
srtee0c2eea2017-12-15 17:44:33 +01002064}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002065
Niels Möller6557d0c2018-04-11 15:18:34 +02002066// Tests that we can add and remove capturers and frames are sent out properly
srtee0c2eea2017-12-15 17:44:33 +01002067TEST_F(WebRtcVideoChannelBaseTest, DISABLED_AddRemoveCapturer) {
Niels Möller6557d0c2018-04-11 15:18:34 +02002068 using cricket::FOURCC_I420;
Jonas Olssona4d87372019-07-05 19:08:33 +02002069 using cricket::VideoCodec;
2070 using cricket::VideoFormat;
2071 using cricket::VideoOptions;
Niels Möller6557d0c2018-04-11 15:18:34 +02002072
2073 VideoCodec codec = DefaultCodec();
2074 const int time_between_send_ms = VideoFormat::FpsToInterval(kFramerate);
2075 EXPECT_TRUE(SetOneCodec(codec));
2076 EXPECT_TRUE(SetSend(true));
Saurav Das749f6602019-12-04 09:31:36 -08002077 channel_->SetDefaultSink(&renderer_);
Niels Möller6557d0c2018-04-11 15:18:34 +02002078 EXPECT_EQ(0, renderer_.num_rendered_frames());
Niels Möller805a27e2019-01-21 12:21:27 +01002079 SendFrame();
Niels Möller6557d0c2018-04-11 15:18:34 +02002080 EXPECT_FRAME_WAIT(1, kVideoWidth, kVideoHeight, kTimeout);
Niels Möller805a27e2019-01-21 12:21:27 +01002081
2082 webrtc::test::FrameForwarder frame_forwarder;
2083 cricket::FakeFrameSource frame_source(480, 360, rtc::kNumMicrosecsPerSec / 30,
2084 rtc::kNumMicrosecsPerSec / 30);
Niels Möller6557d0c2018-04-11 15:18:34 +02002085
2086 // TODO(nisse): This testcase fails if we don't configure
2087 // screencast. It's unclear why, I see nothing obvious in this
2088 // test which is related to screencast logic.
2089 VideoOptions video_options;
2090 video_options.is_screencast = true;
2091 channel_->SetVideoSend(kSsrc, &video_options, nullptr);
2092
Niels Möller6557d0c2018-04-11 15:18:34 +02002093 int captured_frames = 1;
2094 for (int iterations = 0; iterations < 2; ++iterations) {
Niels Möller805a27e2019-01-21 12:21:27 +01002095 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, nullptr, &frame_forwarder));
Niels Möller6557d0c2018-04-11 15:18:34 +02002096 rtc::Thread::Current()->ProcessMessages(time_between_send_ms);
Niels Möller805a27e2019-01-21 12:21:27 +01002097 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
2098
Niels Möller6557d0c2018-04-11 15:18:34 +02002099 ++captured_frames;
2100 // Wait until frame of right size is captured.
2101 EXPECT_TRUE_WAIT(renderer_.num_rendered_frames() >= captured_frames &&
Niels Möller805a27e2019-01-21 12:21:27 +01002102 480 == renderer_.width() &&
2103 360 == renderer_.height() && !renderer_.black_frame(),
Yves Gerey665174f2018-06-19 15:03:05 +02002104 kTimeout);
Niels Möller6557d0c2018-04-11 15:18:34 +02002105 EXPECT_GE(renderer_.num_rendered_frames(), captured_frames);
Niels Möller805a27e2019-01-21 12:21:27 +01002106 EXPECT_EQ(480, renderer_.width());
2107 EXPECT_EQ(360, renderer_.height());
Niels Möller6557d0c2018-04-11 15:18:34 +02002108 captured_frames = renderer_.num_rendered_frames() + 1;
2109 EXPECT_FALSE(renderer_.black_frame());
2110 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, nullptr, nullptr));
2111 // Make sure a black frame is generated within the specified timeout.
2112 // The black frame should be the resolution of the previous frame to
2113 // prevent expensive encoder reconfigurations.
2114 EXPECT_TRUE_WAIT(renderer_.num_rendered_frames() >= captured_frames &&
Niels Möller805a27e2019-01-21 12:21:27 +01002115 480 == renderer_.width() &&
2116 360 == renderer_.height() && renderer_.black_frame(),
Yves Gerey665174f2018-06-19 15:03:05 +02002117 kTimeout);
Niels Möller6557d0c2018-04-11 15:18:34 +02002118 EXPECT_GE(renderer_.num_rendered_frames(), captured_frames);
Niels Möller805a27e2019-01-21 12:21:27 +01002119 EXPECT_EQ(480, renderer_.width());
2120 EXPECT_EQ(360, renderer_.height());
Niels Möller6557d0c2018-04-11 15:18:34 +02002121 EXPECT_TRUE(renderer_.black_frame());
2122
2123 // The black frame has the same timestamp as the next frame since it's
2124 // timestamp is set to the last frame's timestamp + interval. WebRTC will
2125 // not render a frame with the same timestamp so capture another frame
2126 // with the frame capturer to increment the next frame's timestamp.
Niels Möller805a27e2019-01-21 12:21:27 +01002127 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
Niels Möller6557d0c2018-04-11 15:18:34 +02002128 }
srtee0c2eea2017-12-15 17:44:33 +01002129}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002130
Niels Möller6557d0c2018-04-11 15:18:34 +02002131// Tests that if SetVideoSend is called with a NULL capturer after the
2132// capturer was already removed, the application doesn't crash (and no black
2133// frame is sent).
srtee0c2eea2017-12-15 17:44:33 +01002134TEST_F(WebRtcVideoChannelBaseTest, RemoveCapturerWithoutAdd) {
Niels Möller6557d0c2018-04-11 15:18:34 +02002135 EXPECT_TRUE(SetOneCodec(DefaultCodec()));
2136 EXPECT_TRUE(SetSend(true));
Saurav Das749f6602019-12-04 09:31:36 -08002137 channel_->SetDefaultSink(&renderer_);
Niels Möller6557d0c2018-04-11 15:18:34 +02002138 EXPECT_EQ(0, renderer_.num_rendered_frames());
Niels Möller805a27e2019-01-21 12:21:27 +01002139 SendFrame();
Niels Möller6557d0c2018-04-11 15:18:34 +02002140 EXPECT_FRAME_WAIT(1, kVideoWidth, kVideoHeight, kTimeout);
2141 // Wait for one frame so they don't get dropped because we send frames too
2142 // tightly.
2143 rtc::Thread::Current()->ProcessMessages(30);
2144 // Remove the capturer.
2145 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, nullptr, nullptr));
2146
2147 // No capturer was added, so this SetVideoSend shouldn't do anything.
2148 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, nullptr, nullptr));
2149 rtc::Thread::Current()->ProcessMessages(300);
2150 // Verify no more frames were sent.
2151 EXPECT_EQ(1, renderer_.num_rendered_frames());
srtee0c2eea2017-12-15 17:44:33 +01002152}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002153
Niels Möller6557d0c2018-04-11 15:18:34 +02002154// Tests that we can add and remove capturer as unique sources.
srtee0c2eea2017-12-15 17:44:33 +01002155TEST_F(WebRtcVideoChannelBaseTest, AddRemoveCapturerMultipleSources) {
Niels Möller6557d0c2018-04-11 15:18:34 +02002156 // WebRTC implementation will drop frames if pushed to quickly. Wait the
2157 // interval time to avoid that.
2158 // WebRTC implementation will drop frames if pushed to quickly. Wait the
2159 // interval time to avoid that.
2160 // Set up the stream associated with the engine.
Yves Gerey665174f2018-06-19 15:03:05 +02002161 EXPECT_TRUE(
2162 channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
Niels Möller6557d0c2018-04-11 15:18:34 +02002163 EXPECT_TRUE(channel_->SetSink(kSsrc, &renderer_));
2164 cricket::VideoFormat capture_format(
2165 kVideoWidth, kVideoHeight,
2166 cricket::VideoFormat::FpsToInterval(kFramerate), cricket::FOURCC_I420);
2167 // Set up additional stream 1.
2168 cricket::FakeVideoRenderer renderer1;
2169 EXPECT_FALSE(channel_->SetSink(1, &renderer1));
Yves Gerey665174f2018-06-19 15:03:05 +02002170 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
Niels Möller6557d0c2018-04-11 15:18:34 +02002171 EXPECT_TRUE(channel_->SetSink(1, &renderer1));
Yves Gerey665174f2018-06-19 15:03:05 +02002172 EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(1)));
Niels Möller805a27e2019-01-21 12:21:27 +01002173
2174 webrtc::test::FrameForwarder frame_forwarder1;
2175 cricket::FakeFrameSource frame_source(kVideoWidth, kVideoHeight,
2176 rtc::kNumMicrosecsPerSec / kFramerate);
2177
Niels Möller6557d0c2018-04-11 15:18:34 +02002178 // Set up additional stream 2.
2179 cricket::FakeVideoRenderer renderer2;
2180 EXPECT_FALSE(channel_->SetSink(2, &renderer2));
Yves Gerey665174f2018-06-19 15:03:05 +02002181 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
Niels Möller6557d0c2018-04-11 15:18:34 +02002182 EXPECT_TRUE(channel_->SetSink(2, &renderer2));
Yves Gerey665174f2018-06-19 15:03:05 +02002183 EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
Niels Möller805a27e2019-01-21 12:21:27 +01002184 webrtc::test::FrameForwarder frame_forwarder2;
2185
Niels Möller6557d0c2018-04-11 15:18:34 +02002186 // State for all the streams.
2187 EXPECT_TRUE(SetOneCodec(DefaultCodec()));
2188 // A limitation in the lmi implementation requires that SetVideoSend() is
2189 // called after SetOneCodec().
2190 // TODO(hellner): this seems like an unnecessary constraint, fix it.
Niels Möller805a27e2019-01-21 12:21:27 +01002191 EXPECT_TRUE(channel_->SetVideoSend(1, nullptr, &frame_forwarder1));
2192 EXPECT_TRUE(channel_->SetVideoSend(2, nullptr, &frame_forwarder2));
Niels Möller6557d0c2018-04-11 15:18:34 +02002193 EXPECT_TRUE(SetSend(true));
2194 // Test capturer associated with engine.
2195 const int kTestWidth = 160;
2196 const int kTestHeight = 120;
Niels Möller805a27e2019-01-21 12:21:27 +01002197 frame_forwarder1.IncomingCapturedFrame(frame_source.GetFrame(
2198 kTestWidth, kTestHeight, webrtc::VideoRotation::kVideoRotation_0,
2199 rtc::kNumMicrosecsPerSec / kFramerate));
Yves Gerey665174f2018-06-19 15:03:05 +02002200 EXPECT_FRAME_ON_RENDERER_WAIT(renderer1, 1, kTestWidth, kTestHeight,
2201 kTimeout);
Niels Möller6557d0c2018-04-11 15:18:34 +02002202 // Capture a frame with additional capturer2, frames should be received
Niels Möller805a27e2019-01-21 12:21:27 +01002203 frame_forwarder2.IncomingCapturedFrame(frame_source.GetFrame(
2204 kTestWidth, kTestHeight, webrtc::VideoRotation::kVideoRotation_0,
2205 rtc::kNumMicrosecsPerSec / kFramerate));
Yves Gerey665174f2018-06-19 15:03:05 +02002206 EXPECT_FRAME_ON_RENDERER_WAIT(renderer2, 1, kTestWidth, kTestHeight,
2207 kTimeout);
Niels Möller6557d0c2018-04-11 15:18:34 +02002208 // Successfully remove the capturer.
2209 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, nullptr, nullptr));
2210 // The capturers must be unregistered here as it runs out of it's scope
2211 // next.
2212 EXPECT_TRUE(channel_->SetVideoSend(1, nullptr, nullptr));
2213 EXPECT_TRUE(channel_->SetVideoSend(2, nullptr, nullptr));
srtee0c2eea2017-12-15 17:44:33 +01002214}
Niels Möller6557d0c2018-04-11 15:18:34 +02002215
2216// Tests empty StreamParams is rejected.
srtee0c2eea2017-12-15 17:44:33 +01002217TEST_F(WebRtcVideoChannelBaseTest, RejectEmptyStreamParams) {
Niels Möller6557d0c2018-04-11 15:18:34 +02002218 // Remove the send stream that was added during Setup.
2219 EXPECT_TRUE(channel_->RemoveSendStream(kSsrc));
2220
2221 cricket::StreamParams empty;
2222 EXPECT_FALSE(channel_->AddSendStream(empty));
Yves Gerey665174f2018-06-19 15:03:05 +02002223 EXPECT_TRUE(
2224 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(789u)));
srtee0c2eea2017-12-15 17:44:33 +01002225}
Niels Möller6557d0c2018-04-11 15:18:34 +02002226
2227// Test that multiple send streams can be created and deleted properly.
srtee0c2eea2017-12-15 17:44:33 +01002228TEST_F(WebRtcVideoChannelBaseTest, MultipleSendStreams) {
Niels Möller6557d0c2018-04-11 15:18:34 +02002229 // Remove stream added in Setup. I.e. remove stream corresponding to default
2230 // channel.
2231 EXPECT_TRUE(channel_->RemoveSendStream(kSsrc));
Yves Gerey665174f2018-06-19 15:03:05 +02002232 const unsigned int kSsrcsSize = sizeof(kSsrcs4) / sizeof(kSsrcs4[0]);
Niels Möller6557d0c2018-04-11 15:18:34 +02002233 for (unsigned int i = 0; i < kSsrcsSize; ++i) {
2234 EXPECT_TRUE(channel_->AddSendStream(
2235 cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
2236 }
2237 // Delete one of the non default channel streams, let the destructor delete
2238 // the remaining ones.
2239 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcs4[kSsrcsSize - 1]));
2240 // Stream should already be deleted.
2241 EXPECT_FALSE(channel_->RemoveSendStream(kSsrcs4[kSsrcsSize - 1]));
srtee0c2eea2017-12-15 17:44:33 +01002242}
pbos@webrtc.orgc4175b92014-09-03 15:25:49 +00002243
eladalonf1841382017-06-12 01:16:46 -07002244TEST_F(WebRtcVideoChannelBaseTest, SendAndReceiveVp8Vga) {
magjed509e4fe2016-11-18 01:34:11 -08002245 SendAndReceive(GetEngineCodec("VP8"));
pbos@webrtc.org9359cb32014-07-23 15:44:48 +00002246}
2247
eladalonf1841382017-06-12 01:16:46 -07002248TEST_F(WebRtcVideoChannelBaseTest, SendAndReceiveVp8Qvga) {
magjed509e4fe2016-11-18 01:34:11 -08002249 SendAndReceive(GetEngineCodec("VP8"));
pbos@webrtc.org9359cb32014-07-23 15:44:48 +00002250}
2251
eladalonf1841382017-06-12 01:16:46 -07002252TEST_F(WebRtcVideoChannelBaseTest, SendAndReceiveVp8SvcQqvga) {
magjed509e4fe2016-11-18 01:34:11 -08002253 SendAndReceive(GetEngineCodec("VP8"));
pbos@webrtc.org9359cb32014-07-23 15:44:48 +00002254}
2255
eladalonf1841382017-06-12 01:16:46 -07002256TEST_F(WebRtcVideoChannelBaseTest, TwoStreamsSendAndReceive) {
Peter Boströmd1f584b2016-04-20 16:31:53 +02002257 // Set a high bitrate to not be downscaled by VP8 due to low initial start
2258 // bitrates. This currently happens at <250k, and two streams sharing 300k
2259 // initially will use QVGA instead of VGA.
2260 // TODO(pbos): Set up the quality scaler so that both senders reliably start
2261 // at QVGA, then verify that instead.
magjed509e4fe2016-11-18 01:34:11 -08002262 cricket::VideoCodec codec = GetEngineCodec("VP8");
Peter Boströmd1f584b2016-04-20 16:31:53 +02002263 codec.params[kCodecParamStartBitrate] = "1000000";
Niels Möller6557d0c2018-04-11 15:18:34 +02002264 TwoStreamsSendAndReceive(codec);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002265}
2266
philipeld9cc8c02019-09-16 14:53:40 +02002267TEST_F(WebRtcVideoChannelBaseTest, RequestEncoderFallback) {
philipele8ed8302019-07-03 11:53:48 +02002268 cricket::VideoSendParameters parameters;
2269 parameters.codecs.push_back(GetEngineCodec("VP9"));
2270 parameters.codecs.push_back(GetEngineCodec("VP8"));
2271 EXPECT_TRUE(channel_->SetSendParameters(parameters));
2272
2273 VideoCodec codec;
2274 ASSERT_TRUE(channel_->GetSendCodec(&codec));
2275 EXPECT_EQ("VP9", codec.name);
2276
philipeld9cc8c02019-09-16 14:53:40 +02002277 // RequestEncoderFallback will post a task to the worker thread (which is also
philipele8ed8302019-07-03 11:53:48 +02002278 // the current thread), hence the ProcessMessages call.
philipeld9cc8c02019-09-16 14:53:40 +02002279 channel_->RequestEncoderFallback();
philipele8ed8302019-07-03 11:53:48 +02002280 rtc::Thread::Current()->ProcessMessages(30);
2281 ASSERT_TRUE(channel_->GetSendCodec(&codec));
2282 EXPECT_EQ("VP8", codec.name);
2283
2284 // No other codec to fall back to, keep using VP8.
philipeld9cc8c02019-09-16 14:53:40 +02002285 channel_->RequestEncoderFallback();
philipele8ed8302019-07-03 11:53:48 +02002286 rtc::Thread::Current()->ProcessMessages(30);
2287 ASSERT_TRUE(channel_->GetSendCodec(&codec));
2288 EXPECT_EQ("VP8", codec.name);
2289}
2290
philipeld9cc8c02019-09-16 14:53:40 +02002291TEST_F(WebRtcVideoChannelBaseTest, RequestEncoderSwitchWithConfig) {
2292 const std::string kParam = "the-param";
2293 const std::string kPing = "ping";
2294 const std::string kPong = "pong";
2295
2296 cricket::VideoSendParameters parameters;
2297 VideoCodec vp9 = GetEngineCodec("VP9");
2298 vp9.params[kParam] = kPong;
2299 parameters.codecs.push_back(vp9);
2300
2301 VideoCodec vp8 = GetEngineCodec("VP8");
2302 vp8.params[kParam] = kPing;
2303 parameters.codecs.push_back(vp8);
2304
2305 EXPECT_TRUE(channel_->SetSendParameters(parameters));
philipel16cec3b2019-10-25 12:23:02 +02002306 channel_->SetVideoCodecSwitchingEnabled(true);
philipeld9cc8c02019-09-16 14:53:40 +02002307
2308 VideoCodec codec;
2309 ASSERT_TRUE(channel_->GetSendCodec(&codec));
2310 EXPECT_THAT(codec.name, Eq("VP9"));
2311
2312 // RequestEncoderSwitch will post a task to the worker thread (which is also
2313 // the current thread), hence the ProcessMessages call.
2314 webrtc::EncoderSwitchRequestCallback::Config conf1{"VP8", kParam, kPing};
2315 channel_->RequestEncoderSwitch(conf1);
2316 rtc::Thread::Current()->ProcessMessages(30);
2317 ASSERT_TRUE(channel_->GetSendCodec(&codec));
2318 EXPECT_THAT(codec.name, Eq("VP8"));
2319 EXPECT_THAT(codec.params, Contains(Pair(kParam, kPing)));
2320
2321 webrtc::EncoderSwitchRequestCallback::Config conf2{"VP9", kParam, kPong};
2322 channel_->RequestEncoderSwitch(conf2);
2323 rtc::Thread::Current()->ProcessMessages(30);
2324 ASSERT_TRUE(channel_->GetSendCodec(&codec));
2325 EXPECT_THAT(codec.name, Eq("VP9"));
2326 EXPECT_THAT(codec.params, Contains(Pair(kParam, kPong)));
2327}
2328
2329TEST_F(WebRtcVideoChannelBaseTest, RequestEncoderSwitchIncorrectParam) {
2330 const std::string kParam = "the-param";
2331 const std::string kPing = "ping";
2332 const std::string kPong = "pong";
2333
2334 cricket::VideoSendParameters parameters;
2335 VideoCodec vp9 = GetEngineCodec("VP9");
2336 vp9.params[kParam] = kPong;
2337 parameters.codecs.push_back(vp9);
2338
2339 VideoCodec vp8 = GetEngineCodec("VP8");
2340 vp8.params[kParam] = kPing;
2341 parameters.codecs.push_back(vp8);
2342
2343 EXPECT_TRUE(channel_->SetSendParameters(parameters));
philipel16cec3b2019-10-25 12:23:02 +02002344 channel_->SetVideoCodecSwitchingEnabled(true);
philipeld9cc8c02019-09-16 14:53:40 +02002345
2346 VideoCodec codec;
2347 ASSERT_TRUE(channel_->GetSendCodec(&codec));
2348 EXPECT_THAT(codec.name, Eq("VP9"));
2349
2350 // RequestEncoderSwitch will post a task to the worker thread (which is also
2351 // the current thread), hence the ProcessMessages call.
2352 webrtc::EncoderSwitchRequestCallback::Config conf1{"VP8", kParam, kPing};
2353 channel_->RequestEncoderSwitch(conf1);
2354 rtc::Thread::Current()->ProcessMessages(30);
2355 ASSERT_TRUE(channel_->GetSendCodec(&codec));
2356 EXPECT_THAT(codec.name, Eq("VP8"));
2357 EXPECT_THAT(codec.params, Contains(Pair(kParam, kPing)));
2358
2359 // Incorrect conf2.value, expect no codec switch.
2360 webrtc::EncoderSwitchRequestCallback::Config conf2{"VP9", kParam, kPing};
2361 channel_->RequestEncoderSwitch(conf2);
2362 rtc::Thread::Current()->ProcessMessages(30);
2363 ASSERT_TRUE(channel_->GetSendCodec(&codec));
2364 EXPECT_THAT(codec.name, Eq("VP8"));
2365 EXPECT_THAT(codec.params, Contains(Pair(kParam, kPing)));
2366}
2367
philipeldcb4fcc2019-12-11 16:35:27 +01002368TEST_F(WebRtcVideoChannelBaseTest,
2369 RequestEncoderSwitchWithConfigBeforeEnabling) {
2370 const std::string kParam = "the-param";
2371 const std::string kPing = "ping";
2372 const std::string kPong = "pong";
2373
2374 cricket::VideoSendParameters parameters;
2375 VideoCodec vp9 = GetEngineCodec("VP9");
2376 vp9.params[kParam] = kPong;
2377 parameters.codecs.push_back(vp9);
2378
2379 VideoCodec vp8 = GetEngineCodec("VP8");
2380 vp8.params[kParam] = kPing;
2381 parameters.codecs.push_back(vp8);
2382
2383 EXPECT_TRUE(channel_->SetSendParameters(parameters));
2384
2385 VideoCodec codec;
2386 ASSERT_TRUE(channel_->GetSendCodec(&codec));
2387 EXPECT_THAT(codec.name, Eq("VP9"));
2388
2389 webrtc::EncoderSwitchRequestCallback::Config conf{"VP8", kParam, kPing};
2390 channel_->RequestEncoderSwitch(conf);
2391
2392 // Enable codec switching after it has been requested.
2393 channel_->SetVideoCodecSwitchingEnabled(true);
2394
2395 // RequestEncoderSwitch will post a task to the worker thread (which is also
2396 // the current thread), hence the ProcessMessages call.
2397 rtc::Thread::Current()->ProcessMessages(30);
2398 ASSERT_TRUE(channel_->GetSendCodec(&codec));
2399 EXPECT_THAT(codec.name, Eq("VP8"));
2400 EXPECT_THAT(codec.params, Contains(Pair(kParam, kPing)));
2401}
2402
eladalonf1841382017-06-12 01:16:46 -07002403class WebRtcVideoChannelTest : public WebRtcVideoEngineTest {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002404 public:
eladalonf1841382017-06-12 01:16:46 -07002405 WebRtcVideoChannelTest() : WebRtcVideoChannelTest("") {}
2406 explicit WebRtcVideoChannelTest(const char* field_trials)
Niels Möller805a27e2019-01-21 12:21:27 +01002407 : WebRtcVideoEngineTest(field_trials),
2408 frame_source_(1280, 720, rtc::kNumMicrosecsPerSec / 30),
2409 last_ssrc_(0) {}
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002410 void SetUp() override {
Johannes Kron3e983682020-03-29 22:17:00 +02002411 AddSupportedVideoCodecType("VP8");
2412 AddSupportedVideoCodecType("VP9");
Anders Carlsson5f2bb622018-05-14 09:48:06 +02002413#if defined(WEBRTC_USE_H264)
Johannes Kron3e983682020-03-29 22:17:00 +02002414 AddSupportedVideoCodecType("H264");
Anders Carlsson5f2bb622018-05-14 09:48:06 +02002415#endif
2416
Sebastian Jansson8f83b422018-02-21 13:07:13 +01002417 fake_call_.reset(new FakeCall());
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02002418 channel_.reset(engine_.CreateMediaChannel(
2419 fake_call_.get(), GetMediaConfig(), VideoOptions(),
2420 webrtc::CryptoOptions(), video_bitrate_allocator_factory_.get()));
Sergey Ulanove2b15012016-11-22 16:08:30 -08002421 channel_->OnReadyToSend(true);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002422 last_ssrc_ = 123;
Johannes Kron3e983682020-03-29 22:17:00 +02002423 send_parameters_.codecs = engine_.send_codecs();
2424 recv_parameters_.codecs = engine_.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002425 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002426 }
2427
2428 protected:
2429 FakeVideoSendStream* AddSendStream() {
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002430 return AddSendStream(StreamParams::CreateLegacy(++last_ssrc_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002431 }
2432
2433 FakeVideoSendStream* AddSendStream(const StreamParams& sp) {
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002434 size_t num_streams = fake_call_->GetVideoSendStreams().size();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002435 EXPECT_TRUE(channel_->AddSendStream(sp));
2436 std::vector<FakeVideoSendStream*> streams =
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002437 fake_call_->GetVideoSendStreams();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002438 EXPECT_EQ(num_streams + 1, streams.size());
2439 return streams[streams.size() - 1];
2440 }
2441
2442 std::vector<FakeVideoSendStream*> GetFakeSendStreams() {
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002443 return fake_call_->GetVideoSendStreams();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002444 }
2445
2446 FakeVideoReceiveStream* AddRecvStream() {
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002447 return AddRecvStream(StreamParams::CreateLegacy(++last_ssrc_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002448 }
2449
2450 FakeVideoReceiveStream* AddRecvStream(const StreamParams& sp) {
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002451 size_t num_streams = fake_call_->GetVideoReceiveStreams().size();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002452 EXPECT_TRUE(channel_->AddRecvStream(sp));
2453 std::vector<FakeVideoReceiveStream*> streams =
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002454 fake_call_->GetVideoReceiveStreams();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002455 EXPECT_EQ(num_streams + 1, streams.size());
2456 return streams[streams.size() - 1];
2457 }
2458
pbos@webrtc.org00873182014-11-25 14:03:34 +00002459 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps,
2460 int expected_min_bitrate_bps,
2461 const char* start_bitrate_kbps,
2462 int expected_start_bitrate_bps,
2463 const char* max_bitrate_kbps,
2464 int expected_max_bitrate_bps) {
Sebastian Jansson8f83b422018-02-21 13:07:13 +01002465 ExpectSetBitrateParameters(expected_min_bitrate_bps,
2466 expected_start_bitrate_bps,
2467 expected_max_bitrate_bps);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002468 auto& codecs = send_parameters_.codecs;
2469 codecs.clear();
magjed509e4fe2016-11-18 01:34:11 -08002470 codecs.push_back(GetEngineCodec("VP8"));
pbos@webrtc.org00873182014-11-25 14:03:34 +00002471 codecs[0].params[kCodecParamMinBitrate] = min_bitrate_kbps;
2472 codecs[0].params[kCodecParamStartBitrate] = start_bitrate_kbps;
2473 codecs[0].params[kCodecParamMaxBitrate] = max_bitrate_kbps;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002474 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Sebastian Jansson8f83b422018-02-21 13:07:13 +01002475 }
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002476
Sebastian Jansson8f83b422018-02-21 13:07:13 +01002477 void ExpectSetBitrateParameters(int min_bitrate_bps,
2478 int start_bitrate_bps,
2479 int max_bitrate_bps) {
2480 EXPECT_CALL(
2481 *fake_call_->GetMockTransportControllerSend(),
2482 SetSdpBitrateParameters(AllOf(
2483 Field(&BitrateConstraints::min_bitrate_bps, min_bitrate_bps),
2484 Field(&BitrateConstraints::start_bitrate_bps, start_bitrate_bps),
2485 Field(&BitrateConstraints::max_bitrate_bps, max_bitrate_bps))));
2486 }
2487
2488 void ExpectSetMaxBitrate(int max_bitrate_bps) {
2489 EXPECT_CALL(*fake_call_->GetMockTransportControllerSend(),
2490 SetSdpBitrateParameters(Field(
2491 &BitrateConstraints::max_bitrate_bps, max_bitrate_bps)));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002492 }
2493
Johannes Kron9190b822018-10-29 11:22:05 +01002494 void TestExtmapAllowMixedCaller(bool extmap_allow_mixed) {
2495 // For a caller, the answer will be applied in set remote description
2496 // where SetSendParameters() is called.
2497 EXPECT_TRUE(
2498 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
2499 send_parameters_.extmap_allow_mixed = extmap_allow_mixed;
2500 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2501 const webrtc::VideoSendStream::Config& config =
2502 fake_call_->GetVideoSendStreams()[0]->GetConfig();
2503 EXPECT_EQ(extmap_allow_mixed, config.rtp.extmap_allow_mixed);
2504 }
2505
2506 void TestExtmapAllowMixedCallee(bool extmap_allow_mixed) {
2507 // For a callee, the answer will be applied in set local description
2508 // where SetExtmapAllowMixed() and AddSendStream() are called.
2509 channel_->SetExtmapAllowMixed(extmap_allow_mixed);
2510 EXPECT_TRUE(
2511 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
2512 const webrtc::VideoSendStream::Config& config =
2513 fake_call_->GetVideoSendStreams()[0]->GetConfig();
2514 EXPECT_EQ(extmap_allow_mixed, config.rtp.extmap_allow_mixed);
2515 }
2516
isheriff6f8d6862016-05-26 11:24:55 -07002517 void TestSetSendRtpHeaderExtensions(const std::string& ext_uri) {
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002518 // Enable extension.
2519 const int id = 1;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002520 cricket::VideoSendParameters parameters = send_parameters_;
isheriff6f8d6862016-05-26 11:24:55 -07002521 parameters.extensions.push_back(RtpExtension(ext_uri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002522 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002523 FakeVideoSendStream* send_stream =
2524 AddSendStream(cricket::StreamParams::CreateLegacy(123));
2525
2526 // Verify the send extension id.
2527 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
2528 EXPECT_EQ(id, send_stream->GetConfig().rtp.extensions[0].id);
isheriff6f8d6862016-05-26 11:24:55 -07002529 EXPECT_EQ(ext_uri, send_stream->GetConfig().rtp.extensions[0].uri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002530 // Verify call with same set of extensions returns true.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002531 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002532 // Verify that SetSendRtpHeaderExtensions doesn't implicitly add them for
2533 // receivers.
2534 EXPECT_TRUE(AddRecvStream(cricket::StreamParams::CreateLegacy(123))
2535 ->GetConfig()
2536 .rtp.extensions.empty());
2537
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00002538 // Verify that existing RTP header extensions can be removed.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002539 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Fredrik Solenberg709ed672015-09-15 12:26:33 +02002540 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
2541 send_stream = fake_call_->GetVideoSendStreams()[0];
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00002542 EXPECT_TRUE(send_stream->GetConfig().rtp.extensions.empty());
2543
2544 // Verify that adding receive RTP header extensions adds them for existing
2545 // streams.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002546 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Fredrik Solenberg709ed672015-09-15 12:26:33 +02002547 send_stream = fake_call_->GetVideoSendStreams()[0];
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00002548 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
2549 EXPECT_EQ(id, send_stream->GetConfig().rtp.extensions[0].id);
isheriff6f8d6862016-05-26 11:24:55 -07002550 EXPECT_EQ(ext_uri, send_stream->GetConfig().rtp.extensions[0].uri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002551 }
2552
isheriff6f8d6862016-05-26 11:24:55 -07002553 void TestSetRecvRtpHeaderExtensions(const std::string& ext_uri) {
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002554 // Enable extension.
2555 const int id = 1;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002556 cricket::VideoRecvParameters parameters = recv_parameters_;
isheriff6f8d6862016-05-26 11:24:55 -07002557 parameters.extensions.push_back(RtpExtension(ext_uri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002558 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002559
2560 FakeVideoReceiveStream* recv_stream =
2561 AddRecvStream(cricket::StreamParams::CreateLegacy(123));
2562
2563 // Verify the recv extension id.
2564 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.extensions.size());
2565 EXPECT_EQ(id, recv_stream->GetConfig().rtp.extensions[0].id);
isheriff6f8d6862016-05-26 11:24:55 -07002566 EXPECT_EQ(ext_uri, recv_stream->GetConfig().rtp.extensions[0].uri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002567 // Verify call with same set of extensions returns true.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002568 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00002569
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002570 // Verify that SetRecvRtpHeaderExtensions doesn't implicitly add them for
2571 // senders.
2572 EXPECT_TRUE(AddSendStream(cricket::StreamParams::CreateLegacy(123))
2573 ->GetConfig()
2574 .rtp.extensions.empty());
2575
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00002576 // Verify that existing RTP header extensions can be removed.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002577 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
Fredrik Solenberg709ed672015-09-15 12:26:33 +02002578 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
2579 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00002580 EXPECT_TRUE(recv_stream->GetConfig().rtp.extensions.empty());
2581
2582 // Verify that adding receive RTP header extensions adds them for existing
2583 // streams.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002584 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
Fredrik Solenberg709ed672015-09-15 12:26:33 +02002585 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00002586 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.extensions.size());
2587 EXPECT_EQ(id, recv_stream->GetConfig().rtp.extensions[0].id);
isheriff6f8d6862016-05-26 11:24:55 -07002588 EXPECT_EQ(ext_uri, recv_stream->GetConfig().rtp.extensions[0].uri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002589 }
2590
Elad Alonfadb1812019-05-24 13:40:02 +02002591 void TestLossNotificationState(bool expect_lntf_enabled) {
2592 AssignDefaultCodec();
2593 VerifyCodecHasDefaultFeedbackParams(default_codec_, expect_lntf_enabled);
2594
2595 cricket::VideoSendParameters parameters;
Johannes Kron3e983682020-03-29 22:17:00 +02002596 parameters.codecs = engine_.send_codecs();
Elad Alonfadb1812019-05-24 13:40:02 +02002597 EXPECT_TRUE(channel_->SetSendParameters(parameters));
2598 EXPECT_TRUE(channel_->SetSend(true));
2599
2600 // Send side.
2601 FakeVideoSendStream* send_stream =
2602 AddSendStream(cricket::StreamParams::CreateLegacy(1));
2603 EXPECT_EQ(send_stream->GetConfig().rtp.lntf.enabled, expect_lntf_enabled);
2604
2605 // Receiver side.
2606 FakeVideoReceiveStream* recv_stream =
2607 AddRecvStream(cricket::StreamParams::CreateLegacy(1));
2608 EXPECT_EQ(recv_stream->GetConfig().rtp.lntf.enabled, expect_lntf_enabled);
2609 }
2610
Stefan Holmerbbaf3632015-10-29 18:53:23 +01002611 void TestExtensionFilter(const std::vector<std::string>& extensions,
2612 const std::string& expected_extension) {
2613 cricket::VideoSendParameters parameters = send_parameters_;
2614 int expected_id = -1;
2615 int id = 1;
2616 for (const std::string& extension : extensions) {
2617 if (extension == expected_extension)
2618 expected_id = id;
isheriff6f8d6862016-05-26 11:24:55 -07002619 parameters.extensions.push_back(RtpExtension(extension, id++));
Stefan Holmerbbaf3632015-10-29 18:53:23 +01002620 }
2621 EXPECT_TRUE(channel_->SetSendParameters(parameters));
2622 FakeVideoSendStream* send_stream =
2623 AddSendStream(cricket::StreamParams::CreateLegacy(123));
2624
2625 // Verify that only one of them has been set, and that it is the one with
2626 // highest priority (transport sequence number).
2627 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
2628 EXPECT_EQ(expected_id, send_stream->GetConfig().rtp.extensions[0].id);
2629 EXPECT_EQ(expected_extension,
isheriff6f8d6862016-05-26 11:24:55 -07002630 send_stream->GetConfig().rtp.extensions[0].uri);
Stefan Holmerbbaf3632015-10-29 18:53:23 +01002631 }
2632
asapersson3c81a1a2017-06-14 05:52:21 -07002633 void TestDegradationPreference(bool resolution_scaling_enabled,
2634 bool fps_scaling_enabled);
2635
Erik Språngefbde372015-04-29 16:21:28 +02002636 void TestCpuAdaptation(bool enable_overuse, bool is_screenshare);
Peter Boström3548dd22015-05-22 18:48:36 +02002637 void TestReceiverLocalSsrcConfiguration(bool receiver_first);
magjed509e4fe2016-11-18 01:34:11 -08002638 void TestReceiveUnsignaledSsrcPacket(uint8_t payload_type,
2639 bool expect_created_receive_stream);
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002640
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002641 FakeVideoSendStream* SetDenoisingOption(
nisse05103312016-03-16 02:22:50 -07002642 uint32_t ssrc,
Niels Möller805a27e2019-01-21 12:21:27 +01002643 webrtc::test::FrameForwarder* frame_forwarder,
nisse0db023a2016-03-01 04:29:59 -08002644 bool enabled) {
nisse05103312016-03-16 02:22:50 -07002645 cricket::VideoOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002646 options.video_noise_reduction = enabled;
Niels Möller805a27e2019-01-21 12:21:27 +01002647 EXPECT_TRUE(channel_->SetVideoSend(ssrc, &options, frame_forwarder));
nisse0db023a2016-03-01 04:29:59 -08002648 // Options only take effect on the next frame.
Niels Möller805a27e2019-01-21 12:21:27 +01002649 frame_forwarder->IncomingCapturedFrame(frame_source_.GetFrame());
nisse0db023a2016-03-01 04:29:59 -08002650
Erik Språng143cec12015-04-28 10:01:41 +02002651 return fake_call_->GetVideoSendStreams().back();
2652 }
2653
Peter Boström2feafdb2015-09-09 14:32:14 +02002654 FakeVideoSendStream* SetUpSimulcast(bool enabled, bool with_rtx) {
2655 const int kRtxSsrcOffset = 0xDEADBEEF;
Erik Språng143cec12015-04-28 10:01:41 +02002656 last_ssrc_ += 3;
Peter Boström2feafdb2015-09-09 14:32:14 +02002657 std::vector<uint32_t> ssrcs;
2658 std::vector<uint32_t> rtx_ssrcs;
2659 uint32_t num_streams = enabled ? 3 : 1;
2660 for (uint32_t i = 0; i < num_streams; ++i) {
2661 uint32_t ssrc = last_ssrc_ + i;
2662 ssrcs.push_back(ssrc);
2663 if (with_rtx) {
2664 rtx_ssrcs.push_back(ssrc + kRtxSsrcOffset);
2665 }
Erik Språng143cec12015-04-28 10:01:41 +02002666 }
Peter Boström2feafdb2015-09-09 14:32:14 +02002667 if (with_rtx) {
2668 return AddSendStream(
2669 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
2670 }
2671 return AddSendStream(CreateSimStreamParams("cname", ssrcs));
Erik Språng143cec12015-04-28 10:01:41 +02002672 }
2673
perkjfa10b552016-10-02 23:45:26 -07002674 int GetMaxEncoderBitrate() {
skvladdc1c62c2016-03-16 19:07:43 -07002675 std::vector<FakeVideoSendStream*> streams =
2676 fake_call_->GetVideoSendStreams();
perkjfa10b552016-10-02 23:45:26 -07002677 EXPECT_EQ(1u, streams.size());
skvladdc1c62c2016-03-16 19:07:43 -07002678 FakeVideoSendStream* stream = streams[streams.size() - 1];
Mirko Bonadeif859e552018-05-30 15:31:29 +02002679 EXPECT_EQ(1u, stream->GetEncoderConfig().number_of_streams);
perkjfa10b552016-10-02 23:45:26 -07002680 return stream->GetVideoStreams()[0].max_bitrate_bps;
skvladdc1c62c2016-03-16 19:07:43 -07002681 }
2682
perkjfa10b552016-10-02 23:45:26 -07002683 void SetAndExpectMaxBitrate(int global_max,
skvladdc1c62c2016-03-16 19:07:43 -07002684 int stream_max,
2685 int expected_encoder_bitrate) {
2686 VideoSendParameters limited_send_params = send_parameters_;
2687 limited_send_params.max_bandwidth_bps = global_max;
2688 EXPECT_TRUE(channel_->SetSendParameters(limited_send_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07002689 webrtc::RtpParameters parameters =
2690 channel_->GetRtpSendParameters(last_ssrc_);
skvladdc1c62c2016-03-16 19:07:43 -07002691 EXPECT_EQ(1UL, parameters.encodings.size());
Oskar Sundbom78807582017-11-16 11:09:55 +01002692 parameters.encodings[0].max_bitrate_bps = stream_max;
Zach Steinba37b4b2018-01-23 15:02:36 -08002693 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
skvladdc1c62c2016-03-16 19:07:43 -07002694 // Read back the parameteres and verify they have the correct value
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07002695 parameters = channel_->GetRtpSendParameters(last_ssrc_);
skvladdc1c62c2016-03-16 19:07:43 -07002696 EXPECT_EQ(1UL, parameters.encodings.size());
Oskar Sundbom78807582017-11-16 11:09:55 +01002697 EXPECT_EQ(stream_max, parameters.encodings[0].max_bitrate_bps);
skvladdc1c62c2016-03-16 19:07:43 -07002698 // Verify that the new value propagated down to the encoder
perkjfa10b552016-10-02 23:45:26 -07002699 EXPECT_EQ(expected_encoder_bitrate, GetMaxEncoderBitrate());
skvladdc1c62c2016-03-16 19:07:43 -07002700 }
2701
Åsa Persson55659812018-06-18 17:51:32 +02002702 // Values from kSimulcastConfigs in simulcast.cc.
2703 const std::vector<webrtc::VideoStream> GetSimulcastBitrates720p() const {
2704 std::vector<webrtc::VideoStream> layers(3);
2705 layers[0].min_bitrate_bps = 30000;
2706 layers[0].target_bitrate_bps = 150000;
2707 layers[0].max_bitrate_bps = 200000;
2708 layers[1].min_bitrate_bps = 150000;
2709 layers[1].target_bitrate_bps = 500000;
2710 layers[1].max_bitrate_bps = 700000;
2711 layers[2].min_bitrate_bps = 600000;
2712 layers[2].target_bitrate_bps = 2500000;
2713 layers[2].max_bitrate_bps = 2500000;
2714 return layers;
2715 }
2716
Niels Möller805a27e2019-01-21 12:21:27 +01002717 cricket::FakeFrameSource frame_source_;
kwiberg686a8ef2016-02-26 03:00:35 -08002718 std::unique_ptr<FakeCall> fake_call_;
2719 std::unique_ptr<VideoMediaChannel> channel_;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002720 cricket::VideoSendParameters send_parameters_;
2721 cricket::VideoRecvParameters recv_parameters_;
Peter Boström0c4e06b2015-10-07 12:23:21 +02002722 uint32_t last_ssrc_;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002723};
2724
eladalonf1841382017-06-12 01:16:46 -07002725TEST_F(WebRtcVideoChannelTest, SetsSyncGroupFromSyncLabel) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02002726 const uint32_t kVideoSsrc = 123;
pbos8fc7fa72015-07-15 08:02:58 -07002727 const std::string kSyncLabel = "AvSyncLabel";
2728
2729 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kVideoSsrc);
Seth Hampson845e8782018-03-02 11:34:10 -08002730 sp.set_stream_ids({kSyncLabel});
pbos8fc7fa72015-07-15 08:02:58 -07002731 EXPECT_TRUE(channel_->AddRecvStream(sp));
2732
Mirko Bonadeif859e552018-05-30 15:31:29 +02002733 EXPECT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
pbos8fc7fa72015-07-15 08:02:58 -07002734 EXPECT_EQ(kSyncLabel,
2735 fake_call_->GetVideoReceiveStreams()[0]->GetConfig().sync_group)
2736 << "SyncGroup should be set based on sync_label";
2737}
2738
eladalonf1841382017-06-12 01:16:46 -07002739TEST_F(WebRtcVideoChannelTest, RecvStreamWithSimAndRtx) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002740 cricket::VideoSendParameters parameters;
Johannes Kron3e983682020-03-29 22:17:00 +02002741 parameters.codecs = engine_.send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002742 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002743 EXPECT_TRUE(channel_->SetSend(true));
nisse4b4dc862016-02-17 05:25:36 -08002744 parameters.conference_mode = true;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002745 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002746
2747 // Send side.
Peter Boström0c4e06b2015-10-07 12:23:21 +02002748 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
2749 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002750 FakeVideoSendStream* send_stream = AddSendStream(
2751 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
2752
2753 ASSERT_EQ(rtx_ssrcs.size(), send_stream->GetConfig().rtp.rtx.ssrcs.size());
2754 for (size_t i = 0; i < rtx_ssrcs.size(); ++i)
2755 EXPECT_EQ(rtx_ssrcs[i], send_stream->GetConfig().rtp.rtx.ssrcs[i]);
2756
2757 // Receiver side.
2758 FakeVideoReceiveStream* recv_stream = AddRecvStream(
2759 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
nisse26e3abb2017-08-25 04:44:25 -07002760 EXPECT_FALSE(
2761 recv_stream->GetConfig().rtp.rtx_associated_payload_types.empty());
nisseca5706d2017-09-11 02:32:16 -07002762 EXPECT_TRUE(VerifyRtxReceiveAssociations(recv_stream->GetConfig()))
Peter Boströmd8b01092016-05-12 16:44:36 +02002763 << "RTX should be mapped for all decoders/payload types.";
nisseca5706d2017-09-11 02:32:16 -07002764 EXPECT_TRUE(HasRtxReceiveAssociation(recv_stream->GetConfig(),
Yves Gerey665174f2018-06-19 15:03:05 +02002765 GetEngineCodec("red").id))
nisseca5706d2017-09-11 02:32:16 -07002766 << "RTX should be mapped for the RED payload type";
2767
brandtr14742122017-01-27 04:53:07 -08002768 EXPECT_EQ(rtx_ssrcs[0], recv_stream->GetConfig().rtp.rtx_ssrc);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002769}
2770
eladalonf1841382017-06-12 01:16:46 -07002771TEST_F(WebRtcVideoChannelTest, RecvStreamWithRtx) {
pbos@webrtc.orge322a172014-06-13 11:47:28 +00002772 // Setup one channel with an associated RTX stream.
2773 cricket::StreamParams params =
2774 cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
2775 params.AddFidSsrc(kSsrcs1[0], kRtxSsrcs1[0]);
2776 FakeVideoReceiveStream* recv_stream = AddRecvStream(params);
brandtr14742122017-01-27 04:53:07 -08002777 EXPECT_EQ(kRtxSsrcs1[0], recv_stream->GetConfig().rtp.rtx_ssrc);
nisseca5706d2017-09-11 02:32:16 -07002778
2779 EXPECT_TRUE(VerifyRtxReceiveAssociations(recv_stream->GetConfig()))
2780 << "RTX should be mapped for all decoders/payload types.";
2781 EXPECT_TRUE(HasRtxReceiveAssociation(recv_stream->GetConfig(),
Yves Gerey665174f2018-06-19 15:03:05 +02002782 GetEngineCodec("red").id))
nisseca5706d2017-09-11 02:32:16 -07002783 << "RTX should be mapped for the RED payload type";
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002784}
2785
eladalonf1841382017-06-12 01:16:46 -07002786TEST_F(WebRtcVideoChannelTest, RecvStreamNoRtx) {
pbos@webrtc.orge322a172014-06-13 11:47:28 +00002787 // Setup one channel without an associated RTX stream.
2788 cricket::StreamParams params =
2789 cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
2790 FakeVideoReceiveStream* recv_stream = AddRecvStream(params);
brandtr14742122017-01-27 04:53:07 -08002791 ASSERT_EQ(0U, recv_stream->GetConfig().rtp.rtx_ssrc);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002792}
2793
Johannes Kron9190b822018-10-29 11:22:05 +01002794// Test propagation of extmap allow mixed setting.
2795TEST_F(WebRtcVideoChannelTest, SetExtmapAllowMixedAsCaller) {
2796 TestExtmapAllowMixedCaller(/*extmap_allow_mixed=*/true);
2797}
2798TEST_F(WebRtcVideoChannelTest, SetExtmapAllowMixedDisabledAsCaller) {
2799 TestExtmapAllowMixedCaller(/*extmap_allow_mixed=*/false);
2800}
2801TEST_F(WebRtcVideoChannelTest, SetExtmapAllowMixedAsCallee) {
2802 TestExtmapAllowMixedCallee(/*extmap_allow_mixed=*/true);
2803}
2804TEST_F(WebRtcVideoChannelTest, SetExtmapAllowMixedDisabledAsCallee) {
2805 TestExtmapAllowMixedCallee(/*extmap_allow_mixed=*/false);
2806}
2807
eladalonf1841382017-06-12 01:16:46 -07002808TEST_F(WebRtcVideoChannelTest, NoHeaderExtesionsByDefault) {
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002809 FakeVideoSendStream* send_stream =
2810 AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcs1[0]));
2811 ASSERT_TRUE(send_stream->GetConfig().rtp.extensions.empty());
2812
2813 FakeVideoReceiveStream* recv_stream =
2814 AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrcs1[0]));
2815 ASSERT_TRUE(recv_stream->GetConfig().rtp.extensions.empty());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002816}
2817
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002818// Test support for RTP timestamp offset header extension.
eladalonf1841382017-06-12 01:16:46 -07002819TEST_F(WebRtcVideoChannelTest, SendRtpTimestampOffsetHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002820 TestSetSendRtpHeaderExtensions(RtpExtension::kTimestampOffsetUri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002821}
isheriff6f8d6862016-05-26 11:24:55 -07002822
eladalonf1841382017-06-12 01:16:46 -07002823TEST_F(WebRtcVideoChannelTest, RecvRtpTimestampOffsetHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002824 TestSetRecvRtpHeaderExtensions(RtpExtension::kTimestampOffsetUri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002825}
2826
2827// Test support for absolute send time header extension.
eladalonf1841382017-06-12 01:16:46 -07002828TEST_F(WebRtcVideoChannelTest, SendAbsoluteSendTimeHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002829 TestSetSendRtpHeaderExtensions(RtpExtension::kAbsSendTimeUri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002830}
isheriff6f8d6862016-05-26 11:24:55 -07002831
eladalonf1841382017-06-12 01:16:46 -07002832TEST_F(WebRtcVideoChannelTest, RecvAbsoluteSendTimeHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002833 TestSetRecvRtpHeaderExtensions(RtpExtension::kAbsSendTimeUri);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002834}
2835
eladalonf1841382017-06-12 01:16:46 -07002836TEST_F(WebRtcVideoChannelTest, FiltersExtensionsPicksTransportSeqNum) {
Sebastian Jansson41462d52019-12-04 10:02:06 +01002837 webrtc::test::ScopedFieldTrials override_field_trials_(
2838 "WebRTC-FilterAbsSendTimeExtension/Enabled/");
Stefan Holmerbbaf3632015-10-29 18:53:23 +01002839 // Enable three redundant extensions.
2840 std::vector<std::string> extensions;
isheriff6f8d6862016-05-26 11:24:55 -07002841 extensions.push_back(RtpExtension::kAbsSendTimeUri);
2842 extensions.push_back(RtpExtension::kTimestampOffsetUri);
2843 extensions.push_back(RtpExtension::kTransportSequenceNumberUri);
2844 TestExtensionFilter(extensions, RtpExtension::kTransportSequenceNumberUri);
Stefan Holmerbbaf3632015-10-29 18:53:23 +01002845}
2846
eladalonf1841382017-06-12 01:16:46 -07002847TEST_F(WebRtcVideoChannelTest, FiltersExtensionsPicksAbsSendTime) {
Stefan Holmerbbaf3632015-10-29 18:53:23 +01002848 // Enable two redundant extensions.
2849 std::vector<std::string> extensions;
isheriff6f8d6862016-05-26 11:24:55 -07002850 extensions.push_back(RtpExtension::kAbsSendTimeUri);
2851 extensions.push_back(RtpExtension::kTimestampOffsetUri);
2852 TestExtensionFilter(extensions, RtpExtension::kAbsSendTimeUri);
Stefan Holmerbbaf3632015-10-29 18:53:23 +01002853}
2854
stefanc1aeaf02015-10-15 07:26:07 -07002855// Test support for transport sequence number header extension.
eladalonf1841382017-06-12 01:16:46 -07002856TEST_F(WebRtcVideoChannelTest, SendTransportSequenceNumberHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002857 TestSetSendRtpHeaderExtensions(RtpExtension::kTransportSequenceNumberUri);
stefanc1aeaf02015-10-15 07:26:07 -07002858}
eladalonf1841382017-06-12 01:16:46 -07002859TEST_F(WebRtcVideoChannelTest, RecvTransportSequenceNumberHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002860 TestSetRecvRtpHeaderExtensions(RtpExtension::kTransportSequenceNumberUri);
stefanc1aeaf02015-10-15 07:26:07 -07002861}
2862
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -07002863// Test support for video rotation header extension.
eladalonf1841382017-06-12 01:16:46 -07002864TEST_F(WebRtcVideoChannelTest, SendVideoRotationHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002865 TestSetSendRtpHeaderExtensions(RtpExtension::kVideoRotationUri);
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -07002866}
eladalonf1841382017-06-12 01:16:46 -07002867TEST_F(WebRtcVideoChannelTest, RecvVideoRotationHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002868 TestSetRecvRtpHeaderExtensions(RtpExtension::kVideoRotationUri);
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -07002869}
2870
eladalonf1841382017-06-12 01:16:46 -07002871TEST_F(WebRtcVideoChannelTest, IdenticalSendExtensionsDoesntRecreateStream) {
Stefan Holmerbbaf3632015-10-29 18:53:23 +01002872 const int kAbsSendTimeId = 1;
2873 const int kVideoRotationId = 2;
isheriff6f8d6862016-05-26 11:24:55 -07002874 send_parameters_.extensions.push_back(
2875 RtpExtension(RtpExtension::kAbsSendTimeUri, kAbsSendTimeId));
2876 send_parameters_.extensions.push_back(
2877 RtpExtension(RtpExtension::kVideoRotationUri, kVideoRotationId));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00002878
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002879 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00002880 FakeVideoSendStream* send_stream =
2881 AddSendStream(cricket::StreamParams::CreateLegacy(123));
2882
2883 EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());
Stefan Holmerbbaf3632015-10-29 18:53:23 +01002884 ASSERT_EQ(2u, send_stream->GetConfig().rtp.extensions.size());
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00002885
2886 // Setting the same extensions (even if in different order) shouldn't
2887 // reallocate the stream.
Steve Anton2c9ebef2019-01-28 17:27:58 -08002888 absl::c_reverse(send_parameters_.extensions);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002889 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00002890
2891 EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());
2892
2893 // Setting different extensions should recreate the stream.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002894 send_parameters_.extensions.resize(1);
2895 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00002896
2897 EXPECT_EQ(2, fake_call_->GetNumCreatedSendStreams());
2898}
2899
eladalonf1841382017-06-12 01:16:46 -07002900TEST_F(WebRtcVideoChannelTest, IdenticalRecvExtensionsDoesntRecreateStream) {
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00002901 const int kTOffsetId = 1;
2902 const int kAbsSendTimeId = 2;
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -07002903 const int kVideoRotationId = 3;
isheriff6f8d6862016-05-26 11:24:55 -07002904 recv_parameters_.extensions.push_back(
2905 RtpExtension(RtpExtension::kAbsSendTimeUri, kAbsSendTimeId));
2906 recv_parameters_.extensions.push_back(
2907 RtpExtension(RtpExtension::kTimestampOffsetUri, kTOffsetId));
2908 recv_parameters_.extensions.push_back(
2909 RtpExtension(RtpExtension::kVideoRotationUri, kVideoRotationId));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00002910
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002911 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
Peter Boström54be3e02015-05-25 15:04:24 +02002912 FakeVideoReceiveStream* recv_stream =
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00002913 AddRecvStream(cricket::StreamParams::CreateLegacy(123));
2914
2915 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
Peter Boström54be3e02015-05-25 15:04:24 +02002916 ASSERT_EQ(3u, recv_stream->GetConfig().rtp.extensions.size());
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00002917
2918 // Setting the same extensions (even if in different order) shouldn't
2919 // reallocate the stream.
Steve Anton2c9ebef2019-01-28 17:27:58 -08002920 absl::c_reverse(recv_parameters_.extensions);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002921 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00002922
2923 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
2924
2925 // Setting different extensions should recreate the stream.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002926 recv_parameters_.extensions.resize(1);
2927 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00002928
2929 EXPECT_EQ(2, fake_call_->GetNumCreatedReceiveStreams());
2930}
2931
eladalonf1841382017-06-12 01:16:46 -07002932TEST_F(WebRtcVideoChannelTest,
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002933 SetSendRtpHeaderExtensionsExcludeUnsupportedExtensions) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002934 const int kUnsupportedId = 1;
2935 const int kTOffsetId = 2;
2936
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002937 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002938 RtpExtension(kUnsupportedExtensionName, kUnsupportedId));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002939 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002940 RtpExtension(RtpExtension::kTimestampOffsetUri, kTOffsetId));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002941 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002942 FakeVideoSendStream* send_stream =
2943 AddSendStream(cricket::StreamParams::CreateLegacy(123));
2944
2945 // Only timestamp offset extension is set to send stream,
2946 // unsupported rtp extension is ignored.
2947 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
isheriff6f8d6862016-05-26 11:24:55 -07002948 EXPECT_STREQ(RtpExtension::kTimestampOffsetUri,
2949 send_stream->GetConfig().rtp.extensions[0].uri.c_str());
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002950}
2951
eladalonf1841382017-06-12 01:16:46 -07002952TEST_F(WebRtcVideoChannelTest,
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002953 SetRecvRtpHeaderExtensionsExcludeUnsupportedExtensions) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002954 const int kUnsupportedId = 1;
2955 const int kTOffsetId = 2;
2956
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002957 recv_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002958 RtpExtension(kUnsupportedExtensionName, kUnsupportedId));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002959 recv_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002960 RtpExtension(RtpExtension::kTimestampOffsetUri, kTOffsetId));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002961 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002962 FakeVideoReceiveStream* recv_stream =
2963 AddRecvStream(cricket::StreamParams::CreateLegacy(123));
2964
2965 // Only timestamp offset extension is set to receive stream,
2966 // unsupported rtp extension is ignored.
2967 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.extensions.size());
isheriff6f8d6862016-05-26 11:24:55 -07002968 EXPECT_STREQ(RtpExtension::kTimestampOffsetUri,
2969 recv_stream->GetConfig().rtp.extensions[0].uri.c_str());
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002970}
2971
eladalonf1841382017-06-12 01:16:46 -07002972TEST_F(WebRtcVideoChannelTest, SetSendRtpHeaderExtensionsRejectsIncorrectIds) {
Peter Boström23914fe2015-03-31 15:08:04 +02002973 const int kIncorrectIds[] = {-2, -1, 0, 15, 16};
pkasting@chromium.orge7a4a122015-01-28 21:36:55 +00002974 for (size_t i = 0; i < arraysize(kIncorrectIds); ++i) {
isheriff6f8d6862016-05-26 11:24:55 -07002975 send_parameters_.extensions.push_back(
2976 RtpExtension(RtpExtension::kTimestampOffsetUri, kIncorrectIds[i]));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002977 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_))
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002978 << "Bad extension id '" << kIncorrectIds[i] << "' accepted.";
2979 }
2980}
2981
eladalonf1841382017-06-12 01:16:46 -07002982TEST_F(WebRtcVideoChannelTest, SetRecvRtpHeaderExtensionsRejectsIncorrectIds) {
Peter Boström23914fe2015-03-31 15:08:04 +02002983 const int kIncorrectIds[] = {-2, -1, 0, 15, 16};
pkasting@chromium.orge7a4a122015-01-28 21:36:55 +00002984 for (size_t i = 0; i < arraysize(kIncorrectIds); ++i) {
isheriff6f8d6862016-05-26 11:24:55 -07002985 recv_parameters_.extensions.push_back(
2986 RtpExtension(RtpExtension::kTimestampOffsetUri, kIncorrectIds[i]));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002987 EXPECT_FALSE(channel_->SetRecvParameters(recv_parameters_))
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002988 << "Bad extension id '" << kIncorrectIds[i] << "' accepted.";
2989 }
2990}
2991
eladalonf1841382017-06-12 01:16:46 -07002992TEST_F(WebRtcVideoChannelTest, SetSendRtpHeaderExtensionsRejectsDuplicateIds) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002993 const int id = 1;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002994 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002995 RtpExtension(RtpExtension::kTimestampOffsetUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002996 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002997 RtpExtension(RtpExtension::kAbsSendTimeUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002998 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002999
3000 // Duplicate entries are also not supported.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003001 send_parameters_.extensions.clear();
3002 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07003003 RtpExtension(RtpExtension::kTimestampOffsetUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003004 send_parameters_.extensions.push_back(send_parameters_.extensions.back());
3005 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00003006}
3007
eladalonf1841382017-06-12 01:16:46 -07003008TEST_F(WebRtcVideoChannelTest, SetRecvRtpHeaderExtensionsRejectsDuplicateIds) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +00003009 const int id = 1;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003010 recv_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07003011 RtpExtension(RtpExtension::kTimestampOffsetUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003012 recv_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07003013 RtpExtension(RtpExtension::kAbsSendTimeUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003014 EXPECT_FALSE(channel_->SetRecvParameters(recv_parameters_));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00003015
3016 // Duplicate entries are also not supported.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003017 recv_parameters_.extensions.clear();
3018 recv_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07003019 RtpExtension(RtpExtension::kTimestampOffsetUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003020 recv_parameters_.extensions.push_back(recv_parameters_.extensions.back());
3021 EXPECT_FALSE(channel_->SetRecvParameters(recv_parameters_));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00003022}
3023
eladalonf1841382017-06-12 01:16:46 -07003024TEST_F(WebRtcVideoChannelTest, AddRecvStreamOnlyUsesOneReceiveStream) {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003025 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00003026 EXPECT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003027}
3028
eladalonf1841382017-06-12 01:16:46 -07003029TEST_F(WebRtcVideoChannelTest, RtcpIsCompoundByDefault) {
Peter Boströmd7da1202015-06-05 14:09:38 +02003030 FakeVideoReceiveStream* stream = AddRecvStream();
pbosda903ea2015-10-02 02:36:56 -07003031 EXPECT_EQ(webrtc::RtcpMode::kCompound, stream->GetConfig().rtp.rtcp_mode);
Peter Boströmd7da1202015-06-05 14:09:38 +02003032}
3033
eladalonf1841382017-06-12 01:16:46 -07003034TEST_F(WebRtcVideoChannelTest, TransportCcIsEnabledByDefault) {
stefan43edf0f2015-11-20 18:05:48 -08003035 FakeVideoReceiveStream* stream = AddRecvStream();
3036 EXPECT_TRUE(stream->GetConfig().rtp.transport_cc);
3037}
3038
eladalonf1841382017-06-12 01:16:46 -07003039TEST_F(WebRtcVideoChannelTest, TransportCcCanBeEnabledAndDisabled) {
stefan43edf0f2015-11-20 18:05:48 -08003040 FakeVideoReceiveStream* stream = AddRecvStream();
3041 EXPECT_TRUE(stream->GetConfig().rtp.transport_cc);
3042
3043 // Verify that transport cc feedback is turned off when send(!) codecs without
3044 // transport cc feedback are set.
3045 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08003046 parameters.codecs.push_back(RemoveFeedbackParams(GetEngineCodec("VP8")));
stefan43edf0f2015-11-20 18:05:48 -08003047 EXPECT_TRUE(parameters.codecs[0].feedback_params.params().empty());
3048 EXPECT_TRUE(channel_->SetSendParameters(parameters));
3049 stream = fake_call_->GetVideoReceiveStreams()[0];
3050 EXPECT_FALSE(stream->GetConfig().rtp.transport_cc);
3051
3052 // Verify that transport cc feedback is turned on when setting default codecs
3053 // since the default codecs have transport cc feedback enabled.
Johannes Kron3e983682020-03-29 22:17:00 +02003054 parameters.codecs = engine_.send_codecs();
stefan43edf0f2015-11-20 18:05:48 -08003055 EXPECT_TRUE(channel_->SetSendParameters(parameters));
3056 stream = fake_call_->GetVideoReceiveStreams()[0];
3057 EXPECT_TRUE(stream->GetConfig().rtp.transport_cc);
3058}
3059
Elad Alonfadb1812019-05-24 13:40:02 +02003060TEST_F(WebRtcVideoChannelTest, LossNotificationIsDisabledByDefault) {
3061 TestLossNotificationState(false);
3062}
3063
3064TEST_F(WebRtcVideoChannelTest, LossNotificationIsEnabledByFieldTrial) {
3065 RTC_DCHECK(!override_field_trials_);
Mirko Bonadei317a1f02019-09-17 17:06:18 +02003066 override_field_trials_ = std::make_unique<webrtc::test::ScopedFieldTrials>(
Elad Alonfadb1812019-05-24 13:40:02 +02003067 "WebRTC-RtcpLossNotification/Enabled/");
3068 SetUp();
3069 TestLossNotificationState(true);
3070}
3071
3072TEST_F(WebRtcVideoChannelTest, LossNotificationCanBeEnabledAndDisabled) {
3073 RTC_DCHECK(!override_field_trials_);
Mirko Bonadei317a1f02019-09-17 17:06:18 +02003074 override_field_trials_ = std::make_unique<webrtc::test::ScopedFieldTrials>(
Elad Alonfadb1812019-05-24 13:40:02 +02003075 "WebRTC-RtcpLossNotification/Enabled/");
3076 SetUp();
3077
3078 AssignDefaultCodec();
3079 VerifyCodecHasDefaultFeedbackParams(default_codec_, true);
3080
3081 {
3082 cricket::VideoSendParameters parameters;
Johannes Kron3e983682020-03-29 22:17:00 +02003083 parameters.codecs = engine_.send_codecs();
Elad Alonfadb1812019-05-24 13:40:02 +02003084 EXPECT_TRUE(channel_->SetSendParameters(parameters));
3085 EXPECT_TRUE(channel_->SetSend(true));
3086 }
3087
3088 // Start with LNTF enabled.
3089 FakeVideoSendStream* send_stream =
3090 AddSendStream(cricket::StreamParams::CreateLegacy(1));
3091 ASSERT_TRUE(send_stream->GetConfig().rtp.lntf.enabled);
3092 FakeVideoReceiveStream* recv_stream =
3093 AddRecvStream(cricket::StreamParams::CreateLegacy(1));
3094 ASSERT_TRUE(recv_stream->GetConfig().rtp.lntf.enabled);
3095
3096 // Verify that LNTF is turned off when send(!) codecs without LNTF are set.
3097 cricket::VideoSendParameters parameters;
3098 parameters.codecs.push_back(RemoveFeedbackParams(GetEngineCodec("VP8")));
3099 EXPECT_TRUE(parameters.codecs[0].feedback_params.params().empty());
3100 EXPECT_TRUE(channel_->SetSendParameters(parameters));
3101 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
3102 EXPECT_FALSE(recv_stream->GetConfig().rtp.lntf.enabled);
3103 send_stream = fake_call_->GetVideoSendStreams()[0];
3104 EXPECT_FALSE(send_stream->GetConfig().rtp.lntf.enabled);
3105
3106 // Setting the default codecs again, including VP8, turns LNTF back on.
Johannes Kron3e983682020-03-29 22:17:00 +02003107 parameters.codecs = engine_.send_codecs();
Elad Alonfadb1812019-05-24 13:40:02 +02003108 EXPECT_TRUE(channel_->SetSendParameters(parameters));
3109 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
3110 EXPECT_TRUE(recv_stream->GetConfig().rtp.lntf.enabled);
3111 send_stream = fake_call_->GetVideoSendStreams()[0];
3112 EXPECT_TRUE(send_stream->GetConfig().rtp.lntf.enabled);
3113}
3114
eladalonf1841382017-06-12 01:16:46 -07003115TEST_F(WebRtcVideoChannelTest, NackIsEnabledByDefault) {
Anders Carlsson5f2bb622018-05-14 09:48:06 +02003116 AssignDefaultCodec();
Elad Alonfadb1812019-05-24 13:40:02 +02003117 VerifyCodecHasDefaultFeedbackParams(default_codec_, false);
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +00003118
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003119 cricket::VideoSendParameters parameters;
Johannes Kron3e983682020-03-29 22:17:00 +02003120 parameters.codecs = engine_.send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003121 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org19864742014-05-30 07:35:47 +00003122 EXPECT_TRUE(channel_->SetSend(true));
3123
3124 // Send side.
3125 FakeVideoSendStream* send_stream =
3126 AddSendStream(cricket::StreamParams::CreateLegacy(1));
3127 EXPECT_GT(send_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
3128
3129 // Receiver side.
3130 FakeVideoReceiveStream* recv_stream =
3131 AddRecvStream(cricket::StreamParams::CreateLegacy(1));
3132 EXPECT_GT(recv_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
3133
3134 // Nack history size should match between sender and receiver.
3135 EXPECT_EQ(send_stream->GetConfig().rtp.nack.rtp_history_ms,
3136 recv_stream->GetConfig().rtp.nack.rtp_history_ms);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003137}
3138
eladalonf1841382017-06-12 01:16:46 -07003139TEST_F(WebRtcVideoChannelTest, NackCanBeEnabledAndDisabled) {
Peter Boström67c9df72015-05-11 14:34:58 +02003140 FakeVideoSendStream* send_stream = AddSendStream();
Peter Boström3548dd22015-05-22 18:48:36 +02003141 FakeVideoReceiveStream* recv_stream = AddRecvStream();
Peter Boström67c9df72015-05-11 14:34:58 +02003142
3143 EXPECT_GT(recv_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
3144 EXPECT_GT(send_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
3145
3146 // Verify that NACK is turned off when send(!) codecs without NACK are set.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003147 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08003148 parameters.codecs.push_back(RemoveFeedbackParams(GetEngineCodec("VP8")));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003149 EXPECT_TRUE(parameters.codecs[0].feedback_params.params().empty());
3150 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Peter Boström67c9df72015-05-11 14:34:58 +02003151 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
3152 EXPECT_EQ(0, recv_stream->GetConfig().rtp.nack.rtp_history_ms);
3153 send_stream = fake_call_->GetVideoSendStreams()[0];
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +00003154 EXPECT_EQ(0, send_stream->GetConfig().rtp.nack.rtp_history_ms);
3155
Peter Boström67c9df72015-05-11 14:34:58 +02003156 // Verify that NACK is turned on when setting default codecs since the
3157 // default codecs have NACK enabled.
Johannes Kron3e983682020-03-29 22:17:00 +02003158 parameters.codecs = engine_.send_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003159 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Peter Boström67c9df72015-05-11 14:34:58 +02003160 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
3161 EXPECT_GT(recv_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
3162 send_stream = fake_call_->GetVideoSendStreams()[0];
3163 EXPECT_GT(send_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +00003164}
3165
Peter Boströme7ba0862016-03-12 00:02:28 +01003166// This test verifies that new frame sizes reconfigures encoders even though not
3167// (yet) sending. The purpose of this is to permit encoding as quickly as
3168// possible once we start sending. Likely the frames being input are from the
3169// same source that will be sent later, which just means that we're ready
3170// earlier.
eladalonf1841382017-06-12 01:16:46 -07003171TEST_F(WebRtcVideoChannelTest, ReconfiguresEncodersWhenNotSending) {
Peter Boströme7ba0862016-03-12 00:02:28 +01003172 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08003173 parameters.codecs.push_back(GetEngineCodec("VP8"));
Peter Boströme7ba0862016-03-12 00:02:28 +01003174 ASSERT_TRUE(channel_->SetSendParameters(parameters));
3175 channel_->SetSend(false);
3176
3177 FakeVideoSendStream* stream = AddSendStream();
3178
perkjfa10b552016-10-02 23:45:26 -07003179 // No frames entered.
Peter Boströme7ba0862016-03-12 00:02:28 +01003180 std::vector<webrtc::VideoStream> streams = stream->GetVideoStreams();
Danil Chapovalov350531e2018-06-08 11:04:04 +00003181 EXPECT_EQ(0u, streams[0].width);
3182 EXPECT_EQ(0u, streams[0].height);
Peter Boströme7ba0862016-03-12 00:02:28 +01003183
Niels Möller805a27e2019-01-21 12:21:27 +01003184 webrtc::test::FrameForwarder frame_forwarder;
3185 cricket::FakeFrameSource frame_source(1280, 720,
3186 rtc::kNumMicrosecsPerSec / 30);
3187
3188 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));
3189 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
Peter Boströme7ba0862016-03-12 00:02:28 +01003190
3191 // Frame entered, should be reconfigured to new dimensions.
3192 streams = stream->GetVideoStreams();
Niels Möller805a27e2019-01-21 12:21:27 +01003193 EXPECT_EQ(rtc::checked_cast<size_t>(1280), streams[0].width);
3194 EXPECT_EQ(rtc::checked_cast<size_t>(720), streams[0].height);
Peter Boströme7ba0862016-03-12 00:02:28 +01003195
Niels Möllerff40b142018-04-09 08:49:14 +02003196 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
Peter Boströme7ba0862016-03-12 00:02:28 +01003197}
3198
eladalonf1841382017-06-12 01:16:46 -07003199TEST_F(WebRtcVideoChannelTest, UsesCorrectSettingsForScreencast) {
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00003200 static const int kScreenshareMinBitrateKbps = 800;
magjed509e4fe2016-11-18 01:34:11 -08003201 cricket::VideoCodec codec = GetEngineCodec("VP8");
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003202 cricket::VideoSendParameters parameters;
3203 parameters.codecs.push_back(codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003204 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00003205 AddSendStream();
3206
Niels Möller805a27e2019-01-21 12:21:27 +01003207 webrtc::test::FrameForwarder frame_forwarder;
3208 cricket::FakeFrameSource frame_source(1280, 720,
3209 rtc::kNumMicrosecsPerSec / 30);
nisse05103312016-03-16 02:22:50 -07003210 VideoOptions min_bitrate_options;
Oskar Sundbom78807582017-11-16 11:09:55 +01003211 min_bitrate_options.screencast_min_bitrate_kbps = kScreenshareMinBitrateKbps;
Niels Möller805a27e2019-01-21 12:21:27 +01003212 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &min_bitrate_options,
3213 &frame_forwarder));
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00003214
3215 EXPECT_TRUE(channel_->SetSend(true));
3216
Niels Möller805a27e2019-01-21 12:21:27 +01003217 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00003218 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
3219 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
3220
3221 EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());
3222
3223 // Verify non-screencast settings.
perkj26091b12016-09-01 01:17:40 -07003224 webrtc::VideoEncoderConfig encoder_config =
3225 send_stream->GetEncoderConfig().Copy();
Erik Språng143cec12015-04-28 10:01:41 +02003226 EXPECT_EQ(webrtc::VideoEncoderConfig::ContentType::kRealtimeVideo,
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00003227 encoder_config.content_type);
perkjfa10b552016-10-02 23:45:26 -07003228 std::vector<webrtc::VideoStream> streams = send_stream->GetVideoStreams();
Niels Möller805a27e2019-01-21 12:21:27 +01003229 EXPECT_EQ(rtc::checked_cast<size_t>(1280), streams.front().width);
3230 EXPECT_EQ(rtc::checked_cast<size_t>(720), streams.front().height);
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00003231 EXPECT_EQ(0, encoder_config.min_transmit_bitrate_bps)
3232 << "Non-screenshare shouldn't use min-transmit bitrate.";
3233
Niels Möllerff40b142018-04-09 08:49:14 +02003234 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
perkjd533aec2017-01-13 05:57:25 -08003235 EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());
nisse05103312016-03-16 02:22:50 -07003236 VideoOptions screencast_options;
Oskar Sundbom78807582017-11-16 11:09:55 +01003237 screencast_options.is_screencast = true;
Niels Möller805a27e2019-01-21 12:21:27 +01003238 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &screencast_options,
3239 &frame_forwarder));
3240 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
sprangf24a0642017-02-28 13:23:26 -08003241 // Send stream recreated after option change.
3242 ASSERT_EQ(2, fake_call_->GetNumCreatedSendStreams());
3243 send_stream = fake_call_->GetVideoSendStreams().front();
3244 EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00003245
3246 // Verify screencast settings.
perkj26091b12016-09-01 01:17:40 -07003247 encoder_config = send_stream->GetEncoderConfig().Copy();
Erik Språng143cec12015-04-28 10:01:41 +02003248 EXPECT_EQ(webrtc::VideoEncoderConfig::ContentType::kScreen,
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00003249 encoder_config.content_type);
3250 EXPECT_EQ(kScreenshareMinBitrateKbps * 1000,
3251 encoder_config.min_transmit_bitrate_bps);
3252
perkjfa10b552016-10-02 23:45:26 -07003253 streams = send_stream->GetVideoStreams();
Niels Möller805a27e2019-01-21 12:21:27 +01003254 EXPECT_EQ(rtc::checked_cast<size_t>(1280), streams.front().width);
3255 EXPECT_EQ(rtc::checked_cast<size_t>(720), streams.front().height);
Sergey Silkina796a7e2018-03-01 15:11:29 +01003256 EXPECT_FALSE(streams[0].num_temporal_layers.has_value());
Niels Möllerff40b142018-04-09 08:49:14 +02003257 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00003258}
3259
eladalonf1841382017-06-12 01:16:46 -07003260TEST_F(WebRtcVideoChannelTest,
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00003261 ConferenceModeScreencastConfiguresTemporalLayer) {
Rasmus Brandt195d1d72018-05-09 11:28:01 +02003262 static const int kConferenceScreencastTemporalBitrateBps = 200 * 1000;
nisse4b4dc862016-02-17 05:25:36 -08003263 send_parameters_.conference_mode = true;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003264 channel_->SetSendParameters(send_parameters_);
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00003265
3266 AddSendStream();
nisse05103312016-03-16 02:22:50 -07003267 VideoOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01003268 options.is_screencast = true;
Niels Möller805a27e2019-01-21 12:21:27 +01003269 webrtc::test::FrameForwarder frame_forwarder;
3270 cricket::FakeFrameSource frame_source(1280, 720,
3271 rtc::kNumMicrosecsPerSec / 30);
3272 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00003273 EXPECT_TRUE(channel_->SetSend(true));
3274
Niels Möller805a27e2019-01-21 12:21:27 +01003275 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00003276 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
3277 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
3278
perkj26091b12016-09-01 01:17:40 -07003279 webrtc::VideoEncoderConfig encoder_config =
3280 send_stream->GetEncoderConfig().Copy();
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00003281
3282 // Verify screencast settings.
perkj26091b12016-09-01 01:17:40 -07003283 encoder_config = send_stream->GetEncoderConfig().Copy();
Erik Språng143cec12015-04-28 10:01:41 +02003284 EXPECT_EQ(webrtc::VideoEncoderConfig::ContentType::kScreen,
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00003285 encoder_config.content_type);
perkjfa10b552016-10-02 23:45:26 -07003286
3287 std::vector<webrtc::VideoStream> streams = send_stream->GetVideoStreams();
3288 ASSERT_EQ(1u, streams.size());
Sergey Silkina796a7e2018-03-01 15:11:29 +01003289 ASSERT_EQ(2u, streams[0].num_temporal_layers);
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00003290 EXPECT_EQ(kConferenceScreencastTemporalBitrateBps,
Sergey Silkina796a7e2018-03-01 15:11:29 +01003291 streams[0].target_bitrate_bps);
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00003292
Niels Möllerff40b142018-04-09 08:49:14 +02003293 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003294}
3295
eladalonf1841382017-06-12 01:16:46 -07003296TEST_F(WebRtcVideoChannelTest, SuspendBelowMinBitrateDisabledByDefault) {
pbos@webrtc.org5ff71ab2014-07-23 07:28:56 +00003297 FakeVideoSendStream* stream = AddSendStream();
3298 EXPECT_FALSE(stream->GetConfig().suspend_below_min_bitrate);
3299}
3300
eladalonf1841382017-06-12 01:16:46 -07003301TEST_F(WebRtcVideoChannelTest, SetMediaConfigSuspendBelowMinBitrate) {
kthelgason2bc68642017-02-07 07:02:22 -08003302 MediaConfig media_config = GetMediaConfig();
nisse0db023a2016-03-01 04:29:59 -08003303 media_config.video.suspend_below_min_bitrate = true;
3304
Sebastian Jansson84848f22018-11-16 10:40:36 +01003305 channel_.reset(engine_.CreateMediaChannel(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02003306 fake_call_.get(), media_config, VideoOptions(), webrtc::CryptoOptions(),
3307 video_bitrate_allocator_factory_.get()));
Sergey Ulanove2b15012016-11-22 16:08:30 -08003308 channel_->OnReadyToSend(true);
nisse0db023a2016-03-01 04:29:59 -08003309
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003310 channel_->SetSendParameters(send_parameters_);
pbos@webrtc.org5ff71ab2014-07-23 07:28:56 +00003311
3312 FakeVideoSendStream* stream = AddSendStream();
3313 EXPECT_TRUE(stream->GetConfig().suspend_below_min_bitrate);
3314
nisse0db023a2016-03-01 04:29:59 -08003315 media_config.video.suspend_below_min_bitrate = false;
Sebastian Jansson84848f22018-11-16 10:40:36 +01003316 channel_.reset(engine_.CreateMediaChannel(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02003317 fake_call_.get(), media_config, VideoOptions(), webrtc::CryptoOptions(),
3318 video_bitrate_allocator_factory_.get()));
Sergey Ulanove2b15012016-11-22 16:08:30 -08003319 channel_->OnReadyToSend(true);
nisse0db023a2016-03-01 04:29:59 -08003320
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003321 channel_->SetSendParameters(send_parameters_);
pbos@webrtc.org5ff71ab2014-07-23 07:28:56 +00003322
nisse0db023a2016-03-01 04:29:59 -08003323 stream = AddSendStream();
pbos@webrtc.org5ff71ab2014-07-23 07:28:56 +00003324 EXPECT_FALSE(stream->GetConfig().suspend_below_min_bitrate);
3325}
3326
eladalonf1841382017-06-12 01:16:46 -07003327TEST_F(WebRtcVideoChannelTest, Vp8DenoisingEnabledByDefault) {
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00003328 FakeVideoSendStream* stream = AddSendStream();
3329 webrtc::VideoCodecVP8 vp8_settings;
3330 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
3331 EXPECT_TRUE(vp8_settings.denoisingOn);
3332}
3333
eladalonf1841382017-06-12 01:16:46 -07003334TEST_F(WebRtcVideoChannelTest, VerifyVp8SpecificSettings) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003335 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08003336 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003337 ASSERT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00003338
Peter Boström2feafdb2015-09-09 14:32:14 +02003339 // Single-stream settings should apply with RTX as well (verifies that we
3340 // check number of regular SSRCs and not StreamParams::ssrcs which contains
3341 // both RTX and regular SSRCs).
3342 FakeVideoSendStream* stream = SetUpSimulcast(false, true);
Erik Språng143cec12015-04-28 10:01:41 +02003343
Niels Möller805a27e2019-01-21 12:21:27 +01003344 webrtc::test::FrameForwarder frame_forwarder;
3345 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));
Erik Språng143cec12015-04-28 10:01:41 +02003346 channel_->SetSend(true);
3347
Niels Möller805a27e2019-01-21 12:21:27 +01003348 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Erik Språng143cec12015-04-28 10:01:41 +02003349
pbos4cba4eb2015-10-26 11:18:18 -07003350 webrtc::VideoCodecVP8 vp8_settings;
3351 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
3352 EXPECT_TRUE(vp8_settings.denoisingOn)
3353 << "VP8 denoising should be on by default.";
3354
Niels Möller805a27e2019-01-21 12:21:27 +01003355 stream = SetDenoisingOption(last_ssrc_, &frame_forwarder, false);
Erik Språng143cec12015-04-28 10:01:41 +02003356
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00003357 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
3358 EXPECT_FALSE(vp8_settings.denoisingOn);
Erik Språng143cec12015-04-28 10:01:41 +02003359 EXPECT_TRUE(vp8_settings.automaticResizeOn);
3360 EXPECT_TRUE(vp8_settings.frameDroppingOn);
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00003361
Niels Möller805a27e2019-01-21 12:21:27 +01003362 stream = SetDenoisingOption(last_ssrc_, &frame_forwarder, true);
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00003363
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00003364 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
3365 EXPECT_TRUE(vp8_settings.denoisingOn);
Erik Språng143cec12015-04-28 10:01:41 +02003366 EXPECT_TRUE(vp8_settings.automaticResizeOn);
3367 EXPECT_TRUE(vp8_settings.frameDroppingOn);
3368
Niels Möllerff40b142018-04-09 08:49:14 +02003369 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
Peter Boström2feafdb2015-09-09 14:32:14 +02003370 stream = SetUpSimulcast(true, false);
Niels Möller805a27e2019-01-21 12:21:27 +01003371 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));
Erik Språng143cec12015-04-28 10:01:41 +02003372 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01003373 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Erik Språng143cec12015-04-28 10:01:41 +02003374
Mirko Bonadeif859e552018-05-30 15:31:29 +02003375 EXPECT_EQ(3u, stream->GetVideoStreams().size());
Erik Språng143cec12015-04-28 10:01:41 +02003376 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
3377 // Autmatic resize off when using simulcast.
3378 EXPECT_FALSE(vp8_settings.automaticResizeOn);
3379 EXPECT_TRUE(vp8_settings.frameDroppingOn);
3380
Florent Castelli66b38602019-07-10 16:57:57 +02003381 // In screen-share mode, denoising is forced off.
nisse05103312016-03-16 02:22:50 -07003382 VideoOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01003383 options.is_screencast = true;
Niels Möller805a27e2019-01-21 12:21:27 +01003384 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
Niels Möller60653ba2016-03-02 11:41:36 +01003385
Niels Möller805a27e2019-01-21 12:21:27 +01003386 stream = SetDenoisingOption(last_ssrc_, &frame_forwarder, false);
Erik Språng143cec12015-04-28 10:01:41 +02003387
Florent Castelli66b38602019-07-10 16:57:57 +02003388 EXPECT_EQ(3u, stream->GetVideoStreams().size());
Erik Språng143cec12015-04-28 10:01:41 +02003389 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
3390 EXPECT_FALSE(vp8_settings.denoisingOn);
3391 // Resizing and frame dropping always off for screen sharing.
3392 EXPECT_FALSE(vp8_settings.automaticResizeOn);
3393 EXPECT_FALSE(vp8_settings.frameDroppingOn);
3394
Niels Möller805a27e2019-01-21 12:21:27 +01003395 stream = SetDenoisingOption(last_ssrc_, &frame_forwarder, true);
Erik Språng143cec12015-04-28 10:01:41 +02003396
3397 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
3398 EXPECT_FALSE(vp8_settings.denoisingOn);
3399 EXPECT_FALSE(vp8_settings.automaticResizeOn);
3400 EXPECT_FALSE(vp8_settings.frameDroppingOn);
3401
Niels Möllerff40b142018-04-09 08:49:14 +02003402 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
Erik Språng143cec12015-04-28 10:01:41 +02003403}
3404
deadbeef119760a2016-04-04 11:43:27 -07003405// Test that setting the same options doesn't result in the encoder being
3406// reconfigured.
eladalonf1841382017-06-12 01:16:46 -07003407TEST_F(WebRtcVideoChannelTest, SetIdenticalOptionsDoesntReconfigureEncoder) {
deadbeef119760a2016-04-04 11:43:27 -07003408 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01003409 webrtc::test::FrameForwarder frame_forwarder;
deadbeef119760a2016-04-04 11:43:27 -07003410
perkjfa10b552016-10-02 23:45:26 -07003411 AddSendStream();
perkjfa10b552016-10-02 23:45:26 -07003412 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08003413 parameters.codecs.push_back(GetEngineCodec("VP8"));
perkjfa10b552016-10-02 23:45:26 -07003414 ASSERT_TRUE(channel_->SetSendParameters(parameters));
3415 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
3416
Niels Möller805a27e2019-01-21 12:21:27 +01003417 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
3418 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
3419 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
perkjfa10b552016-10-02 23:45:26 -07003420 // Expect 1 reconfigurations at this point from the initial configuration.
3421 EXPECT_EQ(1, send_stream->num_encoder_reconfigurations());
deadbeef119760a2016-04-04 11:43:27 -07003422
3423 // Set the options one more time and expect no additional reconfigurations.
Niels Möller805a27e2019-01-21 12:21:27 +01003424 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
perkjfa10b552016-10-02 23:45:26 -07003425 EXPECT_EQ(1, send_stream->num_encoder_reconfigurations());
3426
3427 // Change |options| and expect 2 reconfigurations.
Oskar Sundbom78807582017-11-16 11:09:55 +01003428 options.video_noise_reduction = true;
Niels Möller805a27e2019-01-21 12:21:27 +01003429 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
deadbeef119760a2016-04-04 11:43:27 -07003430 EXPECT_EQ(2, send_stream->num_encoder_reconfigurations());
3431
Niels Möllerff40b142018-04-09 08:49:14 +02003432 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
deadbeef119760a2016-04-04 11:43:27 -07003433}
3434
eladalonf1841382017-06-12 01:16:46 -07003435class Vp9SettingsTest : public WebRtcVideoChannelTest {
Erik Språng143cec12015-04-28 10:01:41 +02003436 public:
asaperssonc5dabdd2016-03-21 04:15:50 -07003437 Vp9SettingsTest() : Vp9SettingsTest("") {}
3438 explicit Vp9SettingsTest(const char* field_trials)
eladalonf1841382017-06-12 01:16:46 -07003439 : WebRtcVideoChannelTest(field_trials) {
Magnus Jedvert02e7a192017-09-23 17:21:32 +02003440 encoder_factory_->AddSupportedVideoCodecType("VP9");
Erik Språng143cec12015-04-28 10:01:41 +02003441 }
3442 virtual ~Vp9SettingsTest() {}
3443
3444 protected:
Erik Språng143cec12015-04-28 10:01:41 +02003445 void TearDown() override {
3446 // Remove references to encoder_factory_ since this will be destroyed
3447 // before channel_ and engine_.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003448 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
Erik Språng143cec12015-04-28 10:01:41 +02003449 }
Erik Språng143cec12015-04-28 10:01:41 +02003450};
3451
3452TEST_F(Vp9SettingsTest, VerifyVp9SpecificSettings) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003453 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08003454 parameters.codecs.push_back(GetEngineCodec("VP9"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003455 ASSERT_TRUE(channel_->SetSendParameters(parameters));
Erik Språng143cec12015-04-28 10:01:41 +02003456
Peter Boström2feafdb2015-09-09 14:32:14 +02003457 FakeVideoSendStream* stream = SetUpSimulcast(false, false);
Erik Språng143cec12015-04-28 10:01:41 +02003458
Niels Möller805a27e2019-01-21 12:21:27 +01003459 webrtc::test::FrameForwarder frame_forwarder;
3460 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));
Erik Språng143cec12015-04-28 10:01:41 +02003461 channel_->SetSend(true);
3462
Niels Möller805a27e2019-01-21 12:21:27 +01003463 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Erik Språng143cec12015-04-28 10:01:41 +02003464
pbos4cba4eb2015-10-26 11:18:18 -07003465 webrtc::VideoCodecVP9 vp9_settings;
3466 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
jianja5e8aa62017-03-27 10:09:00 -07003467 EXPECT_TRUE(vp9_settings.denoisingOn)
3468 << "VP9 denoising should be on by default.";
pbos4cba4eb2015-10-26 11:18:18 -07003469
Niels Möller805a27e2019-01-21 12:21:27 +01003470 stream = SetDenoisingOption(last_ssrc_, &frame_forwarder, false);
Erik Språng143cec12015-04-28 10:01:41 +02003471
Erik Språng143cec12015-04-28 10:01:41 +02003472 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
3473 EXPECT_FALSE(vp9_settings.denoisingOn);
3474 // Frame dropping always on for real time video.
3475 EXPECT_TRUE(vp9_settings.frameDroppingOn);
3476
Niels Möller805a27e2019-01-21 12:21:27 +01003477 stream = SetDenoisingOption(last_ssrc_, &frame_forwarder, true);
Erik Språng143cec12015-04-28 10:01:41 +02003478
3479 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
3480 EXPECT_TRUE(vp9_settings.denoisingOn);
3481 EXPECT_TRUE(vp9_settings.frameDroppingOn);
3482
3483 // In screen-share mode, denoising is forced off.
nisse05103312016-03-16 02:22:50 -07003484 VideoOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01003485 options.is_screencast = true;
Niels Möller805a27e2019-01-21 12:21:27 +01003486 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
perkj2d5f0912016-02-29 00:04:41 -08003487
Niels Möller805a27e2019-01-21 12:21:27 +01003488 stream = SetDenoisingOption(last_ssrc_, &frame_forwarder, false);
Erik Språng143cec12015-04-28 10:01:41 +02003489
3490 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
3491 EXPECT_FALSE(vp9_settings.denoisingOn);
Sergey Silkinbe71a1e2018-05-17 16:46:43 +02003492 // Frame dropping always on for screen sharing.
3493 EXPECT_TRUE(vp9_settings.frameDroppingOn);
Erik Språng143cec12015-04-28 10:01:41 +02003494
Niels Möller805a27e2019-01-21 12:21:27 +01003495 stream = SetDenoisingOption(last_ssrc_, &frame_forwarder, false);
Erik Språng143cec12015-04-28 10:01:41 +02003496
3497 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
3498 EXPECT_FALSE(vp9_settings.denoisingOn);
Sergey Silkinbe71a1e2018-05-17 16:46:43 +02003499 EXPECT_TRUE(vp9_settings.frameDroppingOn);
Erik Språng143cec12015-04-28 10:01:41 +02003500
Niels Möllerff40b142018-04-09 08:49:14 +02003501 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003502}
3503
Sergey Silkinf18072e2018-03-14 10:35:35 +01003504TEST_F(Vp9SettingsTest, MultipleSsrcsEnablesSvc) {
3505 cricket::VideoSendParameters parameters;
3506 parameters.codecs.push_back(GetEngineCodec("VP9"));
3507 ASSERT_TRUE(channel_->SetSendParameters(parameters));
3508
3509 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
3510
3511 FakeVideoSendStream* stream =
3512 AddSendStream(CreateSimStreamParams("cname", ssrcs));
3513
3514 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
Sergey Silkinf18072e2018-03-14 10:35:35 +01003515
Niels Möller805a27e2019-01-21 12:21:27 +01003516 webrtc::test::FrameForwarder frame_forwarder;
3517 EXPECT_TRUE(channel_->SetVideoSend(ssrcs[0], nullptr, &frame_forwarder));
Sergey Silkinf18072e2018-03-14 10:35:35 +01003518 channel_->SetSend(true);
3519
Niels Möller805a27e2019-01-21 12:21:27 +01003520 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Sergey Silkinf18072e2018-03-14 10:35:35 +01003521
3522 webrtc::VideoCodecVP9 vp9_settings;
3523 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
3524
3525 const size_t kNumSpatialLayers = ssrcs.size();
3526 const size_t kNumTemporalLayers = 3;
3527 EXPECT_EQ(vp9_settings.numberOfSpatialLayers, kNumSpatialLayers);
3528 EXPECT_EQ(vp9_settings.numberOfTemporalLayers, kNumTemporalLayers);
3529
Niels Möllerff40b142018-04-09 08:49:14 +02003530 EXPECT_TRUE(channel_->SetVideoSend(ssrcs[0], nullptr, nullptr));
Sergey Silkinf18072e2018-03-14 10:35:35 +01003531}
3532
Ilya Nikolaevskiy33d2a912019-04-02 11:05:03 +02003533TEST_F(Vp9SettingsTest, SvcModeCreatesSingleRtpStream) {
3534 cricket::VideoSendParameters parameters;
3535 parameters.codecs.push_back(GetEngineCodec("VP9"));
3536 ASSERT_TRUE(channel_->SetSendParameters(parameters));
3537
3538 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
3539
3540 FakeVideoSendStream* stream =
3541 AddSendStream(CreateSimStreamParams("cname", ssrcs));
3542
3543 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
3544
3545 // Despite 3 ssrcs provided, single layer is used.
3546 EXPECT_EQ(1u, config.rtp.ssrcs.size());
3547
3548 webrtc::test::FrameForwarder frame_forwarder;
3549 EXPECT_TRUE(channel_->SetVideoSend(ssrcs[0], nullptr, &frame_forwarder));
3550 channel_->SetSend(true);
3551
3552 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
3553
3554 webrtc::VideoCodecVP9 vp9_settings;
3555 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
3556
3557 const size_t kNumSpatialLayers = ssrcs.size();
3558 EXPECT_EQ(vp9_settings.numberOfSpatialLayers, kNumSpatialLayers);
3559
3560 EXPECT_TRUE(channel_->SetVideoSend(ssrcs[0], nullptr, nullptr));
3561}
3562
Sergey Silkin8b9b5f92018-12-10 09:28:53 +01003563TEST_F(Vp9SettingsTest, AllEncodingParametersCopied) {
3564 cricket::VideoSendParameters send_parameters;
3565 send_parameters.codecs.push_back(GetEngineCodec("VP9"));
3566 ASSERT_TRUE(channel_->SetSendParameters(send_parameters));
3567
3568 const size_t kNumSpatialLayers = 3;
3569 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
3570
3571 FakeVideoSendStream* stream =
3572 AddSendStream(CreateSimStreamParams("cname", ssrcs));
3573
3574 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(ssrcs[0]);
3575 ASSERT_EQ(kNumSpatialLayers, parameters.encodings.size());
3576 ASSERT_TRUE(parameters.encodings[0].active);
3577 ASSERT_TRUE(parameters.encodings[1].active);
3578 ASSERT_TRUE(parameters.encodings[2].active);
3579 // Invert value to verify copying.
3580 parameters.encodings[1].active = false;
3581 EXPECT_TRUE(channel_->SetRtpSendParameters(ssrcs[0], parameters).ok());
3582
3583 webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
3584
3585 // number_of_streams should be 1 since all spatial layers are sent on the
3586 // same SSRC. But encoding parameters of all layers is supposed to be copied
3587 // and stored in simulcast_layers[].
3588 EXPECT_EQ(1u, encoder_config.number_of_streams);
3589 EXPECT_EQ(encoder_config.simulcast_layers.size(), kNumSpatialLayers);
3590 EXPECT_TRUE(encoder_config.simulcast_layers[0].active);
3591 EXPECT_FALSE(encoder_config.simulcast_layers[1].active);
3592 EXPECT_TRUE(encoder_config.simulcast_layers[2].active);
3593}
3594
Sergey Silkincf267052019-04-09 11:40:09 +02003595class Vp9SettingsTestWithFieldTrial
3596 : public Vp9SettingsTest,
3597 public ::testing::WithParamInterface<
3598 ::testing::tuple<const char*, int, int, webrtc::InterLayerPredMode>> {
asaperssonc5dabdd2016-03-21 04:15:50 -07003599 protected:
Sergey Silkincf267052019-04-09 11:40:09 +02003600 Vp9SettingsTestWithFieldTrial()
3601 : Vp9SettingsTest(::testing::get<0>(GetParam())),
3602 num_spatial_layers_(::testing::get<1>(GetParam())),
3603 num_temporal_layers_(::testing::get<2>(GetParam())),
Sergey Silkin19da5ce2019-05-20 17:57:17 +02003604 inter_layer_pred_mode_(::testing::get<3>(GetParam())) {}
Sergey Silkincf267052019-04-09 11:40:09 +02003605
3606 void VerifySettings(int num_spatial_layers,
3607 int num_temporal_layers,
3608 webrtc::InterLayerPredMode interLayerPred) {
asaperssonc5dabdd2016-03-21 04:15:50 -07003609 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08003610 parameters.codecs.push_back(GetEngineCodec("VP9"));
asaperssonc5dabdd2016-03-21 04:15:50 -07003611 ASSERT_TRUE(channel_->SetSendParameters(parameters));
3612
3613 FakeVideoSendStream* stream = SetUpSimulcast(false, false);
3614
Niels Möller805a27e2019-01-21 12:21:27 +01003615 webrtc::test::FrameForwarder frame_forwarder;
3616 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));
asaperssonc5dabdd2016-03-21 04:15:50 -07003617 channel_->SetSend(true);
3618
Niels Möller805a27e2019-01-21 12:21:27 +01003619 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
asaperssonc5dabdd2016-03-21 04:15:50 -07003620
3621 webrtc::VideoCodecVP9 vp9_settings;
3622 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
3623 EXPECT_EQ(num_spatial_layers, vp9_settings.numberOfSpatialLayers);
3624 EXPECT_EQ(num_temporal_layers, vp9_settings.numberOfTemporalLayers);
Sergey Silkin19da5ce2019-05-20 17:57:17 +02003625 EXPECT_EQ(inter_layer_pred_mode_, vp9_settings.interLayerPred);
asaperssonc5dabdd2016-03-21 04:15:50 -07003626
Niels Möllerff40b142018-04-09 08:49:14 +02003627 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
asaperssonc5dabdd2016-03-21 04:15:50 -07003628 }
Sergey Silkincf267052019-04-09 11:40:09 +02003629
3630 const uint8_t num_spatial_layers_;
3631 const uint8_t num_temporal_layers_;
Sergey Silkin19da5ce2019-05-20 17:57:17 +02003632 const webrtc::InterLayerPredMode inter_layer_pred_mode_;
asaperssonc5dabdd2016-03-21 04:15:50 -07003633};
3634
Sergey Silkincf267052019-04-09 11:40:09 +02003635TEST_P(Vp9SettingsTestWithFieldTrial, VerifyCodecSettings) {
Sergey Silkin19da5ce2019-05-20 17:57:17 +02003636 VerifySettings(num_spatial_layers_, num_temporal_layers_,
3637 inter_layer_pred_mode_);
asaperssonc5dabdd2016-03-21 04:15:50 -07003638}
3639
Sergey Silkincf267052019-04-09 11:40:09 +02003640INSTANTIATE_TEST_SUITE_P(
Mirko Bonadei09f11952019-09-29 10:19:42 +02003641 All,
Sergey Silkincf267052019-04-09 11:40:09 +02003642 Vp9SettingsTestWithFieldTrial,
Markus Handell8bc88342020-03-16 10:42:01 +01003643 Values(
Sergey Silkincf267052019-04-09 11:40:09 +02003644 std::make_tuple("", 1, 1, webrtc::InterLayerPredMode::kOnKeyPic),
3645 std::make_tuple("WebRTC-SupportVP9SVC/Default/",
3646 1,
3647 1,
3648 webrtc::InterLayerPredMode::kOnKeyPic),
3649 std::make_tuple("WebRTC-SupportVP9SVC/EnabledByFlag_2SL3TL/",
3650 2,
3651 3,
3652 webrtc::InterLayerPredMode::kOnKeyPic),
Sergey Silkin19da5ce2019-05-20 17:57:17 +02003653 std::make_tuple("WebRTC-Vp9InterLayerPred/Default/",
Sergey Silkincf267052019-04-09 11:40:09 +02003654 1,
3655 1,
Sergey Silkin19da5ce2019-05-20 17:57:17 +02003656 webrtc::InterLayerPredMode::kOnKeyPic),
3657 std::make_tuple("WebRTC-Vp9InterLayerPred/Disabled/",
Sergey Silkincf267052019-04-09 11:40:09 +02003658 1,
3659 1,
Sergey Silkin19da5ce2019-05-20 17:57:17 +02003660 webrtc::InterLayerPredMode::kOnKeyPic),
3661 std::make_tuple(
3662 "WebRTC-Vp9InterLayerPred/Enabled,inter_layer_pred_mode:off/",
3663 1,
3664 1,
3665 webrtc::InterLayerPredMode::kOff),
3666 std::make_tuple(
3667 "WebRTC-Vp9InterLayerPred/Enabled,inter_layer_pred_mode:on/",
3668 1,
3669 1,
3670 webrtc::InterLayerPredMode::kOn),
3671 std::make_tuple(
3672 "WebRTC-Vp9InterLayerPred/Enabled,inter_layer_pred_mode:onkeypic/",
3673 1,
3674 1,
3675 webrtc::InterLayerPredMode::kOnKeyPic)));
asaperssonc5dabdd2016-03-21 04:15:50 -07003676
Åsa Persson45bbc8a2017-11-13 10:16:47 +01003677TEST_F(WebRtcVideoChannelTest, VerifyMinBitrate) {
3678 std::vector<webrtc::VideoStream> streams = AddSendStream()->GetVideoStreams();
3679 ASSERT_EQ(1u, streams.size());
Elad Alon80f53b72019-10-11 16:19:43 +02003680 EXPECT_EQ(webrtc::kDefaultMinVideoBitrateBps, streams[0].min_bitrate_bps);
Åsa Persson45bbc8a2017-11-13 10:16:47 +01003681}
3682
3683TEST_F(WebRtcVideoChannelTest, VerifyMinBitrateWithForcedFallbackFieldTrial) {
Elad Alon040dc432019-05-22 15:40:02 +02003684 RTC_DCHECK(!override_field_trials_);
Mirko Bonadei317a1f02019-09-17 17:06:18 +02003685 override_field_trials_ = std::make_unique<webrtc::test::ScopedFieldTrials>(
Åsa Persson45bbc8a2017-11-13 10:16:47 +01003686 "WebRTC-VP8-Forced-Fallback-Encoder-v2/Enabled-1,2,34567/");
3687 std::vector<webrtc::VideoStream> streams = AddSendStream()->GetVideoStreams();
3688 ASSERT_EQ(1u, streams.size());
3689 EXPECT_EQ(34567, streams[0].min_bitrate_bps);
3690}
3691
asapersson3c81a1a2017-06-14 05:52:21 -07003692TEST_F(WebRtcVideoChannelTest,
3693 BalancedDegradationPreferenceNotSupportedWithoutFieldtrial) {
Elad Alon040dc432019-05-22 15:40:02 +02003694 RTC_DCHECK(!override_field_trials_);
Mirko Bonadei317a1f02019-09-17 17:06:18 +02003695 override_field_trials_ = std::make_unique<webrtc::test::ScopedFieldTrials>(
asapersson3c81a1a2017-06-14 05:52:21 -07003696 "WebRTC-Video-BalancedDegradation/Disabled/");
3697 const bool kResolutionScalingEnabled = true;
3698 const bool kFpsScalingEnabled = false;
3699 TestDegradationPreference(kResolutionScalingEnabled, kFpsScalingEnabled);
3700}
3701
3702TEST_F(WebRtcVideoChannelTest,
3703 BalancedDegradationPreferenceSupportedBehindFieldtrial) {
Elad Alon040dc432019-05-22 15:40:02 +02003704 RTC_DCHECK(!override_field_trials_);
Mirko Bonadei317a1f02019-09-17 17:06:18 +02003705 override_field_trials_ = std::make_unique<webrtc::test::ScopedFieldTrials>(
asapersson3c81a1a2017-06-14 05:52:21 -07003706 "WebRTC-Video-BalancedDegradation/Enabled/");
3707 const bool kResolutionScalingEnabled = true;
3708 const bool kFpsScalingEnabled = true;
3709 TestDegradationPreference(kResolutionScalingEnabled, kFpsScalingEnabled);
3710}
3711
eladalonf1841382017-06-12 01:16:46 -07003712TEST_F(WebRtcVideoChannelTest, AdaptsOnOveruse) {
Erik Språngefbde372015-04-29 16:21:28 +02003713 TestCpuAdaptation(true, false);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003714}
3715
eladalonf1841382017-06-12 01:16:46 -07003716TEST_F(WebRtcVideoChannelTest, DoesNotAdaptOnOveruseWhenDisabled) {
Erik Språngefbde372015-04-29 16:21:28 +02003717 TestCpuAdaptation(false, false);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003718}
3719
Niels Möller3de32e62019-01-18 08:42:18 +01003720TEST_F(WebRtcVideoChannelTest, DoesNotAdaptWhenScreeensharing) {
3721 TestCpuAdaptation(false, true);
3722}
3723
eladalonf1841382017-06-12 01:16:46 -07003724TEST_F(WebRtcVideoChannelTest, DoesNotAdaptOnOveruseWhenScreensharing) {
Erik Språngefbde372015-04-29 16:21:28 +02003725 TestCpuAdaptation(true, true);
3726}
3727
eladalonf1841382017-06-12 01:16:46 -07003728TEST_F(WebRtcVideoChannelTest, PreviousAdaptationDoesNotApplyToScreenshare) {
magjed509e4fe2016-11-18 01:34:11 -08003729 cricket::VideoCodec codec = GetEngineCodec("VP8");
Per766ad3b2016-04-05 15:23:49 +02003730 cricket::VideoSendParameters parameters;
3731 parameters.codecs.push_back(codec);
3732
kthelgason2bc68642017-02-07 07:02:22 -08003733 MediaConfig media_config = GetMediaConfig();
Niels Möller1d7ecd22018-01-18 15:25:12 +01003734 media_config.video.enable_cpu_adaptation = true;
Sebastian Jansson84848f22018-11-16 10:40:36 +01003735 channel_.reset(engine_.CreateMediaChannel(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02003736 fake_call_.get(), media_config, VideoOptions(), webrtc::CryptoOptions(),
3737 video_bitrate_allocator_factory_.get()));
Sergey Ulanove2b15012016-11-22 16:08:30 -08003738 channel_->OnReadyToSend(true);
Per766ad3b2016-04-05 15:23:49 +02003739 ASSERT_TRUE(channel_->SetSendParameters(parameters));
3740
3741 AddSendStream();
Niels Möller805a27e2019-01-21 12:21:27 +01003742 webrtc::test::FrameForwarder frame_forwarder;
Per766ad3b2016-04-05 15:23:49 +02003743
Per766ad3b2016-04-05 15:23:49 +02003744 ASSERT_TRUE(channel_->SetSend(true));
3745 cricket::VideoOptions camera_options;
Oskar Sundbom78807582017-11-16 11:09:55 +01003746 camera_options.is_screencast = false;
Niels Möller805a27e2019-01-21 12:21:27 +01003747 channel_->SetVideoSend(last_ssrc_, &camera_options, &frame_forwarder);
Per766ad3b2016-04-05 15:23:49 +02003748
3749 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
3750 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
Per766ad3b2016-04-05 15:23:49 +02003751
Niels Möllerdcc70292019-01-15 16:32:38 +01003752 EXPECT_TRUE(send_stream->resolution_scaling_enabled());
3753 // Dont' expect anything on framerate_scaling_enabled, since the default is
3754 // transitioning from MAINTAIN_FRAMERATE to BALANCED.
Per766ad3b2016-04-05 15:23:49 +02003755
Niels Möllerdcc70292019-01-15 16:32:38 +01003756 // Switch to screen share. Expect no resolution scaling.
Per766ad3b2016-04-05 15:23:49 +02003757 cricket::VideoOptions screenshare_options;
Oskar Sundbom78807582017-11-16 11:09:55 +01003758 screenshare_options.is_screencast = true;
Niels Möller805a27e2019-01-21 12:21:27 +01003759 channel_->SetVideoSend(last_ssrc_, &screenshare_options, &frame_forwarder);
sprangf24a0642017-02-28 13:23:26 -08003760 ASSERT_EQ(2, fake_call_->GetNumCreatedSendStreams());
3761 send_stream = fake_call_->GetVideoSendStreams().front();
Niels Möllerdcc70292019-01-15 16:32:38 +01003762 EXPECT_FALSE(send_stream->resolution_scaling_enabled());
Per766ad3b2016-04-05 15:23:49 +02003763
Niels Möllerdcc70292019-01-15 16:32:38 +01003764 // Switch back to the normal capturer. Expect resolution scaling to be
3765 // reenabled.
Niels Möller805a27e2019-01-21 12:21:27 +01003766 channel_->SetVideoSend(last_ssrc_, &camera_options, &frame_forwarder);
3767 send_stream = fake_call_->GetVideoSendStreams().front();
sprangf24a0642017-02-28 13:23:26 -08003768 ASSERT_EQ(3, fake_call_->GetNumCreatedSendStreams());
3769 send_stream = fake_call_->GetVideoSendStreams().front();
Niels Möllerdcc70292019-01-15 16:32:38 +01003770 EXPECT_TRUE(send_stream->resolution_scaling_enabled());
Per766ad3b2016-04-05 15:23:49 +02003771
Niels Möllerff40b142018-04-09 08:49:14 +02003772 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
Per766ad3b2016-04-05 15:23:49 +02003773}
3774
asapersson3c81a1a2017-06-14 05:52:21 -07003775// TODO(asapersson): Remove this test when the balanced field trial is removed.
3776void WebRtcVideoChannelTest::TestDegradationPreference(
3777 bool resolution_scaling_enabled,
3778 bool fps_scaling_enabled) {
3779 cricket::VideoCodec codec = GetEngineCodec("VP8");
3780 cricket::VideoSendParameters parameters;
3781 parameters.codecs.push_back(codec);
3782
3783 MediaConfig media_config = GetMediaConfig();
Niels Möller1d7ecd22018-01-18 15:25:12 +01003784 media_config.video.enable_cpu_adaptation = true;
Sebastian Jansson84848f22018-11-16 10:40:36 +01003785 channel_.reset(engine_.CreateMediaChannel(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02003786 fake_call_.get(), media_config, VideoOptions(), webrtc::CryptoOptions(),
3787 video_bitrate_allocator_factory_.get()));
asapersson3c81a1a2017-06-14 05:52:21 -07003788 channel_->OnReadyToSend(true);
3789
3790 EXPECT_TRUE(channel_->SetSendParameters(parameters));
3791
3792 AddSendStream();
3793
Niels Möller805a27e2019-01-21 12:21:27 +01003794 webrtc::test::FrameForwarder frame_forwarder;
asapersson3c81a1a2017-06-14 05:52:21 -07003795 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01003796 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
asapersson3c81a1a2017-06-14 05:52:21 -07003797
3798 EXPECT_TRUE(channel_->SetSend(true));
3799
3800 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
3801 EXPECT_EQ(resolution_scaling_enabled,
3802 send_stream->resolution_scaling_enabled());
3803 EXPECT_EQ(fps_scaling_enabled, send_stream->framerate_scaling_enabled());
3804
Niels Möllerff40b142018-04-09 08:49:14 +02003805 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
asapersson3c81a1a2017-06-14 05:52:21 -07003806}
3807
eladalonf1841382017-06-12 01:16:46 -07003808void WebRtcVideoChannelTest::TestCpuAdaptation(bool enable_overuse,
3809 bool is_screenshare) {
magjed509e4fe2016-11-18 01:34:11 -08003810 cricket::VideoCodec codec = GetEngineCodec("VP8");
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003811 cricket::VideoSendParameters parameters;
3812 parameters.codecs.push_back(codec);
nisse51542be2016-02-12 02:27:06 -08003813
kthelgason2bc68642017-02-07 07:02:22 -08003814 MediaConfig media_config = GetMediaConfig();
3815 if (enable_overuse) {
Niels Möller1d7ecd22018-01-18 15:25:12 +01003816 media_config.video.enable_cpu_adaptation = true;
pbos@webrtc.org42684be2014-10-03 11:25:45 +00003817 }
Sebastian Jansson84848f22018-11-16 10:40:36 +01003818 channel_.reset(engine_.CreateMediaChannel(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02003819 fake_call_.get(), media_config, VideoOptions(), webrtc::CryptoOptions(),
3820 video_bitrate_allocator_factory_.get()));
Sergey Ulanove2b15012016-11-22 16:08:30 -08003821 channel_->OnReadyToSend(true);
nisse51542be2016-02-12 02:27:06 -08003822
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003823 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00003824
3825 AddSendStream();
3826
Niels Möller805a27e2019-01-21 12:21:27 +01003827 webrtc::test::FrameForwarder frame_forwarder;
nisse05103312016-03-16 02:22:50 -07003828 VideoOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01003829 options.is_screencast = is_screenshare;
Niels Möller805a27e2019-01-21 12:21:27 +01003830 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00003831
3832 EXPECT_TRUE(channel_->SetSend(true));
3833
solenberge5269742015-09-08 05:13:22 -07003834 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
perkj2d5f0912016-02-29 00:04:41 -08003835
sprangc5d62e22017-04-02 23:53:04 -07003836 if (!enable_overuse) {
perkj803d97f2016-11-01 11:45:46 -07003837 EXPECT_FALSE(send_stream->resolution_scaling_enabled());
sprangc5d62e22017-04-02 23:53:04 -07003838 EXPECT_FALSE(send_stream->framerate_scaling_enabled());
Niels Möller805a27e2019-01-21 12:21:27 +01003839 } else if (is_screenshare) {
sprangc5d62e22017-04-02 23:53:04 -07003840 EXPECT_FALSE(send_stream->resolution_scaling_enabled());
3841 EXPECT_TRUE(send_stream->framerate_scaling_enabled());
3842 } else {
3843 EXPECT_TRUE(send_stream->resolution_scaling_enabled());
3844 EXPECT_FALSE(send_stream->framerate_scaling_enabled());
3845 }
Niels Möllerff40b142018-04-09 08:49:14 +02003846 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003847}
3848
eladalonf1841382017-06-12 01:16:46 -07003849TEST_F(WebRtcVideoChannelTest, EstimatesNtpStartTimeCorrectly) {
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00003850 // Start at last timestamp to verify that wraparounds are estimated correctly.
3851 static const uint32_t kInitialTimestamp = 0xFFFFFFFFu;
3852 static const int64_t kInitialNtpTimeMs = 1247891230;
3853 static const int kFrameOffsetMs = 20;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003854 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003855
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00003856 FakeVideoReceiveStream* stream = AddRecvStream();
3857 cricket::FakeVideoRenderer renderer;
nisse08582ff2016-02-04 01:24:52 -08003858 EXPECT_TRUE(channel_->SetSink(last_ssrc_, &renderer));
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00003859
Artem Titov1ebfb6a2019-01-03 23:49:37 +01003860 webrtc::VideoFrame video_frame =
3861 webrtc::VideoFrame::Builder()
3862 .set_video_frame_buffer(CreateBlackFrameBuffer(4, 4))
3863 .set_timestamp_rtp(kInitialTimestamp)
3864 .set_timestamp_us(0)
3865 .set_rotation(webrtc::kVideoRotation_0)
3866 .build();
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00003867 // Initial NTP time is not available on the first frame, but should still be
3868 // able to be estimated.
nisseeb83a1a2016-03-21 01:27:56 -07003869 stream->InjectFrame(video_frame);
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00003870
3871 EXPECT_EQ(1, renderer.num_rendered_frames());
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00003872
3873 // This timestamp is kInitialTimestamp (-1) + kFrameOffsetMs * 90, which
3874 // triggers a constant-overflow warning, hence we're calculating it explicitly
3875 // here.
Danil Chapovalov0c626af2020-02-10 11:16:00 +01003876 fake_clock_.AdvanceTime(webrtc::TimeDelta::Millis(kFrameOffsetMs));
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00003877 video_frame.set_timestamp(kFrameOffsetMs * 90 - 1);
3878 video_frame.set_ntp_time_ms(kInitialNtpTimeMs + kFrameOffsetMs);
nisseeb83a1a2016-03-21 01:27:56 -07003879 stream->InjectFrame(video_frame);
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00003880
3881 EXPECT_EQ(2, renderer.num_rendered_frames());
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00003882
3883 // Verify that NTP time has been correctly deduced.
3884 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00003885 ASSERT_TRUE(channel_->GetStats(&info));
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00003886 ASSERT_EQ(1u, info.receivers.size());
3887 EXPECT_EQ(kInitialNtpTimeMs, info.receivers[0].capture_start_ntp_time_ms);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003888}
3889
eladalonf1841382017-06-12 01:16:46 -07003890TEST_F(WebRtcVideoChannelTest, SetDefaultSendCodecs) {
Anders Carlsson5f2bb622018-05-14 09:48:06 +02003891 AssignDefaultAptRtxTypes();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003892 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003893
3894 VideoCodec codec;
3895 EXPECT_TRUE(channel_->GetSendCodec(&codec));
Johannes Kron3e983682020-03-29 22:17:00 +02003896 EXPECT_TRUE(codec.Matches(engine_.send_codecs()[0]));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003897
3898 // Using a RTX setup to verify that the default RTX payload type is good.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003899 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
3900 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003901 FakeVideoSendStream* stream = AddSendStream(
3902 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
perkj26091b12016-09-01 01:17:40 -07003903 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003904
3905 // Make sure NACK and FEC are enabled on the correct payload types.
3906 EXPECT_EQ(1000, config.rtp.nack.rtp_history_ms);
magjed509e4fe2016-11-18 01:34:11 -08003907 EXPECT_EQ(GetEngineCodec("ulpfec").id, config.rtp.ulpfec.ulpfec_payload_type);
3908 EXPECT_EQ(GetEngineCodec("red").id, config.rtp.ulpfec.red_payload_type);
pbos@webrtc.org269605c2014-06-26 08:49:03 +00003909
3910 EXPECT_EQ(1u, config.rtp.rtx.ssrcs.size());
3911 EXPECT_EQ(kRtxSsrcs1[0], config.rtp.rtx.ssrcs[0]);
Shao Changbine62202f2015-04-21 20:24:50 +08003912 VerifySendStreamHasRtxTypes(config, default_apt_rtx_types_);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003913 // TODO(juberti): Check RTCP, PLI, TMMBR.
3914}
3915
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02003916TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithoutPacketization) {
3917 cricket::VideoSendParameters parameters;
3918 parameters.codecs.push_back(GetEngineCodec("VP8"));
3919 EXPECT_TRUE(channel_->SetSendParameters(parameters));
3920
3921 FakeVideoSendStream* stream = AddSendStream();
3922 const webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
3923 EXPECT_FALSE(config.rtp.raw_payload);
3924}
3925
3926TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithPacketization) {
3927 cricket::VideoSendParameters parameters;
3928 parameters.codecs.push_back(GetEngineCodec("VP8"));
3929 parameters.codecs.back().packetization = kPacketizationParamRaw;
3930 EXPECT_TRUE(channel_->SetSendParameters(parameters));
3931
3932 FakeVideoSendStream* stream = AddSendStream();
3933 const webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
3934 EXPECT_TRUE(config.rtp.raw_payload);
3935}
3936
brandtr31bd2242017-05-19 05:47:46 -07003937// The following four tests ensures that FlexFEC is not activated by default
3938// when the field trials are not enabled.
3939// TODO(brandtr): Remove or update these tests when FlexFEC _is_ enabled by
3940// default.
Yves Gerey665174f2018-06-19 15:03:05 +02003941TEST_F(WebRtcVideoChannelTest, FlexfecSendCodecWithoutSsrcNotExposedByDefault) {
brandtr468da7c2016-11-22 02:16:47 -08003942 FakeVideoSendStream* stream = AddSendStream();
3943 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
3944
brandtr3d200bd2017-01-16 06:59:19 -08003945 EXPECT_EQ(-1, config.rtp.flexfec.payload_type);
brandtr31bd2242017-05-19 05:47:46 -07003946 EXPECT_EQ(0U, config.rtp.flexfec.ssrc);
3947 EXPECT_TRUE(config.rtp.flexfec.protected_media_ssrcs.empty());
brandtr468da7c2016-11-22 02:16:47 -08003948}
3949
eladalonf1841382017-06-12 01:16:46 -07003950TEST_F(WebRtcVideoChannelTest, FlexfecSendCodecWithSsrcNotExposedByDefault) {
brandtr468da7c2016-11-22 02:16:47 -08003951 FakeVideoSendStream* stream = AddSendStream(
3952 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
3953 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
3954
brandtr3d200bd2017-01-16 06:59:19 -08003955 EXPECT_EQ(-1, config.rtp.flexfec.payload_type);
brandtr31bd2242017-05-19 05:47:46 -07003956 EXPECT_EQ(0U, config.rtp.flexfec.ssrc);
3957 EXPECT_TRUE(config.rtp.flexfec.protected_media_ssrcs.empty());
3958}
3959
Yves Gerey665174f2018-06-19 15:03:05 +02003960TEST_F(WebRtcVideoChannelTest, FlexfecRecvCodecWithoutSsrcNotExposedByDefault) {
brandtr31bd2242017-05-19 05:47:46 -07003961 AddRecvStream();
3962
3963 const std::vector<FakeFlexfecReceiveStream*>& streams =
3964 fake_call_->GetFlexfecReceiveStreams();
3965 EXPECT_TRUE(streams.empty());
3966}
3967
eladalonf1841382017-06-12 01:16:46 -07003968TEST_F(WebRtcVideoChannelTest, FlexfecRecvCodecWithSsrcNotExposedByDefault) {
brandtr31bd2242017-05-19 05:47:46 -07003969 AddRecvStream(
3970 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
3971
3972 const std::vector<FakeFlexfecReceiveStream*>& streams =
3973 fake_call_->GetFlexfecReceiveStreams();
3974 EXPECT_TRUE(streams.empty());
brandtr468da7c2016-11-22 02:16:47 -08003975}
3976
3977// TODO(brandtr): When FlexFEC is no longer behind a field trial, merge all
3978// tests that use this test fixture into the corresponding "non-field trial"
3979// tests.
eladalonf1841382017-06-12 01:16:46 -07003980class WebRtcVideoChannelFlexfecRecvTest : public WebRtcVideoChannelTest {
brandtr468da7c2016-11-22 02:16:47 -08003981 public:
eladalonf1841382017-06-12 01:16:46 -07003982 WebRtcVideoChannelFlexfecRecvTest()
3983 : WebRtcVideoChannelTest("WebRTC-FlexFEC-03-Advertised/Enabled/") {}
brandtr468da7c2016-11-22 02:16:47 -08003984};
3985
eladalonf1841382017-06-12 01:16:46 -07003986TEST_F(WebRtcVideoChannelFlexfecRecvTest,
brandtr36e7d702017-01-13 07:15:54 -08003987 DefaultFlexfecCodecHasTransportCcAndRembFeedbackParam) {
3988 EXPECT_TRUE(cricket::HasTransportCc(GetEngineCodec("flexfec-03")));
3989 EXPECT_TRUE(cricket::HasRemb(GetEngineCodec("flexfec-03")));
3990}
3991
eladalonf1841382017-06-12 01:16:46 -07003992TEST_F(WebRtcVideoChannelFlexfecRecvTest, SetDefaultRecvCodecsWithoutSsrc) {
brandtr31bd2242017-05-19 05:47:46 -07003993 AddRecvStream();
3994
3995 const std::vector<FakeFlexfecReceiveStream*>& streams =
3996 fake_call_->GetFlexfecReceiveStreams();
3997 EXPECT_TRUE(streams.empty());
Rasmus Brandt60bb6fe2018-02-05 09:51:47 +01003998
3999 const std::vector<FakeVideoReceiveStream*>& video_streams =
4000 fake_call_->GetVideoReceiveStreams();
4001 ASSERT_EQ(1U, video_streams.size());
4002 const FakeVideoReceiveStream& video_stream = *video_streams.front();
4003 EXPECT_EQ(0, video_stream.GetNumAddedSecondarySinks());
4004 EXPECT_EQ(0, video_stream.GetNumRemovedSecondarySinks());
brandtr31bd2242017-05-19 05:47:46 -07004005}
4006
eladalonf1841382017-06-12 01:16:46 -07004007TEST_F(WebRtcVideoChannelFlexfecRecvTest, SetDefaultRecvCodecsWithSsrc) {
brandtr31bd2242017-05-19 05:47:46 -07004008 AddRecvStream(
4009 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
4010
4011 const std::vector<FakeFlexfecReceiveStream*>& streams =
4012 fake_call_->GetFlexfecReceiveStreams();
4013 ASSERT_EQ(1U, streams.size());
4014 const FakeFlexfecReceiveStream* stream = streams.front();
4015 const webrtc::FlexfecReceiveStream::Config& config = stream->GetConfig();
4016 EXPECT_EQ(GetEngineCodec("flexfec-03").id, config.payload_type);
4017 EXPECT_EQ(kFlexfecSsrc, config.remote_ssrc);
4018 ASSERT_EQ(1U, config.protected_media_ssrcs.size());
4019 EXPECT_EQ(kSsrcs1[0], config.protected_media_ssrcs[0]);
brandtr7cd28b92017-09-22 00:26:25 -07004020
4021 const std::vector<FakeVideoReceiveStream*>& video_streams =
4022 fake_call_->GetVideoReceiveStreams();
4023 ASSERT_EQ(1U, video_streams.size());
Rasmus Brandt60bb6fe2018-02-05 09:51:47 +01004024 const FakeVideoReceiveStream& video_stream = *video_streams.front();
4025 EXPECT_EQ(1, video_stream.GetNumAddedSecondarySinks());
brandtr7cd28b92017-09-22 00:26:25 -07004026 const webrtc::VideoReceiveStream::Config& video_config =
Rasmus Brandt60bb6fe2018-02-05 09:51:47 +01004027 video_stream.GetConfig();
brandtr7cd28b92017-09-22 00:26:25 -07004028 EXPECT_TRUE(video_config.rtp.protected_by_flexfec);
brandtr31bd2242017-05-19 05:47:46 -07004029}
4030
eladalonf1841382017-06-12 01:16:46 -07004031TEST_F(WebRtcVideoChannelFlexfecRecvTest,
brandtr11fb4722017-05-30 01:31:37 -07004032 EnablingFlexfecDoesNotRecreateVideoReceiveStream) {
4033 cricket::VideoRecvParameters recv_parameters;
4034 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
4035 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
4036
4037 AddRecvStream(
4038 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
4039 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
Rasmus Brandt60bb6fe2018-02-05 09:51:47 +01004040 const std::vector<FakeVideoReceiveStream*>& video_streams =
4041 fake_call_->GetVideoReceiveStreams();
4042 ASSERT_EQ(1U, video_streams.size());
4043 const FakeVideoReceiveStream& video_stream = *video_streams.front();
4044 EXPECT_EQ(0, video_stream.GetNumAddedSecondarySinks());
4045 EXPECT_EQ(0, video_stream.GetNumRemovedSecondarySinks());
brandtr11fb4722017-05-30 01:31:37 -07004046
4047 // Enable FlexFEC.
4048 recv_parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
4049 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
4050 EXPECT_EQ(2, fake_call_->GetNumCreatedReceiveStreams())
4051 << "Enabling FlexFEC should create FlexfecReceiveStream.";
4052 EXPECT_EQ(1U, fake_call_->GetVideoReceiveStreams().size())
4053 << "Enabling FlexFEC should not create VideoReceiveStream.";
4054 EXPECT_EQ(1U, fake_call_->GetFlexfecReceiveStreams().size())
4055 << "Enabling FlexFEC should create a single FlexfecReceiveStream.";
Rasmus Brandt60bb6fe2018-02-05 09:51:47 +01004056 EXPECT_EQ(1, video_stream.GetNumAddedSecondarySinks());
4057 EXPECT_EQ(0, video_stream.GetNumRemovedSecondarySinks());
brandtr11fb4722017-05-30 01:31:37 -07004058}
4059
eladalonf1841382017-06-12 01:16:46 -07004060TEST_F(WebRtcVideoChannelFlexfecRecvTest,
brandtr11fb4722017-05-30 01:31:37 -07004061 DisablingFlexfecDoesNotRecreateVideoReceiveStream) {
4062 cricket::VideoRecvParameters recv_parameters;
4063 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
4064 recv_parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
4065 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
4066
4067 AddRecvStream(
4068 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
4069 EXPECT_EQ(2, fake_call_->GetNumCreatedReceiveStreams());
brandtr11fb4722017-05-30 01:31:37 -07004070 EXPECT_EQ(1U, fake_call_->GetFlexfecReceiveStreams().size());
Rasmus Brandt60bb6fe2018-02-05 09:51:47 +01004071 const std::vector<FakeVideoReceiveStream*>& video_streams =
4072 fake_call_->GetVideoReceiveStreams();
4073 ASSERT_EQ(1U, video_streams.size());
4074 const FakeVideoReceiveStream& video_stream = *video_streams.front();
4075 EXPECT_EQ(1, video_stream.GetNumAddedSecondarySinks());
4076 EXPECT_EQ(0, video_stream.GetNumRemovedSecondarySinks());
brandtr11fb4722017-05-30 01:31:37 -07004077
4078 // Disable FlexFEC.
4079 recv_parameters.codecs.clear();
4080 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
4081 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
4082 EXPECT_EQ(2, fake_call_->GetNumCreatedReceiveStreams())
4083 << "Disabling FlexFEC should not recreate VideoReceiveStream.";
4084 EXPECT_EQ(1U, fake_call_->GetVideoReceiveStreams().size())
4085 << "Disabling FlexFEC should not destroy VideoReceiveStream.";
4086 EXPECT_TRUE(fake_call_->GetFlexfecReceiveStreams().empty())
4087 << "Disabling FlexFEC should destroy FlexfecReceiveStream.";
Rasmus Brandt60bb6fe2018-02-05 09:51:47 +01004088 EXPECT_EQ(1, video_stream.GetNumAddedSecondarySinks());
4089 EXPECT_EQ(1, video_stream.GetNumRemovedSecondarySinks());
brandtr11fb4722017-05-30 01:31:37 -07004090}
4091
Steve Anton2d2bbb12019-08-07 09:57:59 -07004092TEST_F(WebRtcVideoChannelFlexfecRecvTest, DuplicateFlexfecCodecIsDropped) {
4093 constexpr int kUnusedPayloadType1 = 127;
4094
4095 cricket::VideoRecvParameters recv_parameters;
4096 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
4097 recv_parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
4098 cricket::VideoCodec duplicate = GetEngineCodec("flexfec-03");
4099 duplicate.id = kUnusedPayloadType1;
4100 recv_parameters.codecs.push_back(duplicate);
4101 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
4102
4103 AddRecvStream(
4104 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
4105
4106 const std::vector<FakeFlexfecReceiveStream*>& streams =
4107 fake_call_->GetFlexfecReceiveStreams();
4108 ASSERT_EQ(1U, streams.size());
4109 const FakeFlexfecReceiveStream* stream = streams.front();
4110 const webrtc::FlexfecReceiveStream::Config& config = stream->GetConfig();
4111 EXPECT_EQ(GetEngineCodec("flexfec-03").id, config.payload_type);
4112}
4113
brandtr31bd2242017-05-19 05:47:46 -07004114// TODO(brandtr): When FlexFEC is no longer behind a field trial, merge all
4115// tests that use this test fixture into the corresponding "non-field trial"
4116// tests.
eladalonf1841382017-06-12 01:16:46 -07004117class WebRtcVideoChannelFlexfecSendRecvTest : public WebRtcVideoChannelTest {
brandtr31bd2242017-05-19 05:47:46 -07004118 public:
eladalonf1841382017-06-12 01:16:46 -07004119 WebRtcVideoChannelFlexfecSendRecvTest()
4120 : WebRtcVideoChannelTest(
brandtr31bd2242017-05-19 05:47:46 -07004121 "WebRTC-FlexFEC-03-Advertised/Enabled/WebRTC-FlexFEC-03/Enabled/") {
4122 }
4123};
4124
Yves Gerey665174f2018-06-19 15:03:05 +02004125TEST_F(WebRtcVideoChannelFlexfecSendRecvTest, SetDefaultSendCodecsWithoutSsrc) {
brandtr468da7c2016-11-22 02:16:47 -08004126 FakeVideoSendStream* stream = AddSendStream();
4127 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
4128
brandtr3d200bd2017-01-16 06:59:19 -08004129 EXPECT_EQ(GetEngineCodec("flexfec-03").id, config.rtp.flexfec.payload_type);
4130 EXPECT_EQ(0U, config.rtp.flexfec.ssrc);
4131 EXPECT_TRUE(config.rtp.flexfec.protected_media_ssrcs.empty());
brandtr468da7c2016-11-22 02:16:47 -08004132}
4133
eladalonf1841382017-06-12 01:16:46 -07004134TEST_F(WebRtcVideoChannelFlexfecSendRecvTest, SetDefaultSendCodecsWithSsrc) {
brandtr468da7c2016-11-22 02:16:47 -08004135 FakeVideoSendStream* stream = AddSendStream(
4136 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
4137 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
4138
brandtr3d200bd2017-01-16 06:59:19 -08004139 EXPECT_EQ(GetEngineCodec("flexfec-03").id, config.rtp.flexfec.payload_type);
4140 EXPECT_EQ(kFlexfecSsrc, config.rtp.flexfec.ssrc);
4141 ASSERT_EQ(1U, config.rtp.flexfec.protected_media_ssrcs.size());
4142 EXPECT_EQ(kSsrcs1[0], config.rtp.flexfec.protected_media_ssrcs[0]);
brandtr468da7c2016-11-22 02:16:47 -08004143}
4144
eladalonf1841382017-06-12 01:16:46 -07004145TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithoutFec) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004146 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004147 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004148 ASSERT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004149
4150 FakeVideoSendStream* stream = AddSendStream();
perkj26091b12016-09-01 01:17:40 -07004151 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004152
brandtrb5f2c3f2016-10-04 23:28:39 -07004153 EXPECT_EQ(-1, config.rtp.ulpfec.ulpfec_payload_type);
4154 EXPECT_EQ(-1, config.rtp.ulpfec.red_payload_type);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004155}
4156
eladalonf1841382017-06-12 01:16:46 -07004157TEST_F(WebRtcVideoChannelFlexfecSendRecvTest, SetSendCodecsWithoutFec) {
brandtr468da7c2016-11-22 02:16:47 -08004158 cricket::VideoSendParameters parameters;
4159 parameters.codecs.push_back(GetEngineCodec("VP8"));
4160 ASSERT_TRUE(channel_->SetSendParameters(parameters));
4161
4162 FakeVideoSendStream* stream = AddSendStream();
4163 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
4164
brandtr3d200bd2017-01-16 06:59:19 -08004165 EXPECT_EQ(-1, config.rtp.flexfec.payload_type);
brandtr468da7c2016-11-22 02:16:47 -08004166}
4167
eladalonf1841382017-06-12 01:16:46 -07004168TEST_F(WebRtcVideoChannelFlexfecRecvTest, SetRecvCodecsWithFec) {
brandtr9c3d4c42017-01-23 06:59:13 -08004169 AddRecvStream(
4170 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
brandtr9c3d4c42017-01-23 06:59:13 -08004171
4172 cricket::VideoRecvParameters recv_parameters;
4173 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
4174 recv_parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
4175 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
brandtr9d58d942017-02-03 04:43:41 -08004176
4177 const std::vector<FakeFlexfecReceiveStream*>& flexfec_streams =
4178 fake_call_->GetFlexfecReceiveStreams();
4179 ASSERT_EQ(1U, flexfec_streams.size());
4180 const FakeFlexfecReceiveStream* flexfec_stream = flexfec_streams.front();
4181 const webrtc::FlexfecReceiveStream::Config& flexfec_stream_config =
4182 flexfec_stream->GetConfig();
brandtr9c3d4c42017-01-23 06:59:13 -08004183 EXPECT_EQ(GetEngineCodec("flexfec-03").id,
brandtr9d58d942017-02-03 04:43:41 -08004184 flexfec_stream_config.payload_type);
4185 EXPECT_EQ(kFlexfecSsrc, flexfec_stream_config.remote_ssrc);
4186 ASSERT_EQ(1U, flexfec_stream_config.protected_media_ssrcs.size());
4187 EXPECT_EQ(kSsrcs1[0], flexfec_stream_config.protected_media_ssrcs[0]);
4188 const std::vector<FakeVideoReceiveStream*>& video_streams =
4189 fake_call_->GetVideoReceiveStreams();
4190 const FakeVideoReceiveStream* video_stream = video_streams.front();
4191 const webrtc::VideoReceiveStream::Config& video_stream_config =
4192 video_stream->GetConfig();
4193 EXPECT_EQ(video_stream_config.rtp.local_ssrc,
4194 flexfec_stream_config.local_ssrc);
4195 EXPECT_EQ(video_stream_config.rtp.rtcp_mode, flexfec_stream_config.rtcp_mode);
4196 EXPECT_EQ(video_stream_config.rtcp_send_transport,
4197 flexfec_stream_config.rtcp_send_transport);
4198 // TODO(brandtr): Update this EXPECT when we set |transport_cc| in a
4199 // spec-compliant way.
4200 EXPECT_EQ(video_stream_config.rtp.transport_cc,
4201 flexfec_stream_config.transport_cc);
4202 EXPECT_EQ(video_stream_config.rtp.rtcp_mode, flexfec_stream_config.rtcp_mode);
4203 EXPECT_EQ(video_stream_config.rtp.extensions,
4204 flexfec_stream_config.rtp_header_extensions);
brandtr9c3d4c42017-01-23 06:59:13 -08004205}
4206
brandtr31bd2242017-05-19 05:47:46 -07004207// We should not send FlexFEC, even if we advertise it, unless the right
4208// field trial is set.
4209// TODO(brandtr): Remove when FlexFEC is enabled by default.
eladalonf1841382017-06-12 01:16:46 -07004210TEST_F(WebRtcVideoChannelFlexfecRecvTest,
brandtr31bd2242017-05-19 05:47:46 -07004211 SetSendCodecsWithoutSsrcWithFecDoesNotEnableFec) {
4212 cricket::VideoSendParameters parameters;
4213 parameters.codecs.push_back(GetEngineCodec("VP8"));
4214 parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
4215 ASSERT_TRUE(channel_->SetSendParameters(parameters));
4216
4217 FakeVideoSendStream* stream = AddSendStream();
4218 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
4219
4220 EXPECT_EQ(-1, config.rtp.flexfec.payload_type);
Mirko Bonadeif859e552018-05-30 15:31:29 +02004221 EXPECT_EQ(0u, config.rtp.flexfec.ssrc);
brandtr31bd2242017-05-19 05:47:46 -07004222 EXPECT_TRUE(config.rtp.flexfec.protected_media_ssrcs.empty());
4223}
4224
eladalonf1841382017-06-12 01:16:46 -07004225TEST_F(WebRtcVideoChannelFlexfecRecvTest,
brandtr31bd2242017-05-19 05:47:46 -07004226 SetSendCodecsWithSsrcWithFecDoesNotEnableFec) {
4227 cricket::VideoSendParameters parameters;
4228 parameters.codecs.push_back(GetEngineCodec("VP8"));
4229 parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
4230 ASSERT_TRUE(channel_->SetSendParameters(parameters));
4231
4232 FakeVideoSendStream* stream = AddSendStream(
4233 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
4234 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
4235
4236 EXPECT_EQ(-1, config.rtp.flexfec.payload_type);
Mirko Bonadeif859e552018-05-30 15:31:29 +02004237 EXPECT_EQ(0u, config.rtp.flexfec.ssrc);
brandtr31bd2242017-05-19 05:47:46 -07004238 EXPECT_TRUE(config.rtp.flexfec.protected_media_ssrcs.empty());
4239}
4240
eladalonf1841382017-06-12 01:16:46 -07004241TEST_F(WebRtcVideoChannelTest,
pbos@webrtc.org269605c2014-06-26 08:49:03 +00004242 SetSendCodecRejectsRtxWithoutAssociatedPayloadType) {
magjed509e4fe2016-11-18 01:34:11 -08004243 const int kUnusedPayloadType = 127;
Johannes Kron3e983682020-03-29 22:17:00 +02004244 EXPECT_FALSE(FindCodecById(engine_.send_codecs(), kUnusedPayloadType));
magjed509e4fe2016-11-18 01:34:11 -08004245
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004246 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004247 cricket::VideoCodec rtx_codec(kUnusedPayloadType, "rtx");
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004248 parameters.codecs.push_back(rtx_codec);
4249 EXPECT_FALSE(channel_->SetSendParameters(parameters))
pbos@webrtc.org269605c2014-06-26 08:49:03 +00004250 << "RTX codec without associated payload type should be rejected.";
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004251}
4252
eladalonf1841382017-06-12 01:16:46 -07004253TEST_F(WebRtcVideoChannelTest,
pbos@webrtc.org269605c2014-06-26 08:49:03 +00004254 SetSendCodecRejectsRtxWithoutMatchingVideoCodec) {
magjed509e4fe2016-11-18 01:34:11 -08004255 const int kUnusedPayloadType1 = 126;
4256 const int kUnusedPayloadType2 = 127;
Johannes Kron3e983682020-03-29 22:17:00 +02004257 EXPECT_FALSE(FindCodecById(engine_.send_codecs(), kUnusedPayloadType1));
4258 EXPECT_FALSE(FindCodecById(engine_.send_codecs(), kUnusedPayloadType2));
magjed509e4fe2016-11-18 01:34:11 -08004259 {
4260 cricket::VideoCodec rtx_codec = cricket::VideoCodec::CreateRtxCodec(
4261 kUnusedPayloadType1, GetEngineCodec("VP8").id);
4262 cricket::VideoSendParameters parameters;
4263 parameters.codecs.push_back(GetEngineCodec("VP8"));
4264 parameters.codecs.push_back(rtx_codec);
4265 ASSERT_TRUE(channel_->SetSendParameters(parameters));
4266 }
4267 {
4268 cricket::VideoCodec rtx_codec = cricket::VideoCodec::CreateRtxCodec(
4269 kUnusedPayloadType1, kUnusedPayloadType2);
4270 cricket::VideoSendParameters parameters;
4271 parameters.codecs.push_back(GetEngineCodec("VP8"));
4272 parameters.codecs.push_back(rtx_codec);
4273 EXPECT_FALSE(channel_->SetSendParameters(parameters))
4274 << "RTX without matching video codec should be rejected.";
4275 }
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004276}
4277
eladalonf1841382017-06-12 01:16:46 -07004278TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithChangedRtxPayloadType) {
brandtr14742122017-01-27 04:53:07 -08004279 const int kUnusedPayloadType1 = 126;
4280 const int kUnusedPayloadType2 = 127;
Johannes Kron3e983682020-03-29 22:17:00 +02004281 EXPECT_FALSE(FindCodecById(engine_.send_codecs(), kUnusedPayloadType1));
4282 EXPECT_FALSE(FindCodecById(engine_.send_codecs(), kUnusedPayloadType2));
brandtr14742122017-01-27 04:53:07 -08004283
4284 // SSRCs for RTX.
4285 cricket::StreamParams params =
4286 cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
4287 params.AddFidSsrc(kSsrcs1[0], kRtxSsrcs1[0]);
4288 AddSendStream(params);
4289
4290 // Original payload type for RTX.
4291 cricket::VideoSendParameters parameters;
4292 parameters.codecs.push_back(GetEngineCodec("VP8"));
4293 cricket::VideoCodec rtx_codec(kUnusedPayloadType1, "rtx");
4294 rtx_codec.SetParam("apt", GetEngineCodec("VP8").id);
4295 parameters.codecs.push_back(rtx_codec);
4296 EXPECT_TRUE(channel_->SetSendParameters(parameters));
4297 ASSERT_EQ(1U, fake_call_->GetVideoSendStreams().size());
4298 const webrtc::VideoSendStream::Config& config_before =
4299 fake_call_->GetVideoSendStreams()[0]->GetConfig();
4300 EXPECT_EQ(kUnusedPayloadType1, config_before.rtp.rtx.payload_type);
4301 ASSERT_EQ(1U, config_before.rtp.rtx.ssrcs.size());
4302 EXPECT_EQ(kRtxSsrcs1[0], config_before.rtp.rtx.ssrcs[0]);
4303
4304 // Change payload type for RTX.
4305 parameters.codecs[1].id = kUnusedPayloadType2;
4306 EXPECT_TRUE(channel_->SetSendParameters(parameters));
4307 ASSERT_EQ(1U, fake_call_->GetVideoSendStreams().size());
4308 const webrtc::VideoSendStream::Config& config_after =
4309 fake_call_->GetVideoSendStreams()[0]->GetConfig();
4310 EXPECT_EQ(kUnusedPayloadType2, config_after.rtp.rtx.payload_type);
4311 ASSERT_EQ(1U, config_after.rtp.rtx.ssrcs.size());
4312 EXPECT_EQ(kRtxSsrcs1[0], config_after.rtp.rtx.ssrcs[0]);
4313}
4314
eladalonf1841382017-06-12 01:16:46 -07004315TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithoutFecDisablesFec) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004316 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004317 parameters.codecs.push_back(GetEngineCodec("VP8"));
4318 parameters.codecs.push_back(GetEngineCodec("ulpfec"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004319 ASSERT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org269605c2014-06-26 08:49:03 +00004320
4321 FakeVideoSendStream* stream = AddSendStream();
perkj26091b12016-09-01 01:17:40 -07004322 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
pbos@webrtc.org269605c2014-06-26 08:49:03 +00004323
magjed509e4fe2016-11-18 01:34:11 -08004324 EXPECT_EQ(GetEngineCodec("ulpfec").id, config.rtp.ulpfec.ulpfec_payload_type);
pbos@webrtc.org269605c2014-06-26 08:49:03 +00004325
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004326 parameters.codecs.pop_back();
4327 ASSERT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00004328 stream = fake_call_->GetVideoSendStreams()[0];
brandtr468da7c2016-11-22 02:16:47 -08004329 ASSERT_TRUE(stream != nullptr);
perkj26091b12016-09-01 01:17:40 -07004330 config = stream->GetConfig().Copy();
brandtrb5f2c3f2016-10-04 23:28:39 -07004331 EXPECT_EQ(-1, config.rtp.ulpfec.ulpfec_payload_type)
brandtr468da7c2016-11-22 02:16:47 -08004332 << "SetSendCodec without ULPFEC should disable current ULPFEC.";
4333}
4334
eladalonf1841382017-06-12 01:16:46 -07004335TEST_F(WebRtcVideoChannelFlexfecSendRecvTest,
brandtr31bd2242017-05-19 05:47:46 -07004336 SetSendCodecsWithoutFecDisablesFec) {
brandtr468da7c2016-11-22 02:16:47 -08004337 cricket::VideoSendParameters parameters;
4338 parameters.codecs.push_back(GetEngineCodec("VP8"));
4339 parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
4340 ASSERT_TRUE(channel_->SetSendParameters(parameters));
4341
4342 FakeVideoSendStream* stream = AddSendStream(
4343 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
4344 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
4345
brandtr3d200bd2017-01-16 06:59:19 -08004346 EXPECT_EQ(GetEngineCodec("flexfec-03").id, config.rtp.flexfec.payload_type);
4347 EXPECT_EQ(kFlexfecSsrc, config.rtp.flexfec.ssrc);
brandtr468da7c2016-11-22 02:16:47 -08004348 ASSERT_EQ(1U, config.rtp.flexfec.protected_media_ssrcs.size());
4349 EXPECT_EQ(kSsrcs1[0], config.rtp.flexfec.protected_media_ssrcs[0]);
4350
4351 parameters.codecs.pop_back();
4352 ASSERT_TRUE(channel_->SetSendParameters(parameters));
4353 stream = fake_call_->GetVideoSendStreams()[0];
4354 ASSERT_TRUE(stream != nullptr);
4355 config = stream->GetConfig().Copy();
brandtr3d200bd2017-01-16 06:59:19 -08004356 EXPECT_EQ(-1, config.rtp.flexfec.payload_type)
brandtr468da7c2016-11-22 02:16:47 -08004357 << "SetSendCodec without FlexFEC should disable current FlexFEC.";
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004358}
4359
eladalonf1841382017-06-12 01:16:46 -07004360TEST_F(WebRtcVideoChannelTest, SetSendCodecsChangesExistingStreams) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004361 cricket::VideoSendParameters parameters;
perkj26752742016-10-24 01:21:16 -07004362 cricket::VideoCodec codec(100, "VP8");
4363 codec.SetParam(kCodecParamMaxQuantization, kDefaultQpMax);
4364 parameters.codecs.push_back(codec);
perkjfa10b552016-10-02 23:45:26 -07004365
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004366 ASSERT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org86196c42015-02-16 21:02:00 +00004367 channel_->SetSend(true);
pbos@webrtc.org38ce7d02014-07-16 08:01:38 +00004368
pbos@webrtc.org86196c42015-02-16 21:02:00 +00004369 FakeVideoSendStream* stream = AddSendStream();
Niels Möller805a27e2019-01-21 12:21:27 +01004370 webrtc::test::FrameForwarder frame_forwarder;
4371 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));
pbos@webrtc.org86196c42015-02-16 21:02:00 +00004372
4373 std::vector<webrtc::VideoStream> streams = stream->GetVideoStreams();
perkjfa10b552016-10-02 23:45:26 -07004374 EXPECT_EQ(kDefaultQpMax, streams[0].max_qp);
pbos@webrtc.org38ce7d02014-07-16 08:01:38 +00004375
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004376 parameters.codecs.clear();
perkj26752742016-10-24 01:21:16 -07004377 codec.SetParam(kCodecParamMaxQuantization, kDefaultQpMax + 1);
4378 parameters.codecs.push_back(codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004379 ASSERT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00004380 streams = fake_call_->GetVideoSendStreams()[0]->GetVideoStreams();
perkjfa10b552016-10-02 23:45:26 -07004381 EXPECT_EQ(kDefaultQpMax + 1, streams[0].max_qp);
Niels Möllerff40b142018-04-09 08:49:14 +02004382 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004383}
4384
eladalonf1841382017-06-12 01:16:46 -07004385TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithBitrates) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00004386 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
4387 200000);
4388}
4389
eladalonf1841382017-06-12 01:16:46 -07004390TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithHighMaxBitrate) {
pbos@webrtc.orga5f6fb52015-03-23 22:29:39 +00004391 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
4392 std::vector<webrtc::VideoStream> streams = AddSendStream()->GetVideoStreams();
4393 ASSERT_EQ(1u, streams.size());
4394 EXPECT_EQ(10000000, streams[0].max_bitrate_bps);
4395}
4396
eladalonf1841382017-06-12 01:16:46 -07004397TEST_F(WebRtcVideoChannelTest,
pbos@webrtc.org00873182014-11-25 14:03:34 +00004398 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
Sebastian Jansson8f83b422018-02-21 13:07:13 +01004399 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
pbos@webrtc.org00873182014-11-25 14:03:34 +00004400}
4401
eladalonf1841382017-06-12 01:16:46 -07004402TEST_F(WebRtcVideoChannelTest, SetSendCodecsCapsMinAndStartBitrate) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00004403 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004404}
4405
eladalonf1841382017-06-12 01:16:46 -07004406TEST_F(WebRtcVideoChannelTest, SetSendCodecsRejectsMaxLessThanMinBitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004407 send_parameters_.codecs[0].params[kCodecParamMinBitrate] = "300";
4408 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "200";
4409 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004410}
4411
Taylor Brandstetter58f2bd92016-04-26 17:15:23 -07004412// Test that when both the codec-specific bitrate params and max_bandwidth_bps
4413// are present in the same send parameters, the settings are combined correctly.
eladalonf1841382017-06-12 01:16:46 -07004414TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithBitratesAndMaxSendBandwidth) {
Taylor Brandstetter58f2bd92016-04-26 17:15:23 -07004415 send_parameters_.codecs[0].params[kCodecParamMinBitrate] = "100";
4416 send_parameters_.codecs[0].params[kCodecParamStartBitrate] = "200";
4417 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "300";
4418 send_parameters_.max_bandwidth_bps = 400000;
Taylor Brandstetter58f2bd92016-04-26 17:15:23 -07004419 // We expect max_bandwidth_bps to take priority, if set.
Sebastian Jansson8f83b422018-02-21 13:07:13 +01004420 ExpectSetBitrateParameters(100000, 200000, 400000);
4421 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
4422 // Since the codec isn't changing, start_bitrate_bps should be -1.
4423 ExpectSetBitrateParameters(100000, -1, 350000);
Taylor Brandstetter58f2bd92016-04-26 17:15:23 -07004424
4425 // Decrease max_bandwidth_bps.
4426 send_parameters_.max_bandwidth_bps = 350000;
4427 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Taylor Brandstetter58f2bd92016-04-26 17:15:23 -07004428
4429 // Now try again with the values flipped around.
4430 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "400";
4431 send_parameters_.max_bandwidth_bps = 300000;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01004432 ExpectSetBitrateParameters(100000, 200000, 300000);
Taylor Brandstetter58f2bd92016-04-26 17:15:23 -07004433 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Taylor Brandstetter58f2bd92016-04-26 17:15:23 -07004434
4435 // If we change the codec max, max_bandwidth_bps should still apply.
4436 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "350";
Sebastian Jansson8f83b422018-02-21 13:07:13 +01004437 ExpectSetBitrateParameters(100000, 200000, 300000);
Taylor Brandstetter58f2bd92016-04-26 17:15:23 -07004438 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Taylor Brandstetter58f2bd92016-04-26 17:15:23 -07004439}
4440
Yves Gerey665174f2018-06-19 15:03:05 +02004441TEST_F(WebRtcVideoChannelTest, SetMaxSendBandwidthShouldPreserveOtherBitrates) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00004442 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
4443 200000);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004444 send_parameters_.max_bandwidth_bps = 300000;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01004445 // Setting max bitrate should keep previous min bitrate.
4446 // Setting max bitrate should not reset start bitrate.
4447 ExpectSetBitrateParameters(100000, -1, 300000);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004448 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.org00873182014-11-25 14:03:34 +00004449}
4450
eladalonf1841382017-06-12 01:16:46 -07004451TEST_F(WebRtcVideoChannelTest, SetMaxSendBandwidthShouldBeRemovable) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004452 send_parameters_.max_bandwidth_bps = 300000;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01004453 ExpectSetMaxBitrate(300000);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004454 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos5c7760a2017-03-10 11:23:12 -08004455 // -1 means to disable max bitrate (set infinite).
4456 send_parameters_.max_bandwidth_bps = -1;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01004457 ExpectSetMaxBitrate(-1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004458 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004459}
4460
eladalonf1841382017-06-12 01:16:46 -07004461TEST_F(WebRtcVideoChannelTest, SetMaxSendBandwidthAndAddSendStream) {
perkjfa10b552016-10-02 23:45:26 -07004462 send_parameters_.max_bandwidth_bps = 99999;
4463 FakeVideoSendStream* stream = AddSendStream();
Sebastian Jansson8f83b422018-02-21 13:07:13 +01004464 ExpectSetMaxBitrate(send_parameters_.max_bandwidth_bps);
perkjfa10b552016-10-02 23:45:26 -07004465 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
perkjfa10b552016-10-02 23:45:26 -07004466 ASSERT_EQ(1u, stream->GetVideoStreams().size());
4467 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
4468 stream->GetVideoStreams()[0].max_bitrate_bps);
4469
4470 send_parameters_.max_bandwidth_bps = 77777;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01004471 ExpectSetMaxBitrate(send_parameters_.max_bandwidth_bps);
perkjfa10b552016-10-02 23:45:26 -07004472 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
4473 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
perkjfa10b552016-10-02 23:45:26 -07004474 stream->GetVideoStreams()[0].max_bitrate_bps);
4475}
4476
Seth Hampsonfeec91e2018-07-13 10:41:10 -07004477// Tests that when the codec specific max bitrate and VideoSendParameters
4478// max_bandwidth_bps are used, that it sets the VideoStream's max bitrate
4479// appropriately.
4480TEST_F(WebRtcVideoChannelTest,
4481 MaxBitratePrioritizesVideoSendParametersOverCodecMaxBitrate) {
4482 send_parameters_.codecs[0].params[kCodecParamMinBitrate] = "100";
4483 send_parameters_.codecs[0].params[kCodecParamStartBitrate] = "200";
4484 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "300";
4485 send_parameters_.max_bandwidth_bps = -1;
4486 AddSendStream();
4487 ExpectSetMaxBitrate(300000);
4488 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
4489
4490 std::vector<FakeVideoSendStream*> video_send_streams = GetFakeSendStreams();
4491 ASSERT_EQ(1u, video_send_streams.size());
4492 FakeVideoSendStream* video_send_stream = video_send_streams[0];
4493 ASSERT_EQ(1u, video_send_streams[0]->GetVideoStreams().size());
4494 // First the max bitrate is set based upon the codec param.
4495 EXPECT_EQ(300000,
4496 video_send_streams[0]->GetVideoStreams()[0].max_bitrate_bps);
4497
4498 // The VideoSendParameters max bitrate overrides the codec's.
4499 send_parameters_.max_bandwidth_bps = 500000;
4500 ExpectSetMaxBitrate(send_parameters_.max_bandwidth_bps);
4501 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
4502 ASSERT_EQ(1u, video_send_stream->GetVideoStreams().size());
4503 EXPECT_EQ(500000, video_send_stream->GetVideoStreams()[0].max_bitrate_bps);
4504}
4505
4506// Tests that when the codec specific max bitrate and RtpParameters
4507// max_bitrate_bps are used, that it sets the VideoStream's max bitrate
4508// appropriately.
4509TEST_F(WebRtcVideoChannelTest,
4510 MaxBitratePrioritizesRtpParametersOverCodecMaxBitrate) {
4511 send_parameters_.codecs[0].params[kCodecParamMinBitrate] = "100";
4512 send_parameters_.codecs[0].params[kCodecParamStartBitrate] = "200";
4513 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "300";
4514 send_parameters_.max_bandwidth_bps = -1;
4515 AddSendStream();
4516 ExpectSetMaxBitrate(300000);
4517 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
4518
4519 std::vector<FakeVideoSendStream*> video_send_streams = GetFakeSendStreams();
4520 ASSERT_EQ(1u, video_send_streams.size());
4521 FakeVideoSendStream* video_send_stream = video_send_streams[0];
4522 ASSERT_EQ(1u, video_send_stream->GetVideoStreams().size());
4523 // First the max bitrate is set based upon the codec param.
4524 EXPECT_EQ(300000, video_send_stream->GetVideoStreams()[0].max_bitrate_bps);
4525
4526 // The RtpParameter max bitrate overrides the codec's.
4527 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
4528 ASSERT_EQ(1u, parameters.encodings.size());
4529 parameters.encodings[0].max_bitrate_bps = 500000;
4530 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
4531 ASSERT_EQ(1u, video_send_stream->GetVideoStreams().size());
4532 EXPECT_EQ(parameters.encodings[0].max_bitrate_bps,
4533 video_send_stream->GetVideoStreams()[0].max_bitrate_bps);
4534}
4535
Åsa Persson55659812018-06-18 17:51:32 +02004536TEST_F(WebRtcVideoChannelTest,
4537 MaxBitrateIsMinimumOfMaxSendBandwidthAndMaxEncodingBitrate) {
4538 send_parameters_.max_bandwidth_bps = 99999;
4539 FakeVideoSendStream* stream = AddSendStream();
4540 ExpectSetMaxBitrate(send_parameters_.max_bandwidth_bps);
4541 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
4542 ASSERT_EQ(1u, stream->GetVideoStreams().size());
4543 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
4544 stream->GetVideoStreams()[0].max_bitrate_bps);
4545
4546 // Get and set the rtp encoding parameters.
4547 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
4548 EXPECT_EQ(1u, parameters.encodings.size());
4549
4550 parameters.encodings[0].max_bitrate_bps = 99999 - 1;
4551 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
4552 EXPECT_EQ(parameters.encodings[0].max_bitrate_bps,
4553 stream->GetVideoStreams()[0].max_bitrate_bps);
4554
4555 parameters.encodings[0].max_bitrate_bps = 99999 + 1;
4556 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
4557 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
4558 stream->GetVideoStreams()[0].max_bitrate_bps);
4559}
4560
eladalonf1841382017-06-12 01:16:46 -07004561TEST_F(WebRtcVideoChannelTest, SetMaxSendBitrateCanIncreaseSenderBitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004562 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004563 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004564 ASSERT_TRUE(channel_->SetSendParameters(parameters));
Peter Boströmdfd53fe2015-03-27 15:58:11 +01004565 channel_->SetSend(true);
4566
4567 FakeVideoSendStream* stream = AddSendStream();
4568
Niels Möller805a27e2019-01-21 12:21:27 +01004569 webrtc::test::FrameForwarder frame_forwarder;
4570 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));
Peter Boström3afc8c42016-01-27 16:45:21 +01004571
Peter Boströmdfd53fe2015-03-27 15:58:11 +01004572 std::vector<webrtc::VideoStream> streams = stream->GetVideoStreams();
4573 int initial_max_bitrate_bps = streams[0].max_bitrate_bps;
4574 EXPECT_GT(initial_max_bitrate_bps, 0);
4575
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004576 parameters.max_bandwidth_bps = initial_max_bitrate_bps * 2;
4577 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Peter Boström3afc8c42016-01-27 16:45:21 +01004578 // Insert a frame to update the encoder config.
Niels Möller805a27e2019-01-21 12:21:27 +01004579 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Peter Boströmdfd53fe2015-03-27 15:58:11 +01004580 streams = stream->GetVideoStreams();
4581 EXPECT_EQ(initial_max_bitrate_bps * 2, streams[0].max_bitrate_bps);
Niels Möllerff40b142018-04-09 08:49:14 +02004582 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
Peter Boströmdfd53fe2015-03-27 15:58:11 +01004583}
4584
eladalonf1841382017-06-12 01:16:46 -07004585TEST_F(WebRtcVideoChannelTest,
Peter Boströmdfd53fe2015-03-27 15:58:11 +01004586 SetMaxSendBitrateCanIncreaseSimulcastSenderBitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004587 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004588 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004589 ASSERT_TRUE(channel_->SetSendParameters(parameters));
Peter Boströmdfd53fe2015-03-27 15:58:11 +01004590 channel_->SetSend(true);
4591
4592 FakeVideoSendStream* stream = AddSendStream(
4593 cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kSsrcs3)));
4594
4595 // Send a frame to make sure this scales up to >1 stream (simulcast).
Niels Möller805a27e2019-01-21 12:21:27 +01004596 webrtc::test::FrameForwarder frame_forwarder;
4597 EXPECT_TRUE(channel_->SetVideoSend(kSsrcs3[0], nullptr, &frame_forwarder));
4598 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Peter Boströmdfd53fe2015-03-27 15:58:11 +01004599
4600 std::vector<webrtc::VideoStream> streams = stream->GetVideoStreams();
4601 ASSERT_GT(streams.size(), 1u)
4602 << "Without simulcast this test doesn't make sense.";
Oskar Segersvärddc81e112020-02-12 16:45:53 +01004603 int initial_max_bitrate_bps = GetTotalMaxBitrate(streams).bps();
Peter Boströmdfd53fe2015-03-27 15:58:11 +01004604 EXPECT_GT(initial_max_bitrate_bps, 0);
4605
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004606 parameters.max_bandwidth_bps = initial_max_bitrate_bps * 2;
4607 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Peter Boström3afc8c42016-01-27 16:45:21 +01004608 // Insert a frame to update the encoder config.
Niels Möller805a27e2019-01-21 12:21:27 +01004609 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Peter Boströmdfd53fe2015-03-27 15:58:11 +01004610 streams = stream->GetVideoStreams();
Oskar Segersvärddc81e112020-02-12 16:45:53 +01004611 int increased_max_bitrate_bps = GetTotalMaxBitrate(streams).bps();
Peter Boströmdfd53fe2015-03-27 15:58:11 +01004612 EXPECT_EQ(initial_max_bitrate_bps * 2, increased_max_bitrate_bps);
4613
Niels Möllerff40b142018-04-09 08:49:14 +02004614 EXPECT_TRUE(channel_->SetVideoSend(kSsrcs3[0], nullptr, nullptr));
Peter Boströmdfd53fe2015-03-27 15:58:11 +01004615}
4616
eladalonf1841382017-06-12 01:16:46 -07004617TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithMaxQuantization) {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004618 static const char* kMaxQuantization = "21";
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004619 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004620 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004621 parameters.codecs[0].params[kCodecParamMaxQuantization] = kMaxQuantization;
4622 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Mirko Bonadeif859e552018-05-30 15:31:29 +02004623 EXPECT_EQ(atoi(kMaxQuantization),
pbos@webrtc.org6ae48c62014-06-06 10:49:19 +00004624 AddSendStream()->GetVideoStreams().back().max_qp);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004625
4626 VideoCodec codec;
4627 EXPECT_TRUE(channel_->GetSendCodec(&codec));
4628 EXPECT_EQ(kMaxQuantization, codec.params[kCodecParamMaxQuantization]);
4629}
4630
eladalonf1841382017-06-12 01:16:46 -07004631TEST_F(WebRtcVideoChannelTest, SetSendCodecsRejectBadPayloadTypes) {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004632 // TODO(pbos): Should we only allow the dynamic range?
pkasting@chromium.orge7a4a122015-01-28 21:36:55 +00004633 static const int kIncorrectPayloads[] = {-2, -1, 128, 129};
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004634 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004635 parameters.codecs.push_back(GetEngineCodec("VP8"));
pkasting@chromium.orge7a4a122015-01-28 21:36:55 +00004636 for (size_t i = 0; i < arraysize(kIncorrectPayloads); ++i) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004637 parameters.codecs[0].id = kIncorrectPayloads[i];
4638 EXPECT_FALSE(channel_->SetSendParameters(parameters))
pkasting@chromium.orgd3245462015-02-23 21:28:22 +00004639 << "Bad payload type '" << kIncorrectPayloads[i] << "' accepted.";
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004640 }
4641}
4642
eladalonf1841382017-06-12 01:16:46 -07004643TEST_F(WebRtcVideoChannelTest, SetSendCodecsAcceptAllValidPayloadTypes) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004644 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004645 parameters.codecs.push_back(GetEngineCodec("VP8"));
magjedf823ede2016-11-12 09:53:04 -08004646 for (int payload_type = 96; payload_type <= 127; ++payload_type) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004647 parameters.codecs[0].id = payload_type;
4648 EXPECT_TRUE(channel_->SetSendParameters(parameters))
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004649 << "Payload type '" << payload_type << "' rejected.";
4650 }
4651}
4652
deadbeef67cf2c12016-04-13 10:07:16 -07004653// Test that setting the a different set of codecs but with an identical front
4654// codec doesn't result in the stream being recreated.
4655// This may happen when a subsequent negotiation includes fewer codecs, as a
4656// result of one of the codecs being rejected.
eladalonf1841382017-06-12 01:16:46 -07004657TEST_F(WebRtcVideoChannelTest,
deadbeef67cf2c12016-04-13 10:07:16 -07004658 SetSendCodecsIdenticalFirstCodecDoesntRecreateStream) {
4659 cricket::VideoSendParameters parameters1;
magjed509e4fe2016-11-18 01:34:11 -08004660 parameters1.codecs.push_back(GetEngineCodec("VP8"));
4661 parameters1.codecs.push_back(GetEngineCodec("VP9"));
deadbeef67cf2c12016-04-13 10:07:16 -07004662 EXPECT_TRUE(channel_->SetSendParameters(parameters1));
4663
4664 AddSendStream();
4665 EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());
4666
4667 cricket::VideoSendParameters parameters2;
magjed509e4fe2016-11-18 01:34:11 -08004668 parameters2.codecs.push_back(GetEngineCodec("VP8"));
deadbeef67cf2c12016-04-13 10:07:16 -07004669 EXPECT_TRUE(channel_->SetSendParameters(parameters2));
4670 EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());
4671}
4672
eladalonf1841382017-06-12 01:16:46 -07004673TEST_F(WebRtcVideoChannelTest, SetRecvCodecsWithOnlyVp8) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004674 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004675 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004676 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004677}
4678
pbos@webrtc.orge322a172014-06-13 11:47:28 +00004679// Test that we set our inbound RTX codecs properly.
eladalonf1841382017-06-12 01:16:46 -07004680TEST_F(WebRtcVideoChannelTest, SetRecvCodecsWithRtx) {
magjed509e4fe2016-11-18 01:34:11 -08004681 const int kUnusedPayloadType1 = 126;
4682 const int kUnusedPayloadType2 = 127;
Johannes Kron3e983682020-03-29 22:17:00 +02004683 EXPECT_FALSE(FindCodecById(engine_.recv_codecs(), kUnusedPayloadType1));
4684 EXPECT_FALSE(FindCodecById(engine_.recv_codecs(), kUnusedPayloadType2));
magjed509e4fe2016-11-18 01:34:11 -08004685
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004686 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004687 parameters.codecs.push_back(GetEngineCodec("VP8"));
4688 cricket::VideoCodec rtx_codec(kUnusedPayloadType1, "rtx");
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004689 parameters.codecs.push_back(rtx_codec);
4690 EXPECT_FALSE(channel_->SetRecvParameters(parameters))
pbos@webrtc.orge322a172014-06-13 11:47:28 +00004691 << "RTX codec without associated payload should be rejected.";
4692
magjed509e4fe2016-11-18 01:34:11 -08004693 parameters.codecs[1].SetParam("apt", kUnusedPayloadType2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004694 EXPECT_FALSE(channel_->SetRecvParameters(parameters))
pbos@webrtc.orge322a172014-06-13 11:47:28 +00004695 << "RTX codec with invalid associated payload type should be rejected.";
4696
magjed509e4fe2016-11-18 01:34:11 -08004697 parameters.codecs[1].SetParam("apt", GetEngineCodec("VP8").id);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004698 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orge322a172014-06-13 11:47:28 +00004699
magjed509e4fe2016-11-18 01:34:11 -08004700 cricket::VideoCodec rtx_codec2(kUnusedPayloadType2, "rtx");
pbos@webrtc.orge322a172014-06-13 11:47:28 +00004701 rtx_codec2.SetParam("apt", rtx_codec.id);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004702 parameters.codecs.push_back(rtx_codec2);
pbos@webrtc.orge322a172014-06-13 11:47:28 +00004703
Yves Gerey665174f2018-06-19 15:03:05 +02004704 EXPECT_FALSE(channel_->SetRecvParameters(parameters))
4705 << "RTX codec with another RTX as associated payload type should be "
4706 "rejected.";
pbos@webrtc.orge322a172014-06-13 11:47:28 +00004707}
4708
Mirta Dvornicic479a3c02019-06-04 15:38:50 +02004709TEST_F(WebRtcVideoChannelTest, SetRecvCodecsWithPacketization) {
4710 cricket::VideoCodec vp8_codec = GetEngineCodec("VP8");
4711 vp8_codec.packetization = kPacketizationParamRaw;
4712
4713 cricket::VideoRecvParameters parameters;
4714 parameters.codecs = {vp8_codec, GetEngineCodec("VP9")};
4715 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
4716
4717 const cricket::StreamParams params =
4718 cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
4719 AddRecvStream(params);
4720 ASSERT_THAT(fake_call_->GetVideoReceiveStreams(), testing::SizeIs(1));
4721
4722 const webrtc::VideoReceiveStream::Config& config =
4723 fake_call_->GetVideoReceiveStreams()[0]->GetConfig();
4724 ASSERT_THAT(config.rtp.raw_payload_types, testing::SizeIs(1));
4725 EXPECT_EQ(config.rtp.raw_payload_types.count(vp8_codec.id), 1U);
4726}
4727
4728TEST_F(WebRtcVideoChannelTest, SetRecvCodecsWithPacketizationRecreatesStream) {
4729 cricket::VideoRecvParameters parameters;
4730 parameters.codecs = {GetEngineCodec("VP8"), GetEngineCodec("VP9")};
4731 parameters.codecs.back().packetization = kPacketizationParamRaw;
4732 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
4733
4734 const cricket::StreamParams params =
4735 cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
4736 AddRecvStream(params);
4737 ASSERT_THAT(fake_call_->GetVideoReceiveStreams(), testing::SizeIs(1));
4738 EXPECT_EQ(fake_call_->GetNumCreatedReceiveStreams(), 1);
4739
4740 parameters.codecs.back().packetization.reset();
4741 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
4742 EXPECT_EQ(fake_call_->GetNumCreatedReceiveStreams(), 2);
4743}
4744
Steve Anton2d2bbb12019-08-07 09:57:59 -07004745TEST_F(WebRtcVideoChannelTest, DuplicateUlpfecCodecIsDropped) {
4746 constexpr int kFirstUlpfecPayloadType = 126;
4747 constexpr int kSecondUlpfecPayloadType = 127;
4748
4749 cricket::VideoRecvParameters parameters;
4750 parameters.codecs.push_back(GetEngineCodec("VP8"));
4751 parameters.codecs.push_back(
4752 cricket::VideoCodec(kFirstUlpfecPayloadType, cricket::kUlpfecCodecName));
4753 parameters.codecs.push_back(
4754 cricket::VideoCodec(kSecondUlpfecPayloadType, cricket::kUlpfecCodecName));
4755 ASSERT_TRUE(channel_->SetRecvParameters(parameters));
4756
4757 FakeVideoReceiveStream* recv_stream = AddRecvStream();
4758 EXPECT_EQ(kFirstUlpfecPayloadType,
4759 recv_stream->GetConfig().rtp.ulpfec_payload_type);
4760}
4761
4762TEST_F(WebRtcVideoChannelTest, DuplicateRedCodecIsDropped) {
4763 constexpr int kFirstRedPayloadType = 126;
4764 constexpr int kSecondRedPayloadType = 127;
4765
4766 cricket::VideoRecvParameters parameters;
4767 parameters.codecs.push_back(GetEngineCodec("VP8"));
4768 parameters.codecs.push_back(
4769 cricket::VideoCodec(kFirstRedPayloadType, cricket::kRedCodecName));
4770 parameters.codecs.push_back(
4771 cricket::VideoCodec(kSecondRedPayloadType, cricket::kRedCodecName));
4772 ASSERT_TRUE(channel_->SetRecvParameters(parameters));
4773
4774 FakeVideoReceiveStream* recv_stream = AddRecvStream();
4775 EXPECT_EQ(kFirstRedPayloadType,
4776 recv_stream->GetConfig().rtp.red_payload_type);
4777}
4778
eladalonf1841382017-06-12 01:16:46 -07004779TEST_F(WebRtcVideoChannelTest, SetRecvCodecsWithChangedRtxPayloadType) {
brandtr14742122017-01-27 04:53:07 -08004780 const int kUnusedPayloadType1 = 126;
4781 const int kUnusedPayloadType2 = 127;
Johannes Kron3e983682020-03-29 22:17:00 +02004782 EXPECT_FALSE(FindCodecById(engine_.recv_codecs(), kUnusedPayloadType1));
4783 EXPECT_FALSE(FindCodecById(engine_.recv_codecs(), kUnusedPayloadType2));
brandtr14742122017-01-27 04:53:07 -08004784
4785 // SSRCs for RTX.
4786 cricket::StreamParams params =
4787 cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
4788 params.AddFidSsrc(kSsrcs1[0], kRtxSsrcs1[0]);
4789 AddRecvStream(params);
4790
4791 // Original payload type for RTX.
4792 cricket::VideoRecvParameters parameters;
4793 parameters.codecs.push_back(GetEngineCodec("VP8"));
4794 cricket::VideoCodec rtx_codec(kUnusedPayloadType1, "rtx");
4795 rtx_codec.SetParam("apt", GetEngineCodec("VP8").id);
4796 parameters.codecs.push_back(rtx_codec);
4797 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
4798 ASSERT_EQ(1U, fake_call_->GetVideoReceiveStreams().size());
4799 const webrtc::VideoReceiveStream::Config& config_before =
4800 fake_call_->GetVideoReceiveStreams()[0]->GetConfig();
nisse26e3abb2017-08-25 04:44:25 -07004801 EXPECT_EQ(1U, config_before.rtp.rtx_associated_payload_types.size());
4802 const int* payload_type_before = FindKeyByValue(
4803 config_before.rtp.rtx_associated_payload_types, GetEngineCodec("VP8").id);
4804 ASSERT_NE(payload_type_before, nullptr);
4805 EXPECT_EQ(kUnusedPayloadType1, *payload_type_before);
brandtr14742122017-01-27 04:53:07 -08004806 EXPECT_EQ(kRtxSsrcs1[0], config_before.rtp.rtx_ssrc);
4807
4808 // Change payload type for RTX.
4809 parameters.codecs[1].id = kUnusedPayloadType2;
4810 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
4811 ASSERT_EQ(1U, fake_call_->GetVideoReceiveStreams().size());
4812 const webrtc::VideoReceiveStream::Config& config_after =
4813 fake_call_->GetVideoReceiveStreams()[0]->GetConfig();
nisse26e3abb2017-08-25 04:44:25 -07004814 EXPECT_EQ(1U, config_after.rtp.rtx_associated_payload_types.size());
4815 const int* payload_type_after = FindKeyByValue(
4816 config_after.rtp.rtx_associated_payload_types, GetEngineCodec("VP8").id);
4817 ASSERT_NE(payload_type_after, nullptr);
4818 EXPECT_EQ(kUnusedPayloadType2, *payload_type_after);
brandtr14742122017-01-27 04:53:07 -08004819 EXPECT_EQ(kRtxSsrcs1[0], config_after.rtp.rtx_ssrc);
4820}
4821
eladalonf1841382017-06-12 01:16:46 -07004822TEST_F(WebRtcVideoChannelTest, SetRecvCodecsDifferentPayloadType) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004823 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004824 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004825 parameters.codecs[0].id = 99;
4826 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004827}
4828
eladalonf1841382017-06-12 01:16:46 -07004829TEST_F(WebRtcVideoChannelTest, SetRecvCodecsAcceptDefaultCodecs) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004830 cricket::VideoRecvParameters parameters;
Johannes Kron3e983682020-03-29 22:17:00 +02004831 parameters.codecs = engine_.recv_codecs();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004832 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgccbed3b2014-07-11 13:02:54 +00004833
4834 FakeVideoReceiveStream* stream = AddRecvStream();
Tommi733b5472016-06-10 17:58:01 +02004835 const webrtc::VideoReceiveStream::Config& config = stream->GetConfig();
Johannes Kron3e983682020-03-29 22:17:00 +02004836 EXPECT_EQ(engine_.recv_codecs()[0].name,
4837 config.decoders[0].video_format.name);
4838 EXPECT_EQ(engine_.recv_codecs()[0].id, config.decoders[0].payload_type);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004839}
4840
eladalonf1841382017-06-12 01:16:46 -07004841TEST_F(WebRtcVideoChannelTest, SetRecvCodecsRejectUnsupportedCodec) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004842 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004843 parameters.codecs.push_back(GetEngineCodec("VP8"));
perkj26752742016-10-24 01:21:16 -07004844 parameters.codecs.push_back(VideoCodec(101, "WTF3"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004845 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004846}
4847
eladalonf1841382017-06-12 01:16:46 -07004848TEST_F(WebRtcVideoChannelTest, SetRecvCodecsAcceptsMultipleVideoCodecs) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004849 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004850 parameters.codecs.push_back(GetEngineCodec("VP8"));
4851 parameters.codecs.push_back(GetEngineCodec("VP9"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004852 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004853}
4854
eladalonf1841382017-06-12 01:16:46 -07004855TEST_F(WebRtcVideoChannelTest, SetRecvCodecsWithoutFecDisablesFec) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004856 cricket::VideoSendParameters send_parameters;
magjed509e4fe2016-11-18 01:34:11 -08004857 send_parameters.codecs.push_back(GetEngineCodec("VP8"));
4858 send_parameters.codecs.push_back(GetEngineCodec("red"));
4859 send_parameters.codecs.push_back(GetEngineCodec("ulpfec"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004860 ASSERT_TRUE(channel_->SetSendParameters(send_parameters));
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00004861
4862 FakeVideoReceiveStream* stream = AddRecvStream();
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00004863
magjed509e4fe2016-11-18 01:34:11 -08004864 EXPECT_EQ(GetEngineCodec("ulpfec").id,
nisse3b3622f2017-09-26 02:49:21 -07004865 stream->GetConfig().rtp.ulpfec_payload_type);
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00004866
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004867 cricket::VideoRecvParameters recv_parameters;
magjed509e4fe2016-11-18 01:34:11 -08004868 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004869 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00004870 stream = fake_call_->GetVideoReceiveStreams()[0];
brandtr468da7c2016-11-22 02:16:47 -08004871 ASSERT_TRUE(stream != nullptr);
nisse3b3622f2017-09-26 02:49:21 -07004872 EXPECT_EQ(-1, stream->GetConfig().rtp.ulpfec_payload_type)
brandtr468da7c2016-11-22 02:16:47 -08004873 << "SetSendCodec without ULPFEC should disable current ULPFEC.";
4874}
4875
eladalonf1841382017-06-12 01:16:46 -07004876TEST_F(WebRtcVideoChannelFlexfecRecvTest, SetRecvParamsWithoutFecDisablesFec) {
brandtr468da7c2016-11-22 02:16:47 -08004877 AddRecvStream(
4878 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
brandtr9c3d4c42017-01-23 06:59:13 -08004879 const std::vector<FakeFlexfecReceiveStream*>& streams =
brandtr468da7c2016-11-22 02:16:47 -08004880 fake_call_->GetFlexfecReceiveStreams();
4881
4882 ASSERT_EQ(1U, streams.size());
brandtr9c3d4c42017-01-23 06:59:13 -08004883 const FakeFlexfecReceiveStream* stream = streams.front();
4884 EXPECT_EQ(GetEngineCodec("flexfec-03").id, stream->GetConfig().payload_type);
4885 EXPECT_EQ(kFlexfecSsrc, stream->GetConfig().remote_ssrc);
4886 ASSERT_EQ(1U, stream->GetConfig().protected_media_ssrcs.size());
4887 EXPECT_EQ(kSsrcs1[0], stream->GetConfig().protected_media_ssrcs[0]);
brandtr468da7c2016-11-22 02:16:47 -08004888
4889 cricket::VideoRecvParameters recv_parameters;
4890 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
4891 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
4892 EXPECT_TRUE(streams.empty())
4893 << "SetSendCodec without FlexFEC should disable current FlexFEC.";
pbos@webrtc.org269605c2014-06-26 08:49:03 +00004894}
4895
eladalonf1841382017-06-12 01:16:46 -07004896TEST_F(WebRtcVideoChannelTest, SetSendParamsWithFecEnablesFec) {
Stefan Holmer2b1f6512016-05-17 16:33:30 +02004897 FakeVideoReceiveStream* stream = AddRecvStream();
magjed509e4fe2016-11-18 01:34:11 -08004898 EXPECT_EQ(GetEngineCodec("ulpfec").id,
nisse3b3622f2017-09-26 02:49:21 -07004899 stream->GetConfig().rtp.ulpfec_payload_type);
Stefan Holmer2b1f6512016-05-17 16:33:30 +02004900
4901 cricket::VideoRecvParameters recv_parameters;
magjed509e4fe2016-11-18 01:34:11 -08004902 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
4903 recv_parameters.codecs.push_back(GetEngineCodec("red"));
4904 recv_parameters.codecs.push_back(GetEngineCodec("ulpfec"));
Stefan Holmer2b1f6512016-05-17 16:33:30 +02004905 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
4906 stream = fake_call_->GetVideoReceiveStreams()[0];
brandtr468da7c2016-11-22 02:16:47 -08004907 ASSERT_TRUE(stream != nullptr);
magjed509e4fe2016-11-18 01:34:11 -08004908 EXPECT_EQ(GetEngineCodec("ulpfec").id,
nisse3b3622f2017-09-26 02:49:21 -07004909 stream->GetConfig().rtp.ulpfec_payload_type)
brandtr468da7c2016-11-22 02:16:47 -08004910 << "ULPFEC should be enabled on the receive stream.";
Stefan Holmer2b1f6512016-05-17 16:33:30 +02004911
4912 cricket::VideoSendParameters send_parameters;
magjed509e4fe2016-11-18 01:34:11 -08004913 send_parameters.codecs.push_back(GetEngineCodec("VP8"));
4914 send_parameters.codecs.push_back(GetEngineCodec("red"));
4915 send_parameters.codecs.push_back(GetEngineCodec("ulpfec"));
Stefan Holmer2b1f6512016-05-17 16:33:30 +02004916 ASSERT_TRUE(channel_->SetSendParameters(send_parameters));
4917 stream = fake_call_->GetVideoReceiveStreams()[0];
magjed509e4fe2016-11-18 01:34:11 -08004918 EXPECT_EQ(GetEngineCodec("ulpfec").id,
nisse3b3622f2017-09-26 02:49:21 -07004919 stream->GetConfig().rtp.ulpfec_payload_type)
brandtr468da7c2016-11-22 02:16:47 -08004920 << "ULPFEC should be enabled on the receive stream.";
4921}
4922
eladalonf1841382017-06-12 01:16:46 -07004923TEST_F(WebRtcVideoChannelFlexfecSendRecvTest,
brandtr31bd2242017-05-19 05:47:46 -07004924 SetSendRecvParamsWithFecEnablesFec) {
brandtr468da7c2016-11-22 02:16:47 -08004925 AddRecvStream(
4926 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
brandtr9c3d4c42017-01-23 06:59:13 -08004927 const std::vector<FakeFlexfecReceiveStream*>& streams =
brandtr468da7c2016-11-22 02:16:47 -08004928 fake_call_->GetFlexfecReceiveStreams();
4929
4930 cricket::VideoRecvParameters recv_parameters;
4931 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
4932 recv_parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
4933 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
4934 ASSERT_EQ(1U, streams.size());
brandtr9c3d4c42017-01-23 06:59:13 -08004935 const FakeFlexfecReceiveStream* stream_with_recv_params = streams.front();
brandtr468da7c2016-11-22 02:16:47 -08004936 EXPECT_EQ(GetEngineCodec("flexfec-03").id,
brandtr9c3d4c42017-01-23 06:59:13 -08004937 stream_with_recv_params->GetConfig().payload_type);
4938 EXPECT_EQ(kFlexfecSsrc, stream_with_recv_params->GetConfig().remote_ssrc);
brandtr468da7c2016-11-22 02:16:47 -08004939 EXPECT_EQ(1U,
brandtr9c3d4c42017-01-23 06:59:13 -08004940 stream_with_recv_params->GetConfig().protected_media_ssrcs.size());
brandtr468da7c2016-11-22 02:16:47 -08004941 EXPECT_EQ(kSsrcs1[0],
brandtr9c3d4c42017-01-23 06:59:13 -08004942 stream_with_recv_params->GetConfig().protected_media_ssrcs[0]);
brandtr468da7c2016-11-22 02:16:47 -08004943
4944 cricket::VideoSendParameters send_parameters;
4945 send_parameters.codecs.push_back(GetEngineCodec("VP8"));
4946 send_parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
4947 ASSERT_TRUE(channel_->SetSendParameters(send_parameters));
4948 ASSERT_EQ(1U, streams.size());
brandtr9c3d4c42017-01-23 06:59:13 -08004949 const FakeFlexfecReceiveStream* stream_with_send_params = streams.front();
brandtr468da7c2016-11-22 02:16:47 -08004950 EXPECT_EQ(GetEngineCodec("flexfec-03").id,
brandtr9c3d4c42017-01-23 06:59:13 -08004951 stream_with_send_params->GetConfig().payload_type);
4952 EXPECT_EQ(kFlexfecSsrc, stream_with_send_params->GetConfig().remote_ssrc);
brandtr468da7c2016-11-22 02:16:47 -08004953 EXPECT_EQ(1U,
brandtr9c3d4c42017-01-23 06:59:13 -08004954 stream_with_send_params->GetConfig().protected_media_ssrcs.size());
brandtr468da7c2016-11-22 02:16:47 -08004955 EXPECT_EQ(kSsrcs1[0],
brandtr9c3d4c42017-01-23 06:59:13 -08004956 stream_with_send_params->GetConfig().protected_media_ssrcs[0]);
Stefan Holmer2b1f6512016-05-17 16:33:30 +02004957}
4958
eladalonf1841382017-06-12 01:16:46 -07004959TEST_F(WebRtcVideoChannelTest, SetRecvCodecsRejectDuplicateFecPayloads) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004960 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004961 parameters.codecs.push_back(GetEngineCodec("VP8"));
4962 parameters.codecs.push_back(GetEngineCodec("red"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004963 parameters.codecs[1].id = parameters.codecs[0].id;
4964 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004965}
4966
eladalonf1841382017-06-12 01:16:46 -07004967TEST_F(WebRtcVideoChannelFlexfecRecvTest,
brandtr31bd2242017-05-19 05:47:46 -07004968 SetRecvCodecsRejectDuplicateFecPayloads) {
brandtr468da7c2016-11-22 02:16:47 -08004969 cricket::VideoRecvParameters parameters;
4970 parameters.codecs.push_back(GetEngineCodec("VP8"));
4971 parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
4972 parameters.codecs[1].id = parameters.codecs[0].id;
4973 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
4974}
4975
eladalonf1841382017-06-12 01:16:46 -07004976TEST_F(WebRtcVideoChannelTest, SetRecvCodecsRejectDuplicateCodecPayloads) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004977 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004978 parameters.codecs.push_back(GetEngineCodec("VP8"));
4979 parameters.codecs.push_back(GetEngineCodec("VP9"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004980 parameters.codecs[1].id = parameters.codecs[0].id;
4981 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004982}
4983
eladalonf1841382017-06-12 01:16:46 -07004984TEST_F(WebRtcVideoChannelTest,
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004985 SetRecvCodecsAcceptSameCodecOnMultiplePayloadTypes) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004986 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004987 parameters.codecs.push_back(GetEngineCodec("VP8"));
4988 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004989 parameters.codecs[1].id += 1;
4990 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004991}
4992
deadbeef67cf2c12016-04-13 10:07:16 -07004993// Test that setting the same codecs but with a different order
deadbeef874ca3a2015-08-20 17:19:20 -07004994// doesn't result in the stream being recreated.
eladalonf1841382017-06-12 01:16:46 -07004995TEST_F(WebRtcVideoChannelTest,
deadbeef67cf2c12016-04-13 10:07:16 -07004996 SetRecvCodecsDifferentOrderDoesntRecreateStream) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004997 cricket::VideoRecvParameters parameters1;
magjed509e4fe2016-11-18 01:34:11 -08004998 parameters1.codecs.push_back(GetEngineCodec("VP8"));
4999 parameters1.codecs.push_back(GetEngineCodec("red"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02005000 EXPECT_TRUE(channel_->SetRecvParameters(parameters1));
deadbeef874ca3a2015-08-20 17:19:20 -07005001
5002 AddRecvStream(cricket::StreamParams::CreateLegacy(123));
5003 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
5004
Fredrik Solenbergb071a192015-09-17 16:42:56 +02005005 cricket::VideoRecvParameters parameters2;
magjed509e4fe2016-11-18 01:34:11 -08005006 parameters2.codecs.push_back(GetEngineCodec("red"));
5007 parameters2.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02005008 EXPECT_TRUE(channel_->SetRecvParameters(parameters2));
deadbeef874ca3a2015-08-20 17:19:20 -07005009 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
5010}
5011
eladalonf1841382017-06-12 01:16:46 -07005012TEST_F(WebRtcVideoChannelTest, SendStreamNotSendingByDefault) {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00005013 EXPECT_FALSE(AddSendStream()->IsSending());
5014}
5015
eladalonf1841382017-06-12 01:16:46 -07005016TEST_F(WebRtcVideoChannelTest, ReceiveStreamReceivingByDefault) {
pbos@webrtc.org85f42942014-07-22 09:14:58 +00005017 EXPECT_TRUE(AddRecvStream()->IsReceiving());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00005018}
5019
eladalonf1841382017-06-12 01:16:46 -07005020TEST_F(WebRtcVideoChannelTest, SetSend) {
pbos@webrtc.org5301b0f2014-07-17 08:51:46 +00005021 FakeVideoSendStream* stream = AddSendStream();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00005022 EXPECT_FALSE(stream->IsSending());
5023
5024 // false->true
5025 EXPECT_TRUE(channel_->SetSend(true));
5026 EXPECT_TRUE(stream->IsSending());
5027 // true->true
5028 EXPECT_TRUE(channel_->SetSend(true));
5029 EXPECT_TRUE(stream->IsSending());
5030 // true->false
5031 EXPECT_TRUE(channel_->SetSend(false));
5032 EXPECT_FALSE(stream->IsSending());
5033 // false->false
5034 EXPECT_TRUE(channel_->SetSend(false));
5035 EXPECT_FALSE(stream->IsSending());
5036
5037 EXPECT_TRUE(channel_->SetSend(true));
5038 FakeVideoSendStream* new_stream = AddSendStream();
5039 EXPECT_TRUE(new_stream->IsSending())
5040 << "Send stream created after SetSend(true) not sending initially.";
5041}
5042
pbos@webrtc.orgd8198032014-11-10 14:41:43 +00005043// This test verifies DSCP settings are properly applied on video media channel.
eladalonf1841382017-06-12 01:16:46 -07005044TEST_F(WebRtcVideoChannelTest, TestSetDscpOptions) {
kwiberg686a8ef2016-02-26 03:00:35 -08005045 std::unique_ptr<cricket::FakeNetworkInterface> network_interface(
pbos@webrtc.orgd8198032014-11-10 14:41:43 +00005046 new cricket::FakeNetworkInterface);
nisse51542be2016-02-12 02:27:06 -08005047 MediaConfig config;
Tim Haloun6ca98362018-09-17 17:06:08 -07005048 std::unique_ptr<cricket::WebRtcVideoChannel> channel;
Tim Haloun648d28a2018-10-18 16:52:22 -07005049 webrtc::RtpParameters parameters;
nisse51542be2016-02-12 02:27:06 -08005050
Sebastian Jansson84848f22018-11-16 10:40:36 +01005051 channel.reset(
5052 static_cast<cricket::WebRtcVideoChannel*>(engine_.CreateMediaChannel(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02005053 call_.get(), config, VideoOptions(), webrtc::CryptoOptions(),
5054 video_bitrate_allocator_factory_.get())));
Anton Sukhanov4f08faa2019-05-21 11:12:57 -07005055 channel->SetInterface(network_interface.get(),
5056 webrtc::MediaTransportConfig());
nisse51542be2016-02-12 02:27:06 -08005057 // Default value when DSCP is disabled should be DSCP_DEFAULT.
pbos@webrtc.orgd8198032014-11-10 14:41:43 +00005058 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface->dscp());
nisse51542be2016-02-12 02:27:06 -08005059
Tim Haloun648d28a2018-10-18 16:52:22 -07005060 // Default value when DSCP is enabled is also DSCP_DEFAULT, until it is set
5061 // through rtp parameters.
nisse51542be2016-02-12 02:27:06 -08005062 config.enable_dscp = true;
Sebastian Jansson84848f22018-11-16 10:40:36 +01005063 channel.reset(
5064 static_cast<cricket::WebRtcVideoChannel*>(engine_.CreateMediaChannel(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02005065 call_.get(), config, VideoOptions(), webrtc::CryptoOptions(),
5066 video_bitrate_allocator_factory_.get())));
Anton Sukhanov4f08faa2019-05-21 11:12:57 -07005067 channel->SetInterface(network_interface.get(),
5068 webrtc::MediaTransportConfig());
Tim Haloun648d28a2018-10-18 16:52:22 -07005069 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface->dscp());
5070
5071 // Create a send stream to configure
5072 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(kSsrc)));
5073 parameters = channel->GetRtpSendParameters(kSsrc);
5074 ASSERT_FALSE(parameters.encodings.empty());
5075
5076 // Various priorities map to various dscp values.
Taylor Brandstetter3f1aee32020-02-27 11:59:23 -08005077 parameters.encodings[0].network_priority = webrtc::Priority::kHigh;
Tim Haloun648d28a2018-10-18 16:52:22 -07005078 ASSERT_TRUE(channel->SetRtpSendParameters(kSsrc, parameters).ok());
nisse51542be2016-02-12 02:27:06 -08005079 EXPECT_EQ(rtc::DSCP_AF41, network_interface->dscp());
Taylor Brandstetter3f1aee32020-02-27 11:59:23 -08005080 parameters.encodings[0].network_priority = webrtc::Priority::kVeryLow;
Tim Haloun648d28a2018-10-18 16:52:22 -07005081 ASSERT_TRUE(channel->SetRtpSendParameters(kSsrc, parameters).ok());
5082 EXPECT_EQ(rtc::DSCP_CS1, network_interface->dscp());
5083
Tim Haloun6ca98362018-09-17 17:06:08 -07005084 // Packets should also self-identify their dscp in PacketOptions.
5085 const uint8_t kData[10] = {0};
5086 EXPECT_TRUE(static_cast<webrtc::Transport*>(channel.get())
5087 ->SendRtcp(kData, sizeof(kData)));
Tim Haloun648d28a2018-10-18 16:52:22 -07005088 EXPECT_EQ(rtc::DSCP_CS1, network_interface->options().dscp);
Tim Haloun6ca98362018-09-17 17:06:08 -07005089
nisse51542be2016-02-12 02:27:06 -08005090 // Verify that setting the option to false resets the
5091 // DiffServCodePoint.
5092 config.enable_dscp = false;
Sebastian Jansson84848f22018-11-16 10:40:36 +01005093 channel.reset(
5094 static_cast<cricket::WebRtcVideoChannel*>(engine_.CreateMediaChannel(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02005095 call_.get(), config, VideoOptions(), webrtc::CryptoOptions(),
5096 video_bitrate_allocator_factory_.get())));
Anton Sukhanov4f08faa2019-05-21 11:12:57 -07005097 channel->SetInterface(network_interface.get(),
5098 webrtc::MediaTransportConfig());
nisse51542be2016-02-12 02:27:06 -08005099 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface->dscp());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00005100}
5101
deadbeef13871492015-12-09 12:37:51 -08005102// This test verifies that the RTCP reduced size mode is properly applied to
5103// send video streams.
eladalonf1841382017-06-12 01:16:46 -07005104TEST_F(WebRtcVideoChannelTest, TestSetSendRtcpReducedSize) {
deadbeef13871492015-12-09 12:37:51 -08005105 // Create stream, expecting that default mode is "compound".
5106 FakeVideoSendStream* stream1 = AddSendStream();
5107 EXPECT_EQ(webrtc::RtcpMode::kCompound, stream1->GetConfig().rtp.rtcp_mode);
Florent Castellidacec712018-05-24 16:24:21 +02005108 webrtc::RtpParameters rtp_parameters =
5109 channel_->GetRtpSendParameters(last_ssrc_);
5110 EXPECT_FALSE(rtp_parameters.rtcp.reduced_size);
deadbeef13871492015-12-09 12:37:51 -08005111
5112 // Now enable reduced size mode.
5113 send_parameters_.rtcp.reduced_size = true;
5114 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
5115 stream1 = fake_call_->GetVideoSendStreams()[0];
5116 EXPECT_EQ(webrtc::RtcpMode::kReducedSize, stream1->GetConfig().rtp.rtcp_mode);
Florent Castellidacec712018-05-24 16:24:21 +02005117 rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
5118 EXPECT_TRUE(rtp_parameters.rtcp.reduced_size);
deadbeef13871492015-12-09 12:37:51 -08005119
5120 // Create a new stream and ensure it picks up the reduced size mode.
5121 FakeVideoSendStream* stream2 = AddSendStream();
5122 EXPECT_EQ(webrtc::RtcpMode::kReducedSize, stream2->GetConfig().rtp.rtcp_mode);
5123}
5124
5125// This test verifies that the RTCP reduced size mode is properly applied to
5126// receive video streams.
eladalonf1841382017-06-12 01:16:46 -07005127TEST_F(WebRtcVideoChannelTest, TestSetRecvRtcpReducedSize) {
deadbeef13871492015-12-09 12:37:51 -08005128 // Create stream, expecting that default mode is "compound".
5129 FakeVideoReceiveStream* stream1 = AddRecvStream();
5130 EXPECT_EQ(webrtc::RtcpMode::kCompound, stream1->GetConfig().rtp.rtcp_mode);
5131
5132 // Now enable reduced size mode.
Taylor Brandstetter5f0b83b2016-03-18 15:02:07 -07005133 // TODO(deadbeef): Once "recv_parameters" becomes "receiver_parameters",
5134 // the reduced_size flag should come from that.
5135 send_parameters_.rtcp.reduced_size = true;
5136 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
deadbeef13871492015-12-09 12:37:51 -08005137 stream1 = fake_call_->GetVideoReceiveStreams()[0];
5138 EXPECT_EQ(webrtc::RtcpMode::kReducedSize, stream1->GetConfig().rtp.rtcp_mode);
5139
5140 // Create a new stream and ensure it picks up the reduced size mode.
5141 FakeVideoReceiveStream* stream2 = AddRecvStream();
5142 EXPECT_EQ(webrtc::RtcpMode::kReducedSize, stream2->GetConfig().rtp.rtcp_mode);
5143}
5144
eladalonf1841382017-06-12 01:16:46 -07005145TEST_F(WebRtcVideoChannelTest, OnReadyToSendSignalsNetworkState) {
skvlad7a43d252016-03-22 15:32:27 -07005146 EXPECT_EQ(webrtc::kNetworkUp,
5147 fake_call_->GetNetworkState(webrtc::MediaType::VIDEO));
5148 EXPECT_EQ(webrtc::kNetworkUp,
5149 fake_call_->GetNetworkState(webrtc::MediaType::AUDIO));
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00005150
5151 channel_->OnReadyToSend(false);
skvlad7a43d252016-03-22 15:32:27 -07005152 EXPECT_EQ(webrtc::kNetworkDown,
5153 fake_call_->GetNetworkState(webrtc::MediaType::VIDEO));
5154 EXPECT_EQ(webrtc::kNetworkUp,
5155 fake_call_->GetNetworkState(webrtc::MediaType::AUDIO));
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00005156
5157 channel_->OnReadyToSend(true);
skvlad7a43d252016-03-22 15:32:27 -07005158 EXPECT_EQ(webrtc::kNetworkUp,
5159 fake_call_->GetNetworkState(webrtc::MediaType::VIDEO));
5160 EXPECT_EQ(webrtc::kNetworkUp,
5161 fake_call_->GetNetworkState(webrtc::MediaType::AUDIO));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00005162}
5163
eladalonf1841382017-06-12 01:16:46 -07005164TEST_F(WebRtcVideoChannelTest, GetStatsReportsSentCodecName) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02005165 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08005166 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02005167 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Peter Boström74d9ed72015-03-26 16:28:31 +01005168
5169 AddSendStream();
5170
5171 cricket::VideoMediaInfo info;
5172 ASSERT_TRUE(channel_->GetStats(&info));
magjed509e4fe2016-11-18 01:34:11 -08005173 EXPECT_EQ("VP8", info.senders[0].codec_name);
Peter Boström74d9ed72015-03-26 16:28:31 +01005174}
5175
eladalonf1841382017-06-12 01:16:46 -07005176TEST_F(WebRtcVideoChannelTest, GetStatsReportsEncoderImplementationName) {
Peter Boströmb7d9a972015-12-18 16:01:11 +01005177 FakeVideoSendStream* stream = AddSendStream();
5178 webrtc::VideoSendStream::Stats stats;
5179 stats.encoder_implementation_name = "encoder_implementation_name";
5180 stream->SetStats(stats);
5181
5182 cricket::VideoMediaInfo info;
5183 ASSERT_TRUE(channel_->GetStats(&info));
5184 EXPECT_EQ(stats.encoder_implementation_name,
5185 info.senders[0].encoder_implementation_name);
5186}
5187
eladalonf1841382017-06-12 01:16:46 -07005188TEST_F(WebRtcVideoChannelTest, GetStatsReportsCpuOveruseMetrics) {
pbos@webrtc.org3e6e2712015-02-26 12:19:31 +00005189 FakeVideoSendStream* stream = AddSendStream();
5190 webrtc::VideoSendStream::Stats stats;
5191 stats.avg_encode_time_ms = 13;
5192 stats.encode_usage_percent = 42;
5193 stream->SetStats(stats);
5194
5195 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00005196 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org3e6e2712015-02-26 12:19:31 +00005197 EXPECT_EQ(stats.avg_encode_time_ms, info.senders[0].avg_encode_ms);
5198 EXPECT_EQ(stats.encode_usage_percent, info.senders[0].encode_usage_percent);
5199}
5200
eladalonf1841382017-06-12 01:16:46 -07005201TEST_F(WebRtcVideoChannelTest, GetStatsReportsFramesEncoded) {
sakal43536c32016-10-24 01:46:43 -07005202 FakeVideoSendStream* stream = AddSendStream();
5203 webrtc::VideoSendStream::Stats stats;
5204 stats.frames_encoded = 13;
5205 stream->SetStats(stats);
5206
5207 cricket::VideoMediaInfo info;
5208 ASSERT_TRUE(channel_->GetStats(&info));
5209 EXPECT_EQ(stats.frames_encoded, info.senders[0].frames_encoded);
5210}
5211
Rasmus Brandt2efae772019-06-27 14:29:34 +02005212TEST_F(WebRtcVideoChannelTest, GetStatsReportsKeyFramesEncoded) {
5213 FakeVideoSendStream* stream = AddSendStream();
5214 webrtc::VideoSendStream::Stats stats;
5215 stats.substreams[123].frame_counts.key_frames = 10;
5216 stats.substreams[456].frame_counts.key_frames = 87;
5217 stream->SetStats(stats);
5218
5219 cricket::VideoMediaInfo info;
5220 ASSERT_TRUE(channel_->GetStats(&info));
5221 // TODO(bugs.webrtc.org/9547): Populate individual outbound-rtp stats objects
5222 // for each simulcast stream, instead of accumulating all keyframes encoded
5223 // over all simulcast streams in the same outbound-rtp stats object.
5224 EXPECT_EQ(97u, info.senders[0].key_frames_encoded);
5225}
5226
eladalonf1841382017-06-12 01:16:46 -07005227TEST_F(WebRtcVideoChannelTest, GetStatsReportsQpSum) {
sakal87da4042016-10-31 06:53:47 -07005228 FakeVideoSendStream* stream = AddSendStream();
5229 webrtc::VideoSendStream::Stats stats;
Oskar Sundbom78807582017-11-16 11:09:55 +01005230 stats.qp_sum = 13;
sakal87da4042016-10-31 06:53:47 -07005231 stream->SetStats(stats);
5232
5233 cricket::VideoMediaInfo info;
5234 ASSERT_TRUE(channel_->GetStats(&info));
5235 EXPECT_EQ(stats.qp_sum, info.senders[0].qp_sum);
5236}
5237
eladalonf1841382017-06-12 01:16:46 -07005238TEST_F(WebRtcVideoChannelTest, GetStatsReportsUpperResolution) {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00005239 FakeVideoSendStream* stream = AddSendStream();
5240 webrtc::VideoSendStream::Stats stats;
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00005241 stats.substreams[17].width = 123;
5242 stats.substreams[17].height = 40;
5243 stats.substreams[42].width = 80;
5244 stats.substreams[42].height = 31;
5245 stats.substreams[11].width = 20;
5246 stats.substreams[11].height = 90;
pbos@webrtc.org273a4142014-12-01 15:23:21 +00005247 stream->SetStats(stats);
5248
5249 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00005250 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org273a4142014-12-01 15:23:21 +00005251 ASSERT_EQ(1u, info.senders.size());
5252 EXPECT_EQ(123, info.senders[0].send_frame_width);
5253 EXPECT_EQ(90, info.senders[0].send_frame_height);
5254}
5255
eladalonf1841382017-06-12 01:16:46 -07005256TEST_F(WebRtcVideoChannelTest, GetStatsReportsCpuAdaptationStats) {
perkj803d97f2016-11-01 11:45:46 -07005257 FakeVideoSendStream* stream = AddSendStream();
5258 webrtc::VideoSendStream::Stats stats;
5259 stats.number_of_cpu_adapt_changes = 2;
5260 stats.cpu_limited_resolution = true;
5261 stream->SetStats(stats);
pbos@webrtc.org9a4410e2015-02-26 10:03:39 +00005262
pbos@webrtc.org9a4410e2015-02-26 10:03:39 +00005263 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00005264 EXPECT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org9a4410e2015-02-26 10:03:39 +00005265 ASSERT_EQ(1U, info.senders.size());
eladalonf1841382017-06-12 01:16:46 -07005266 EXPECT_EQ(WebRtcVideoChannel::ADAPTREASON_CPU, info.senders[0].adapt_reason);
perkj803d97f2016-11-01 11:45:46 -07005267 EXPECT_EQ(stats.number_of_cpu_adapt_changes, info.senders[0].adapt_changes);
pbos@webrtc.org9a4410e2015-02-26 10:03:39 +00005268}
5269
eladalonf1841382017-06-12 01:16:46 -07005270TEST_F(WebRtcVideoChannelTest, GetStatsReportsAdaptationAndBandwidthStats) {
perkj803d97f2016-11-01 11:45:46 -07005271 FakeVideoSendStream* stream = AddSendStream();
asapersson17821db2015-12-14 02:08:12 -08005272 webrtc::VideoSendStream::Stats stats;
perkj803d97f2016-11-01 11:45:46 -07005273 stats.number_of_cpu_adapt_changes = 2;
5274 stats.cpu_limited_resolution = true;
asapersson17821db2015-12-14 02:08:12 -08005275 stats.bw_limited_resolution = true;
perkj803d97f2016-11-01 11:45:46 -07005276 stream->SetStats(stats);
5277
5278 cricket::VideoMediaInfo info;
asapersson17821db2015-12-14 02:08:12 -08005279 EXPECT_TRUE(channel_->GetStats(&info));
5280 ASSERT_EQ(1U, info.senders.size());
eladalonf1841382017-06-12 01:16:46 -07005281 EXPECT_EQ(WebRtcVideoChannel::ADAPTREASON_CPU |
5282 WebRtcVideoChannel::ADAPTREASON_BANDWIDTH,
asapersson17821db2015-12-14 02:08:12 -08005283 info.senders[0].adapt_reason);
perkj803d97f2016-11-01 11:45:46 -07005284 EXPECT_EQ(stats.number_of_cpu_adapt_changes, info.senders[0].adapt_changes);
asapersson17821db2015-12-14 02:08:12 -08005285}
5286
Henrik Boströmf45ca372020-03-24 13:30:50 +01005287TEST(WebRtcVideoChannelHelperTest, MergeInfoAboutOutboundRtpSubstreams) {
5288 const uint32_t kFirstMediaStreamSsrc = 10;
5289 const uint32_t kSecondMediaStreamSsrc = 20;
5290 const uint32_t kRtxSsrc = 30;
5291 const uint32_t kFlexfecSsrc = 40;
5292 std::map<uint32_t, webrtc::VideoSendStream::StreamStats> substreams;
5293 // First kMedia stream.
5294 substreams[kFirstMediaStreamSsrc].type =
5295 webrtc::VideoSendStream::StreamStats::StreamType::kMedia;
5296 substreams[kFirstMediaStreamSsrc].rtp_stats.transmitted.header_bytes = 1;
5297 substreams[kFirstMediaStreamSsrc].rtp_stats.transmitted.padding_bytes = 2;
5298 substreams[kFirstMediaStreamSsrc].rtp_stats.transmitted.payload_bytes = 3;
5299 substreams[kFirstMediaStreamSsrc].rtp_stats.transmitted.packets = 4;
5300 substreams[kFirstMediaStreamSsrc].rtp_stats.retransmitted.header_bytes = 5;
5301 substreams[kFirstMediaStreamSsrc].rtp_stats.retransmitted.padding_bytes = 6;
5302 substreams[kFirstMediaStreamSsrc].rtp_stats.retransmitted.payload_bytes = 7;
5303 substreams[kFirstMediaStreamSsrc].rtp_stats.retransmitted.packets = 8;
5304 substreams[kFirstMediaStreamSsrc].referenced_media_ssrc = absl::nullopt;
5305 substreams[kFirstMediaStreamSsrc].width = 1280;
5306 substreams[kFirstMediaStreamSsrc].height = 720;
5307 // Second kMedia stream.
5308 substreams[kSecondMediaStreamSsrc].type =
5309 webrtc::VideoSendStream::StreamStats::StreamType::kMedia;
5310 substreams[kSecondMediaStreamSsrc].rtp_stats.transmitted.header_bytes = 10;
5311 substreams[kSecondMediaStreamSsrc].rtp_stats.transmitted.padding_bytes = 11;
5312 substreams[kSecondMediaStreamSsrc].rtp_stats.transmitted.payload_bytes = 12;
5313 substreams[kSecondMediaStreamSsrc].rtp_stats.transmitted.packets = 13;
5314 substreams[kSecondMediaStreamSsrc].rtp_stats.retransmitted.header_bytes = 14;
5315 substreams[kSecondMediaStreamSsrc].rtp_stats.retransmitted.padding_bytes = 15;
5316 substreams[kSecondMediaStreamSsrc].rtp_stats.retransmitted.payload_bytes = 16;
5317 substreams[kSecondMediaStreamSsrc].rtp_stats.retransmitted.packets = 17;
5318 substreams[kSecondMediaStreamSsrc].referenced_media_ssrc = absl::nullopt;
5319 substreams[kSecondMediaStreamSsrc].width = 640;
5320 substreams[kSecondMediaStreamSsrc].height = 480;
5321 // kRtx stream referencing the first kMedia stream.
5322 substreams[kRtxSsrc].type =
5323 webrtc::VideoSendStream::StreamStats::StreamType::kRtx;
5324 substreams[kRtxSsrc].rtp_stats.transmitted.header_bytes = 19;
5325 substreams[kRtxSsrc].rtp_stats.transmitted.padding_bytes = 20;
5326 substreams[kRtxSsrc].rtp_stats.transmitted.payload_bytes = 21;
5327 substreams[kRtxSsrc].rtp_stats.transmitted.packets = 22;
5328 substreams[kRtxSsrc].rtp_stats.retransmitted.header_bytes = 23;
5329 substreams[kRtxSsrc].rtp_stats.retransmitted.padding_bytes = 24;
5330 substreams[kRtxSsrc].rtp_stats.retransmitted.payload_bytes = 25;
5331 substreams[kRtxSsrc].rtp_stats.retransmitted.packets = 26;
5332 substreams[kRtxSsrc].referenced_media_ssrc = kFirstMediaStreamSsrc;
5333 // kFlexfec stream referencing the second kMedia stream.
5334 substreams[kFlexfecSsrc].type =
5335 webrtc::VideoSendStream::StreamStats::StreamType::kFlexfec;
5336 substreams[kFlexfecSsrc].rtp_stats.transmitted.header_bytes = 19;
5337 substreams[kFlexfecSsrc].rtp_stats.transmitted.padding_bytes = 20;
5338 substreams[kFlexfecSsrc].rtp_stats.transmitted.payload_bytes = 21;
5339 substreams[kFlexfecSsrc].rtp_stats.transmitted.packets = 22;
5340 substreams[kFlexfecSsrc].rtp_stats.retransmitted.header_bytes = 23;
5341 substreams[kFlexfecSsrc].rtp_stats.retransmitted.padding_bytes = 24;
5342 substreams[kFlexfecSsrc].rtp_stats.retransmitted.payload_bytes = 25;
5343 substreams[kFlexfecSsrc].rtp_stats.retransmitted.packets = 26;
5344 substreams[kFlexfecSsrc].referenced_media_ssrc = kSecondMediaStreamSsrc;
5345
5346 auto merged_substreams =
5347 MergeInfoAboutOutboundRtpSubstreamsForTesting(substreams);
5348 // Only kMedia substreams remain.
5349 EXPECT_TRUE(merged_substreams.find(kFirstMediaStreamSsrc) !=
5350 merged_substreams.end());
5351 EXPECT_EQ(merged_substreams[kFirstMediaStreamSsrc].type,
5352 webrtc::VideoSendStream::StreamStats::StreamType::kMedia);
5353 EXPECT_TRUE(merged_substreams.find(kSecondMediaStreamSsrc) !=
5354 merged_substreams.end());
5355 EXPECT_EQ(merged_substreams[kSecondMediaStreamSsrc].type,
5356 webrtc::VideoSendStream::StreamStats::StreamType::kMedia);
5357 EXPECT_FALSE(merged_substreams.find(kRtxSsrc) != merged_substreams.end());
5358 EXPECT_FALSE(merged_substreams.find(kFlexfecSsrc) != merged_substreams.end());
5359 // Expect kFirstMediaStreamSsrc's rtp_stats to be merged with kRtxSsrc.
5360 webrtc::StreamDataCounters first_media_expected_rtp_stats =
5361 substreams[kFirstMediaStreamSsrc].rtp_stats;
5362 first_media_expected_rtp_stats.Add(substreams[kRtxSsrc].rtp_stats);
5363 EXPECT_EQ(merged_substreams[kFirstMediaStreamSsrc].rtp_stats.transmitted,
5364 first_media_expected_rtp_stats.transmitted);
5365 EXPECT_EQ(merged_substreams[kFirstMediaStreamSsrc].rtp_stats.retransmitted,
5366 first_media_expected_rtp_stats.retransmitted);
5367 // Expect kSecondMediaStreamSsrc' rtp_stats to be merged with kFlexfecSsrc.
5368 webrtc::StreamDataCounters second_media_expected_rtp_stats =
5369 substreams[kSecondMediaStreamSsrc].rtp_stats;
5370 second_media_expected_rtp_stats.Add(substreams[kFlexfecSsrc].rtp_stats);
5371 EXPECT_EQ(merged_substreams[kSecondMediaStreamSsrc].rtp_stats.transmitted,
5372 second_media_expected_rtp_stats.transmitted);
5373 EXPECT_EQ(merged_substreams[kSecondMediaStreamSsrc].rtp_stats.retransmitted,
5374 second_media_expected_rtp_stats.retransmitted);
5375 // Expect other metrics to come from the original kMedia stats.
5376 EXPECT_EQ(merged_substreams[kFirstMediaStreamSsrc].width,
5377 substreams[kFirstMediaStreamSsrc].width);
5378 EXPECT_EQ(merged_substreams[kFirstMediaStreamSsrc].height,
5379 substreams[kFirstMediaStreamSsrc].height);
5380 EXPECT_EQ(merged_substreams[kSecondMediaStreamSsrc].width,
5381 substreams[kSecondMediaStreamSsrc].width);
5382 EXPECT_EQ(merged_substreams[kSecondMediaStreamSsrc].height,
5383 substreams[kSecondMediaStreamSsrc].height);
5384}
5385
eladalonf1841382017-06-12 01:16:46 -07005386TEST_F(WebRtcVideoChannelTest,
Henrik Boströmfc29b0a2020-03-18 16:52:17 +01005387 GetStatsReportsTransmittedAndRetransmittedBytesAndPacketsCorrectly) {
5388 FakeVideoSendStream* stream = AddSendStream();
5389 webrtc::VideoSendStream::Stats stats;
5390 // Simulcast layer 1, RTP stream. header+padding=10, payload=20, packets=3.
Henrik Boströmf45ca372020-03-24 13:30:50 +01005391 stats.substreams[101].type =
5392 webrtc::VideoSendStream::StreamStats::StreamType::kMedia;
Henrik Boströmfc29b0a2020-03-18 16:52:17 +01005393 stats.substreams[101].rtp_stats.transmitted.header_bytes = 5;
5394 stats.substreams[101].rtp_stats.transmitted.padding_bytes = 5;
5395 stats.substreams[101].rtp_stats.transmitted.payload_bytes = 20;
5396 stats.substreams[101].rtp_stats.transmitted.packets = 3;
5397 stats.substreams[101].rtp_stats.retransmitted.header_bytes = 0;
5398 stats.substreams[101].rtp_stats.retransmitted.padding_bytes = 0;
5399 stats.substreams[101].rtp_stats.retransmitted.payload_bytes = 0;
5400 stats.substreams[101].rtp_stats.retransmitted.packets = 0;
Henrik Boströmf45ca372020-03-24 13:30:50 +01005401 stats.substreams[101].referenced_media_ssrc = absl::nullopt;
Henrik Boströmfc29b0a2020-03-18 16:52:17 +01005402 // Simulcast layer 1, RTX stream. header+padding=5, payload=10, packets=1.
Henrik Boströmf45ca372020-03-24 13:30:50 +01005403 stats.substreams[102].type =
5404 webrtc::VideoSendStream::StreamStats::StreamType::kRtx;
Henrik Boströmfc29b0a2020-03-18 16:52:17 +01005405 stats.substreams[102].rtp_stats.retransmitted.header_bytes = 3;
5406 stats.substreams[102].rtp_stats.retransmitted.padding_bytes = 2;
5407 stats.substreams[102].rtp_stats.retransmitted.payload_bytes = 10;
5408 stats.substreams[102].rtp_stats.retransmitted.packets = 1;
5409 stats.substreams[102].rtp_stats.transmitted =
5410 stats.substreams[102].rtp_stats.retransmitted;
Henrik Boströmf45ca372020-03-24 13:30:50 +01005411 stats.substreams[102].referenced_media_ssrc = 101;
Henrik Boströmfc29b0a2020-03-18 16:52:17 +01005412 // Simulcast layer 2, RTP stream. header+padding=20, payload=40, packets=7.
Henrik Boströmf45ca372020-03-24 13:30:50 +01005413 stats.substreams[201].type =
5414 webrtc::VideoSendStream::StreamStats::StreamType::kMedia;
Henrik Boströmfc29b0a2020-03-18 16:52:17 +01005415 stats.substreams[201].rtp_stats.transmitted.header_bytes = 10;
5416 stats.substreams[201].rtp_stats.transmitted.padding_bytes = 10;
5417 stats.substreams[201].rtp_stats.transmitted.payload_bytes = 40;
5418 stats.substreams[201].rtp_stats.transmitted.packets = 7;
5419 stats.substreams[201].rtp_stats.retransmitted.header_bytes = 0;
5420 stats.substreams[201].rtp_stats.retransmitted.padding_bytes = 0;
5421 stats.substreams[201].rtp_stats.retransmitted.payload_bytes = 0;
5422 stats.substreams[201].rtp_stats.retransmitted.packets = 0;
Henrik Boströmf45ca372020-03-24 13:30:50 +01005423 stats.substreams[201].referenced_media_ssrc = absl::nullopt;
Henrik Boströmfc29b0a2020-03-18 16:52:17 +01005424 // Simulcast layer 2, RTX stream. header+padding=10, payload=20, packets=4.
Henrik Boströmf45ca372020-03-24 13:30:50 +01005425 stats.substreams[202].type =
5426 webrtc::VideoSendStream::StreamStats::StreamType::kRtx;
Henrik Boströmfc29b0a2020-03-18 16:52:17 +01005427 stats.substreams[202].rtp_stats.retransmitted.header_bytes = 6;
5428 stats.substreams[202].rtp_stats.retransmitted.padding_bytes = 4;
5429 stats.substreams[202].rtp_stats.retransmitted.payload_bytes = 20;
5430 stats.substreams[202].rtp_stats.retransmitted.packets = 4;
5431 stats.substreams[202].rtp_stats.transmitted =
5432 stats.substreams[202].rtp_stats.retransmitted;
Henrik Boströmf45ca372020-03-24 13:30:50 +01005433 stats.substreams[202].referenced_media_ssrc = 201;
5434 // FlexFEC stream associated with the Simulcast layer 2.
5435 // header+padding=15, payload=17, packets=5.
5436 stats.substreams[301].type =
5437 webrtc::VideoSendStream::StreamStats::StreamType::kFlexfec;
5438 stats.substreams[301].rtp_stats.transmitted.header_bytes = 13;
5439 stats.substreams[301].rtp_stats.transmitted.padding_bytes = 2;
5440 stats.substreams[301].rtp_stats.transmitted.payload_bytes = 17;
5441 stats.substreams[301].rtp_stats.transmitted.packets = 5;
5442 stats.substreams[301].rtp_stats.retransmitted.header_bytes = 0;
5443 stats.substreams[301].rtp_stats.retransmitted.padding_bytes = 0;
5444 stats.substreams[301].rtp_stats.retransmitted.payload_bytes = 0;
5445 stats.substreams[301].rtp_stats.retransmitted.packets = 0;
5446 stats.substreams[301].referenced_media_ssrc = 201;
Henrik Boströmfc29b0a2020-03-18 16:52:17 +01005447 stream->SetStats(stats);
5448
5449 cricket::VideoMediaInfo info;
5450 ASSERT_TRUE(channel_->GetStats(&info));
5451 // TODO(https://crbug.com/webrtc/9547): Populate individual VideoSenderInfo
5452 // objects for each simulcast stream, instead of accumulating all layers into
5453 // a single VideoSenderInfo. When this is fixed, this test should expect that
5454 // there are two VideoSenderInfo, where the first info accounts for the first
5455 // RTX and the second info accounts for the second RTX. In order for the test
5456 // to be set up correctly, it may need to be updated such that the
5457 // relationship between RTP and RTX streams are known. See also
5458 // https://crbug.com/webrtc/11439.
Henrik Boströmf45ca372020-03-24 13:30:50 +01005459 EXPECT_EQ(60u, info.senders[0].header_and_padding_bytes_sent);
5460 EXPECT_EQ(107u, info.senders[0].payload_bytes_sent);
5461 EXPECT_EQ(20, info.senders[0].packets_sent);
Henrik Boströmfc29b0a2020-03-18 16:52:17 +01005462 EXPECT_EQ(30u, info.senders[0].retransmitted_bytes_sent);
5463 EXPECT_EQ(5u, info.senders[0].retransmitted_packets_sent);
5464}
5465
5466TEST_F(WebRtcVideoChannelTest,
asapersson17821db2015-12-14 02:08:12 -08005467 GetStatsTranslatesBandwidthLimitedResolutionCorrectly) {
5468 FakeVideoSendStream* stream = AddSendStream();
5469 webrtc::VideoSendStream::Stats stats;
5470 stats.bw_limited_resolution = true;
5471 stream->SetStats(stats);
5472
5473 cricket::VideoMediaInfo info;
5474 EXPECT_TRUE(channel_->GetStats(&info));
5475 ASSERT_EQ(1U, info.senders.size());
eladalonf1841382017-06-12 01:16:46 -07005476 EXPECT_EQ(WebRtcVideoChannel::ADAPTREASON_BANDWIDTH,
asapersson17821db2015-12-14 02:08:12 -08005477 info.senders[0].adapt_reason);
5478}
5479
Yves Gerey665174f2018-06-19 15:03:05 +02005480TEST_F(WebRtcVideoChannelTest, GetStatsTranslatesSendRtcpPacketTypesCorrectly) {
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00005481 FakeVideoSendStream* stream = AddSendStream();
5482 webrtc::VideoSendStream::Stats stats;
5483 stats.substreams[17].rtcp_packet_type_counts.fir_packets = 2;
5484 stats.substreams[17].rtcp_packet_type_counts.nack_packets = 3;
5485 stats.substreams[17].rtcp_packet_type_counts.pli_packets = 4;
5486
5487 stats.substreams[42].rtcp_packet_type_counts.fir_packets = 5;
5488 stats.substreams[42].rtcp_packet_type_counts.nack_packets = 7;
5489 stats.substreams[42].rtcp_packet_type_counts.pli_packets = 9;
5490
5491 stream->SetStats(stats);
5492
5493 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00005494 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00005495 EXPECT_EQ(7, info.senders[0].firs_rcvd);
5496 EXPECT_EQ(10, info.senders[0].nacks_rcvd);
5497 EXPECT_EQ(13, info.senders[0].plis_rcvd);
5498}
5499
eladalonf1841382017-06-12 01:16:46 -07005500TEST_F(WebRtcVideoChannelTest,
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00005501 GetStatsTranslatesReceiveRtcpPacketTypesCorrectly) {
5502 FakeVideoReceiveStream* stream = AddRecvStream();
5503 webrtc::VideoReceiveStream::Stats stats;
5504 stats.rtcp_packet_type_counts.fir_packets = 2;
5505 stats.rtcp_packet_type_counts.nack_packets = 3;
5506 stats.rtcp_packet_type_counts.pli_packets = 4;
5507 stream->SetStats(stats);
5508
5509 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00005510 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00005511 EXPECT_EQ(stats.rtcp_packet_type_counts.fir_packets,
Mirko Bonadeif859e552018-05-30 15:31:29 +02005512 rtc::checked_cast<unsigned int>(info.receivers[0].firs_sent));
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00005513 EXPECT_EQ(stats.rtcp_packet_type_counts.nack_packets,
Mirko Bonadeif859e552018-05-30 15:31:29 +02005514 rtc::checked_cast<unsigned int>(info.receivers[0].nacks_sent));
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00005515 EXPECT_EQ(stats.rtcp_packet_type_counts.pli_packets,
Mirko Bonadeif859e552018-05-30 15:31:29 +02005516 rtc::checked_cast<unsigned int>(info.receivers[0].plis_sent));
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00005517}
5518
eladalonf1841382017-06-12 01:16:46 -07005519TEST_F(WebRtcVideoChannelTest, GetStatsTranslatesDecodeStatsCorrectly) {
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00005520 FakeVideoReceiveStream* stream = AddRecvStream();
5521 webrtc::VideoReceiveStream::Stats stats;
Peter Boströmb7d9a972015-12-18 16:01:11 +01005522 stats.decoder_implementation_name = "decoder_implementation_name";
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00005523 stats.decode_ms = 2;
5524 stats.max_decode_ms = 3;
5525 stats.current_delay_ms = 4;
5526 stats.target_delay_ms = 5;
5527 stats.jitter_buffer_ms = 6;
Guido Urdaneta67378412019-05-28 17:38:08 +02005528 stats.jitter_buffer_delay_seconds = 60;
5529 stats.jitter_buffer_emitted_count = 6;
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00005530 stats.min_playout_delay_ms = 7;
5531 stats.render_delay_ms = 8;
asapersson26dd92b2016-08-30 00:45:45 -07005532 stats.width = 9;
5533 stats.height = 10;
hbos42f6d2f2017-01-20 03:56:50 -08005534 stats.frame_counts.key_frames = 11;
5535 stats.frame_counts.delta_frames = 12;
hbos50cfe1f2017-01-23 07:21:55 -08005536 stats.frames_rendered = 13;
5537 stats.frames_decoded = 14;
Oskar Sundbom78807582017-11-16 11:09:55 +01005538 stats.qp_sum = 15;
Johannes Kronbfd343b2019-07-01 10:07:50 +02005539 stats.total_decode_time_ms = 16;
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00005540 stream->SetStats(stats);
5541
5542 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00005543 ASSERT_TRUE(channel_->GetStats(&info));
Peter Boströmb7d9a972015-12-18 16:01:11 +01005544 EXPECT_EQ(stats.decoder_implementation_name,
5545 info.receivers[0].decoder_implementation_name);
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00005546 EXPECT_EQ(stats.decode_ms, info.receivers[0].decode_ms);
5547 EXPECT_EQ(stats.max_decode_ms, info.receivers[0].max_decode_ms);
5548 EXPECT_EQ(stats.current_delay_ms, info.receivers[0].current_delay_ms);
5549 EXPECT_EQ(stats.target_delay_ms, info.receivers[0].target_delay_ms);
5550 EXPECT_EQ(stats.jitter_buffer_ms, info.receivers[0].jitter_buffer_ms);
Guido Urdaneta67378412019-05-28 17:38:08 +02005551 EXPECT_EQ(stats.jitter_buffer_delay_seconds,
5552 info.receivers[0].jitter_buffer_delay_seconds);
5553 EXPECT_EQ(stats.jitter_buffer_emitted_count,
5554 info.receivers[0].jitter_buffer_emitted_count);
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00005555 EXPECT_EQ(stats.min_playout_delay_ms, info.receivers[0].min_playout_delay_ms);
5556 EXPECT_EQ(stats.render_delay_ms, info.receivers[0].render_delay_ms);
asapersson26dd92b2016-08-30 00:45:45 -07005557 EXPECT_EQ(stats.width, info.receivers[0].frame_width);
5558 EXPECT_EQ(stats.height, info.receivers[0].frame_height);
Mirko Bonadeif859e552018-05-30 15:31:29 +02005559 EXPECT_EQ(rtc::checked_cast<unsigned int>(stats.frame_counts.key_frames +
5560 stats.frame_counts.delta_frames),
hbos42f6d2f2017-01-20 03:56:50 -08005561 info.receivers[0].frames_received);
hbos50cfe1f2017-01-23 07:21:55 -08005562 EXPECT_EQ(stats.frames_rendered, info.receivers[0].frames_rendered);
sakale5ba44e2016-10-26 07:09:24 -07005563 EXPECT_EQ(stats.frames_decoded, info.receivers[0].frames_decoded);
Rasmus Brandt2efae772019-06-27 14:29:34 +02005564 EXPECT_EQ(rtc::checked_cast<unsigned int>(stats.frame_counts.key_frames),
5565 info.receivers[0].key_frames_decoded);
sakalcc452e12017-02-09 04:53:45 -08005566 EXPECT_EQ(stats.qp_sum, info.receivers[0].qp_sum);
Johannes Kronbfd343b2019-07-01 10:07:50 +02005567 EXPECT_EQ(stats.total_decode_time_ms, info.receivers[0].total_decode_time_ms);
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00005568}
5569
Johannes Kron00376e12019-11-25 10:25:42 +01005570TEST_F(WebRtcVideoChannelTest,
5571 GetStatsTranslatesInterFrameDelayStatsCorrectly) {
5572 FakeVideoReceiveStream* stream = AddRecvStream();
5573 webrtc::VideoReceiveStream::Stats stats;
5574 stats.total_inter_frame_delay = 0.123;
5575 stats.total_squared_inter_frame_delay = 0.00456;
5576 stream->SetStats(stats);
5577
5578 cricket::VideoMediaInfo info;
5579 ASSERT_TRUE(channel_->GetStats(&info));
5580 EXPECT_EQ(stats.total_inter_frame_delay,
5581 info.receivers[0].total_inter_frame_delay);
5582 EXPECT_EQ(stats.total_squared_inter_frame_delay,
5583 info.receivers[0].total_squared_inter_frame_delay);
5584}
5585
eladalonf1841382017-06-12 01:16:46 -07005586TEST_F(WebRtcVideoChannelTest, GetStatsTranslatesReceivePacketStatsCorrectly) {
Peter Boström393347f2015-04-22 14:52:45 +02005587 FakeVideoReceiveStream* stream = AddRecvStream();
5588 webrtc::VideoReceiveStream::Stats stats;
Niels Möllerd77cc242019-08-22 09:40:25 +02005589 stats.rtp_stats.packet_counter.payload_bytes = 2;
5590 stats.rtp_stats.packet_counter.header_bytes = 3;
5591 stats.rtp_stats.packet_counter.padding_bytes = 4;
5592 stats.rtp_stats.packet_counter.packets = 5;
5593 stats.rtp_stats.packets_lost = 6;
Peter Boström393347f2015-04-22 14:52:45 +02005594 stream->SetStats(stats);
5595
5596 cricket::VideoMediaInfo info;
5597 ASSERT_TRUE(channel_->GetStats(&info));
Niels Möllerd77cc242019-08-22 09:40:25 +02005598 EXPECT_EQ(stats.rtp_stats.packet_counter.payload_bytes,
Niels Möllerac0a4cb2019-10-09 15:01:33 +02005599 rtc::checked_cast<size_t>(info.receivers[0].payload_bytes_rcvd));
Niels Möllerd77cc242019-08-22 09:40:25 +02005600 EXPECT_EQ(stats.rtp_stats.packet_counter.packets,
Mirko Bonadeif859e552018-05-30 15:31:29 +02005601 rtc::checked_cast<unsigned int>(info.receivers[0].packets_rcvd));
Niels Möllerd77cc242019-08-22 09:40:25 +02005602 EXPECT_EQ(stats.rtp_stats.packets_lost, info.receivers[0].packets_lost);
Peter Boström393347f2015-04-22 14:52:45 +02005603}
5604
eladalonf1841382017-06-12 01:16:46 -07005605TEST_F(WebRtcVideoChannelTest, TranslatesCallStatsCorrectly) {
pbos@webrtc.org2b19f062014-12-11 13:26:09 +00005606 AddSendStream();
5607 AddSendStream();
5608 webrtc::Call::Stats stats;
5609 stats.rtt_ms = 123;
5610 fake_call_->SetStats(stats);
5611
5612 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00005613 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org2b19f062014-12-11 13:26:09 +00005614 ASSERT_EQ(2u, info.senders.size());
5615 EXPECT_EQ(stats.rtt_ms, info.senders[0].rtt_ms);
5616 EXPECT_EQ(stats.rtt_ms, info.senders[1].rtt_ms);
5617}
5618
eladalonf1841382017-06-12 01:16:46 -07005619TEST_F(WebRtcVideoChannelTest, TranslatesSenderBitrateStatsCorrectly) {
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00005620 FakeVideoSendStream* stream = AddSendStream();
5621 webrtc::VideoSendStream::Stats stats;
pbos@webrtc.org891d4832015-02-26 13:15:22 +00005622 stats.target_media_bitrate_bps = 156;
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00005623 stats.media_bitrate_bps = 123;
5624 stats.substreams[17].total_bitrate_bps = 1;
5625 stats.substreams[17].retransmit_bitrate_bps = 2;
5626 stats.substreams[42].total_bitrate_bps = 3;
5627 stats.substreams[42].retransmit_bitrate_bps = 4;
5628 stream->SetStats(stats);
5629
5630 FakeVideoSendStream* stream2 = AddSendStream();
5631 webrtc::VideoSendStream::Stats stats2;
pbos@webrtc.org891d4832015-02-26 13:15:22 +00005632 stats2.target_media_bitrate_bps = 200;
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00005633 stats2.media_bitrate_bps = 321;
5634 stats2.substreams[13].total_bitrate_bps = 5;
5635 stats2.substreams[13].retransmit_bitrate_bps = 6;
5636 stats2.substreams[21].total_bitrate_bps = 7;
5637 stats2.substreams[21].retransmit_bitrate_bps = 8;
5638 stream2->SetStats(stats2);
5639
5640 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00005641 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00005642 ASSERT_EQ(2u, info.senders.size());
stefanf79ade12017-06-02 06:44:03 -07005643 BandwidthEstimationInfo bwe_info;
5644 channel_->FillBitrateInfo(&bwe_info);
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00005645 // Assuming stream and stream2 corresponds to senders[0] and [1] respectively
5646 // is OK as std::maps are sorted and AddSendStream() gives increasing SSRCs.
5647 EXPECT_EQ(stats.media_bitrate_bps, info.senders[0].nominal_bitrate);
5648 EXPECT_EQ(stats2.media_bitrate_bps, info.senders[1].nominal_bitrate);
pbos@webrtc.org891d4832015-02-26 13:15:22 +00005649 EXPECT_EQ(stats.target_media_bitrate_bps + stats2.target_media_bitrate_bps,
stefanf79ade12017-06-02 06:44:03 -07005650 bwe_info.target_enc_bitrate);
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00005651 EXPECT_EQ(stats.media_bitrate_bps + stats2.media_bitrate_bps,
stefanf79ade12017-06-02 06:44:03 -07005652 bwe_info.actual_enc_bitrate);
5653 EXPECT_EQ(1 + 3 + 5 + 7, bwe_info.transmit_bitrate)
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00005654 << "Bandwidth stats should take all streams into account.";
stefanf79ade12017-06-02 06:44:03 -07005655 EXPECT_EQ(2 + 4 + 6 + 8, bwe_info.retransmit_bitrate)
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00005656 << "Bandwidth stats should take all streams into account.";
5657}
5658
eladalonf1841382017-06-12 01:16:46 -07005659TEST_F(WebRtcVideoChannelTest, DefaultReceiveStreamReconfiguresToUseRtx) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02005660 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orga2a6fe62015-03-06 15:35:19 +00005661
Peter Boström0c4e06b2015-10-07 12:23:21 +02005662 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
5663 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
pbos@webrtc.orga2a6fe62015-03-06 15:35:19 +00005664
5665 ASSERT_EQ(0u, fake_call_->GetVideoReceiveStreams().size());
5666 const size_t kDataLength = 12;
5667 uint8_t data[kDataLength];
5668 memset(data, 0, sizeof(data));
5669 rtc::SetBE32(&data[8], ssrcs[0]);
jbaucheec21bd2016-03-20 06:15:43 -07005670 rtc::CopyOnWriteBuffer packet(data, kDataLength);
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07005671 channel_->OnPacketReceived(packet, /* packet_time_us */ -1);
pbos@webrtc.orga2a6fe62015-03-06 15:35:19 +00005672
5673 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size())
5674 << "No default receive stream created.";
5675 FakeVideoReceiveStream* recv_stream = fake_call_->GetVideoReceiveStreams()[0];
brandtr14742122017-01-27 04:53:07 -08005676 EXPECT_EQ(0u, recv_stream->GetConfig().rtp.rtx_ssrc)
pbos@webrtc.orga2a6fe62015-03-06 15:35:19 +00005677 << "Default receive stream should not have configured RTX";
5678
5679 EXPECT_TRUE(channel_->AddRecvStream(
5680 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs)));
5681 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size())
brandtr14742122017-01-27 04:53:07 -08005682 << "AddRecvStream should have reconfigured, not added a new receiver.";
pbos@webrtc.orga2a6fe62015-03-06 15:35:19 +00005683 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
nisse26e3abb2017-08-25 04:44:25 -07005684 EXPECT_FALSE(
5685 recv_stream->GetConfig().rtp.rtx_associated_payload_types.empty());
nisseca5706d2017-09-11 02:32:16 -07005686 EXPECT_TRUE(VerifyRtxReceiveAssociations(recv_stream->GetConfig()))
Peter Boströmd8b01092016-05-12 16:44:36 +02005687 << "RTX should be mapped for all decoders/payload types.";
nisseca5706d2017-09-11 02:32:16 -07005688 EXPECT_TRUE(HasRtxReceiveAssociation(recv_stream->GetConfig(),
Yves Gerey665174f2018-06-19 15:03:05 +02005689 GetEngineCodec("red").id))
nisseca5706d2017-09-11 02:32:16 -07005690 << "RTX should be mapped also for the RED payload type";
brandtr14742122017-01-27 04:53:07 -08005691 EXPECT_EQ(rtx_ssrcs[0], recv_stream->GetConfig().rtp.rtx_ssrc);
pbos@webrtc.orga2a6fe62015-03-06 15:35:19 +00005692}
5693
eladalonf1841382017-06-12 01:16:46 -07005694TEST_F(WebRtcVideoChannelTest, RejectsAddingStreamsWithMissingSsrcsForRtx) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02005695 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Peter Boströmd4362cd2015-03-25 14:17:23 +01005696
Peter Boström0c4e06b2015-10-07 12:23:21 +02005697 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
5698 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
Peter Boströmd4362cd2015-03-25 14:17:23 +01005699
5700 StreamParams sp =
5701 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs);
5702 sp.ssrcs = ssrcs; // Without RTXs, this is the important part.
5703
5704 EXPECT_FALSE(channel_->AddSendStream(sp));
5705 EXPECT_FALSE(channel_->AddRecvStream(sp));
5706}
5707
eladalonf1841382017-06-12 01:16:46 -07005708TEST_F(WebRtcVideoChannelTest, RejectsAddingStreamsWithOverlappingRtxSsrcs) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02005709 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Peter Boströmd6f4c252015-03-26 16:23:04 +01005710
Peter Boström0c4e06b2015-10-07 12:23:21 +02005711 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
5712 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
Peter Boströmd6f4c252015-03-26 16:23:04 +01005713
5714 StreamParams sp =
5715 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs);
5716
5717 EXPECT_TRUE(channel_->AddSendStream(sp));
5718 EXPECT_TRUE(channel_->AddRecvStream(sp));
5719
5720 // The RTX SSRC is already used in previous streams, using it should fail.
5721 sp = cricket::StreamParams::CreateLegacy(rtx_ssrcs[0]);
5722 EXPECT_FALSE(channel_->AddSendStream(sp));
5723 EXPECT_FALSE(channel_->AddRecvStream(sp));
5724
5725 // After removing the original stream this should be fine to add (makes sure
5726 // that RTX ssrcs are not forever taken).
5727 EXPECT_TRUE(channel_->RemoveSendStream(ssrcs[0]));
5728 EXPECT_TRUE(channel_->RemoveRecvStream(ssrcs[0]));
5729 EXPECT_TRUE(channel_->AddSendStream(sp));
5730 EXPECT_TRUE(channel_->AddRecvStream(sp));
5731}
5732
eladalonf1841382017-06-12 01:16:46 -07005733TEST_F(WebRtcVideoChannelTest,
Peter Boströmd6f4c252015-03-26 16:23:04 +01005734 RejectsAddingStreamsWithOverlappingSimulcastSsrcs) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02005735 static const uint32_t kFirstStreamSsrcs[] = {1, 2, 3};
5736 static const uint32_t kOverlappingStreamSsrcs[] = {4, 3, 5};
Fredrik Solenbergb071a192015-09-17 16:42:56 +02005737 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Peter Boströmd6f4c252015-03-26 16:23:04 +01005738
Peter Boströmd6f4c252015-03-26 16:23:04 +01005739 StreamParams sp =
5740 cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kFirstStreamSsrcs));
5741
5742 EXPECT_TRUE(channel_->AddSendStream(sp));
5743 EXPECT_TRUE(channel_->AddRecvStream(sp));
5744
5745 // One of the SSRCs is already used in previous streams, using it should fail.
5746 sp = cricket::CreateSimStreamParams("cname",
5747 MAKE_VECTOR(kOverlappingStreamSsrcs));
5748 EXPECT_FALSE(channel_->AddSendStream(sp));
5749 EXPECT_FALSE(channel_->AddRecvStream(sp));
5750
5751 // After removing the original stream this should be fine to add (makes sure
5752 // that RTX ssrcs are not forever taken).
Peter Boström3548dd22015-05-22 18:48:36 +02005753 EXPECT_TRUE(channel_->RemoveSendStream(kFirstStreamSsrcs[0]));
5754 EXPECT_TRUE(channel_->RemoveRecvStream(kFirstStreamSsrcs[0]));
Peter Boströmd6f4c252015-03-26 16:23:04 +01005755 EXPECT_TRUE(channel_->AddSendStream(sp));
5756 EXPECT_TRUE(channel_->AddRecvStream(sp));
5757}
5758
eladalonf1841382017-06-12 01:16:46 -07005759TEST_F(WebRtcVideoChannelTest, ReportsSsrcGroupsInStats) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02005760 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Peter Boström259bd202015-05-28 13:39:50 +02005761
5762 static const uint32_t kSenderSsrcs[] = {4, 7, 10};
5763 static const uint32_t kSenderRtxSsrcs[] = {5, 8, 11};
5764
5765 StreamParams sender_sp = cricket::CreateSimWithRtxStreamParams(
5766 "cname", MAKE_VECTOR(kSenderSsrcs), MAKE_VECTOR(kSenderRtxSsrcs));
5767
5768 EXPECT_TRUE(channel_->AddSendStream(sender_sp));
5769
5770 static const uint32_t kReceiverSsrcs[] = {3};
5771 static const uint32_t kReceiverRtxSsrcs[] = {2};
5772
5773 StreamParams receiver_sp = cricket::CreateSimWithRtxStreamParams(
5774 "cname", MAKE_VECTOR(kReceiverSsrcs), MAKE_VECTOR(kReceiverRtxSsrcs));
5775 EXPECT_TRUE(channel_->AddRecvStream(receiver_sp));
5776
5777 cricket::VideoMediaInfo info;
5778 ASSERT_TRUE(channel_->GetStats(&info));
5779
5780 ASSERT_EQ(1u, info.senders.size());
5781 ASSERT_EQ(1u, info.receivers.size());
5782
5783 EXPECT_NE(sender_sp.ssrc_groups, receiver_sp.ssrc_groups);
5784 EXPECT_EQ(sender_sp.ssrc_groups, info.senders[0].ssrc_groups);
5785 EXPECT_EQ(receiver_sp.ssrc_groups, info.receivers[0].ssrc_groups);
5786}
5787
eladalonf1841382017-06-12 01:16:46 -07005788TEST_F(WebRtcVideoChannelTest, MapsReceivedPayloadTypeToCodecName) {
pbosf42376c2015-08-28 07:35:32 -07005789 FakeVideoReceiveStream* stream = AddRecvStream();
5790 webrtc::VideoReceiveStream::Stats stats;
5791 cricket::VideoMediaInfo info;
5792
5793 // Report no codec name before receiving.
5794 stream->SetStats(stats);
5795 ASSERT_TRUE(channel_->GetStats(&info));
5796 EXPECT_STREQ("", info.receivers[0].codec_name.c_str());
5797
5798 // Report VP8 if we're receiving it.
magjed509e4fe2016-11-18 01:34:11 -08005799 stats.current_payload_type = GetEngineCodec("VP8").id;
pbosf42376c2015-08-28 07:35:32 -07005800 stream->SetStats(stats);
5801 ASSERT_TRUE(channel_->GetStats(&info));
5802 EXPECT_STREQ(kVp8CodecName, info.receivers[0].codec_name.c_str());
5803
5804 // Report no codec name for unknown playload types.
5805 stats.current_payload_type = 3;
5806 stream->SetStats(stats);
5807 ASSERT_TRUE(channel_->GetStats(&info));
5808 EXPECT_STREQ("", info.receivers[0].codec_name.c_str());
5809}
5810
Seth Hampson5897a6e2018-04-03 11:16:33 -07005811// Tests that when we add a stream without SSRCs, but contains a stream_id
5812// that it is stored and its stream id is later used when the first packet
5813// arrives to properly create a receive stream with a sync label.
5814TEST_F(WebRtcVideoChannelTest, RecvUnsignaledSsrcWithSignaledStreamId) {
5815 const char kSyncLabel[] = "sync_label";
5816 cricket::StreamParams unsignaled_stream;
5817 unsignaled_stream.set_stream_ids({kSyncLabel});
5818 ASSERT_TRUE(channel_->AddRecvStream(unsignaled_stream));
5819 // The stream shouldn't have been created at this point because it doesn't
5820 // have any SSRCs.
Mirko Bonadeif859e552018-05-30 15:31:29 +02005821 EXPECT_EQ(0u, fake_call_->GetVideoReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07005822
5823 // Create and deliver packet.
5824 const size_t kDataLength = 12;
5825 uint8_t data[kDataLength];
5826 memset(data, 0, sizeof(data));
5827 rtc::SetBE32(&data[8], kIncomingUnsignalledSsrc);
5828 rtc::CopyOnWriteBuffer packet(data, kDataLength);
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07005829 channel_->OnPacketReceived(packet, /* packet_time_us */ -1);
Seth Hampson5897a6e2018-04-03 11:16:33 -07005830
5831 // The stream should now be created with the appropriate sync label.
5832 EXPECT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
5833 EXPECT_EQ(kSyncLabel,
5834 fake_call_->GetVideoReceiveStreams()[0]->GetConfig().sync_group);
5835
Saurav Dasff27da52019-09-20 11:05:30 -07005836 // Reset the unsignaled stream to clear the cache. This time when
Seth Hampson5897a6e2018-04-03 11:16:33 -07005837 // a default video receive stream is created it won't have a sync_group.
Saurav Dasff27da52019-09-20 11:05:30 -07005838 channel_->ResetUnsignaledRecvStream();
Rasmus Brandtc6b2f342020-04-02 12:26:05 +00005839 ASSERT_TRUE(channel_->RemoveRecvStream(kIncomingUnsignalledSsrc));
Seth Hampson5897a6e2018-04-03 11:16:33 -07005840 EXPECT_EQ(0u, fake_call_->GetVideoReceiveStreams().size());
5841
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07005842 channel_->OnPacketReceived(packet, /* packet_time_us */ -1);
Seth Hampson5897a6e2018-04-03 11:16:33 -07005843 EXPECT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
5844 EXPECT_TRUE(
5845 fake_call_->GetVideoReceiveStreams()[0]->GetConfig().sync_group.empty());
5846}
5847
Ruslan Burakov493a6502019-02-27 15:32:48 +01005848// Test BaseMinimumPlayoutDelayMs on receive streams.
5849TEST_F(WebRtcVideoChannelTest, BaseMinimumPlayoutDelayMs) {
5850 // Test that set won't work for non-existing receive streams.
5851 EXPECT_FALSE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrc + 2, 200));
5852 // Test that get won't work for non-existing receive streams.
5853 EXPECT_FALSE(channel_->GetBaseMinimumPlayoutDelayMs(kSsrc + 2));
5854
5855 EXPECT_TRUE(AddRecvStream());
5856 // Test that set works for the existing receive stream.
5857 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(last_ssrc_, 200));
5858 auto* recv_stream = fake_call_->GetVideoReceiveStream(last_ssrc_);
5859 EXPECT_TRUE(recv_stream);
5860 EXPECT_EQ(recv_stream->base_mininum_playout_delay_ms(), 200);
5861 EXPECT_EQ(channel_->GetBaseMinimumPlayoutDelayMs(last_ssrc_).value_or(0),
5862 200);
5863}
5864
5865// Test BaseMinimumPlayoutDelayMs on unsignaled receive streams.
5866TEST_F(WebRtcVideoChannelTest, BaseMinimumPlayoutDelayMsUnsignaledRecvStream) {
5867 absl::optional<int> delay_ms;
5868 const FakeVideoReceiveStream* recv_stream;
5869
5870 // Set default stream with SSRC 0
5871 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(0, 200));
5872 EXPECT_EQ(200, channel_->GetBaseMinimumPlayoutDelayMs(0).value_or(0));
5873
5874 // Spawn an unsignaled stream by sending a packet, it should inherit
5875 // default delay 200.
5876 const size_t kDataLength = 12;
5877 uint8_t data[kDataLength];
5878 memset(data, 0, sizeof(data));
5879 rtc::SetBE32(&data[8], kIncomingUnsignalledSsrc);
5880 rtc::CopyOnWriteBuffer packet(data, kDataLength);
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07005881 channel_->OnPacketReceived(packet, /* packet_time_us */ -1);
Ruslan Burakov493a6502019-02-27 15:32:48 +01005882
5883 recv_stream = fake_call_->GetVideoReceiveStream(kIncomingUnsignalledSsrc);
5884 EXPECT_EQ(recv_stream->base_mininum_playout_delay_ms(), 200);
5885 delay_ms = channel_->GetBaseMinimumPlayoutDelayMs(kIncomingUnsignalledSsrc);
5886 EXPECT_EQ(200, delay_ms.value_or(0));
5887
5888 // Check that now if we change delay for SSRC 0 it will change delay for the
5889 // default receiving stream as well.
5890 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(0, 300));
5891 EXPECT_EQ(300, channel_->GetBaseMinimumPlayoutDelayMs(0).value_or(0));
5892 delay_ms = channel_->GetBaseMinimumPlayoutDelayMs(kIncomingUnsignalledSsrc);
5893 EXPECT_EQ(300, delay_ms.value_or(0));
5894 recv_stream = fake_call_->GetVideoReceiveStream(kIncomingUnsignalledSsrc);
5895 EXPECT_EQ(recv_stream->base_mininum_playout_delay_ms(), 300);
5896}
5897
eladalonf1841382017-06-12 01:16:46 -07005898void WebRtcVideoChannelTest::TestReceiveUnsignaledSsrcPacket(
noahricd10a68e2015-07-10 11:27:55 -07005899 uint8_t payload_type,
5900 bool expect_created_receive_stream) {
magjed509e4fe2016-11-18 01:34:11 -08005901 // kRedRtxPayloadType must currently be unused.
Johannes Kron3e983682020-03-29 22:17:00 +02005902 EXPECT_FALSE(FindCodecById(engine_.recv_codecs(), kRedRtxPayloadType));
magjed509e4fe2016-11-18 01:34:11 -08005903
noahricd10a68e2015-07-10 11:27:55 -07005904 // Add a RED RTX codec.
5905 VideoCodec red_rtx_codec =
magjed509e4fe2016-11-18 01:34:11 -08005906 VideoCodec::CreateRtxCodec(kRedRtxPayloadType, GetEngineCodec("red").id);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02005907 recv_parameters_.codecs.push_back(red_rtx_codec);
5908 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
noahricd10a68e2015-07-10 11:27:55 -07005909
5910 ASSERT_EQ(0u, fake_call_->GetVideoReceiveStreams().size());
5911 const size_t kDataLength = 12;
5912 uint8_t data[kDataLength];
5913 memset(data, 0, sizeof(data));
5914
5915 rtc::Set8(data, 1, payload_type);
5916 rtc::SetBE32(&data[8], kIncomingUnsignalledSsrc);
jbaucheec21bd2016-03-20 06:15:43 -07005917 rtc::CopyOnWriteBuffer packet(data, kDataLength);
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07005918 channel_->OnPacketReceived(packet, /* packet_time_us */ -1);
noahricd10a68e2015-07-10 11:27:55 -07005919
5920 if (expect_created_receive_stream) {
5921 EXPECT_EQ(1u, fake_call_->GetVideoReceiveStreams().size())
5922 << "Should have created a receive stream for payload type: "
5923 << payload_type;
5924 } else {
5925 EXPECT_EQ(0u, fake_call_->GetVideoReceiveStreams().size())
5926 << "Shouldn't have created a receive stream for payload type: "
5927 << payload_type;
5928 }
5929}
5930
Åsa Persson2c7149b2018-10-15 09:36:10 +02005931class WebRtcVideoChannelDiscardUnknownSsrcTest : public WebRtcVideoChannelTest {
5932 public:
5933 WebRtcVideoChannelDiscardUnknownSsrcTest()
5934 : WebRtcVideoChannelTest(
5935 "WebRTC-Video-DiscardPacketsWithUnknownSsrc/Enabled/") {}
5936};
5937
5938TEST_F(WebRtcVideoChannelDiscardUnknownSsrcTest, NoUnsignalledStreamCreated) {
5939 TestReceiveUnsignaledSsrcPacket(GetEngineCodec("VP8").id,
5940 false /* expect_created_receive_stream */);
5941}
5942
eladalonf1841382017-06-12 01:16:46 -07005943TEST_F(WebRtcVideoChannelTest, Vp8PacketCreatesUnsignalledStream) {
magjed509e4fe2016-11-18 01:34:11 -08005944 TestReceiveUnsignaledSsrcPacket(GetEngineCodec("VP8").id,
5945 true /* expect_created_receive_stream */);
noahricd10a68e2015-07-10 11:27:55 -07005946}
5947
eladalonf1841382017-06-12 01:16:46 -07005948TEST_F(WebRtcVideoChannelTest, Vp9PacketCreatesUnsignalledStream) {
magjed509e4fe2016-11-18 01:34:11 -08005949 TestReceiveUnsignaledSsrcPacket(GetEngineCodec("VP9").id,
5950 true /* expect_created_receive_stream */);
noahricd10a68e2015-07-10 11:27:55 -07005951}
5952
eladalonf1841382017-06-12 01:16:46 -07005953TEST_F(WebRtcVideoChannelTest, RtxPacketDoesntCreateUnsignalledStream) {
Anders Carlsson5f2bb622018-05-14 09:48:06 +02005954 AssignDefaultAptRtxTypes();
magjed509e4fe2016-11-18 01:34:11 -08005955 const cricket::VideoCodec vp8 = GetEngineCodec("VP8");
5956 const int rtx_vp8_payload_type = default_apt_rtx_types_[vp8.id];
5957 TestReceiveUnsignaledSsrcPacket(rtx_vp8_payload_type,
5958 false /* expect_created_receive_stream */);
noahricd10a68e2015-07-10 11:27:55 -07005959}
5960
eladalonf1841382017-06-12 01:16:46 -07005961TEST_F(WebRtcVideoChannelTest, UlpfecPacketDoesntCreateUnsignalledStream) {
magjed509e4fe2016-11-18 01:34:11 -08005962 TestReceiveUnsignaledSsrcPacket(GetEngineCodec("ulpfec").id,
5963 false /* expect_created_receive_stream */);
noahricd10a68e2015-07-10 11:27:55 -07005964}
5965
eladalonf1841382017-06-12 01:16:46 -07005966TEST_F(WebRtcVideoChannelFlexfecRecvTest,
brandtr468da7c2016-11-22 02:16:47 -08005967 FlexfecPacketDoesntCreateUnsignalledStream) {
5968 TestReceiveUnsignaledSsrcPacket(GetEngineCodec("flexfec-03").id,
5969 false /* expect_created_receive_stream */);
5970}
5971
eladalonf1841382017-06-12 01:16:46 -07005972TEST_F(WebRtcVideoChannelTest, RedRtxPacketDoesntCreateUnsignalledStream) {
magjed509e4fe2016-11-18 01:34:11 -08005973 TestReceiveUnsignaledSsrcPacket(kRedRtxPayloadType,
5974 false /* expect_created_receive_stream */);
noahricd10a68e2015-07-10 11:27:55 -07005975}
5976
mzanaty8a855d62017-02-17 15:46:43 -08005977// Test that receiving any unsignalled SSRC works even if it changes.
5978// The first unsignalled SSRC received will create a default receive stream.
5979// Any different unsignalled SSRC received will replace the default.
eladalonf1841382017-06-12 01:16:46 -07005980TEST_F(WebRtcVideoChannelTest, ReceiveDifferentUnsignaledSsrc) {
mzanaty8a855d62017-02-17 15:46:43 -08005981 // Allow receiving VP8, VP9, H264 (if enabled).
5982 cricket::VideoRecvParameters parameters;
5983 parameters.codecs.push_back(GetEngineCodec("VP8"));
5984 parameters.codecs.push_back(GetEngineCodec("VP9"));
5985
5986#if defined(WEBRTC_USE_H264)
5987 cricket::VideoCodec H264codec(126, "H264");
5988 parameters.codecs.push_back(H264codec);
5989#endif
5990
5991 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
5992 // No receive streams yet.
5993 ASSERT_EQ(0u, fake_call_->GetVideoReceiveStreams().size());
5994 cricket::FakeVideoRenderer renderer;
Saurav Das749f6602019-12-04 09:31:36 -08005995 channel_->SetDefaultSink(&renderer);
mzanaty8a855d62017-02-17 15:46:43 -08005996
5997 // Receive VP8 packet on first SSRC.
5998 uint8_t data[kMinRtpPacketLen];
5999 cricket::RtpHeader rtpHeader;
6000 rtpHeader.payload_type = GetEngineCodec("VP8").id;
6001 rtpHeader.seq_num = rtpHeader.timestamp = 0;
Yves Gerey665174f2018-06-19 15:03:05 +02006002 rtpHeader.ssrc = kIncomingUnsignalledSsrc + 1;
mzanaty8a855d62017-02-17 15:46:43 -08006003 cricket::SetRtpHeader(data, sizeof(data), rtpHeader);
6004 rtc::CopyOnWriteBuffer packet(data, sizeof(data));
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07006005 channel_->OnPacketReceived(packet, /* packet_time_us */ -1);
mzanaty8a855d62017-02-17 15:46:43 -08006006 // VP8 packet should create default receive stream.
6007 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02006008 FakeVideoReceiveStream* recv_stream = fake_call_->GetVideoReceiveStreams()[0];
mzanaty8a855d62017-02-17 15:46:43 -08006009 EXPECT_EQ(rtpHeader.ssrc, recv_stream->GetConfig().rtp.remote_ssrc);
6010 // Verify that the receive stream sinks to a renderer.
Artem Titov1ebfb6a2019-01-03 23:49:37 +01006011 webrtc::VideoFrame video_frame =
6012 webrtc::VideoFrame::Builder()
6013 .set_video_frame_buffer(CreateBlackFrameBuffer(4, 4))
6014 .set_timestamp_rtp(100)
6015 .set_timestamp_us(0)
6016 .set_rotation(webrtc::kVideoRotation_0)
6017 .build();
mzanaty8a855d62017-02-17 15:46:43 -08006018 recv_stream->InjectFrame(video_frame);
6019 EXPECT_EQ(1, renderer.num_rendered_frames());
6020
6021 // Receive VP9 packet on second SSRC.
6022 rtpHeader.payload_type = GetEngineCodec("VP9").id;
Yves Gerey665174f2018-06-19 15:03:05 +02006023 rtpHeader.ssrc = kIncomingUnsignalledSsrc + 2;
mzanaty8a855d62017-02-17 15:46:43 -08006024 cricket::SetRtpHeader(data, sizeof(data), rtpHeader);
6025 rtc::CopyOnWriteBuffer packet2(data, sizeof(data));
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07006026 channel_->OnPacketReceived(packet2, /* packet_time_us */ -1);
mzanaty8a855d62017-02-17 15:46:43 -08006027 // VP9 packet should replace the default receive SSRC.
6028 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
6029 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
6030 EXPECT_EQ(rtpHeader.ssrc, recv_stream->GetConfig().rtp.remote_ssrc);
6031 // Verify that the receive stream sinks to a renderer.
Artem Titov1ebfb6a2019-01-03 23:49:37 +01006032 webrtc::VideoFrame video_frame2 =
6033 webrtc::VideoFrame::Builder()
6034 .set_video_frame_buffer(CreateBlackFrameBuffer(4, 4))
6035 .set_timestamp_rtp(200)
6036 .set_timestamp_us(0)
6037 .set_rotation(webrtc::kVideoRotation_0)
6038 .build();
mzanaty8a855d62017-02-17 15:46:43 -08006039 recv_stream->InjectFrame(video_frame2);
6040 EXPECT_EQ(2, renderer.num_rendered_frames());
6041
6042#if defined(WEBRTC_USE_H264)
6043 // Receive H264 packet on third SSRC.
6044 rtpHeader.payload_type = 126;
Yves Gerey665174f2018-06-19 15:03:05 +02006045 rtpHeader.ssrc = kIncomingUnsignalledSsrc + 3;
mzanaty8a855d62017-02-17 15:46:43 -08006046 cricket::SetRtpHeader(data, sizeof(data), rtpHeader);
6047 rtc::CopyOnWriteBuffer packet3(data, sizeof(data));
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07006048 channel_->OnPacketReceived(packet3, /* packet_time_us */ -1);
mzanaty8a855d62017-02-17 15:46:43 -08006049 // H264 packet should replace the default receive SSRC.
6050 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
6051 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
6052 EXPECT_EQ(rtpHeader.ssrc, recv_stream->GetConfig().rtp.remote_ssrc);
6053 // Verify that the receive stream sinks to a renderer.
Artem Titov1ebfb6a2019-01-03 23:49:37 +01006054 webrtc::VideoFrame video_frame3 =
6055 webrtc::VideoFrame::Builder()
6056 .set_video_frame_buffer(CreateBlackFrameBuffer(4, 4))
6057 .set_timestamp_rtp(300)
6058 .set_timestamp_us(0)
6059 .set_rotation(webrtc::kVideoRotation_0)
6060 .build();
mzanaty8a855d62017-02-17 15:46:43 -08006061 recv_stream->InjectFrame(video_frame3);
6062 EXPECT_EQ(3, renderer.num_rendered_frames());
6063#endif
6064}
6065
brandtr0dc57ea2017-05-29 23:33:31 -07006066// This test verifies that when a new default stream is created for a new
6067// unsignaled SSRC, the new stream does not overwrite any old stream that had
6068// been the default receive stream before being properly signaled.
eladalonf1841382017-06-12 01:16:46 -07006069TEST_F(WebRtcVideoChannelTest,
brandtr0dc57ea2017-05-29 23:33:31 -07006070 NewUnsignaledStreamDoesNotDestroyPreviouslyUnsignaledStream) {
6071 cricket::VideoRecvParameters parameters;
6072 parameters.codecs.push_back(GetEngineCodec("VP8"));
6073 ASSERT_TRUE(channel_->SetRecvParameters(parameters));
6074
6075 // No streams signaled and no packets received, so we should not have any
6076 // stream objects created yet.
6077 EXPECT_EQ(0u, fake_call_->GetVideoReceiveStreams().size());
6078
6079 // Receive packet on an unsignaled SSRC.
6080 uint8_t data[kMinRtpPacketLen];
6081 cricket::RtpHeader rtp_header;
6082 rtp_header.payload_type = GetEngineCodec("VP8").id;
6083 rtp_header.seq_num = rtp_header.timestamp = 0;
6084 rtp_header.ssrc = kSsrcs3[0];
6085 cricket::SetRtpHeader(data, sizeof(data), rtp_header);
6086 rtc::CopyOnWriteBuffer packet(data, sizeof(data));
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07006087 channel_->OnPacketReceived(packet, /* packet_time_us */ -1);
brandtr0dc57ea2017-05-29 23:33:31 -07006088 // Default receive stream should be created.
6089 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
6090 FakeVideoReceiveStream* recv_stream0 =
6091 fake_call_->GetVideoReceiveStreams()[0];
6092 EXPECT_EQ(kSsrcs3[0], recv_stream0->GetConfig().rtp.remote_ssrc);
6093
6094 // Signal the SSRC.
6095 EXPECT_TRUE(
6096 channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrcs3[0])));
6097 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
6098 recv_stream0 = fake_call_->GetVideoReceiveStreams()[0];
6099 EXPECT_EQ(kSsrcs3[0], recv_stream0->GetConfig().rtp.remote_ssrc);
6100
6101 // Receive packet on a different unsignaled SSRC.
6102 rtp_header.ssrc = kSsrcs3[1];
6103 cricket::SetRtpHeader(data, sizeof(data), rtp_header);
6104 packet.SetData(data, sizeof(data));
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07006105 channel_->OnPacketReceived(packet, /* packet_time_us */ -1);
brandtr0dc57ea2017-05-29 23:33:31 -07006106 // New default receive stream should be created, but old stream should remain.
6107 ASSERT_EQ(2u, fake_call_->GetVideoReceiveStreams().size());
6108 EXPECT_EQ(recv_stream0, fake_call_->GetVideoReceiveStreams()[0]);
6109 FakeVideoReceiveStream* recv_stream1 =
6110 fake_call_->GetVideoReceiveStreams()[1];
6111 EXPECT_EQ(kSsrcs3[1], recv_stream1->GetConfig().rtp.remote_ssrc);
6112}
6113
Seth Hampson7c682e02018-05-04 16:28:15 -07006114TEST_F(WebRtcVideoChannelTest, CanSetMaxBitrateForExistingStream) {
skvladdc1c62c2016-03-16 19:07:43 -07006115 AddSendStream();
6116
Niels Möller805a27e2019-01-21 12:21:27 +01006117 webrtc::test::FrameForwarder frame_forwarder;
6118 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));
skvladdc1c62c2016-03-16 19:07:43 -07006119 EXPECT_TRUE(channel_->SetSend(true));
Niels Möller805a27e2019-01-21 12:21:27 +01006120 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
skvladdc1c62c2016-03-16 19:07:43 -07006121
perkjfa10b552016-10-02 23:45:26 -07006122 int default_encoder_bitrate = GetMaxEncoderBitrate();
brandtr468da7c2016-11-22 02:16:47 -08006123 EXPECT_GT(default_encoder_bitrate, 1000);
skvladdc1c62c2016-03-16 19:07:43 -07006124
6125 // TODO(skvlad): Resolve the inconsistency between the interpretation
6126 // of the global bitrate limit for audio and video:
6127 // - Audio: max_bandwidth_bps = 0 - fail the operation,
6128 // max_bandwidth_bps = -1 - remove the bandwidth limit
6129 // - Video: max_bandwidth_bps = 0 - remove the bandwidth limit,
pbos5c7760a2017-03-10 11:23:12 -08006130 // max_bandwidth_bps = -1 - remove the bandwidth limit
skvladdc1c62c2016-03-16 19:07:43 -07006131
perkjfa10b552016-10-02 23:45:26 -07006132 SetAndExpectMaxBitrate(1000, 0, 1000);
6133 SetAndExpectMaxBitrate(1000, 800, 800);
6134 SetAndExpectMaxBitrate(600, 800, 600);
6135 SetAndExpectMaxBitrate(0, 800, 800);
6136 SetAndExpectMaxBitrate(0, 0, default_encoder_bitrate);
skvladdc1c62c2016-03-16 19:07:43 -07006137
Niels Möllerff40b142018-04-09 08:49:14 +02006138 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
skvladdc1c62c2016-03-16 19:07:43 -07006139}
6140
eladalonf1841382017-06-12 01:16:46 -07006141TEST_F(WebRtcVideoChannelTest, CannotSetMaxBitrateForNonexistentStream) {
skvladdc1c62c2016-03-16 19:07:43 -07006142 webrtc::RtpParameters nonexistent_parameters =
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07006143 channel_->GetRtpSendParameters(last_ssrc_);
Mirko Bonadeif859e552018-05-30 15:31:29 +02006144 EXPECT_EQ(0u, nonexistent_parameters.encodings.size());
skvladdc1c62c2016-03-16 19:07:43 -07006145
6146 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07006147 EXPECT_FALSE(
Zach Steinba37b4b2018-01-23 15:02:36 -08006148 channel_->SetRtpSendParameters(last_ssrc_, nonexistent_parameters).ok());
skvladdc1c62c2016-03-16 19:07:43 -07006149}
6150
eladalonf1841382017-06-12 01:16:46 -07006151TEST_F(WebRtcVideoChannelTest,
Seth Hampson7c682e02018-05-04 16:28:15 -07006152 SetLowMaxBitrateOverwritesVideoStreamMinBitrate) {
Åsa Perssonbdee46d2018-06-25 11:28:06 +02006153 FakeVideoSendStream* stream = AddSendStream();
6154
Seth Hampson7c682e02018-05-04 16:28:15 -07006155 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6156 EXPECT_EQ(1UL, parameters.encodings.size());
6157 EXPECT_FALSE(parameters.encodings[0].max_bitrate_bps.has_value());
6158 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6159
6160 // Note that this is testing the behavior of the FakeVideoSendStream, which
6161 // also calls to CreateEncoderStreams to get the VideoStreams, so essentially
6162 // we are just testing the behavior of
6163 // EncoderStreamFactory::CreateEncoderStreams.
Åsa Perssonbdee46d2018-06-25 11:28:06 +02006164 ASSERT_EQ(1UL, stream->GetVideoStreams().size());
Elad Alon80f53b72019-10-11 16:19:43 +02006165 EXPECT_EQ(webrtc::kDefaultMinVideoBitrateBps,
6166 stream->GetVideoStreams()[0].min_bitrate_bps);
Seth Hampson7c682e02018-05-04 16:28:15 -07006167
6168 // Set a low max bitrate & check that VideoStream.min_bitrate_bps is limited
6169 // by this amount.
6170 parameters = channel_->GetRtpSendParameters(last_ssrc_);
Elad Alon80f53b72019-10-11 16:19:43 +02006171 int low_max_bitrate_bps = webrtc::kDefaultMinVideoBitrateBps - 1000;
Seth Hampson7c682e02018-05-04 16:28:15 -07006172 parameters.encodings[0].max_bitrate_bps = low_max_bitrate_bps;
6173 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6174
Åsa Perssonbdee46d2018-06-25 11:28:06 +02006175 ASSERT_EQ(1UL, stream->GetVideoStreams().size());
6176 EXPECT_EQ(low_max_bitrate_bps, stream->GetVideoStreams()[0].min_bitrate_bps);
6177 EXPECT_EQ(low_max_bitrate_bps, stream->GetVideoStreams()[0].max_bitrate_bps);
6178}
6179
6180TEST_F(WebRtcVideoChannelTest,
6181 SetHighMinBitrateOverwritesVideoStreamMaxBitrate) {
6182 FakeVideoSendStream* stream = AddSendStream();
6183
6184 // Note that this is testing the behavior of the FakeVideoSendStream, which
6185 // also calls to CreateEncoderStreams to get the VideoStreams, so essentially
6186 // we are just testing the behavior of
6187 // EncoderStreamFactory::CreateEncoderStreams.
6188 ASSERT_EQ(1UL, stream->GetVideoStreams().size());
6189 int high_min_bitrate_bps = stream->GetVideoStreams()[0].max_bitrate_bps + 1;
6190
6191 // Set a high min bitrate and check that max_bitrate_bps is adjusted up.
6192 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6193 EXPECT_EQ(1UL, parameters.encodings.size());
6194 parameters.encodings[0].min_bitrate_bps = high_min_bitrate_bps;
6195 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6196
6197 ASSERT_EQ(1UL, stream->GetVideoStreams().size());
6198 EXPECT_EQ(high_min_bitrate_bps, stream->GetVideoStreams()[0].min_bitrate_bps);
6199 EXPECT_EQ(high_min_bitrate_bps, stream->GetVideoStreams()[0].max_bitrate_bps);
6200}
6201
6202TEST_F(WebRtcVideoChannelTest,
6203 SetMinBitrateAboveMaxBitrateLimitAdjustsMinBitrateDown) {
6204 send_parameters_.max_bandwidth_bps = 99999;
6205 FakeVideoSendStream* stream = AddSendStream();
6206 ExpectSetMaxBitrate(send_parameters_.max_bandwidth_bps);
6207 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
6208 ASSERT_EQ(1UL, stream->GetVideoStreams().size());
Elad Alon80f53b72019-10-11 16:19:43 +02006209 EXPECT_EQ(webrtc::kDefaultMinVideoBitrateBps,
6210 stream->GetVideoStreams()[0].min_bitrate_bps);
Åsa Perssonbdee46d2018-06-25 11:28:06 +02006211 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
6212 stream->GetVideoStreams()[0].max_bitrate_bps);
6213
6214 // Set min bitrate above global max bitrate and check that min_bitrate_bps is
6215 // adjusted down.
6216 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6217 EXPECT_EQ(1UL, parameters.encodings.size());
6218 parameters.encodings[0].min_bitrate_bps = 99999 + 1;
6219 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6220 ASSERT_EQ(1UL, stream->GetVideoStreams().size());
6221 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
6222 stream->GetVideoStreams()[0].min_bitrate_bps);
6223 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
6224 stream->GetVideoStreams()[0].max_bitrate_bps);
Seth Hampson7c682e02018-05-04 16:28:15 -07006225}
6226
Åsa Persson8c1bf952018-09-13 10:42:19 +02006227TEST_F(WebRtcVideoChannelTest, SetMaxFramerateOneStream) {
6228 FakeVideoSendStream* stream = AddSendStream();
6229
6230 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6231 EXPECT_EQ(1UL, parameters.encodings.size());
6232 EXPECT_FALSE(parameters.encodings[0].max_framerate.has_value());
6233 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6234
6235 // Note that this is testing the behavior of the FakeVideoSendStream, which
6236 // also calls to CreateEncoderStreams to get the VideoStreams, so essentially
6237 // we are just testing the behavior of
6238 // EncoderStreamFactory::CreateEncoderStreams.
6239 ASSERT_EQ(1UL, stream->GetVideoStreams().size());
6240 EXPECT_EQ(kDefaultVideoMaxFramerate,
6241 stream->GetVideoStreams()[0].max_framerate);
6242
6243 // Set max framerate and check that VideoStream.max_framerate is set.
6244 const int kNewMaxFramerate = kDefaultVideoMaxFramerate - 1;
6245 parameters = channel_->GetRtpSendParameters(last_ssrc_);
6246 parameters.encodings[0].max_framerate = kNewMaxFramerate;
6247 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6248
6249 ASSERT_EQ(1UL, stream->GetVideoStreams().size());
6250 EXPECT_EQ(kNewMaxFramerate, stream->GetVideoStreams()[0].max_framerate);
6251}
6252
Åsa Persson23eba222018-10-02 14:47:06 +02006253TEST_F(WebRtcVideoChannelTest, SetNumTemporalLayersForSingleStream) {
6254 FakeVideoSendStream* stream = AddSendStream();
6255
6256 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6257 EXPECT_EQ(1UL, parameters.encodings.size());
6258 EXPECT_FALSE(parameters.encodings[0].num_temporal_layers.has_value());
6259 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6260
6261 // Note that this is testing the behavior of the FakeVideoSendStream, which
6262 // also calls to CreateEncoderStreams to get the VideoStreams, so essentially
6263 // we are just testing the behavior of
6264 // EncoderStreamFactory::CreateEncoderStreams.
6265 ASSERT_EQ(1UL, stream->GetVideoStreams().size());
6266 EXPECT_FALSE(stream->GetVideoStreams()[0].num_temporal_layers.has_value());
6267
6268 // Set temporal layers and check that VideoStream.num_temporal_layers is set.
6269 parameters = channel_->GetRtpSendParameters(last_ssrc_);
6270 parameters.encodings[0].num_temporal_layers = 2;
6271 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6272
6273 ASSERT_EQ(1UL, stream->GetVideoStreams().size());
6274 EXPECT_EQ(2UL, stream->GetVideoStreams()[0].num_temporal_layers);
6275}
6276
Seth Hampson7c682e02018-05-04 16:28:15 -07006277TEST_F(WebRtcVideoChannelTest,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07006278 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvladdc1c62c2016-03-16 19:07:43 -07006279 AddSendStream();
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07006280 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
skvladdc1c62c2016-03-16 19:07:43 -07006281 // Two or more encodings should result in failure.
6282 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08006283 EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08006284 // Zero encodings should also fail.
6285 parameters.encodings.clear();
Zach Steinba37b4b2018-01-23 15:02:36 -08006286 EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08006287}
6288
Zach Stein3ca452b2018-01-18 10:01:24 -08006289TEST_F(WebRtcVideoChannelTest,
6290 CannotSetSimulcastRtpSendParametersWithIncorrectNumberOfEncodings) {
6291 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
6292 StreamParams sp = CreateSimStreamParams("cname", ssrcs);
6293 AddSendStream(sp);
6294
6295 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6296
6297 // Additional encodings should result in failure.
6298 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08006299 EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
Zach Stein3ca452b2018-01-18 10:01:24 -08006300 // Zero encodings should also fail.
6301 parameters.encodings.clear();
Zach Steinba37b4b2018-01-23 15:02:36 -08006302 EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
Zach Stein3ca452b2018-01-18 10:01:24 -08006303}
6304
deadbeeffb2aced2017-01-06 23:05:37 -08006305// Changing the SSRC through RtpParameters is not allowed.
eladalonf1841382017-06-12 01:16:46 -07006306TEST_F(WebRtcVideoChannelTest, CannotSetSsrcInRtpSendParameters) {
deadbeeffb2aced2017-01-06 23:05:37 -08006307 AddSendStream();
6308 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
Oskar Sundbom78807582017-11-16 11:09:55 +01006309 parameters.encodings[0].ssrc = 0xdeadbeef;
Zach Steinba37b4b2018-01-23 15:02:36 -08006310 EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
skvladdc1c62c2016-03-16 19:07:43 -07006311}
6312
Seth Hampson24722b32017-12-22 09:36:42 -08006313// Tests that when RTCRtpEncodingParameters.bitrate_priority gets set to
6314// a value <= 0, setting the parameters returns false.
6315TEST_F(WebRtcVideoChannelTest, SetRtpSendParametersInvalidBitratePriority) {
6316 AddSendStream();
6317 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6318 EXPECT_EQ(1UL, parameters.encodings.size());
6319 EXPECT_EQ(webrtc::kDefaultBitratePriority,
6320 parameters.encodings[0].bitrate_priority);
6321
6322 parameters.encodings[0].bitrate_priority = 0;
Zach Steinba37b4b2018-01-23 15:02:36 -08006323 EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08006324 parameters.encodings[0].bitrate_priority = -2;
Zach Steinba37b4b2018-01-23 15:02:36 -08006325 EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08006326}
6327
6328// Tests when the the RTCRtpEncodingParameters.bitrate_priority gets set
6329// properly on the VideoChannel and propogates down to the video encoder.
6330TEST_F(WebRtcVideoChannelTest, SetRtpSendParametersPriorityOneStream) {
6331 AddSendStream();
6332 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6333 EXPECT_EQ(1UL, parameters.encodings.size());
6334 EXPECT_EQ(webrtc::kDefaultBitratePriority,
6335 parameters.encodings[0].bitrate_priority);
6336
6337 // Change the value and set it on the VideoChannel.
6338 double new_bitrate_priority = 2.0;
6339 parameters.encodings[0].bitrate_priority = new_bitrate_priority;
Zach Steinba37b4b2018-01-23 15:02:36 -08006340 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08006341
6342 // Verify that the encoding parameters bitrate_priority is set for the
6343 // VideoChannel.
6344 parameters = channel_->GetRtpSendParameters(last_ssrc_);
6345 EXPECT_EQ(1UL, parameters.encodings.size());
6346 EXPECT_EQ(new_bitrate_priority, parameters.encodings[0].bitrate_priority);
6347
6348 // Verify that the new value propagated down to the encoder.
6349 std::vector<FakeVideoSendStream*> video_send_streams =
6350 fake_call_->GetVideoSendStreams();
6351 EXPECT_EQ(1UL, video_send_streams.size());
6352 FakeVideoSendStream* video_send_stream = video_send_streams.front();
6353 // Check that the WebRtcVideoSendStream updated the VideoEncoderConfig
6354 // appropriately.
6355 EXPECT_EQ(new_bitrate_priority,
6356 video_send_stream->GetEncoderConfig().bitrate_priority);
6357 // Check that the vector of VideoStreams also was propagated correctly. Note
6358 // that this is testing the behavior of the FakeVideoSendStream, which mimics
6359 // the calls to CreateEncoderStreams to get the VideoStreams.
Danil Chapovalov00c71832018-06-15 15:58:38 +02006360 EXPECT_EQ(absl::optional<double>(new_bitrate_priority),
Seth Hampson24722b32017-12-22 09:36:42 -08006361 video_send_stream->GetVideoStreams()[0].bitrate_priority);
6362}
6363
6364// Tests that the RTCRtpEncodingParameters.bitrate_priority is set for the
6365// VideoChannel and the value propogates to the video encoder with all simulcast
6366// streams.
6367TEST_F(WebRtcVideoChannelTest, SetRtpSendParametersPrioritySimulcastStreams) {
6368 // Create the stream params with multiple ssrcs for simulcast.
Åsa Persson31cb8f92018-06-27 10:44:56 +02006369 const size_t kNumSimulcastStreams = 3;
Seth Hampson24722b32017-12-22 09:36:42 -08006370 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
6371 StreamParams stream_params = CreateSimStreamParams("cname", ssrcs);
6372 AddSendStream(stream_params);
6373 uint32_t primary_ssrc = stream_params.first_ssrc();
6374
Niels Möller805a27e2019-01-21 12:21:27 +01006375 // Using the FrameForwarder, we manually send a full size
Tommi85959932018-02-07 19:26:06 +01006376 // frame. This creates multiple VideoStreams for all simulcast layers when
6377 // reconfiguring, and allows us to test this behavior.
Niels Möller805a27e2019-01-21 12:21:27 +01006378 webrtc::test::FrameForwarder frame_forwarder;
Seth Hampson24722b32017-12-22 09:36:42 -08006379 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01006380 EXPECT_TRUE(channel_->SetVideoSend(primary_ssrc, &options, &frame_forwarder));
Seth Hampson24722b32017-12-22 09:36:42 -08006381 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01006382 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame(
6383 1920, 1080, webrtc::VideoRotation::kVideoRotation_0,
6384 rtc::kNumMicrosecsPerSec / 30));
6385
Seth Hampson24722b32017-12-22 09:36:42 -08006386 // Get and set the rtp encoding parameters.
6387 webrtc::RtpParameters parameters =
6388 channel_->GetRtpSendParameters(primary_ssrc);
Åsa Persson31cb8f92018-06-27 10:44:56 +02006389 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
Seth Hampson24722b32017-12-22 09:36:42 -08006390 EXPECT_EQ(webrtc::kDefaultBitratePriority,
6391 parameters.encodings[0].bitrate_priority);
6392 // Change the value and set it on the VideoChannel.
6393 double new_bitrate_priority = 2.0;
6394 parameters.encodings[0].bitrate_priority = new_bitrate_priority;
Zach Steinba37b4b2018-01-23 15:02:36 -08006395 EXPECT_TRUE(channel_->SetRtpSendParameters(primary_ssrc, parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08006396
6397 // Verify that the encoding parameters priority is set on the VideoChannel.
6398 parameters = channel_->GetRtpSendParameters(primary_ssrc);
Åsa Persson31cb8f92018-06-27 10:44:56 +02006399 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
Seth Hampson24722b32017-12-22 09:36:42 -08006400 EXPECT_EQ(new_bitrate_priority, parameters.encodings[0].bitrate_priority);
6401
6402 // Verify that the new value propagated down to the encoder.
6403 std::vector<FakeVideoSendStream*> video_send_streams =
6404 fake_call_->GetVideoSendStreams();
6405 EXPECT_EQ(1UL, video_send_streams.size());
6406 FakeVideoSendStream* video_send_stream = video_send_streams.front();
6407 // Check that the WebRtcVideoSendStream updated the VideoEncoderConfig
6408 // appropriately.
Åsa Persson31cb8f92018-06-27 10:44:56 +02006409 EXPECT_EQ(kNumSimulcastStreams,
Seth Hampson24722b32017-12-22 09:36:42 -08006410 video_send_stream->GetEncoderConfig().number_of_streams);
6411 EXPECT_EQ(new_bitrate_priority,
6412 video_send_stream->GetEncoderConfig().bitrate_priority);
6413 // Check that the vector of VideoStreams also propagated correctly. The
6414 // FakeVideoSendStream calls CreateEncoderStreams, and we are testing that
6415 // these are created appropriately for the simulcast case.
Åsa Persson31cb8f92018-06-27 10:44:56 +02006416 EXPECT_EQ(kNumSimulcastStreams, video_send_stream->GetVideoStreams().size());
Danil Chapovalov00c71832018-06-15 15:58:38 +02006417 EXPECT_EQ(absl::optional<double>(new_bitrate_priority),
Seth Hampson24722b32017-12-22 09:36:42 -08006418 video_send_stream->GetVideoStreams()[0].bitrate_priority);
6419 // Since we are only setting bitrate priority per-sender, the other
6420 // VideoStreams should have a bitrate priority of 0.
Danil Chapovalov00c71832018-06-15 15:58:38 +02006421 EXPECT_EQ(absl::nullopt,
Seth Hampson24722b32017-12-22 09:36:42 -08006422 video_send_stream->GetVideoStreams()[1].bitrate_priority);
Danil Chapovalov00c71832018-06-15 15:58:38 +02006423 EXPECT_EQ(absl::nullopt,
Seth Hampson24722b32017-12-22 09:36:42 -08006424 video_send_stream->GetVideoStreams()[2].bitrate_priority);
Niels Möllerff40b142018-04-09 08:49:14 +02006425 EXPECT_TRUE(channel_->SetVideoSend(primary_ssrc, nullptr, nullptr));
Seth Hampson24722b32017-12-22 09:36:42 -08006426}
6427
Florent Castellic1a0bcb2019-01-29 14:26:48 +01006428TEST_F(WebRtcVideoChannelTest,
6429 GetAndSetRtpSendParametersScaleResolutionDownByVP8) {
Rasmus Brandt9387b522019-02-05 14:23:26 +01006430 VideoSendParameters parameters;
6431 parameters.codecs.push_back(VideoCodec(kVp8CodecName));
Florent Castellic1a0bcb2019-01-29 14:26:48 +01006432 ASSERT_TRUE(channel_->SetSendParameters(parameters));
6433 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
6434
6435 webrtc::test::FrameForwarder frame_forwarder;
Rasmus Brandt9387b522019-02-05 14:23:26 +01006436 FakeFrameSource frame_source(1280, 720, rtc::kNumMicrosecsPerSec / 30);
Florent Castellic1a0bcb2019-01-29 14:26:48 +01006437
6438 VideoOptions options;
6439 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
6440 channel_->SetSend(true);
6441
6442 // Try layers in natural order (smallest to largest).
6443 {
6444 auto rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
6445 ASSERT_EQ(3u, rtp_parameters.encodings.size());
6446 rtp_parameters.encodings[0].scale_resolution_down_by = 4.0;
6447 rtp_parameters.encodings[1].scale_resolution_down_by = 2.0;
6448 rtp_parameters.encodings[2].scale_resolution_down_by = 1.0;
6449 auto result = channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
6450 ASSERT_TRUE(result.ok());
6451
6452 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
6453
6454 std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
6455 ASSERT_EQ(3u, video_streams.size());
6456 EXPECT_EQ(320u, video_streams[0].width);
6457 EXPECT_EQ(180u, video_streams[0].height);
6458 EXPECT_EQ(640u, video_streams[1].width);
6459 EXPECT_EQ(360u, video_streams[1].height);
6460 EXPECT_EQ(1280u, video_streams[2].width);
6461 EXPECT_EQ(720u, video_streams[2].height);
6462 }
6463
6464 // Try layers in reverse natural order (largest to smallest).
6465 {
6466 auto rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
6467 ASSERT_EQ(3u, rtp_parameters.encodings.size());
6468 rtp_parameters.encodings[0].scale_resolution_down_by = 1.0;
6469 rtp_parameters.encodings[1].scale_resolution_down_by = 2.0;
6470 rtp_parameters.encodings[2].scale_resolution_down_by = 4.0;
6471 auto result = channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
6472 ASSERT_TRUE(result.ok());
6473
6474 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
6475
6476 std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
6477 ASSERT_EQ(3u, video_streams.size());
6478 EXPECT_EQ(1280u, video_streams[0].width);
6479 EXPECT_EQ(720u, video_streams[0].height);
6480 EXPECT_EQ(640u, video_streams[1].width);
6481 EXPECT_EQ(360u, video_streams[1].height);
6482 EXPECT_EQ(320u, video_streams[2].width);
6483 EXPECT_EQ(180u, video_streams[2].height);
6484 }
6485
6486 // Try layers in mixed order.
6487 {
6488 auto rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
6489 ASSERT_EQ(3u, rtp_parameters.encodings.size());
6490 rtp_parameters.encodings[0].scale_resolution_down_by = 10.0;
6491 rtp_parameters.encodings[1].scale_resolution_down_by = 2.0;
6492 rtp_parameters.encodings[2].scale_resolution_down_by = 4.0;
6493 auto result = channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
6494 ASSERT_TRUE(result.ok());
6495
6496 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
6497
6498 std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
6499 ASSERT_EQ(3u, video_streams.size());
6500 EXPECT_EQ(128u, video_streams[0].width);
6501 EXPECT_EQ(72u, video_streams[0].height);
6502 EXPECT_EQ(640u, video_streams[1].width);
6503 EXPECT_EQ(360u, video_streams[1].height);
6504 EXPECT_EQ(320u, video_streams[2].width);
6505 EXPECT_EQ(180u, video_streams[2].height);
6506 }
6507
6508 // Try with a missing scale setting, defaults to 1.0 if any other is set.
6509 {
6510 auto rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
6511 ASSERT_EQ(3u, rtp_parameters.encodings.size());
6512 rtp_parameters.encodings[0].scale_resolution_down_by = 1.0;
6513 rtp_parameters.encodings[1].scale_resolution_down_by.reset();
6514 rtp_parameters.encodings[2].scale_resolution_down_by = 4.0;
6515 auto result = channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
6516 ASSERT_TRUE(result.ok());
6517
6518 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
6519
6520 std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
6521 ASSERT_EQ(3u, video_streams.size());
6522 EXPECT_EQ(1280u, video_streams[0].width);
6523 EXPECT_EQ(720u, video_streams[0].height);
6524 EXPECT_EQ(1280u, video_streams[1].width);
6525 EXPECT_EQ(720u, video_streams[1].height);
6526 EXPECT_EQ(320u, video_streams[2].width);
6527 EXPECT_EQ(180u, video_streams[2].height);
6528 }
6529
6530 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
6531}
6532
6533TEST_F(WebRtcVideoChannelTest,
Rasmus Brandt9387b522019-02-05 14:23:26 +01006534 GetAndSetRtpSendParametersScaleResolutionDownByVP8WithOddResolution) {
6535 // Ensure that the top layer has width and height divisible by 2^3,
6536 // so that the bottom layer has width and height divisible by 2.
6537 // TODO(bugs.webrtc.org/8785): Remove this field trial when we fully trust
6538 // the number of simulcast layers set by the app.
6539 webrtc::test::ScopedFieldTrials field_trial(
6540 "WebRTC-NormalizeSimulcastResolution/Enabled-3/");
6541
6542 // Set up WebRtcVideoChannel for 3-layer VP8 simulcast.
6543 VideoSendParameters parameters;
6544 parameters.codecs.push_back(VideoCodec(kVp8CodecName));
6545 ASSERT_TRUE(channel_->SetSendParameters(parameters));
6546 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
6547 webrtc::test::FrameForwarder frame_forwarder;
6548 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, /*options=*/nullptr,
6549 &frame_forwarder));
6550 channel_->SetSend(true);
6551
6552 // Set |scale_resolution_down_by|'s.
6553 auto rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
6554 ASSERT_EQ(rtp_parameters.encodings.size(), 3u);
6555 rtp_parameters.encodings[0].scale_resolution_down_by = 1.0;
6556 rtp_parameters.encodings[1].scale_resolution_down_by = 2.0;
6557 rtp_parameters.encodings[2].scale_resolution_down_by = 4.0;
6558 const auto result =
6559 channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
6560 ASSERT_TRUE(result.ok());
6561
6562 // Use a capture resolution whose width and height are not divisible by 2^3.
6563 // (See field trial set at the top of the test.)
6564 FakeFrameSource frame_source(2007, 1207, rtc::kNumMicrosecsPerSec / 30);
6565 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
6566
6567 // Ensure the scaling is correct.
6568 const auto video_streams = stream->GetVideoStreams();
6569 ASSERT_EQ(video_streams.size(), 3u);
6570 // Ensure that we round the capture resolution down for the top layer...
6571 EXPECT_EQ(video_streams[0].width, 2000u);
6572 EXPECT_EQ(video_streams[0].height, 1200u);
6573 EXPECT_EQ(video_streams[1].width, 1000u);
6574 EXPECT_EQ(video_streams[1].height, 600u);
6575 // ...and that the bottom layer has a width/height divisible by 2.
6576 EXPECT_EQ(video_streams[2].width, 500u);
6577 EXPECT_EQ(video_streams[2].height, 300u);
6578
6579 // Tear down.
6580 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
6581}
6582
6583TEST_F(WebRtcVideoChannelTest,
Florent Castellic1a0bcb2019-01-29 14:26:48 +01006584 GetAndSetRtpSendParametersScaleResolutionDownByH264) {
Rasmus Brandt9387b522019-02-05 14:23:26 +01006585 encoder_factory_->AddSupportedVideoCodecType(kH264CodecName);
6586 VideoSendParameters parameters;
6587 parameters.codecs.push_back(VideoCodec(kH264CodecName));
Florent Castellic1a0bcb2019-01-29 14:26:48 +01006588 ASSERT_TRUE(channel_->SetSendParameters(parameters));
6589 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
6590
6591 webrtc::test::FrameForwarder frame_forwarder;
Rasmus Brandt9387b522019-02-05 14:23:26 +01006592 FakeFrameSource frame_source(1280, 720, rtc::kNumMicrosecsPerSec / 30);
Florent Castellic1a0bcb2019-01-29 14:26:48 +01006593
6594 VideoOptions options;
6595 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
6596 channel_->SetSend(true);
6597
6598 // Try layers in natural order (smallest to largest).
6599 {
6600 auto rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
6601 ASSERT_EQ(3u, rtp_parameters.encodings.size());
6602 rtp_parameters.encodings[0].scale_resolution_down_by = 4.0;
6603 rtp_parameters.encodings[1].scale_resolution_down_by = 2.0;
6604 rtp_parameters.encodings[2].scale_resolution_down_by = 1.0;
6605 auto result = channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
6606 ASSERT_TRUE(result.ok());
6607
6608 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
6609
6610 std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
6611 ASSERT_EQ(3u, video_streams.size());
6612 EXPECT_EQ(320u, video_streams[0].width);
6613 EXPECT_EQ(180u, video_streams[0].height);
6614 EXPECT_EQ(640u, video_streams[1].width);
6615 EXPECT_EQ(360u, video_streams[1].height);
6616 EXPECT_EQ(1280u, video_streams[2].width);
6617 EXPECT_EQ(720u, video_streams[2].height);
6618 }
6619
6620 // Try layers in reverse natural order (largest to smallest).
6621 {
6622 auto rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
6623 ASSERT_EQ(3u, rtp_parameters.encodings.size());
6624 rtp_parameters.encodings[0].scale_resolution_down_by = 1.0;
6625 rtp_parameters.encodings[1].scale_resolution_down_by = 2.0;
6626 rtp_parameters.encodings[2].scale_resolution_down_by = 4.0;
6627 auto result = channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
6628 ASSERT_TRUE(result.ok());
6629
6630 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
6631
6632 std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
6633 ASSERT_EQ(3u, video_streams.size());
6634 EXPECT_EQ(1280u, video_streams[0].width);
6635 EXPECT_EQ(720u, video_streams[0].height);
6636 EXPECT_EQ(640u, video_streams[1].width);
6637 EXPECT_EQ(360u, video_streams[1].height);
6638 EXPECT_EQ(320u, video_streams[2].width);
6639 EXPECT_EQ(180u, video_streams[2].height);
6640 }
6641
6642 // Try layers in mixed order.
6643 {
6644 auto rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
6645 ASSERT_EQ(3u, rtp_parameters.encodings.size());
6646 rtp_parameters.encodings[0].scale_resolution_down_by = 10.0;
6647 rtp_parameters.encodings[1].scale_resolution_down_by = 2.0;
6648 rtp_parameters.encodings[2].scale_resolution_down_by = 4.0;
6649 auto result = channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
6650 ASSERT_TRUE(result.ok());
6651
6652 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
6653
6654 std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
6655 ASSERT_EQ(3u, video_streams.size());
6656 EXPECT_EQ(128u, video_streams[0].width);
6657 EXPECT_EQ(72u, video_streams[0].height);
6658 EXPECT_EQ(640u, video_streams[1].width);
6659 EXPECT_EQ(360u, video_streams[1].height);
6660 EXPECT_EQ(320u, video_streams[2].width);
6661 EXPECT_EQ(180u, video_streams[2].height);
6662 }
6663
6664 // Try with a missing scale setting, defaults to 1.0 if any other is set.
6665 {
6666 auto rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
6667 ASSERT_EQ(3u, rtp_parameters.encodings.size());
6668 rtp_parameters.encodings[0].scale_resolution_down_by = 1.0;
6669 rtp_parameters.encodings[1].scale_resolution_down_by.reset();
6670 rtp_parameters.encodings[2].scale_resolution_down_by = 4.0;
6671 auto result = channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
6672 ASSERT_TRUE(result.ok());
6673
6674 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
6675
6676 std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
6677 ASSERT_EQ(3u, video_streams.size());
6678 EXPECT_EQ(1280u, video_streams[0].width);
6679 EXPECT_EQ(720u, video_streams[0].height);
6680 EXPECT_EQ(1280u, video_streams[1].width);
6681 EXPECT_EQ(720u, video_streams[1].height);
6682 EXPECT_EQ(320u, video_streams[2].width);
6683 EXPECT_EQ(180u, video_streams[2].height);
6684 }
6685 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
6686}
6687
Rasmus Brandt9387b522019-02-05 14:23:26 +01006688TEST_F(WebRtcVideoChannelTest,
6689 GetAndSetRtpSendParametersScaleResolutionDownByH264WithOddResolution) {
6690 // Ensure that the top layer has width and height divisible by 2^3,
6691 // so that the bottom layer has width and height divisible by 2.
6692 // TODO(bugs.webrtc.org/8785): Remove this field trial when we fully trust
6693 // the number of simulcast layers set by the app.
6694 webrtc::test::ScopedFieldTrials field_trial(
6695 "WebRTC-NormalizeSimulcastResolution/Enabled-3/");
6696
6697 // Set up WebRtcVideoChannel for 3-layer H264 simulcast.
6698 encoder_factory_->AddSupportedVideoCodecType(kH264CodecName);
6699 VideoSendParameters parameters;
6700 parameters.codecs.push_back(VideoCodec(kH264CodecName));
6701 ASSERT_TRUE(channel_->SetSendParameters(parameters));
6702 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
6703 webrtc::test::FrameForwarder frame_forwarder;
6704 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, /*options=*/nullptr,
6705 &frame_forwarder));
6706 channel_->SetSend(true);
6707
6708 // Set |scale_resolution_down_by|'s.
6709 auto rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
6710 ASSERT_EQ(rtp_parameters.encodings.size(), 3u);
6711 rtp_parameters.encodings[0].scale_resolution_down_by = 1.0;
6712 rtp_parameters.encodings[1].scale_resolution_down_by = 2.0;
6713 rtp_parameters.encodings[2].scale_resolution_down_by = 4.0;
6714 const auto result =
6715 channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
6716 ASSERT_TRUE(result.ok());
6717
6718 // Use a capture resolution whose width and height are not divisible by 2^3.
6719 // (See field trial set at the top of the test.)
6720 FakeFrameSource frame_source(2007, 1207, rtc::kNumMicrosecsPerSec / 30);
6721 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
6722
6723 // Ensure the scaling is correct.
6724 const auto video_streams = stream->GetVideoStreams();
6725 ASSERT_EQ(video_streams.size(), 3u);
6726 // Ensure that we round the capture resolution down for the top layer...
6727 EXPECT_EQ(video_streams[0].width, 2000u);
6728 EXPECT_EQ(video_streams[0].height, 1200u);
6729 EXPECT_EQ(video_streams[1].width, 1000u);
6730 EXPECT_EQ(video_streams[1].height, 600u);
6731 // ...and that the bottom layer has a width/height divisible by 2.
6732 EXPECT_EQ(video_streams[2].width, 500u);
6733 EXPECT_EQ(video_streams[2].height, 300u);
6734
6735 // Tear down.
6736 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
6737}
6738
Åsa Persson8c1bf952018-09-13 10:42:19 +02006739TEST_F(WebRtcVideoChannelTest, GetAndSetRtpSendParametersMaxFramerate) {
6740 const size_t kNumSimulcastStreams = 3;
6741 SetUpSimulcast(true, false);
6742
6743 // Get and set the rtp encoding parameters.
6744 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6745 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6746 for (const auto& encoding : parameters.encodings) {
6747 EXPECT_FALSE(encoding.max_framerate);
6748 }
6749
6750 // Change the value and set it on the VideoChannel.
6751 parameters.encodings[0].max_framerate = 10;
6752 parameters.encodings[1].max_framerate = 20;
6753 parameters.encodings[2].max_framerate = 25;
6754 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6755
6756 // Verify that the bitrates are set on the VideoChannel.
6757 parameters = channel_->GetRtpSendParameters(last_ssrc_);
6758 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6759 EXPECT_EQ(10, parameters.encodings[0].max_framerate);
6760 EXPECT_EQ(20, parameters.encodings[1].max_framerate);
6761 EXPECT_EQ(25, parameters.encodings[2].max_framerate);
6762}
6763
Åsa Persson23eba222018-10-02 14:47:06 +02006764TEST_F(WebRtcVideoChannelTest,
6765 SetRtpSendParametersNumTemporalLayersFailsForInvalidRange) {
6766 const size_t kNumSimulcastStreams = 3;
6767 SetUpSimulcast(true, false);
6768
6769 // Get and set the rtp encoding parameters.
6770 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6771 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6772
6773 // Num temporal layers should be in the range [1, kMaxTemporalStreams].
6774 parameters.encodings[0].num_temporal_layers = 0;
6775 EXPECT_EQ(webrtc::RTCErrorType::INVALID_RANGE,
6776 channel_->SetRtpSendParameters(last_ssrc_, parameters).type());
6777 parameters.encodings[0].num_temporal_layers = webrtc::kMaxTemporalStreams + 1;
6778 EXPECT_EQ(webrtc::RTCErrorType::INVALID_RANGE,
6779 channel_->SetRtpSendParameters(last_ssrc_, parameters).type());
6780}
6781
6782TEST_F(WebRtcVideoChannelTest,
6783 SetRtpSendParametersNumTemporalLayersFailsForInvalidModification) {
6784 const size_t kNumSimulcastStreams = 3;
6785 SetUpSimulcast(true, false);
6786
6787 // Get and set the rtp encoding parameters.
6788 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6789 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6790
6791 // No/all layers should be set.
6792 parameters.encodings[0].num_temporal_layers = 1;
6793 EXPECT_EQ(webrtc::RTCErrorType::INVALID_MODIFICATION,
6794 channel_->SetRtpSendParameters(last_ssrc_, parameters).type());
6795
6796 // Different values not supported.
6797 parameters.encodings[0].num_temporal_layers = 1;
6798 parameters.encodings[1].num_temporal_layers = 2;
6799 parameters.encodings[2].num_temporal_layers = 2;
6800 EXPECT_EQ(webrtc::RTCErrorType::INVALID_MODIFICATION,
6801 channel_->SetRtpSendParameters(last_ssrc_, parameters).type());
6802}
6803
6804TEST_F(WebRtcVideoChannelTest, GetAndSetRtpSendParametersNumTemporalLayers) {
6805 const size_t kNumSimulcastStreams = 3;
6806 SetUpSimulcast(true, false);
6807
6808 // Get and set the rtp encoding parameters.
6809 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6810 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6811 for (const auto& encoding : parameters.encodings)
6812 EXPECT_FALSE(encoding.num_temporal_layers);
6813
6814 // Change the value and set it on the VideoChannel.
6815 parameters.encodings[0].num_temporal_layers = 3;
6816 parameters.encodings[1].num_temporal_layers = 3;
6817 parameters.encodings[2].num_temporal_layers = 3;
6818 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6819
6820 // Verify that the number of temporal layers are set on the VideoChannel.
6821 parameters = channel_->GetRtpSendParameters(last_ssrc_);
6822 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6823 EXPECT_EQ(3, parameters.encodings[0].num_temporal_layers);
6824 EXPECT_EQ(3, parameters.encodings[1].num_temporal_layers);
6825 EXPECT_EQ(3, parameters.encodings[2].num_temporal_layers);
6826}
6827
6828TEST_F(WebRtcVideoChannelTest, NumTemporalLayersPropagatedToEncoder) {
6829 const size_t kNumSimulcastStreams = 3;
6830 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
6831
6832 // Send a full size frame so all simulcast layers are used when reconfiguring.
Niels Möller805a27e2019-01-21 12:21:27 +01006833 webrtc::test::FrameForwarder frame_forwarder;
Åsa Persson23eba222018-10-02 14:47:06 +02006834 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01006835 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
Åsa Persson23eba222018-10-02 14:47:06 +02006836 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01006837 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Åsa Persson23eba222018-10-02 14:47:06 +02006838
6839 // Get and set the rtp encoding parameters.
6840 // Change the value and set it on the VideoChannel.
6841 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6842 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6843 parameters.encodings[0].num_temporal_layers = 2;
6844 parameters.encodings[1].num_temporal_layers = 2;
6845 parameters.encodings[2].num_temporal_layers = 2;
6846 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6847
6848 // Verify that the new value is propagated down to the encoder.
6849 // Check that WebRtcVideoSendStream updates VideoEncoderConfig correctly.
6850 EXPECT_EQ(2, stream->num_encoder_reconfigurations());
6851 webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
6852 EXPECT_EQ(kNumSimulcastStreams, encoder_config.number_of_streams);
6853 EXPECT_EQ(kNumSimulcastStreams, encoder_config.simulcast_layers.size());
6854 EXPECT_EQ(2UL, encoder_config.simulcast_layers[0].num_temporal_layers);
6855 EXPECT_EQ(2UL, encoder_config.simulcast_layers[1].num_temporal_layers);
6856 EXPECT_EQ(2UL, encoder_config.simulcast_layers[2].num_temporal_layers);
6857
6858 // FakeVideoSendStream calls CreateEncoderStreams, test that the vector of
6859 // VideoStreams are created appropriately for the simulcast case.
6860 EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
6861 EXPECT_EQ(2UL, stream->GetVideoStreams()[0].num_temporal_layers);
6862 EXPECT_EQ(2UL, stream->GetVideoStreams()[1].num_temporal_layers);
6863 EXPECT_EQ(2UL, stream->GetVideoStreams()[2].num_temporal_layers);
6864
6865 // No parameter changed, encoder should not be reconfigured.
6866 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6867 EXPECT_EQ(2, stream->num_encoder_reconfigurations());
6868
6869 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
6870}
6871
6872TEST_F(WebRtcVideoChannelTest,
6873 DefaultValuePropagatedToEncoderForUnsetNumTemporalLayers) {
6874 const size_t kDefaultNumTemporalLayers = 3;
6875 const size_t kNumSimulcastStreams = 3;
6876 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
6877
6878 // Send a full size frame so all simulcast layers are used when reconfiguring.
Niels Möller805a27e2019-01-21 12:21:27 +01006879 webrtc::test::FrameForwarder frame_forwarder;
Åsa Persson23eba222018-10-02 14:47:06 +02006880 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01006881 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
Åsa Persson23eba222018-10-02 14:47:06 +02006882 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01006883 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Åsa Persson23eba222018-10-02 14:47:06 +02006884
6885 // Change rtp encoding parameters, num_temporal_layers not changed.
6886 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6887 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6888 parameters.encodings[0].min_bitrate_bps = 33000;
6889 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6890
6891 // Verify that no value is propagated down to the encoder.
6892 webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
6893 EXPECT_EQ(kNumSimulcastStreams, encoder_config.number_of_streams);
6894 EXPECT_EQ(kNumSimulcastStreams, encoder_config.simulcast_layers.size());
6895 EXPECT_FALSE(encoder_config.simulcast_layers[0].num_temporal_layers);
6896 EXPECT_FALSE(encoder_config.simulcast_layers[1].num_temporal_layers);
6897 EXPECT_FALSE(encoder_config.simulcast_layers[2].num_temporal_layers);
6898
6899 // FakeVideoSendStream calls CreateEncoderStreams, test that the vector of
6900 // VideoStreams are created appropriately for the simulcast case.
6901 EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
6902 EXPECT_EQ(kDefaultNumTemporalLayers,
6903 stream->GetVideoStreams()[0].num_temporal_layers);
6904 EXPECT_EQ(kDefaultNumTemporalLayers,
6905 stream->GetVideoStreams()[1].num_temporal_layers);
6906 EXPECT_EQ(kDefaultNumTemporalLayers,
6907 stream->GetVideoStreams()[2].num_temporal_layers);
6908
6909 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
6910}
6911
Åsa Persson8c1bf952018-09-13 10:42:19 +02006912TEST_F(WebRtcVideoChannelTest,
6913 DefaultValuePropagatedToEncoderForUnsetFramerate) {
6914 const size_t kNumSimulcastStreams = 3;
6915 const std::vector<webrtc::VideoStream> kDefault = GetSimulcastBitrates720p();
6916 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
6917
6918 // Send a full size frame so all simulcast layers are used when reconfiguring.
Niels Möller805a27e2019-01-21 12:21:27 +01006919 webrtc::test::FrameForwarder frame_forwarder;
Åsa Persson8c1bf952018-09-13 10:42:19 +02006920 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01006921 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
Åsa Persson8c1bf952018-09-13 10:42:19 +02006922 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01006923 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Åsa Persson8c1bf952018-09-13 10:42:19 +02006924
6925 // Get and set the rtp encoding parameters.
6926 // Change the value and set it on the VideoChannel.
6927 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6928 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6929 parameters.encodings[0].max_framerate = 15;
6930 parameters.encodings[2].max_framerate = 20;
6931 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6932
6933 // Verify that the new value propagated down to the encoder.
6934 // Check that WebRtcVideoSendStream updates VideoEncoderConfig correctly.
6935 webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
6936 EXPECT_EQ(kNumSimulcastStreams, encoder_config.number_of_streams);
6937 EXPECT_EQ(kNumSimulcastStreams, encoder_config.simulcast_layers.size());
6938 EXPECT_EQ(15, encoder_config.simulcast_layers[0].max_framerate);
6939 EXPECT_EQ(-1, encoder_config.simulcast_layers[1].max_framerate);
6940 EXPECT_EQ(20, encoder_config.simulcast_layers[2].max_framerate);
6941
6942 // FakeVideoSendStream calls CreateEncoderStreams, test that the vector of
6943 // VideoStreams are created appropriately for the simulcast case.
6944 // The maximum |max_framerate| is used, kDefaultVideoMaxFramerate: 60.
6945 EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
Florent Castelli907dc802019-12-06 15:03:19 +01006946 EXPECT_EQ(15, stream->GetVideoStreams()[0].max_framerate);
Åsa Persson8c1bf952018-09-13 10:42:19 +02006947 EXPECT_EQ(kDefaultVideoMaxFramerate,
6948 stream->GetVideoStreams()[1].max_framerate);
Florent Castelli907dc802019-12-06 15:03:19 +01006949 EXPECT_EQ(20, stream->GetVideoStreams()[2].max_framerate);
Åsa Persson8c1bf952018-09-13 10:42:19 +02006950
6951 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
6952}
6953
Åsa Persson55659812018-06-18 17:51:32 +02006954TEST_F(WebRtcVideoChannelTest, GetAndSetRtpSendParametersMinAndMaxBitrate) {
6955 const size_t kNumSimulcastStreams = 3;
6956 SetUpSimulcast(true, false);
6957
6958 // Get and set the rtp encoding parameters.
6959 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6960 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6961 for (const auto& encoding : parameters.encodings) {
6962 EXPECT_FALSE(encoding.min_bitrate_bps);
6963 EXPECT_FALSE(encoding.max_bitrate_bps);
6964 }
6965
6966 // Change the value and set it on the VideoChannel.
6967 parameters.encodings[0].min_bitrate_bps = 100000;
6968 parameters.encodings[0].max_bitrate_bps = 200000;
6969 parameters.encodings[1].min_bitrate_bps = 300000;
6970 parameters.encodings[1].max_bitrate_bps = 400000;
6971 parameters.encodings[2].min_bitrate_bps = 500000;
6972 parameters.encodings[2].max_bitrate_bps = 600000;
6973 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6974
6975 // Verify that the bitrates are set on the VideoChannel.
6976 parameters = channel_->GetRtpSendParameters(last_ssrc_);
6977 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6978 EXPECT_EQ(100000, parameters.encodings[0].min_bitrate_bps);
6979 EXPECT_EQ(200000, parameters.encodings[0].max_bitrate_bps);
6980 EXPECT_EQ(300000, parameters.encodings[1].min_bitrate_bps);
6981 EXPECT_EQ(400000, parameters.encodings[1].max_bitrate_bps);
6982 EXPECT_EQ(500000, parameters.encodings[2].min_bitrate_bps);
6983 EXPECT_EQ(600000, parameters.encodings[2].max_bitrate_bps);
6984}
6985
6986TEST_F(WebRtcVideoChannelTest, SetRtpSendParametersFailsWithIncorrectBitrate) {
6987 const size_t kNumSimulcastStreams = 3;
6988 SetUpSimulcast(true, false);
6989
6990 // Get and set the rtp encoding parameters.
6991 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6992 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6993
6994 // Max bitrate lower than min bitrate should fail.
6995 parameters.encodings[2].min_bitrate_bps = 100000;
6996 parameters.encodings[2].max_bitrate_bps = 100000 - 1;
6997 EXPECT_EQ(webrtc::RTCErrorType::INVALID_RANGE,
6998 channel_->SetRtpSendParameters(last_ssrc_, parameters).type());
6999}
7000
7001// Test that min and max bitrate values set via RtpParameters are correctly
7002// propagated to the underlying encoder, and that the target is set to 3/4 of
7003// the maximum (3/4 was chosen because it's similar to the simulcast defaults
7004// that are used if no min/max are specified).
7005TEST_F(WebRtcVideoChannelTest, MinAndMaxSimulcastBitratePropagatedToEncoder) {
7006 const size_t kNumSimulcastStreams = 3;
7007 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
7008
7009 // Send a full size frame so all simulcast layers are used when reconfiguring.
Niels Möller805a27e2019-01-21 12:21:27 +01007010 webrtc::test::FrameForwarder frame_forwarder;
Åsa Persson55659812018-06-18 17:51:32 +02007011 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01007012 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
Åsa Persson55659812018-06-18 17:51:32 +02007013 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01007014 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Åsa Persson55659812018-06-18 17:51:32 +02007015
7016 // Get and set the rtp encoding parameters.
7017 // Change the value and set it on the VideoChannel.
7018 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
7019 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
7020 parameters.encodings[0].min_bitrate_bps = 100000;
7021 parameters.encodings[0].max_bitrate_bps = 200000;
7022 parameters.encodings[1].min_bitrate_bps = 300000;
7023 parameters.encodings[1].max_bitrate_bps = 400000;
7024 parameters.encodings[2].min_bitrate_bps = 500000;
7025 parameters.encodings[2].max_bitrate_bps = 600000;
7026 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
7027
7028 // Verify that the new value propagated down to the encoder.
7029 // Check that WebRtcVideoSendStream updates VideoEncoderConfig correctly.
7030 EXPECT_EQ(2, stream->num_encoder_reconfigurations());
7031 webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
7032 EXPECT_EQ(kNumSimulcastStreams, encoder_config.number_of_streams);
7033 EXPECT_EQ(kNumSimulcastStreams, encoder_config.simulcast_layers.size());
7034 EXPECT_EQ(100000, encoder_config.simulcast_layers[0].min_bitrate_bps);
7035 EXPECT_EQ(200000, encoder_config.simulcast_layers[0].max_bitrate_bps);
7036 EXPECT_EQ(300000, encoder_config.simulcast_layers[1].min_bitrate_bps);
7037 EXPECT_EQ(400000, encoder_config.simulcast_layers[1].max_bitrate_bps);
7038 EXPECT_EQ(500000, encoder_config.simulcast_layers[2].min_bitrate_bps);
7039 EXPECT_EQ(600000, encoder_config.simulcast_layers[2].max_bitrate_bps);
7040
7041 // FakeVideoSendStream calls CreateEncoderStreams, test that the vector of
7042 // VideoStreams are created appropriately for the simulcast case.
7043 EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
7044 // Target bitrate: 200000 * 3 / 4 = 150000.
7045 EXPECT_EQ(100000, stream->GetVideoStreams()[0].min_bitrate_bps);
7046 EXPECT_EQ(150000, stream->GetVideoStreams()[0].target_bitrate_bps);
7047 EXPECT_EQ(200000, stream->GetVideoStreams()[0].max_bitrate_bps);
7048 // Target bitrate: 400000 * 3 / 4 = 300000.
7049 EXPECT_EQ(300000, stream->GetVideoStreams()[1].min_bitrate_bps);
7050 EXPECT_EQ(300000, stream->GetVideoStreams()[1].target_bitrate_bps);
7051 EXPECT_EQ(400000, stream->GetVideoStreams()[1].max_bitrate_bps);
7052 // Target bitrate: 600000 * 3 / 4 = 450000, less than min -> max.
7053 EXPECT_EQ(500000, stream->GetVideoStreams()[2].min_bitrate_bps);
7054 EXPECT_EQ(600000, stream->GetVideoStreams()[2].target_bitrate_bps);
7055 EXPECT_EQ(600000, stream->GetVideoStreams()[2].max_bitrate_bps);
7056
7057 // No parameter changed, encoder should not be reconfigured.
7058 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
7059 EXPECT_EQ(2, stream->num_encoder_reconfigurations());
7060
7061 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
7062}
7063
7064// Test to only specify the min or max bitrate value for a layer via
7065// RtpParameters. The unspecified min/max and target value should be set to the
7066// simulcast default that is used if no min/max are specified.
7067TEST_F(WebRtcVideoChannelTest, MinOrMaxSimulcastBitratePropagatedToEncoder) {
7068 const size_t kNumSimulcastStreams = 3;
7069 const std::vector<webrtc::VideoStream> kDefault = GetSimulcastBitrates720p();
7070 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
7071
7072 // Send a full size frame so all simulcast layers are used when reconfiguring.
Niels Möller805a27e2019-01-21 12:21:27 +01007073 webrtc::test::FrameForwarder frame_forwarder;
Åsa Persson55659812018-06-18 17:51:32 +02007074 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01007075 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
Åsa Persson55659812018-06-18 17:51:32 +02007076 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01007077 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Åsa Persson55659812018-06-18 17:51:32 +02007078
7079 // Get and set the rtp encoding parameters.
7080 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
7081 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
7082
7083 // Change the value and set it on the VideoChannel.
7084 // Layer 0: only configure min bitrate.
7085 const int kMinBpsLayer0 = kDefault[0].min_bitrate_bps + 1;
7086 parameters.encodings[0].min_bitrate_bps = kMinBpsLayer0;
7087 // Layer 1: only configure max bitrate.
7088 const int kMaxBpsLayer1 = kDefault[1].max_bitrate_bps - 1;
7089 parameters.encodings[1].max_bitrate_bps = kMaxBpsLayer1;
7090 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
7091
7092 // Verify that the new value propagated down to the encoder.
7093 // Check that WebRtcVideoSendStream updates VideoEncoderConfig correctly.
7094 webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
7095 EXPECT_EQ(kNumSimulcastStreams, encoder_config.number_of_streams);
7096 EXPECT_EQ(kNumSimulcastStreams, encoder_config.simulcast_layers.size());
7097 EXPECT_EQ(kMinBpsLayer0, encoder_config.simulcast_layers[0].min_bitrate_bps);
7098 EXPECT_EQ(-1, encoder_config.simulcast_layers[0].max_bitrate_bps);
7099 EXPECT_EQ(-1, encoder_config.simulcast_layers[1].min_bitrate_bps);
7100 EXPECT_EQ(kMaxBpsLayer1, encoder_config.simulcast_layers[1].max_bitrate_bps);
7101 EXPECT_EQ(-1, encoder_config.simulcast_layers[2].min_bitrate_bps);
7102 EXPECT_EQ(-1, encoder_config.simulcast_layers[2].max_bitrate_bps);
7103
7104 // FakeVideoSendStream calls CreateEncoderStreams, test that the vector of
7105 // VideoStreams are created appropriately for the simulcast case.
7106 EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
7107 // Layer 0: min configured bitrate should overwrite min default.
7108 EXPECT_EQ(kMinBpsLayer0, stream->GetVideoStreams()[0].min_bitrate_bps);
7109 EXPECT_EQ(kDefault[0].target_bitrate_bps,
7110 stream->GetVideoStreams()[0].target_bitrate_bps);
7111 EXPECT_EQ(kDefault[0].max_bitrate_bps,
7112 stream->GetVideoStreams()[0].max_bitrate_bps);
7113 // Layer 1: max configured bitrate should overwrite max default.
7114 EXPECT_EQ(kDefault[1].min_bitrate_bps,
7115 stream->GetVideoStreams()[1].min_bitrate_bps);
7116 EXPECT_EQ(kDefault[1].target_bitrate_bps,
7117 stream->GetVideoStreams()[1].target_bitrate_bps);
7118 EXPECT_EQ(kMaxBpsLayer1, stream->GetVideoStreams()[1].max_bitrate_bps);
7119 // Layer 2: min and max bitrate not configured, default expected.
7120 EXPECT_EQ(kDefault[2].min_bitrate_bps,
7121 stream->GetVideoStreams()[2].min_bitrate_bps);
7122 EXPECT_EQ(kDefault[2].target_bitrate_bps,
7123 stream->GetVideoStreams()[2].target_bitrate_bps);
7124 EXPECT_EQ(kDefault[2].max_bitrate_bps,
7125 stream->GetVideoStreams()[2].max_bitrate_bps);
7126
7127 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
7128}
7129
7130// Test that specifying the min (or max) bitrate value for a layer via
7131// RtpParameters above (or below) the simulcast default max (or min) adjusts the
7132// unspecified values accordingly.
7133TEST_F(WebRtcVideoChannelTest, SetMinAndMaxSimulcastBitrateAboveBelowDefault) {
7134 const size_t kNumSimulcastStreams = 3;
7135 const std::vector<webrtc::VideoStream> kDefault = GetSimulcastBitrates720p();
7136 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
7137
7138 // Send a full size frame so all simulcast layers are used when reconfiguring.
Niels Möller805a27e2019-01-21 12:21:27 +01007139 webrtc::test::FrameForwarder frame_forwarder;
Åsa Persson55659812018-06-18 17:51:32 +02007140 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01007141 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
Åsa Persson55659812018-06-18 17:51:32 +02007142 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01007143 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Åsa Persson55659812018-06-18 17:51:32 +02007144
7145 // Get and set the rtp encoding parameters.
7146 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
7147 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
7148
7149 // Change the value and set it on the VideoChannel.
7150 // For layer 0, set the min bitrate above the default max.
7151 const int kMinBpsLayer0 = kDefault[0].max_bitrate_bps + 1;
7152 parameters.encodings[0].min_bitrate_bps = kMinBpsLayer0;
7153 // For layer 1, set the max bitrate below the default min.
7154 const int kMaxBpsLayer1 = kDefault[1].min_bitrate_bps - 1;
7155 parameters.encodings[1].max_bitrate_bps = kMaxBpsLayer1;
7156 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
7157
7158 // Verify that the new value propagated down to the encoder.
7159 // FakeVideoSendStream calls CreateEncoderStreams, test that the vector of
7160 // VideoStreams are created appropriately for the simulcast case.
7161 EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
7162 // Layer 0: Min bitrate above default max (target/max should be adjusted).
7163 EXPECT_EQ(kMinBpsLayer0, stream->GetVideoStreams()[0].min_bitrate_bps);
7164 EXPECT_EQ(kMinBpsLayer0, stream->GetVideoStreams()[0].target_bitrate_bps);
7165 EXPECT_EQ(kMinBpsLayer0, stream->GetVideoStreams()[0].max_bitrate_bps);
7166 // Layer 1: Max bitrate below default min (min/target should be adjusted).
7167 EXPECT_EQ(kMaxBpsLayer1, stream->GetVideoStreams()[1].min_bitrate_bps);
7168 EXPECT_EQ(kMaxBpsLayer1, stream->GetVideoStreams()[1].target_bitrate_bps);
7169 EXPECT_EQ(kMaxBpsLayer1, stream->GetVideoStreams()[1].max_bitrate_bps);
7170 // Layer 2: min and max bitrate not configured, default expected.
7171 EXPECT_EQ(kDefault[2].min_bitrate_bps,
7172 stream->GetVideoStreams()[2].min_bitrate_bps);
7173 EXPECT_EQ(kDefault[2].target_bitrate_bps,
7174 stream->GetVideoStreams()[2].target_bitrate_bps);
7175 EXPECT_EQ(kDefault[2].max_bitrate_bps,
7176 stream->GetVideoStreams()[2].max_bitrate_bps);
7177
7178 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
7179}
7180
7181TEST_F(WebRtcVideoChannelTest, BandwidthAboveTotalMaxBitrateGivenToMaxLayer) {
7182 const size_t kNumSimulcastStreams = 3;
7183 const std::vector<webrtc::VideoStream> kDefault = GetSimulcastBitrates720p();
7184 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
7185
7186 // Send a full size frame so all simulcast layers are used when reconfiguring.
Niels Möller805a27e2019-01-21 12:21:27 +01007187 webrtc::test::FrameForwarder frame_forwarder;
Åsa Persson55659812018-06-18 17:51:32 +02007188 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01007189 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
Åsa Persson55659812018-06-18 17:51:32 +02007190 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01007191 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Åsa Persson55659812018-06-18 17:51:32 +02007192
7193 // Set max bitrate for all but the highest layer.
7194 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
7195 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
7196 parameters.encodings[0].max_bitrate_bps = kDefault[0].max_bitrate_bps;
7197 parameters.encodings[1].max_bitrate_bps = kDefault[1].max_bitrate_bps;
7198 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
7199
7200 // Set max bandwidth equal to total max bitrate.
7201 send_parameters_.max_bandwidth_bps =
Oskar Segersvärddc81e112020-02-12 16:45:53 +01007202 GetTotalMaxBitrate(stream->GetVideoStreams()).bps();
Åsa Persson55659812018-06-18 17:51:32 +02007203 ExpectSetMaxBitrate(send_parameters_.max_bandwidth_bps);
7204 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
7205
7206 // No bitrate above the total max to give to the highest layer.
7207 EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
7208 EXPECT_EQ(kDefault[2].max_bitrate_bps,
7209 stream->GetVideoStreams()[2].max_bitrate_bps);
7210
7211 // Set max bandwidth above the total max bitrate.
7212 send_parameters_.max_bandwidth_bps =
Oskar Segersvärddc81e112020-02-12 16:45:53 +01007213 GetTotalMaxBitrate(stream->GetVideoStreams()).bps() + 1;
Åsa Persson55659812018-06-18 17:51:32 +02007214 ExpectSetMaxBitrate(send_parameters_.max_bandwidth_bps);
7215 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
7216
7217 // The highest layer has no max bitrate set -> the bitrate above the total
7218 // max should be given to the highest layer.
7219 EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
7220 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
Oskar Segersvärddc81e112020-02-12 16:45:53 +01007221 GetTotalMaxBitrate(stream->GetVideoStreams()).bps());
Åsa Persson55659812018-06-18 17:51:32 +02007222 EXPECT_EQ(kDefault[2].max_bitrate_bps + 1,
7223 stream->GetVideoStreams()[2].max_bitrate_bps);
7224
7225 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
7226}
7227
7228TEST_F(WebRtcVideoChannelTest,
7229 BandwidthAboveTotalMaxBitrateNotGivenToMaxLayerIfMaxBitrateSet) {
7230 const size_t kNumSimulcastStreams = 3;
7231 const std::vector<webrtc::VideoStream> kDefault = GetSimulcastBitrates720p();
7232 EXPECT_EQ(kNumSimulcastStreams, kDefault.size());
7233 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
7234
7235 // Send a full size frame so all simulcast layers are used when reconfiguring.
Niels Möller805a27e2019-01-21 12:21:27 +01007236 webrtc::test::FrameForwarder frame_forwarder;
Åsa Persson55659812018-06-18 17:51:32 +02007237 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01007238 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
Åsa Persson55659812018-06-18 17:51:32 +02007239 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01007240 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Åsa Persson55659812018-06-18 17:51:32 +02007241
7242 // Set max bitrate for the highest layer.
7243 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
7244 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
7245 parameters.encodings[2].max_bitrate_bps = kDefault[2].max_bitrate_bps;
7246 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
7247
7248 // Set max bandwidth above the total max bitrate.
7249 send_parameters_.max_bandwidth_bps =
Oskar Segersvärddc81e112020-02-12 16:45:53 +01007250 GetTotalMaxBitrate(stream->GetVideoStreams()).bps() + 1;
Åsa Persson55659812018-06-18 17:51:32 +02007251 ExpectSetMaxBitrate(send_parameters_.max_bandwidth_bps);
7252 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
7253
7254 // The highest layer has the max bitrate set -> the bitrate above the total
7255 // max should not be given to the highest layer.
7256 EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
7257 EXPECT_EQ(*parameters.encodings[2].max_bitrate_bps,
7258 stream->GetVideoStreams()[2].max_bitrate_bps);
7259
7260 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
7261}
7262
Åsa Perssonbdee46d2018-06-25 11:28:06 +02007263// Test that min and max bitrate values set via RtpParameters are correctly
7264// propagated to the underlying encoder for a single stream.
7265TEST_F(WebRtcVideoChannelTest, MinAndMaxBitratePropagatedToEncoder) {
7266 FakeVideoSendStream* stream = AddSendStream();
7267 EXPECT_TRUE(channel_->SetSend(true));
7268 EXPECT_TRUE(stream->IsSending());
7269
7270 // Set min and max bitrate.
7271 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
7272 EXPECT_EQ(1u, parameters.encodings.size());
7273 parameters.encodings[0].min_bitrate_bps = 80000;
7274 parameters.encodings[0].max_bitrate_bps = 150000;
7275 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
7276
7277 // Check that WebRtcVideoSendStream updates VideoEncoderConfig correctly.
7278 webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
7279 EXPECT_EQ(1u, encoder_config.number_of_streams);
7280 EXPECT_EQ(1u, encoder_config.simulcast_layers.size());
7281 EXPECT_EQ(80000, encoder_config.simulcast_layers[0].min_bitrate_bps);
7282 EXPECT_EQ(150000, encoder_config.simulcast_layers[0].max_bitrate_bps);
7283
7284 // FakeVideoSendStream calls CreateEncoderStreams, test that the vector of
7285 // VideoStreams are created appropriately.
7286 EXPECT_EQ(1u, stream->GetVideoStreams().size());
7287 EXPECT_EQ(80000, stream->GetVideoStreams()[0].min_bitrate_bps);
7288 EXPECT_EQ(150000, stream->GetVideoStreams()[0].target_bitrate_bps);
7289 EXPECT_EQ(150000, stream->GetVideoStreams()[0].max_bitrate_bps);
7290}
7291
7292// Test the default min and max bitrate value are correctly propagated to the
7293// underlying encoder for a single stream (when the values are not set via
7294// RtpParameters).
7295TEST_F(WebRtcVideoChannelTest, DefaultMinAndMaxBitratePropagatedToEncoder) {
7296 FakeVideoSendStream* stream = AddSendStream();
7297 EXPECT_TRUE(channel_->SetSend(true));
7298 EXPECT_TRUE(stream->IsSending());
7299
7300 // Check that WebRtcVideoSendStream updates VideoEncoderConfig correctly.
7301 webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
7302 EXPECT_EQ(1u, encoder_config.number_of_streams);
7303 EXPECT_EQ(1u, encoder_config.simulcast_layers.size());
7304 EXPECT_EQ(-1, encoder_config.simulcast_layers[0].min_bitrate_bps);
7305 EXPECT_EQ(-1, encoder_config.simulcast_layers[0].max_bitrate_bps);
7306
7307 // FakeVideoSendStream calls CreateEncoderStreams, test that the vector of
7308 // VideoStreams are created appropriately.
7309 EXPECT_EQ(1u, stream->GetVideoStreams().size());
Elad Alon80f53b72019-10-11 16:19:43 +02007310 EXPECT_EQ(webrtc::kDefaultMinVideoBitrateBps,
Åsa Perssonbdee46d2018-06-25 11:28:06 +02007311 stream->GetVideoStreams()[0].min_bitrate_bps);
7312 EXPECT_GT(stream->GetVideoStreams()[0].max_bitrate_bps,
7313 stream->GetVideoStreams()[0].min_bitrate_bps);
7314 EXPECT_EQ(stream->GetVideoStreams()[0].max_bitrate_bps,
7315 stream->GetVideoStreams()[0].target_bitrate_bps);
7316}
7317
Taylor Brandstetter14b9d792016-09-07 17:16:54 -07007318// Test that a stream will not be sending if its encoding is made inactive
7319// through SetRtpSendParameters.
Seth Hampson8234ead2018-02-02 15:16:24 -08007320TEST_F(WebRtcVideoChannelTest, SetRtpSendParametersOneEncodingActive) {
deadbeefdbe2b872016-03-22 15:42:00 -07007321 FakeVideoSendStream* stream = AddSendStream();
7322 EXPECT_TRUE(channel_->SetSend(true));
7323 EXPECT_TRUE(stream->IsSending());
7324
7325 // Get current parameters and change "active" to false.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07007326 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
deadbeefdbe2b872016-03-22 15:42:00 -07007327 ASSERT_EQ(1u, parameters.encodings.size());
7328 ASSERT_TRUE(parameters.encodings[0].active);
7329 parameters.encodings[0].active = false;
Zach Steinba37b4b2018-01-23 15:02:36 -08007330 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
deadbeefdbe2b872016-03-22 15:42:00 -07007331 EXPECT_FALSE(stream->IsSending());
7332
7333 // Now change it back to active and verify we resume sending.
7334 parameters.encodings[0].active = true;
Zach Steinba37b4b2018-01-23 15:02:36 -08007335 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
deadbeefdbe2b872016-03-22 15:42:00 -07007336 EXPECT_TRUE(stream->IsSending());
7337}
7338
Seth Hampson8234ead2018-02-02 15:16:24 -08007339// Tests that when active is updated for any simulcast layer then the send
7340// stream's sending state will be updated and it will be reconfigured with the
7341// new appropriate active simulcast streams.
7342TEST_F(WebRtcVideoChannelTest, SetRtpSendParametersMultipleEncodingsActive) {
7343 // Create the stream params with multiple ssrcs for simulcast.
Åsa Persson31cb8f92018-06-27 10:44:56 +02007344 const size_t kNumSimulcastStreams = 3;
Seth Hampson8234ead2018-02-02 15:16:24 -08007345 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
7346 StreamParams stream_params = CreateSimStreamParams("cname", ssrcs);
7347 FakeVideoSendStream* fake_video_send_stream = AddSendStream(stream_params);
7348 uint32_t primary_ssrc = stream_params.first_ssrc();
7349
Niels Möller805a27e2019-01-21 12:21:27 +01007350 // Using the FrameForwarder, we manually send a full size
Tommi85959932018-02-07 19:26:06 +01007351 // frame. This allows us to test that ReconfigureEncoder is called
7352 // appropriately.
Niels Möller805a27e2019-01-21 12:21:27 +01007353 webrtc::test::FrameForwarder frame_forwarder;
Seth Hampson8234ead2018-02-02 15:16:24 -08007354 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01007355 EXPECT_TRUE(channel_->SetVideoSend(primary_ssrc, &options, &frame_forwarder));
Seth Hampson8234ead2018-02-02 15:16:24 -08007356 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01007357 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame(
7358 1920, 1080, webrtc::VideoRotation::kVideoRotation_0,
7359 rtc::kNumMicrosecsPerSec / 30));
Seth Hampson8234ead2018-02-02 15:16:24 -08007360
7361 // Check that all encodings are initially active.
7362 webrtc::RtpParameters parameters =
7363 channel_->GetRtpSendParameters(primary_ssrc);
Åsa Persson31cb8f92018-06-27 10:44:56 +02007364 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
Seth Hampson8234ead2018-02-02 15:16:24 -08007365 EXPECT_TRUE(parameters.encodings[0].active);
7366 EXPECT_TRUE(parameters.encodings[1].active);
7367 EXPECT_TRUE(parameters.encodings[2].active);
7368 EXPECT_TRUE(fake_video_send_stream->IsSending());
7369
7370 // Only turn on only the middle stream.
7371 parameters.encodings[0].active = false;
7372 parameters.encodings[1].active = true;
7373 parameters.encodings[2].active = false;
7374 EXPECT_TRUE(channel_->SetRtpSendParameters(primary_ssrc, parameters).ok());
7375 // Verify that the active fields are set on the VideoChannel.
7376 parameters = channel_->GetRtpSendParameters(primary_ssrc);
Åsa Persson31cb8f92018-06-27 10:44:56 +02007377 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
Seth Hampson8234ead2018-02-02 15:16:24 -08007378 EXPECT_FALSE(parameters.encodings[0].active);
7379 EXPECT_TRUE(parameters.encodings[1].active);
7380 EXPECT_FALSE(parameters.encodings[2].active);
7381 // Check that the VideoSendStream is updated appropriately. This means its
7382 // send state was updated and it was reconfigured.
7383 EXPECT_TRUE(fake_video_send_stream->IsSending());
7384 std::vector<webrtc::VideoStream> simulcast_streams =
7385 fake_video_send_stream->GetVideoStreams();
Åsa Persson31cb8f92018-06-27 10:44:56 +02007386 EXPECT_EQ(kNumSimulcastStreams, simulcast_streams.size());
Seth Hampson8234ead2018-02-02 15:16:24 -08007387 EXPECT_FALSE(simulcast_streams[0].active);
7388 EXPECT_TRUE(simulcast_streams[1].active);
7389 EXPECT_FALSE(simulcast_streams[2].active);
7390
7391 // Turn off all streams.
7392 parameters.encodings[0].active = false;
7393 parameters.encodings[1].active = false;
7394 parameters.encodings[2].active = false;
7395 EXPECT_TRUE(channel_->SetRtpSendParameters(primary_ssrc, parameters).ok());
7396 // Verify that the active fields are set on the VideoChannel.
7397 parameters = channel_->GetRtpSendParameters(primary_ssrc);
Åsa Persson31cb8f92018-06-27 10:44:56 +02007398 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
Seth Hampson8234ead2018-02-02 15:16:24 -08007399 EXPECT_FALSE(parameters.encodings[0].active);
7400 EXPECT_FALSE(parameters.encodings[1].active);
7401 EXPECT_FALSE(parameters.encodings[2].active);
7402 // Check that the VideoSendStream is off.
7403 EXPECT_FALSE(fake_video_send_stream->IsSending());
7404 simulcast_streams = fake_video_send_stream->GetVideoStreams();
Åsa Persson31cb8f92018-06-27 10:44:56 +02007405 EXPECT_EQ(kNumSimulcastStreams, simulcast_streams.size());
Seth Hampson8234ead2018-02-02 15:16:24 -08007406 EXPECT_FALSE(simulcast_streams[0].active);
7407 EXPECT_FALSE(simulcast_streams[1].active);
7408 EXPECT_FALSE(simulcast_streams[2].active);
7409
Niels Möllerff40b142018-04-09 08:49:14 +02007410 EXPECT_TRUE(channel_->SetVideoSend(primary_ssrc, nullptr, nullptr));
Seth Hampson8234ead2018-02-02 15:16:24 -08007411}
7412
Taylor Brandstetter14b9d792016-09-07 17:16:54 -07007413// Test that if a stream is reconfigured (due to a codec change or other
7414// change) while its encoding is still inactive, it doesn't start sending.
eladalonf1841382017-06-12 01:16:46 -07007415TEST_F(WebRtcVideoChannelTest,
Taylor Brandstetter14b9d792016-09-07 17:16:54 -07007416 InactiveStreamDoesntStartSendingWhenReconfigured) {
7417 // Set an initial codec list, which will be modified later.
7418 cricket::VideoSendParameters parameters1;
magjed509e4fe2016-11-18 01:34:11 -08007419 parameters1.codecs.push_back(GetEngineCodec("VP8"));
7420 parameters1.codecs.push_back(GetEngineCodec("VP9"));
Taylor Brandstetter14b9d792016-09-07 17:16:54 -07007421 EXPECT_TRUE(channel_->SetSendParameters(parameters1));
7422
7423 FakeVideoSendStream* stream = AddSendStream();
7424 EXPECT_TRUE(channel_->SetSend(true));
7425 EXPECT_TRUE(stream->IsSending());
7426
7427 // Get current parameters and change "active" to false.
7428 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
7429 ASSERT_EQ(1u, parameters.encodings.size());
7430 ASSERT_TRUE(parameters.encodings[0].active);
7431 parameters.encodings[0].active = false;
7432 EXPECT_EQ(1u, GetFakeSendStreams().size());
7433 EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());
Zach Steinba37b4b2018-01-23 15:02:36 -08007434 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
Taylor Brandstetter14b9d792016-09-07 17:16:54 -07007435 EXPECT_FALSE(stream->IsSending());
7436
7437 // Reorder the codec list, causing the stream to be reconfigured.
7438 cricket::VideoSendParameters parameters2;
magjed509e4fe2016-11-18 01:34:11 -08007439 parameters2.codecs.push_back(GetEngineCodec("VP9"));
7440 parameters2.codecs.push_back(GetEngineCodec("VP8"));
Taylor Brandstetter14b9d792016-09-07 17:16:54 -07007441 EXPECT_TRUE(channel_->SetSendParameters(parameters2));
7442 auto new_streams = GetFakeSendStreams();
7443 // Assert that a new underlying stream was created due to the codec change.
7444 // Otherwise, this test isn't testing what it set out to test.
7445 EXPECT_EQ(1u, GetFakeSendStreams().size());
7446 EXPECT_EQ(2, fake_call_->GetNumCreatedSendStreams());
7447
7448 // Verify that we still are not sending anything, due to the inactive
7449 // encoding.
7450 EXPECT_FALSE(new_streams[0]->IsSending());
7451}
7452
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07007453// Test that GetRtpSendParameters returns the currently configured codecs.
eladalonf1841382017-06-12 01:16:46 -07007454TEST_F(WebRtcVideoChannelTest, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07007455 AddSendStream();
7456 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08007457 parameters.codecs.push_back(GetEngineCodec("VP8"));
7458 parameters.codecs.push_back(GetEngineCodec("VP9"));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07007459 EXPECT_TRUE(channel_->SetSendParameters(parameters));
7460
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07007461 webrtc::RtpParameters rtp_parameters =
7462 channel_->GetRtpSendParameters(last_ssrc_);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07007463 ASSERT_EQ(2u, rtp_parameters.codecs.size());
magjed509e4fe2016-11-18 01:34:11 -08007464 EXPECT_EQ(GetEngineCodec("VP8").ToCodecParameters(),
7465 rtp_parameters.codecs[0]);
7466 EXPECT_EQ(GetEngineCodec("VP9").ToCodecParameters(),
7467 rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07007468}
7469
Florent Castellidacec712018-05-24 16:24:21 +02007470// Test that GetRtpSendParameters returns the currently configured RTCP CNAME.
7471TEST_F(WebRtcVideoChannelTest, GetRtpSendParametersRtcpCname) {
7472 StreamParams params = StreamParams::CreateLegacy(kSsrc);
7473 params.cname = "rtcpcname";
7474 AddSendStream(params);
7475
7476 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrc);
7477 EXPECT_STREQ("rtcpcname", rtp_parameters.rtcp.cname.c_str());
7478}
7479
deadbeeffb2aced2017-01-06 23:05:37 -08007480// Test that RtpParameters for send stream has one encoding and it has
7481// the correct SSRC.
eladalonf1841382017-06-12 01:16:46 -07007482TEST_F(WebRtcVideoChannelTest, GetRtpSendParametersSsrc) {
deadbeeffb2aced2017-01-06 23:05:37 -08007483 AddSendStream();
7484
7485 webrtc::RtpParameters rtp_parameters =
7486 channel_->GetRtpSendParameters(last_ssrc_);
7487 ASSERT_EQ(1u, rtp_parameters.encodings.size());
Oskar Sundbom78807582017-11-16 11:09:55 +01007488 EXPECT_EQ(last_ssrc_, rtp_parameters.encodings[0].ssrc);
deadbeeffb2aced2017-01-06 23:05:37 -08007489}
7490
Florent Castelliabe301f2018-06-12 18:33:49 +02007491TEST_F(WebRtcVideoChannelTest, DetectRtpSendParameterHeaderExtensionsChange) {
7492 AddSendStream();
7493
7494 webrtc::RtpParameters rtp_parameters =
7495 channel_->GetRtpSendParameters(last_ssrc_);
7496 rtp_parameters.header_extensions.emplace_back();
7497
7498 EXPECT_NE(0u, rtp_parameters.header_extensions.size());
7499
7500 webrtc::RTCError result =
7501 channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
7502 EXPECT_EQ(webrtc::RTCErrorType::INVALID_MODIFICATION, result.type());
7503}
7504
Florent Castelli87b3c512018-07-18 16:00:28 +02007505TEST_F(WebRtcVideoChannelTest, GetRtpSendParametersDegradationPreference) {
7506 AddSendStream();
7507
Niels Möller805a27e2019-01-21 12:21:27 +01007508 webrtc::test::FrameForwarder frame_forwarder;
7509 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));
Florent Castelli87b3c512018-07-18 16:00:28 +02007510
7511 webrtc::RtpParameters rtp_parameters =
7512 channel_->GetRtpSendParameters(last_ssrc_);
Florent Castellib05ca4b2020-03-05 13:39:55 +01007513 EXPECT_FALSE(rtp_parameters.degradation_preference.has_value());
Florent Castelli87b3c512018-07-18 16:00:28 +02007514 rtp_parameters.degradation_preference =
7515 webrtc::DegradationPreference::MAINTAIN_FRAMERATE;
7516
7517 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters).ok());
7518
7519 webrtc::RtpParameters updated_rtp_parameters =
7520 channel_->GetRtpSendParameters(last_ssrc_);
7521 EXPECT_EQ(updated_rtp_parameters.degradation_preference,
7522 webrtc::DegradationPreference::MAINTAIN_FRAMERATE);
7523
7524 // Remove the source since it will be destroyed before the channel
7525 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
7526}
7527
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07007528// Test that if we set/get parameters multiple times, we get the same results.
eladalonf1841382017-06-12 01:16:46 -07007529TEST_F(WebRtcVideoChannelTest, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07007530 AddSendStream();
7531 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08007532 parameters.codecs.push_back(GetEngineCodec("VP8"));
7533 parameters.codecs.push_back(GetEngineCodec("VP9"));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07007534 EXPECT_TRUE(channel_->SetSendParameters(parameters));
7535
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07007536 webrtc::RtpParameters initial_params =
7537 channel_->GetRtpSendParameters(last_ssrc_);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07007538
7539 // We should be able to set the params we just got.
Zach Steinba37b4b2018-01-23 15:02:36 -08007540 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, initial_params).ok());
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07007541
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07007542 // ... And this shouldn't change the params returned by GetRtpSendParameters.
7543 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(last_ssrc_));
7544}
7545
7546// Test that GetRtpReceiveParameters returns the currently configured codecs.
eladalonf1841382017-06-12 01:16:46 -07007547TEST_F(WebRtcVideoChannelTest, GetRtpReceiveParametersCodecs) {
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07007548 AddRecvStream();
7549 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08007550 parameters.codecs.push_back(GetEngineCodec("VP8"));
7551 parameters.codecs.push_back(GetEngineCodec("VP9"));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07007552 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
7553
7554 webrtc::RtpParameters rtp_parameters =
7555 channel_->GetRtpReceiveParameters(last_ssrc_);
7556 ASSERT_EQ(2u, rtp_parameters.codecs.size());
magjed509e4fe2016-11-18 01:34:11 -08007557 EXPECT_EQ(GetEngineCodec("VP8").ToCodecParameters(),
7558 rtp_parameters.codecs[0]);
7559 EXPECT_EQ(GetEngineCodec("VP9").ToCodecParameters(),
7560 rtp_parameters.codecs[1]);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07007561}
7562
johan073ece42016-08-26 02:59:47 -07007563#if defined(WEBRTC_USE_H264)
eladalonf1841382017-06-12 01:16:46 -07007564TEST_F(WebRtcVideoChannelTest, GetRtpReceiveFmtpSprop) {
johan073ece42016-08-26 02:59:47 -07007565#else
eladalonf1841382017-06-12 01:16:46 -07007566TEST_F(WebRtcVideoChannelTest, DISABLED_GetRtpReceiveFmtpSprop) {
johan073ece42016-08-26 02:59:47 -07007567#endif
johan3859c892016-08-05 09:19:25 -07007568 cricket::VideoRecvParameters parameters;
perkj26752742016-10-24 01:21:16 -07007569 cricket::VideoCodec kH264sprop1(101, "H264");
magjed5dfac562016-11-25 03:56:37 -08007570 kH264sprop1.SetParam(kH264FmtpSpropParameterSets, "uvw");
johan3859c892016-08-05 09:19:25 -07007571 parameters.codecs.push_back(kH264sprop1);
perkj26752742016-10-24 01:21:16 -07007572 cricket::VideoCodec kH264sprop2(102, "H264");
magjed5dfac562016-11-25 03:56:37 -08007573 kH264sprop2.SetParam(kH264FmtpSpropParameterSets, "xyz");
johan3859c892016-08-05 09:19:25 -07007574 parameters.codecs.push_back(kH264sprop2);
7575 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
7576
7577 FakeVideoReceiveStream* recv_stream = AddRecvStream();
7578 const webrtc::VideoReceiveStream::Config& cfg = recv_stream->GetConfig();
7579 webrtc::RtpParameters rtp_parameters =
7580 channel_->GetRtpReceiveParameters(last_ssrc_);
7581 ASSERT_EQ(2u, rtp_parameters.codecs.size());
7582 EXPECT_EQ(kH264sprop1.ToCodecParameters(), rtp_parameters.codecs[0]);
7583 ASSERT_EQ(2u, cfg.decoders.size());
7584 EXPECT_EQ(101, cfg.decoders[0].payload_type);
Niels Möllercb7e1d22018-09-11 15:56:04 +02007585 EXPECT_EQ("H264", cfg.decoders[0].video_format.name);
magjed5dfac562016-11-25 03:56:37 -08007586 const auto it0 =
Niels Möllercb7e1d22018-09-11 15:56:04 +02007587 cfg.decoders[0].video_format.parameters.find(kH264FmtpSpropParameterSets);
7588 ASSERT_TRUE(it0 != cfg.decoders[0].video_format.parameters.end());
magjed5dfac562016-11-25 03:56:37 -08007589 EXPECT_EQ("uvw", it0->second);
johan3859c892016-08-05 09:19:25 -07007590
7591 EXPECT_EQ(102, cfg.decoders[1].payload_type);
Niels Möllercb7e1d22018-09-11 15:56:04 +02007592 EXPECT_EQ("H264", cfg.decoders[1].video_format.name);
magjed5dfac562016-11-25 03:56:37 -08007593 const auto it1 =
Niels Möllercb7e1d22018-09-11 15:56:04 +02007594 cfg.decoders[1].video_format.parameters.find(kH264FmtpSpropParameterSets);
7595 ASSERT_TRUE(it1 != cfg.decoders[1].video_format.parameters.end());
magjed5dfac562016-11-25 03:56:37 -08007596 EXPECT_EQ("xyz", it1->second);
johan3859c892016-08-05 09:19:25 -07007597}
7598
sakal1fd95952016-06-22 00:46:15 -07007599// Test that RtpParameters for receive stream has one encoding and it has
7600// the correct SSRC.
eladalonf1841382017-06-12 01:16:46 -07007601TEST_F(WebRtcVideoChannelTest, GetRtpReceiveParametersSsrc) {
sakal1fd95952016-06-22 00:46:15 -07007602 AddRecvStream();
7603
7604 webrtc::RtpParameters rtp_parameters =
7605 channel_->GetRtpReceiveParameters(last_ssrc_);
7606 ASSERT_EQ(1u, rtp_parameters.encodings.size());
Oskar Sundbom78807582017-11-16 11:09:55 +01007607 EXPECT_EQ(last_ssrc_, rtp_parameters.encodings[0].ssrc);
sakal1fd95952016-06-22 00:46:15 -07007608}
7609
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07007610// Test that if we set/get parameters multiple times, we get the same results.
eladalonf1841382017-06-12 01:16:46 -07007611TEST_F(WebRtcVideoChannelTest, SetAndGetRtpReceiveParameters) {
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07007612 AddRecvStream();
7613 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08007614 parameters.codecs.push_back(GetEngineCodec("VP8"));
7615 parameters.codecs.push_back(GetEngineCodec("VP9"));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07007616 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
7617
7618 webrtc::RtpParameters initial_params =
7619 channel_->GetRtpReceiveParameters(last_ssrc_);
7620
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07007621 // ... And this shouldn't change the params returned by
7622 // GetRtpReceiveParameters.
7623 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(last_ssrc_));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07007624}
7625
Saurav Das749f6602019-12-04 09:31:36 -08007626// Test that GetDefaultRtpReceiveParameters returns parameters correctly when
7627// SSRCs aren't signaled. It should always return an empty
7628// "RtpEncodingParameters", even after a packet is received and the unsignaled
7629// SSRC is known.
7630TEST_F(WebRtcVideoChannelTest,
7631 GetDefaultRtpReceiveParametersWithUnsignaledSsrc) {
deadbeef3bc15102017-04-20 19:25:07 -07007632 // Call necessary methods to configure receiving a default stream as
7633 // soon as it arrives.
7634 cricket::VideoRecvParameters parameters;
7635 parameters.codecs.push_back(GetEngineCodec("VP8"));
7636 parameters.codecs.push_back(GetEngineCodec("VP9"));
7637 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
7638
7639 // Call GetRtpReceiveParameters before configured to receive an unsignaled
7640 // stream. Should return nothing.
Saurav Das749f6602019-12-04 09:31:36 -08007641 EXPECT_EQ(webrtc::RtpParameters(),
7642 channel_->GetDefaultRtpReceiveParameters());
deadbeef3bc15102017-04-20 19:25:07 -07007643
7644 // Set a sink for an unsignaled stream.
7645 cricket::FakeVideoRenderer renderer;
Saurav Das749f6602019-12-04 09:31:36 -08007646 channel_->SetDefaultSink(&renderer);
deadbeef3bc15102017-04-20 19:25:07 -07007647
Saurav Das749f6602019-12-04 09:31:36 -08007648 // Call GetDefaultRtpReceiveParameters before the SSRC is known.
7649 webrtc::RtpParameters rtp_parameters =
7650 channel_->GetDefaultRtpReceiveParameters();
deadbeef3bc15102017-04-20 19:25:07 -07007651 ASSERT_EQ(1u, rtp_parameters.encodings.size());
7652 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
7653
7654 // Receive VP8 packet.
7655 uint8_t data[kMinRtpPacketLen];
7656 cricket::RtpHeader rtpHeader;
7657 rtpHeader.payload_type = GetEngineCodec("VP8").id;
7658 rtpHeader.seq_num = rtpHeader.timestamp = 0;
7659 rtpHeader.ssrc = kIncomingUnsignalledSsrc;
7660 cricket::SetRtpHeader(data, sizeof(data), rtpHeader);
7661 rtc::CopyOnWriteBuffer packet(data, sizeof(data));
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07007662 channel_->OnPacketReceived(packet, /* packet_time_us */ -1);
deadbeef3bc15102017-04-20 19:25:07 -07007663
7664 // The |ssrc| member should still be unset.
Saurav Das749f6602019-12-04 09:31:36 -08007665 rtp_parameters = channel_->GetDefaultRtpReceiveParameters();
deadbeef3bc15102017-04-20 19:25:07 -07007666 ASSERT_EQ(1u, rtp_parameters.encodings.size());
7667 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
7668}
7669
eladalonf1841382017-06-12 01:16:46 -07007670void WebRtcVideoChannelTest::TestReceiverLocalSsrcConfiguration(
Peter Boström3548dd22015-05-22 18:48:36 +02007671 bool receiver_first) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02007672 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Peter Boström3548dd22015-05-22 18:48:36 +02007673
7674 const uint32_t kSenderSsrc = 0xC0FFEE;
Peter Boströmdfa28152015-10-21 17:21:10 +02007675 const uint32_t kSecondSenderSsrc = 0xBADCAFE;
Peter Boström3548dd22015-05-22 18:48:36 +02007676 const uint32_t kReceiverSsrc = 0x4711;
Peter Boströmdfa28152015-10-21 17:21:10 +02007677 const uint32_t kExpectedDefaultReceiverSsrc = 1;
Peter Boström3548dd22015-05-22 18:48:36 +02007678
7679 if (receiver_first) {
7680 AddRecvStream(StreamParams::CreateLegacy(kReceiverSsrc));
7681 std::vector<FakeVideoReceiveStream*> receive_streams =
7682 fake_call_->GetVideoReceiveStreams();
7683 ASSERT_EQ(1u, receive_streams.size());
Peter Boströmdfa28152015-10-21 17:21:10 +02007684 // Default local SSRC when we have no sender.
7685 EXPECT_EQ(kExpectedDefaultReceiverSsrc,
7686 receive_streams[0]->GetConfig().rtp.local_ssrc);
Peter Boström3548dd22015-05-22 18:48:36 +02007687 }
7688 AddSendStream(StreamParams::CreateLegacy(kSenderSsrc));
7689 if (!receiver_first)
7690 AddRecvStream(StreamParams::CreateLegacy(kReceiverSsrc));
7691 std::vector<FakeVideoReceiveStream*> receive_streams =
7692 fake_call_->GetVideoReceiveStreams();
7693 ASSERT_EQ(1u, receive_streams.size());
7694 EXPECT_EQ(kSenderSsrc, receive_streams[0]->GetConfig().rtp.local_ssrc);
Peter Boströmdfa28152015-10-21 17:21:10 +02007695
7696 // Removing first sender should fall back to another (in this case the second)
7697 // local send stream's SSRC.
7698 AddSendStream(StreamParams::CreateLegacy(kSecondSenderSsrc));
7699 ASSERT_TRUE(channel_->RemoveSendStream(kSenderSsrc));
Yves Gerey665174f2018-06-19 15:03:05 +02007700 receive_streams = fake_call_->GetVideoReceiveStreams();
Peter Boströmdfa28152015-10-21 17:21:10 +02007701 ASSERT_EQ(1u, receive_streams.size());
7702 EXPECT_EQ(kSecondSenderSsrc, receive_streams[0]->GetConfig().rtp.local_ssrc);
7703
7704 // Removing the last sender should fall back to default local SSRC.
7705 ASSERT_TRUE(channel_->RemoveSendStream(kSecondSenderSsrc));
Yves Gerey665174f2018-06-19 15:03:05 +02007706 receive_streams = fake_call_->GetVideoReceiveStreams();
Peter Boströmdfa28152015-10-21 17:21:10 +02007707 ASSERT_EQ(1u, receive_streams.size());
7708 EXPECT_EQ(kExpectedDefaultReceiverSsrc,
7709 receive_streams[0]->GetConfig().rtp.local_ssrc);
Peter Boström3548dd22015-05-22 18:48:36 +02007710}
7711
eladalonf1841382017-06-12 01:16:46 -07007712TEST_F(WebRtcVideoChannelTest, ConfiguresLocalSsrc) {
Peter Boström3548dd22015-05-22 18:48:36 +02007713 TestReceiverLocalSsrcConfiguration(false);
7714}
7715
eladalonf1841382017-06-12 01:16:46 -07007716TEST_F(WebRtcVideoChannelTest, ConfiguresLocalSsrcOnExistingReceivers) {
Peter Boström3548dd22015-05-22 18:48:36 +02007717 TestReceiverLocalSsrcConfiguration(true);
7718}
7719
Mirko Bonadei6a489f22019-04-09 15:11:12 +02007720class WebRtcVideoChannelSimulcastTest : public ::testing::Test {
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007721 public:
eladalonf1841382017-06-12 01:16:46 -07007722 WebRtcVideoChannelSimulcastTest()
Sebastian Jansson8f83b422018-02-21 13:07:13 +01007723 : fake_call_(),
Magnus Jedvert02e7a192017-09-23 17:21:32 +02007724 encoder_factory_(new cricket::FakeWebRtcVideoEncoderFactory),
7725 decoder_factory_(new cricket::FakeWebRtcVideoDecoderFactory),
Jiawei Ouc2ebe212018-11-08 10:02:56 -08007726 mock_rate_allocator_factory_(
Mirko Bonadei317a1f02019-09-17 17:06:18 +02007727 std::make_unique<webrtc::MockVideoBitrateAllocatorFactory>()),
Anders Carlsson67537952018-05-03 11:28:29 +02007728 engine_(std::unique_ptr<cricket::FakeWebRtcVideoEncoderFactory>(
Magnus Jedvert02e7a192017-09-23 17:21:32 +02007729 encoder_factory_),
Anders Carlsson67537952018-05-03 11:28:29 +02007730 std::unique_ptr<cricket::FakeWebRtcVideoDecoderFactory>(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02007731 decoder_factory_)),
magjed2475ae22017-09-12 04:42:15 -07007732 last_ssrc_(0) {}
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007733
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00007734 void SetUp() override {
Anders Carlsson5f2bb622018-05-14 09:48:06 +02007735 encoder_factory_->AddSupportedVideoCodecType("VP8");
Johannes Kron3e983682020-03-29 22:17:00 +02007736 decoder_factory_->AddSupportedVideoCodecType("VP8");
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02007737 channel_.reset(engine_.CreateMediaChannel(
7738 &fake_call_, GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
7739 mock_rate_allocator_factory_.get()));
Sergey Ulanove2b15012016-11-22 16:08:30 -08007740 channel_->OnReadyToSend(true);
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007741 last_ssrc_ = 123;
7742 }
7743
7744 protected:
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007745 void VerifySimulcastSettings(const VideoCodec& codec,
perkj26752742016-10-24 01:21:16 -07007746 int capture_width,
7747 int capture_height,
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007748 size_t num_configured_streams,
sprang429600d2017-01-26 06:12:26 -08007749 size_t expected_num_streams,
7750 bool screenshare,
7751 bool conference_mode) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02007752 cricket::VideoSendParameters parameters;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02007753 parameters.codecs.push_back(codec);
sprang429600d2017-01-26 06:12:26 -08007754 parameters.conference_mode = conference_mode;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02007755 ASSERT_TRUE(channel_->SetSendParameters(parameters));
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007756
Peter Boström0c4e06b2015-10-07 12:23:21 +02007757 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
henrikg91d6ede2015-09-17 00:24:34 -07007758 RTC_DCHECK(num_configured_streams <= ssrcs.size());
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007759 ssrcs.resize(num_configured_streams);
7760
sprangf24a0642017-02-28 13:23:26 -08007761 AddSendStream(CreateSimStreamParams("cname", ssrcs));
pbos@webrtc.org86196c42015-02-16 21:02:00 +00007762 // Send a full-size frame to trigger a stream reconfiguration to use all
7763 // expected simulcast layers.
Niels Möller805a27e2019-01-21 12:21:27 +01007764 webrtc::test::FrameForwarder frame_forwarder;
7765 cricket::FakeFrameSource frame_source(capture_width, capture_height,
7766 rtc::kNumMicrosecsPerSec / 30);
7767
sprangf24a0642017-02-28 13:23:26 -08007768 VideoOptions options;
7769 if (screenshare)
Oskar Sundbom78807582017-11-16 11:09:55 +01007770 options.is_screencast = screenshare;
Niels Möller805a27e2019-01-21 12:21:27 +01007771 EXPECT_TRUE(
7772 channel_->SetVideoSend(ssrcs.front(), &options, &frame_forwarder));
sprangf24a0642017-02-28 13:23:26 -08007773 // Fetch the latest stream since SetVideoSend() may recreate it if the
7774 // screen content setting is changed.
7775 FakeVideoSendStream* stream = fake_call_.GetVideoSendStreams().front();
pbos@webrtc.org86196c42015-02-16 21:02:00 +00007776 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01007777 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007778
Zach Stein3ca452b2018-01-18 10:01:24 -08007779 auto rtp_parameters = channel_->GetRtpSendParameters(kSsrcs3[0]);
7780 EXPECT_EQ(num_configured_streams, rtp_parameters.encodings.size());
7781
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007782 std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
7783 ASSERT_EQ(expected_num_streams, video_streams.size());
Ilya Nikolaevskiy33d2a912019-04-02 11:05:03 +02007784 EXPECT_LE(expected_num_streams, stream->GetConfig().rtp.ssrcs.size());
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007785
sprang429600d2017-01-26 06:12:26 -08007786 std::vector<webrtc::VideoStream> expected_streams;
Florent Castelli66b38602019-07-10 16:57:57 +02007787 if (num_configured_streams > 1 || conference_mode) {
sprang429600d2017-01-26 06:12:26 -08007788 expected_streams = GetSimulcastConfig(
Ilya Nikolaevskiy03d90962020-02-11 12:50:38 +01007789 /*min_layers=*/1, num_configured_streams, capture_width,
7790 capture_height, webrtc::kDefaultBitratePriority, kDefaultQpMax,
Florent Castelli66b38602019-07-10 16:57:57 +02007791 screenshare && conference_mode, true);
7792 if (screenshare && conference_mode) {
sprang3ebabf12017-02-16 07:35:22 -08007793 for (const webrtc::VideoStream& stream : expected_streams) {
7794 // Never scale screen content.
Danil Chapovalov350531e2018-06-08 11:04:04 +00007795 EXPECT_EQ(stream.width, rtc::checked_cast<size_t>(capture_width));
7796 EXPECT_EQ(stream.height, rtc::checked_cast<size_t>(capture_height));
sprang3ebabf12017-02-16 07:35:22 -08007797 }
7798 }
sprang429600d2017-01-26 06:12:26 -08007799 } else {
7800 webrtc::VideoStream stream;
7801 stream.width = capture_width;
7802 stream.height = capture_height;
7803 stream.max_framerate = kDefaultVideoMaxFramerate;
Elad Alon80f53b72019-10-11 16:19:43 +02007804 stream.min_bitrate_bps = webrtc::kDefaultMinVideoBitrateBps;
sprang429600d2017-01-26 06:12:26 -08007805 stream.target_bitrate_bps = stream.max_bitrate_bps =
Åsa Perssonbdee46d2018-06-25 11:28:06 +02007806 GetMaxDefaultBitrateBps(capture_width, capture_height);
sprang429600d2017-01-26 06:12:26 -08007807 stream.max_qp = kDefaultQpMax;
7808 expected_streams.push_back(stream);
7809 }
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007810
7811 ASSERT_EQ(expected_streams.size(), video_streams.size());
7812
7813 size_t num_streams = video_streams.size();
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00007814 int total_max_bitrate_bps = 0;
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007815 for (size_t i = 0; i < num_streams; ++i) {
7816 EXPECT_EQ(expected_streams[i].width, video_streams[i].width);
7817 EXPECT_EQ(expected_streams[i].height, video_streams[i].height);
7818
7819 EXPECT_GT(video_streams[i].max_framerate, 0);
7820 EXPECT_EQ(expected_streams[i].max_framerate,
7821 video_streams[i].max_framerate);
7822
7823 EXPECT_GT(video_streams[i].min_bitrate_bps, 0);
7824 EXPECT_EQ(expected_streams[i].min_bitrate_bps,
7825 video_streams[i].min_bitrate_bps);
7826
7827 EXPECT_GT(video_streams[i].target_bitrate_bps, 0);
7828 EXPECT_EQ(expected_streams[i].target_bitrate_bps,
7829 video_streams[i].target_bitrate_bps);
7830
7831 EXPECT_GT(video_streams[i].max_bitrate_bps, 0);
7832 EXPECT_EQ(expected_streams[i].max_bitrate_bps,
7833 video_streams[i].max_bitrate_bps);
7834
7835 EXPECT_GT(video_streams[i].max_qp, 0);
7836 EXPECT_EQ(expected_streams[i].max_qp, video_streams[i].max_qp);
7837
Florent Castelli66b38602019-07-10 16:57:57 +02007838 EXPECT_EQ(num_configured_streams > 1 || conference_mode,
Sergey Silkina796a7e2018-03-01 15:11:29 +01007839 expected_streams[i].num_temporal_layers.has_value());
7840
7841 if (conference_mode) {
7842 EXPECT_EQ(expected_streams[i].num_temporal_layers,
7843 video_streams[i].num_temporal_layers);
7844 }
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00007845
7846 if (i == num_streams - 1) {
7847 total_max_bitrate_bps += video_streams[i].max_bitrate_bps;
7848 } else {
7849 total_max_bitrate_bps += video_streams[i].target_bitrate_bps;
7850 }
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007851 }
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00007852
Niels Möllerff40b142018-04-09 08:49:14 +02007853 EXPECT_TRUE(channel_->SetVideoSend(ssrcs.front(), nullptr, nullptr));
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007854 }
7855
7856 FakeVideoSendStream* AddSendStream() {
7857 return AddSendStream(StreamParams::CreateLegacy(last_ssrc_++));
7858 }
7859
7860 FakeVideoSendStream* AddSendStream(const StreamParams& sp) {
Yves Gerey665174f2018-06-19 15:03:05 +02007861 size_t num_streams = fake_call_.GetVideoSendStreams().size();
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007862 EXPECT_TRUE(channel_->AddSendStream(sp));
7863 std::vector<FakeVideoSendStream*> streams =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02007864 fake_call_.GetVideoSendStreams();
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007865 EXPECT_EQ(num_streams + 1, streams.size());
7866 return streams[streams.size() - 1];
7867 }
7868
7869 std::vector<FakeVideoSendStream*> GetFakeSendStreams() {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02007870 return fake_call_.GetVideoSendStreams();
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007871 }
7872
7873 FakeVideoReceiveStream* AddRecvStream() {
7874 return AddRecvStream(StreamParams::CreateLegacy(last_ssrc_++));
7875 }
7876
7877 FakeVideoReceiveStream* AddRecvStream(const StreamParams& sp) {
Yves Gerey665174f2018-06-19 15:03:05 +02007878 size_t num_streams = fake_call_.GetVideoReceiveStreams().size();
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007879 EXPECT_TRUE(channel_->AddRecvStream(sp));
7880 std::vector<FakeVideoReceiveStream*> streams =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02007881 fake_call_.GetVideoReceiveStreams();
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007882 EXPECT_EQ(num_streams + 1, streams.size());
7883 return streams[streams.size() - 1];
7884 }
7885
Danil Chapovalov83bbe912019-08-07 12:24:53 +02007886 webrtc::RtcEventLogNull event_log_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +02007887 FakeCall fake_call_;
Magnus Jedvert02e7a192017-09-23 17:21:32 +02007888 cricket::FakeWebRtcVideoEncoderFactory* encoder_factory_;
7889 cricket::FakeWebRtcVideoDecoderFactory* decoder_factory_;
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02007890 std::unique_ptr<webrtc::MockVideoBitrateAllocatorFactory>
7891 mock_rate_allocator_factory_;
eladalonf1841382017-06-12 01:16:46 -07007892 WebRtcVideoEngine engine_;
kwiberg686a8ef2016-02-26 03:00:35 -08007893 std::unique_ptr<VideoMediaChannel> channel_;
Peter Boström0c4e06b2015-10-07 12:23:21 +02007894 uint32_t last_ssrc_;
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007895};
7896
eladalonf1841382017-06-12 01:16:46 -07007897TEST_F(WebRtcVideoChannelSimulcastTest, SetSendCodecsWith2SimulcastStreams) {
sprang429600d2017-01-26 06:12:26 -08007898 VerifySimulcastSettings(cricket::VideoCodec("VP8"), 640, 360, 2, 2, false,
7899 true);
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007900}
7901
eladalonf1841382017-06-12 01:16:46 -07007902TEST_F(WebRtcVideoChannelSimulcastTest, SetSendCodecsWith3SimulcastStreams) {
sprang429600d2017-01-26 06:12:26 -08007903 VerifySimulcastSettings(cricket::VideoCodec("VP8"), 1280, 720, 3, 3, false,
7904 true);
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007905}
7906
7907// Test that we normalize send codec format size in simulcast.
eladalonf1841382017-06-12 01:16:46 -07007908TEST_F(WebRtcVideoChannelSimulcastTest, SetSendCodecsWithOddSizeInSimulcast) {
sprang429600d2017-01-26 06:12:26 -08007909 VerifySimulcastSettings(cricket::VideoCodec("VP8"), 541, 271, 2, 2, false,
7910 true);
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007911}
sprang429600d2017-01-26 06:12:26 -08007912
Ilya Nikolaevskiy3df1d5d2018-08-22 09:26:51 +02007913TEST_F(WebRtcVideoChannelSimulcastTest, SetSendCodecsForScreenshare) {
Florent Castelli66b38602019-07-10 16:57:57 +02007914 VerifySimulcastSettings(cricket::VideoCodec("VP8"), 1280, 720, 3, 3, true,
Ilya Nikolaevskiy3df1d5d2018-08-22 09:26:51 +02007915 false);
7916}
7917
eladalonf1841382017-06-12 01:16:46 -07007918TEST_F(WebRtcVideoChannelSimulcastTest, SetSendCodecsForSimulcastScreenshare) {
sprang429600d2017-01-26 06:12:26 -08007919 VerifySimulcastSettings(cricket::VideoCodec("VP8"), 1280, 720, 3, 2, true,
7920 true);
7921}
7922
Florent Castelli66b38602019-07-10 16:57:57 +02007923TEST_F(WebRtcVideoChannelSimulcastTest, SimulcastScreenshareWithoutConference) {
7924 VerifySimulcastSettings(cricket::VideoCodec("VP8"), 1280, 720, 3, 3, true,
sprangfe627f32017-03-29 08:24:59 -07007925 false);
7926}
7927
Chen Xing90f3b892019-06-25 10:16:14 +02007928TEST_F(WebRtcVideoChannelBaseTest, GetSources) {
7929 EXPECT_THAT(channel_->GetSources(kSsrc), IsEmpty());
Jonas Oreland49ac5952018-09-26 16:04:32 +02007930
Saurav Das749f6602019-12-04 09:31:36 -08007931 channel_->SetDefaultSink(&renderer_);
Jonas Oreland49ac5952018-09-26 16:04:32 +02007932 EXPECT_TRUE(SetDefaultCodec());
7933 EXPECT_TRUE(SetSend(true));
Chen Xing90f3b892019-06-25 10:16:14 +02007934 EXPECT_EQ(renderer_.num_rendered_frames(), 0);
Jonas Oreland49ac5952018-09-26 16:04:32 +02007935
Chen Xing90f3b892019-06-25 10:16:14 +02007936 // Send and receive one frame.
7937 SendFrame();
7938 EXPECT_FRAME_WAIT(1, kVideoWidth, kVideoHeight, kTimeout);
Jonas Oreland49ac5952018-09-26 16:04:32 +02007939
Chen Xing90f3b892019-06-25 10:16:14 +02007940 EXPECT_THAT(channel_->GetSources(kSsrc - 1), IsEmpty());
7941 EXPECT_THAT(channel_->GetSources(kSsrc), SizeIs(1));
7942 EXPECT_THAT(channel_->GetSources(kSsrc + 1), IsEmpty());
Jonas Oreland49ac5952018-09-26 16:04:32 +02007943
Chen Xing90f3b892019-06-25 10:16:14 +02007944 webrtc::RtpSource source = channel_->GetSources(kSsrc)[0];
7945 EXPECT_EQ(source.source_id(), kSsrc);
7946 EXPECT_EQ(source.source_type(), webrtc::RtpSourceType::SSRC);
7947 int64_t rtp_timestamp_1 = source.rtp_timestamp();
7948 int64_t timestamp_ms_1 = source.timestamp_ms();
Jonas Oreland49ac5952018-09-26 16:04:32 +02007949
Chen Xing90f3b892019-06-25 10:16:14 +02007950 // Send and receive another frame.
7951 SendFrame();
7952 EXPECT_FRAME_WAIT(2, kVideoWidth, kVideoHeight, kTimeout);
Jonas Oreland49ac5952018-09-26 16:04:32 +02007953
Chen Xing90f3b892019-06-25 10:16:14 +02007954 EXPECT_THAT(channel_->GetSources(kSsrc - 1), IsEmpty());
7955 EXPECT_THAT(channel_->GetSources(kSsrc), SizeIs(1));
7956 EXPECT_THAT(channel_->GetSources(kSsrc + 1), IsEmpty());
Jonas Oreland49ac5952018-09-26 16:04:32 +02007957
Chen Xing90f3b892019-06-25 10:16:14 +02007958 source = channel_->GetSources(kSsrc)[0];
7959 EXPECT_EQ(source.source_id(), kSsrc);
7960 EXPECT_EQ(source.source_type(), webrtc::RtpSourceType::SSRC);
7961 int64_t rtp_timestamp_2 = source.rtp_timestamp();
7962 int64_t timestamp_ms_2 = source.timestamp_ms();
Jonas Oreland49ac5952018-09-26 16:04:32 +02007963
Chen Xing90f3b892019-06-25 10:16:14 +02007964 EXPECT_GT(rtp_timestamp_2, rtp_timestamp_1);
7965 EXPECT_GT(timestamp_ms_2, timestamp_ms_1);
Jonas Oreland49ac5952018-09-26 16:04:32 +02007966}
7967
Amit Hilbuchb000b712019-02-25 10:22:14 -08007968TEST_F(WebRtcVideoChannelTest, SetsRidsOnSendStream) {
7969 StreamParams sp = CreateSimStreamParams("cname", {123, 456, 789});
7970
7971 std::vector<std::string> rids = {"f", "h", "q"};
7972 std::vector<cricket::RidDescription> rid_descriptions;
7973 for (const auto& rid : rids) {
7974 rid_descriptions.emplace_back(rid, cricket::RidDirection::kSend);
7975 }
7976 sp.set_rids(rid_descriptions);
7977
7978 ASSERT_TRUE(channel_->AddSendStream(sp));
7979 const auto& streams = fake_call_->GetVideoSendStreams();
7980 ASSERT_EQ(1u, streams.size());
7981 auto stream = streams[0];
7982 ASSERT_NE(stream, nullptr);
7983 const auto& config = stream->GetConfig();
Markus Handell8bc88342020-03-16 10:42:01 +01007984 EXPECT_THAT(config.rtp.rids, ElementsAreArray(rids));
Amit Hilbuchb000b712019-02-25 10:22:14 -08007985}
7986
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00007987} // namespace cricket