blob: 58c97ac3a3336ae0640a24510048b8433c476357 [file] [log] [blame]
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001/*
kjellander1afca732016-02-07 20:46:45 -08002 * Copyright (c) 2004 The WebRTC project authors. All Rights Reserved.
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003 *
kjellander1afca732016-02-07 20:46:45 -08004 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00009 */
10
11#include <map>
kwiberg686a8ef2016-02-26 03:00:35 -080012#include <memory>
Steve Antone78bcb92017-10-31 09:53:08 -070013#include <utility>
pbos@webrtc.org86f613d2014-06-10 08:53:05 +000014#include <vector>
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000015
Steve Anton2c9ebef2019-01-28 17:27:58 -080016#include "absl/algorithm/container.h"
Niels Möller805a27e2019-01-21 12:21:27 +010017#include "absl/memory/memory.h"
Niels Möller039743e2018-10-23 10:07:25 +020018#include "absl/strings/match.h"
Steve Anton10542f22019-01-11 09:11:00 -080019#include "api/rtp_parameters.h"
Piotr (Peter) Slatala946b9682019-03-18 10:25:02 -070020#include "api/test/fake_media_transport.h"
Jiawei Ouc2ebe212018-11-08 10:02:56 -080021#include "api/test/mock_video_bitrate_allocator.h"
22#include "api/test/mock_video_bitrate_allocator_factory.h"
Emircan Uysalerdbcac7f2017-10-30 23:10:12 -070023#include "api/test/mock_video_decoder_factory.h"
24#include "api/test/mock_video_encoder_factory.h"
Jonas Oreland49ac5952018-09-26 16:04:32 +020025#include "api/units/time_delta.h"
Jiawei Ouc2ebe212018-11-08 10:02:56 -080026#include "api/video/builtin_video_bitrate_allocator_factory.h"
Niels Möller805a27e2019-01-21 12:21:27 +010027#include "api/video/i420_buffer.h"
Åsa Persson23eba222018-10-02 14:47:06 +020028#include "api/video/video_bitrate_allocation.h"
Anders Carlsson5f2bb622018-05-14 09:48:06 +020029#include "api/video_codecs/builtin_video_decoder_factory.h"
30#include "api/video_codecs/builtin_video_encoder_factory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020031#include "api/video_codecs/sdp_video_format.h"
32#include "api/video_codecs/video_decoder_factory.h"
33#include "api/video_codecs/video_encoder.h"
34#include "api/video_codecs/video_encoder_factory.h"
35#include "call/flexfec_receive_stream.h"
36#include "common_video/h264/profile_level_id.h"
37#include "logging/rtc_event_log/rtc_event_log.h"
Niels Möller805a27e2019-01-21 12:21:27 +010038#include "media/base/fake_frame_source.h"
Steve Anton10542f22019-01-11 09:11:00 -080039#include "media/base/fake_network_interface.h"
Steve Anton10542f22019-01-11 09:11:00 -080040#include "media/base/fake_video_renderer.h"
41#include "media/base/media_constants.h"
42#include "media/base/rtp_utils.h"
43#include "media/base/test_utils.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020044#include "media/engine/constants.h"
Steve Anton10542f22019-01-11 09:11:00 -080045#include "media/engine/fake_webrtc_call.h"
46#include "media/engine/fake_webrtc_video_engine.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020047#include "media/engine/simulcast.h"
Steve Anton10542f22019-01-11 09:11:00 -080048#include "media/engine/webrtc_video_engine.h"
49#include "media/engine/webrtc_voice_engine.h"
Åsa Persson23cd45a2018-07-03 10:40:40 +020050#include "modules/rtp_rtcp/include/rtp_header_parser.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020051#include "rtc_base/arraysize.h"
Steve Anton10542f22019-01-11 09:11:00 -080052#include "rtc_base/fake_clock.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020053#include "rtc_base/gunit.h"
Yves Gerey665174f2018-06-19 15:03:05 +020054#include "rtc_base/numerics/safe_conversions.h"
Steve Antonf3802842019-01-24 19:07:40 -080055#include "rtc_base/time_utils.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020056#include "test/field_trial.h"
Niels Möllerd0f0f682019-01-14 09:09:53 +010057#include "test/frame_generator.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020058#include "test/gmock.h"
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000059
Niels Möller805a27e2019-01-21 12:21:27 +010060using testing::Field;
Sebastian Jansson8f83b422018-02-21 13:07:13 +010061using webrtc::BitrateConstraints;
isheriff6f8d6862016-05-26 11:24:55 -070062using webrtc::RtpExtension;
63
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000064namespace {
buildbot@webrtc.orga8530772014-12-10 09:01:18 +000065static const int kDefaultQpMax = 56;
buildbot@webrtc.orga8530772014-12-10 09:01:18 +000066
noahricd10a68e2015-07-10 11:27:55 -070067static const uint8_t kRedRtxPayloadType = 125;
68
Niels Möller6557d0c2018-04-11 15:18:34 +020069static const uint32_t kTimeout = 5000U;
70static const uint32_t kDefaultReceiveSsrc = 0;
71static const uint32_t kSsrc = 1234u;
72static const uint32_t kSsrcs4[] = {1, 2, 3, 4};
73static const int kVideoWidth = 640;
74static const int kVideoHeight = 360;
75static const int kFramerate = 30;
76
Peter Boström0c4e06b2015-10-07 12:23:21 +020077static const uint32_t kSsrcs1[] = {1};
78static const uint32_t kSsrcs3[] = {1, 2, 3};
79static const uint32_t kRtxSsrcs1[] = {4};
brandtr468da7c2016-11-22 02:16:47 -080080static const uint32_t kFlexfecSsrc = 5;
Peter Boström0c4e06b2015-10-07 12:23:21 +020081static const uint32_t kIncomingUnsignalledSsrc = 0xC0FFEE;
mzanaty8a855d62017-02-17 15:46:43 -080082static const uint32_t kDefaultRecvSsrc = 0;
83
pbos@webrtc.org3c107582014-07-20 15:27:35 +000084static const char kUnsupportedExtensionName[] =
85 "urn:ietf:params:rtp-hdrext:unsupported";
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +000086
magjed509e4fe2016-11-18 01:34:11 -080087cricket::VideoCodec RemoveFeedbackParams(cricket::VideoCodec&& codec) {
88 codec.feedback_params = cricket::FeedbackParams();
Mirko Bonadei29a8d102018-04-25 23:58:26 +020089 return std::move(codec);
magjed509e4fe2016-11-18 01:34:11 -080090}
91
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +000092void VerifyCodecHasDefaultFeedbackParams(const cricket::VideoCodec& codec) {
93 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
94 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty)));
95 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
96 cricket::kRtcpFbParamNack, cricket::kRtcpFbNackParamPli)));
97 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
98 cricket::kRtcpFbParamRemb, cricket::kParamValueEmpty)));
99 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
stefan43edf0f2015-11-20 18:05:48 -0800100 cricket::kRtcpFbParamTransportCc, cricket::kParamValueEmpty)));
101 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +0000102 cricket::kRtcpFbParamCcm, cricket::kRtcpFbCcmParamFir)));
103}
104
magjed725e4842016-11-16 00:48:13 -0800105// Return true if any codec in |codecs| is an RTX codec with associated payload
106// type |payload_type|.
107bool HasRtxCodec(const std::vector<cricket::VideoCodec>& codecs,
108 int payload_type) {
109 for (const cricket::VideoCodec& codec : codecs) {
110 int associated_payload_type;
Niels Möller039743e2018-10-23 10:07:25 +0200111 if (absl::EqualsIgnoreCase(codec.name.c_str(), "rtx") &&
magjed725e4842016-11-16 00:48:13 -0800112 codec.GetParam(cricket::kCodecParamAssociatedPayloadType,
113 &associated_payload_type) &&
114 associated_payload_type == payload_type) {
115 return true;
116 }
117 }
118 return false;
119}
120
nisseca5706d2017-09-11 02:32:16 -0700121// TODO(nisse): Duplicated in call.cc.
122const int* FindKeyByValue(const std::map<int, int>& m, int v) {
123 for (const auto& kv : m) {
124 if (kv.second == v)
125 return &kv.first;
126 }
127 return nullptr;
128}
129
Yves Gerey665174f2018-06-19 15:03:05 +0200130bool HasRtxReceiveAssociation(const webrtc::VideoReceiveStream::Config& config,
131 int payload_type) {
nisseca5706d2017-09-11 02:32:16 -0700132 return FindKeyByValue(config.rtp.rtx_associated_payload_types,
133 payload_type) != nullptr;
134}
135
136// Check that there's an Rtx payload type for each decoder.
137bool VerifyRtxReceiveAssociations(
138 const webrtc::VideoReceiveStream::Config& config) {
139 for (const auto& decoder : config.decoders) {
140 if (!HasRtxReceiveAssociation(config, decoder.payload_type))
141 return false;
142 }
143 return true;
144}
145
brandtrffc61182016-11-28 06:02:22 -0800146rtc::scoped_refptr<webrtc::VideoFrameBuffer> CreateBlackFrameBuffer(
nisse64ec8f82016-09-27 00:17:25 -0700147 int width,
148 int height) {
149 rtc::scoped_refptr<webrtc::I420Buffer> buffer =
150 webrtc::I420Buffer::Create(width, height);
nisseaf916892017-01-10 07:44:26 -0800151 webrtc::I420Buffer::SetBlack(buffer);
nisse64ec8f82016-09-27 00:17:25 -0700152 return buffer;
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +0000153}
154
Shao Changbine62202f2015-04-21 20:24:50 +0800155void VerifySendStreamHasRtxTypes(const webrtc::VideoSendStream::Config& config,
156 const std::map<int, int>& rtx_types) {
157 std::map<int, int>::const_iterator it;
Niels Möller259a4972018-04-05 15:36:51 +0200158 it = rtx_types.find(config.rtp.payload_type);
Shao Changbine62202f2015-04-21 20:24:50 +0800159 EXPECT_TRUE(it != rtx_types.end() &&
160 it->second == config.rtp.rtx.payload_type);
161
brandtrb5f2c3f2016-10-04 23:28:39 -0700162 if (config.rtp.ulpfec.red_rtx_payload_type != -1) {
163 it = rtx_types.find(config.rtp.ulpfec.red_payload_type);
Shao Changbine62202f2015-04-21 20:24:50 +0800164 EXPECT_TRUE(it != rtx_types.end() &&
brandtrb5f2c3f2016-10-04 23:28:39 -0700165 it->second == config.rtp.ulpfec.red_rtx_payload_type);
Shao Changbine62202f2015-04-21 20:24:50 +0800166 }
167}
kthelgason2bc68642017-02-07 07:02:22 -0800168
169cricket::MediaConfig GetMediaConfig() {
170 cricket::MediaConfig media_config;
Niels Möller1d7ecd22018-01-18 15:25:12 +0100171 media_config.video.enable_cpu_adaptation = false;
kthelgason2bc68642017-02-07 07:02:22 -0800172 return media_config;
173}
nisse26e3abb2017-08-25 04:44:25 -0700174
Åsa Perssonbdee46d2018-06-25 11:28:06 +0200175// Values from GetMaxDefaultVideoBitrateKbps in webrtcvideoengine.cc.
176int GetMaxDefaultBitrateBps(size_t width, size_t height) {
177 if (width * height <= 320 * 240) {
178 return 600000;
179 } else if (width * height <= 640 * 480) {
180 return 1700000;
181 } else if (width * height <= 960 * 540) {
182 return 2000000;
183 } else {
184 return 2500000;
185 }
186}
187
Niels Möller731a2c22018-07-30 15:08:07 +0200188class MockVideoSource : public rtc::VideoSourceInterface<webrtc::VideoFrame> {
189 public:
190 MOCK_METHOD2(AddOrUpdateSink,
191 void(rtc::VideoSinkInterface<webrtc::VideoFrame>* sink,
192 const rtc::VideoSinkWants& wants));
193 MOCK_METHOD1(RemoveSink,
194 void(rtc::VideoSinkInterface<webrtc::VideoFrame>* sink));
195};
196
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000197} // namespace
198
Yves Gerey665174f2018-06-19 15:03:05 +0200199#define EXPECT_FRAME_WAIT(c, w, h, t) \
Niels Möller6557d0c2018-04-11 15:18:34 +0200200 EXPECT_EQ_WAIT((c), renderer_.num_rendered_frames(), (t)); \
Yves Gerey665174f2018-06-19 15:03:05 +0200201 EXPECT_EQ((w), renderer_.width()); \
202 EXPECT_EQ((h), renderer_.height()); \
Niels Möller6557d0c2018-04-11 15:18:34 +0200203 EXPECT_EQ(0, renderer_.errors());
204
Yves Gerey665174f2018-06-19 15:03:05 +0200205#define EXPECT_FRAME_ON_RENDERER_WAIT(r, c, w, h, t) \
Niels Möller6557d0c2018-04-11 15:18:34 +0200206 EXPECT_EQ_WAIT((c), (r).num_rendered_frames(), (t)); \
Yves Gerey665174f2018-06-19 15:03:05 +0200207 EXPECT_EQ((w), (r).width()); \
208 EXPECT_EQ((h), (r).height()); \
Niels Möller6557d0c2018-04-11 15:18:34 +0200209 EXPECT_EQ(0, (r).errors());
210
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000211namespace cricket {
eladalonf1841382017-06-12 01:16:46 -0700212class WebRtcVideoEngineTest : public ::testing::Test {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000213 public:
eladalonf1841382017-06-12 01:16:46 -0700214 WebRtcVideoEngineTest() : WebRtcVideoEngineTest("") {}
215 explicit WebRtcVideoEngineTest(const char* field_trials)
stefanc1aeaf02015-10-15 07:26:07 -0700216 : override_field_trials_(field_trials),
skvlad11a9cbf2016-10-07 11:53:05 -0700217 call_(webrtc::Call::Create(webrtc::Call::Config(&event_log_))),
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200218 encoder_factory_(new cricket::FakeWebRtcVideoEncoderFactory),
219 decoder_factory_(new cricket::FakeWebRtcVideoDecoderFactory),
Anders Carlsson67537952018-05-03 11:28:29 +0200220 engine_(std::unique_ptr<cricket::FakeWebRtcVideoEncoderFactory>(
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200221 encoder_factory_),
Anders Carlsson67537952018-05-03 11:28:29 +0200222 std::unique_ptr<cricket::FakeWebRtcVideoDecoderFactory>(
Jiawei Ouc2ebe212018-11-08 10:02:56 -0800223 decoder_factory_),
224 webrtc::CreateBuiltinVideoBitrateAllocatorFactory()) {
Ilya Nikolaevskiy9c38c472018-09-03 16:11:42 +0200225 // Ensure fake clock doesn't return 0, which will cause some initializations
226 // fail inside RTP senders.
227 fake_clock_.AdvanceTimeMicros(1);
228 }
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000229
230 protected:
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200231 void AssignDefaultAptRtxTypes();
232 void AssignDefaultCodec();
233
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +0100234 // Find the index of the codec in the engine with the given name. The codec
235 // must be present.
Oleh Prypina40f8242017-12-21 13:32:23 +0100236 size_t GetEngineCodecIndex(const std::string& name) const;
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +0100237
magjed509e4fe2016-11-18 01:34:11 -0800238 // Find the codec in the engine with the given name. The codec must be
239 // present.
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +0100240 cricket::VideoCodec GetEngineCodec(const std::string& name) const;
magjed509e4fe2016-11-18 01:34:11 -0800241
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200242 VideoMediaChannel* SetSendParamsWithAllSupportedCodecs();
pbos@webrtc.orgfa553ef2014-10-20 11:07:07 +0000243
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200244 VideoMediaChannel* SetRecvParamsWithSupportedCodecs(
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000245 const std::vector<VideoCodec>& codecs);
246
Elad Alon157540a2019-02-08 23:37:52 +0100247 void ExpectRtpCapabilitySupport(const char* uri, bool supported) const;
Peter Boströme4499152016-02-05 11:13:28 +0100248
Ilya Nikolaevskiy9c38c472018-09-03 16:11:42 +0200249 // Has to be the first one, so it is initialized before the call or there is a
250 // race condition in the clock access.
251 rtc::ScopedFakeClock fake_clock_;
stefanc1aeaf02015-10-15 07:26:07 -0700252 webrtc::test::ScopedFieldTrials override_field_trials_;
skvlad11a9cbf2016-10-07 11:53:05 -0700253 webrtc::RtcEventLogNullImpl event_log_;
eladalonf1841382017-06-12 01:16:46 -0700254 // Used in WebRtcVideoEngineVoiceTest, but defined here so it's properly
pbos@webrtc.orgf1f0d9a2015-03-02 13:30:15 +0000255 // initialized when the constructor is called.
kwiberg686a8ef2016-02-26 03:00:35 -0800256 std::unique_ptr<webrtc::Call> call_;
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200257 cricket::FakeWebRtcVideoEncoderFactory* encoder_factory_;
258 cricket::FakeWebRtcVideoDecoderFactory* decoder_factory_;
eladalonf1841382017-06-12 01:16:46 -0700259 WebRtcVideoEngine engine_;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000260 VideoCodec default_codec_;
Shao Changbine62202f2015-04-21 20:24:50 +0800261 std::map<int, int> default_apt_rtx_types_;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000262};
263
eladalonf1841382017-06-12 01:16:46 -0700264TEST_F(WebRtcVideoEngineTest, DefaultRtxCodecHasAssociatedPayloadTypeSet) {
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200265 encoder_factory_->AddSupportedVideoCodecType("VP8");
266 AssignDefaultCodec();
267
pbos@webrtc.orge322a172014-06-13 11:47:28 +0000268 std::vector<VideoCodec> engine_codecs = engine_.codecs();
269 for (size_t i = 0; i < engine_codecs.size(); ++i) {
270 if (engine_codecs[i].name != kRtxCodecName)
271 continue;
272 int associated_payload_type;
273 EXPECT_TRUE(engine_codecs[i].GetParam(kCodecParamAssociatedPayloadType,
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000274 &associated_payload_type));
pbos@webrtc.orge322a172014-06-13 11:47:28 +0000275 EXPECT_EQ(default_codec_.id, associated_payload_type);
276 return;
277 }
278 FAIL() << "No RTX codec found among default codecs.";
279}
280
eladalonf1841382017-06-12 01:16:46 -0700281TEST_F(WebRtcVideoEngineTest, SupportsTimestampOffsetHeaderExtension) {
Elad Alon157540a2019-02-08 23:37:52 +0100282 ExpectRtpCapabilitySupport(RtpExtension::kTimestampOffsetUri, true);
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000283}
284
eladalonf1841382017-06-12 01:16:46 -0700285TEST_F(WebRtcVideoEngineTest, SupportsAbsoluteSenderTimeHeaderExtension) {
Elad Alon157540a2019-02-08 23:37:52 +0100286 ExpectRtpCapabilitySupport(RtpExtension::kAbsSendTimeUri, true);
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000287}
288
eladalonf1841382017-06-12 01:16:46 -0700289TEST_F(WebRtcVideoEngineTest, SupportsTransportSequenceNumberHeaderExtension) {
Elad Alon157540a2019-02-08 23:37:52 +0100290 ExpectRtpCapabilitySupport(RtpExtension::kTransportSequenceNumberUri, true);
stefanc1aeaf02015-10-15 07:26:07 -0700291}
292
eladalonf1841382017-06-12 01:16:46 -0700293TEST_F(WebRtcVideoEngineTest, SupportsVideoRotationHeaderExtension) {
Elad Alon157540a2019-02-08 23:37:52 +0100294 ExpectRtpCapabilitySupport(RtpExtension::kVideoRotationUri, true);
295}
296
297TEST_F(WebRtcVideoEngineTest, SupportsPlayoutDelayHeaderExtension) {
298 ExpectRtpCapabilitySupport(RtpExtension::kPlayoutDelayUri, true);
299}
300
301TEST_F(WebRtcVideoEngineTest, SupportsVideoContentTypeHeaderExtension) {
302 ExpectRtpCapabilitySupport(RtpExtension::kVideoContentTypeUri, true);
303}
304
305TEST_F(WebRtcVideoEngineTest, SupportsVideoTimingHeaderExtension) {
306 ExpectRtpCapabilitySupport(RtpExtension::kVideoTimingUri, true);
307}
308
309TEST_F(WebRtcVideoEngineTest, SupportsFrameMarkingHeaderExtension) {
310 ExpectRtpCapabilitySupport(RtpExtension::kFrameMarkingUri, true);
Johannes Krond0b69a82018-12-03 14:18:53 +0100311}
312
313TEST_F(WebRtcVideoEngineTest, SupportsColorSpaceHeaderExtension) {
Elad Alon157540a2019-02-08 23:37:52 +0100314 ExpectRtpCapabilitySupport(RtpExtension::kColorSpaceUri, true);
315}
316
Elad Alonccb9b752019-02-19 13:01:31 +0100317TEST_F(WebRtcVideoEngineTest, AdvertiseGenericDescriptor00) {
318 ExpectRtpCapabilitySupport(RtpExtension::kGenericFrameDescriptorUri00, false);
319}
320
321TEST_F(WebRtcVideoEngineTest, AdvertiseGenericDescriptor01) {
322 ExpectRtpCapabilitySupport(RtpExtension::kGenericFrameDescriptorUri01, false);
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700323}
324
philipel1e054862018-10-08 16:13:53 +0200325class WebRtcVideoEngineTestWithGenericDescriptor
326 : public WebRtcVideoEngineTest {
327 public:
328 WebRtcVideoEngineTestWithGenericDescriptor()
329 : WebRtcVideoEngineTest("WebRTC-GenericDescriptorAdvertised/Enabled/") {}
330};
331
Elad Alonccb9b752019-02-19 13:01:31 +0100332TEST_F(WebRtcVideoEngineTestWithGenericDescriptor,
333 AdvertiseGenericDescriptor00) {
334 ExpectRtpCapabilitySupport(RtpExtension::kGenericFrameDescriptorUri00, true);
335}
336
337TEST_F(WebRtcVideoEngineTestWithGenericDescriptor,
338 AdvertiseGenericDescriptor01) {
339 ExpectRtpCapabilitySupport(RtpExtension::kGenericFrameDescriptorUri01, true);
philipel1e054862018-10-08 16:13:53 +0200340}
341
eladalonf1841382017-06-12 01:16:46 -0700342TEST_F(WebRtcVideoEngineTest, CVOSetHeaderExtensionBeforeCapturer) {
Niels Möller731a2c22018-07-30 15:08:07 +0200343 // Allocate the source first to prevent early destruction before channel's
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700344 // dtor is called.
Niels Möller731a2c22018-07-30 15:08:07 +0200345 testing::NiceMock<MockVideoSource> video_source;
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700346
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200347 encoder_factory_->AddSupportedVideoCodecType("VP8");
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700348
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200349 std::unique_ptr<VideoMediaChannel> channel(
350 SetSendParamsWithAllSupportedCodecs());
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700351 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(kSsrc)));
352
353 // Add CVO extension.
354 const int id = 1;
magjed509e4fe2016-11-18 01:34:11 -0800355 cricket::VideoSendParameters parameters;
356 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200357 parameters.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -0700358 RtpExtension(RtpExtension::kVideoRotationUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200359 EXPECT_TRUE(channel->SetSendParameters(parameters));
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700360
Niels Möller731a2c22018-07-30 15:08:07 +0200361 EXPECT_CALL(
362 video_source,
363 AddOrUpdateSink(testing::_,
364 Field(&rtc::VideoSinkWants::rotation_applied, false)));
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700365 // Set capturer.
Niels Möller731a2c22018-07-30 15:08:07 +0200366 EXPECT_TRUE(channel->SetVideoSend(kSsrc, nullptr, &video_source));
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700367
368 // Verify capturer has turned off applying rotation.
Niels Möller731a2c22018-07-30 15:08:07 +0200369 testing::Mock::VerifyAndClear(&video_source);
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700370
371 // Verify removing header extension turns on applying rotation.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200372 parameters.extensions.clear();
Niels Möller731a2c22018-07-30 15:08:07 +0200373 EXPECT_CALL(
374 video_source,
375 AddOrUpdateSink(testing::_,
376 Field(&rtc::VideoSinkWants::rotation_applied, true)));
377
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200378 EXPECT_TRUE(channel->SetSendParameters(parameters));
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700379}
380
eladalonf1841382017-06-12 01:16:46 -0700381TEST_F(WebRtcVideoEngineTest, CVOSetHeaderExtensionBeforeAddSendStream) {
Niels Möller731a2c22018-07-30 15:08:07 +0200382 // Allocate the source first to prevent early destruction before channel's
perkj91e1c152016-03-02 05:34:00 -0800383 // dtor is called.
Niels Möller731a2c22018-07-30 15:08:07 +0200384 testing::NiceMock<MockVideoSource> video_source;
perkj91e1c152016-03-02 05:34:00 -0800385
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200386 encoder_factory_->AddSupportedVideoCodecType("VP8");
perkj91e1c152016-03-02 05:34:00 -0800387
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200388 std::unique_ptr<VideoMediaChannel> channel(
389 SetSendParamsWithAllSupportedCodecs());
perkj91e1c152016-03-02 05:34:00 -0800390 // Add CVO extension.
391 const int id = 1;
magjed509e4fe2016-11-18 01:34:11 -0800392 cricket::VideoSendParameters parameters;
393 parameters.codecs.push_back(GetEngineCodec("VP8"));
perkj91e1c152016-03-02 05:34:00 -0800394 parameters.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -0700395 RtpExtension(RtpExtension::kVideoRotationUri, id));
perkj91e1c152016-03-02 05:34:00 -0800396 EXPECT_TRUE(channel->SetSendParameters(parameters));
397 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(kSsrc)));
398
Niels Möller731a2c22018-07-30 15:08:07 +0200399 // Set source.
400 EXPECT_CALL(
401 video_source,
402 AddOrUpdateSink(testing::_,
403 Field(&rtc::VideoSinkWants::rotation_applied, false)));
404 EXPECT_TRUE(channel->SetVideoSend(kSsrc, nullptr, &video_source));
perkj91e1c152016-03-02 05:34:00 -0800405}
406
eladalonf1841382017-06-12 01:16:46 -0700407TEST_F(WebRtcVideoEngineTest, CVOSetHeaderExtensionAfterCapturer) {
Niels Möller731a2c22018-07-30 15:08:07 +0200408 testing::NiceMock<MockVideoSource> video_source;
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700409
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200410 encoder_factory_->AddSupportedVideoCodecType("VP8");
411 encoder_factory_->AddSupportedVideoCodecType("VP9");
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700412
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200413 std::unique_ptr<VideoMediaChannel> channel(
414 SetSendParamsWithAllSupportedCodecs());
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700415 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(kSsrc)));
416
417 // Set capturer.
Niels Möller731a2c22018-07-30 15:08:07 +0200418 EXPECT_CALL(
419 video_source,
420 AddOrUpdateSink(testing::_,
421 Field(&rtc::VideoSinkWants::rotation_applied, true)));
422 EXPECT_TRUE(channel->SetVideoSend(kSsrc, nullptr, &video_source));
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700423
perkjcaafdba2016-03-20 07:34:29 -0700424 // Verify capturer has turned on applying rotation.
Niels Möller731a2c22018-07-30 15:08:07 +0200425 testing::Mock::VerifyAndClear(&video_source);
perkjcaafdba2016-03-20 07:34:29 -0700426
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700427 // Add CVO extension.
428 const int id = 1;
magjed509e4fe2016-11-18 01:34:11 -0800429 cricket::VideoSendParameters parameters;
430 parameters.codecs.push_back(GetEngineCodec("VP8"));
431 parameters.codecs.push_back(GetEngineCodec("VP9"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200432 parameters.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -0700433 RtpExtension(RtpExtension::kVideoRotationUri, id));
perkjcaafdba2016-03-20 07:34:29 -0700434 // Also remove the first codec to trigger a codec change as well.
435 parameters.codecs.erase(parameters.codecs.begin());
Niels Möller731a2c22018-07-30 15:08:07 +0200436 EXPECT_CALL(
437 video_source,
438 AddOrUpdateSink(testing::_,
439 Field(&rtc::VideoSinkWants::rotation_applied, false)));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200440 EXPECT_TRUE(channel->SetSendParameters(parameters));
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700441
442 // Verify capturer has turned off applying rotation.
Niels Möller731a2c22018-07-30 15:08:07 +0200443 testing::Mock::VerifyAndClear(&video_source);
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700444
445 // Verify removing header extension turns on applying rotation.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200446 parameters.extensions.clear();
Niels Möller731a2c22018-07-30 15:08:07 +0200447 EXPECT_CALL(
448 video_source,
449 AddOrUpdateSink(testing::_,
450 Field(&rtc::VideoSinkWants::rotation_applied, true)));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200451 EXPECT_TRUE(channel->SetSendParameters(parameters));
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700452}
453
eladalonf1841382017-06-12 01:16:46 -0700454TEST_F(WebRtcVideoEngineTest, SetSendFailsBeforeSettingCodecs) {
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200455 encoder_factory_->AddSupportedVideoCodecType("VP8");
456
Sebastian Jansson84848f22018-11-16 10:40:36 +0100457 std::unique_ptr<VideoMediaChannel> channel(engine_.CreateMediaChannel(
Benjamin Wrightbfb444c2018-10-15 10:20:24 -0700458 call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions()));
pbos@webrtc.org5301b0f2014-07-17 08:51:46 +0000459
460 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(123)));
461
462 EXPECT_FALSE(channel->SetSend(true))
463 << "Channel should not start without codecs.";
464 EXPECT_TRUE(channel->SetSend(false))
465 << "Channel should be stoppable even without set codecs.";
466}
467
eladalonf1841382017-06-12 01:16:46 -0700468TEST_F(WebRtcVideoEngineTest, GetStatsWithoutSendCodecsSetDoesNotCrash) {
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200469 encoder_factory_->AddSupportedVideoCodecType("VP8");
470
Sebastian Jansson84848f22018-11-16 10:40:36 +0100471 std::unique_ptr<VideoMediaChannel> channel(engine_.CreateMediaChannel(
Benjamin Wrightbfb444c2018-10-15 10:20:24 -0700472 call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions()));
pbos@webrtc.orgc3d2bd22014-08-12 20:55:10 +0000473 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(123)));
474 VideoMediaInfo info;
475 channel->GetStats(&info);
476}
477
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200478TEST_F(WebRtcVideoEngineTest, UseFactoryForVp8WhenSupported) {
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200479 encoder_factory_->AddSupportedVideoCodecType("VP8");
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000480
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200481 std::unique_ptr<VideoMediaChannel> channel(
482 SetSendParamsWithAllSupportedCodecs());
Sergey Ulanove2b15012016-11-22 16:08:30 -0800483 channel->OnReadyToSend(true);
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000484
485 EXPECT_TRUE(
486 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200487 EXPECT_EQ(0, encoder_factory_->GetNumCreatedEncoders());
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000488 EXPECT_TRUE(channel->SetSend(true));
Niels Möllerd0f0f682019-01-14 09:09:53 +0100489 webrtc::test::FrameForwarder frame_forwarder;
490 cricket::FakeFrameSource frame_source(1280, 720,
491 rtc::kNumMicrosecsPerSec / 30);
492 EXPECT_TRUE(channel->SetVideoSend(kSsrc, nullptr, &frame_forwarder));
493 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
Per21d45d22016-10-30 21:37:57 +0100494 // Sending one frame will have allocate the encoder.
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200495 ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(1));
496 EXPECT_TRUE_WAIT(encoder_factory_->encoders()[0]->GetNumEncodedFrames() > 0,
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000497 kTimeout);
498
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200499 int num_created_encoders = encoder_factory_->GetNumCreatedEncoders();
Per21d45d22016-10-30 21:37:57 +0100500 EXPECT_EQ(num_created_encoders, 1);
pbos@webrtc.org86196c42015-02-16 21:02:00 +0000501
502 // Setting codecs of the same type should not reallocate any encoders
503 // (expecting a no-op).
magjed509e4fe2016-11-18 01:34:11 -0800504 cricket::VideoSendParameters parameters;
505 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200506 EXPECT_TRUE(channel->SetSendParameters(parameters));
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200507 EXPECT_EQ(num_created_encoders, encoder_factory_->GetNumCreatedEncoders());
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000508
509 // Remove stream previously added to free the external encoder instance.
510 EXPECT_TRUE(channel->RemoveSendStream(kSsrc));
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200511 EXPECT_EQ(0u, encoder_factory_->encoders().size());
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000512}
513
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200514// Test that when an encoder factory supports H264, we add an RTX
515// codec for it.
516// TODO(deadbeef): This test should be updated if/when we start
517// adding RTX codecs for unrecognized codec names.
518TEST_F(WebRtcVideoEngineTest, RtxCodecAddedForH264Codec) {
magjed725e4842016-11-16 00:48:13 -0800519 using webrtc::H264::ProfileLevelIdToString;
520 using webrtc::H264::ProfileLevelId;
521 using webrtc::H264::kLevel1;
Anders Carlsson67537952018-05-03 11:28:29 +0200522 webrtc::SdpVideoFormat h264_constrained_baseline("H264");
523 h264_constrained_baseline.parameters[kH264FmtpProfileLevelId] =
magjed725e4842016-11-16 00:48:13 -0800524 *ProfileLevelIdToString(
525 ProfileLevelId(webrtc::H264::kProfileConstrainedBaseline, kLevel1));
Anders Carlsson67537952018-05-03 11:28:29 +0200526 webrtc::SdpVideoFormat h264_constrained_high("H264");
527 h264_constrained_high.parameters[kH264FmtpProfileLevelId] =
magjed725e4842016-11-16 00:48:13 -0800528 *ProfileLevelIdToString(
529 ProfileLevelId(webrtc::H264::kProfileConstrainedHigh, kLevel1));
Anders Carlsson67537952018-05-03 11:28:29 +0200530 webrtc::SdpVideoFormat h264_high("H264");
531 h264_high.parameters[kH264FmtpProfileLevelId] = *ProfileLevelIdToString(
magjed725e4842016-11-16 00:48:13 -0800532 ProfileLevelId(webrtc::H264::kProfileHigh, kLevel1));
533
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200534 encoder_factory_->AddSupportedVideoCodec(h264_constrained_baseline);
535 encoder_factory_->AddSupportedVideoCodec(h264_constrained_high);
536 encoder_factory_->AddSupportedVideoCodec(h264_high);
Taylor Brandstetter6c3e7882016-06-29 11:14:19 -0700537
magjed725e4842016-11-16 00:48:13 -0800538 // First figure out what payload types the test codecs got assigned.
539 const std::vector<cricket::VideoCodec> codecs = engine_.codecs();
magjed509e4fe2016-11-18 01:34:11 -0800540 // Now search for RTX codecs for them. Expect that they all have associated
541 // RTX codecs.
magjed725e4842016-11-16 00:48:13 -0800542 EXPECT_TRUE(HasRtxCodec(
Anders Carlsson67537952018-05-03 11:28:29 +0200543 codecs,
544 FindMatchingCodec(codecs, cricket::VideoCodec(h264_constrained_baseline))
545 ->id));
magjed725e4842016-11-16 00:48:13 -0800546 EXPECT_TRUE(HasRtxCodec(
Anders Carlsson67537952018-05-03 11:28:29 +0200547 codecs,
548 FindMatchingCodec(codecs, cricket::VideoCodec(h264_constrained_high))
549 ->id));
magjed509e4fe2016-11-18 01:34:11 -0800550 EXPECT_TRUE(HasRtxCodec(
Anders Carlsson67537952018-05-03 11:28:29 +0200551 codecs, FindMatchingCodec(codecs, cricket::VideoCodec(h264_high))->id));
Taylor Brandstetter6c3e7882016-06-29 11:14:19 -0700552}
553
Mirko Bonadei8ef57932018-11-16 14:38:03 +0100554#if defined(RTC_ENABLE_VP9)
eladalonf1841382017-06-12 01:16:46 -0700555TEST_F(WebRtcVideoEngineTest, CanConstructDecoderForVp9EncoderFactory) {
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200556 encoder_factory_->AddSupportedVideoCodecType("VP9");
Peter Boström53eda3d2015-03-27 15:53:18 +0100557
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200558 std::unique_ptr<VideoMediaChannel> channel(
559 SetSendParamsWithAllSupportedCodecs());
Peter Boström53eda3d2015-03-27 15:53:18 +0100560
561 EXPECT_TRUE(
562 channel->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
563}
Mirko Bonadei8ef57932018-11-16 14:38:03 +0100564#endif // defined(RTC_ENABLE_VP9)
Peter Boström53eda3d2015-03-27 15:53:18 +0100565
eladalonf1841382017-06-12 01:16:46 -0700566TEST_F(WebRtcVideoEngineTest, PropagatesInputFrameTimestamp) {
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200567 encoder_factory_->AddSupportedVideoCodecType("VP8");
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100568 FakeCall* fake_call = new FakeCall();
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200569 call_.reset(fake_call);
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200570 std::unique_ptr<VideoMediaChannel> channel(
571 SetSendParamsWithAllSupportedCodecs());
qiangchenc27d89f2015-07-16 10:27:16 -0700572
573 EXPECT_TRUE(
574 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
575
Niels Möllerd0f0f682019-01-14 09:09:53 +0100576 webrtc::test::FrameForwarder frame_forwarder;
577 cricket::FakeFrameSource frame_source(1280, 720,
578 rtc::kNumMicrosecsPerSec / 60);
579 EXPECT_TRUE(channel->SetVideoSend(kSsrc, nullptr, &frame_forwarder));
qiangchenc27d89f2015-07-16 10:27:16 -0700580 channel->SetSend(true);
581
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200582 FakeVideoSendStream* stream = fake_call->GetVideoSendStreams()[0];
qiangchenc27d89f2015-07-16 10:27:16 -0700583
Niels Möllerd0f0f682019-01-14 09:09:53 +0100584 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
pbos1cb121d2015-09-14 11:38:38 -0700585 int64_t last_timestamp = stream->GetLastTimestamp();
qiangchenc27d89f2015-07-16 10:27:16 -0700586 for (int i = 0; i < 10; i++) {
Niels Möllerd0f0f682019-01-14 09:09:53 +0100587 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
pbos1cb121d2015-09-14 11:38:38 -0700588 int64_t timestamp = stream->GetLastTimestamp();
qiangchenc27d89f2015-07-16 10:27:16 -0700589 int64_t interval = timestamp - last_timestamp;
590
591 // Precision changes from nanosecond to millisecond.
592 // Allow error to be no more than 1.
593 EXPECT_NEAR(cricket::VideoFormat::FpsToInterval(60) / 1E6, interval, 1);
594
595 last_timestamp = timestamp;
596 }
597
Niels Möllerd0f0f682019-01-14 09:09:53 +0100598 frame_forwarder.IncomingCapturedFrame(
599 frame_source.GetFrame(1280, 720, webrtc::VideoRotation::kVideoRotation_0,
600 rtc::kNumMicrosecsPerSec / 30));
qiangchenc27d89f2015-07-16 10:27:16 -0700601 last_timestamp = stream->GetLastTimestamp();
602 for (int i = 0; i < 10; i++) {
Niels Möllerd0f0f682019-01-14 09:09:53 +0100603 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame(
604 1280, 720, webrtc::VideoRotation::kVideoRotation_0,
605 rtc::kNumMicrosecsPerSec / 30));
pbos1cb121d2015-09-14 11:38:38 -0700606 int64_t timestamp = stream->GetLastTimestamp();
qiangchenc27d89f2015-07-16 10:27:16 -0700607 int64_t interval = timestamp - last_timestamp;
608
609 // Precision changes from nanosecond to millisecond.
610 // Allow error to be no more than 1.
611 EXPECT_NEAR(cricket::VideoFormat::FpsToInterval(30) / 1E6, interval, 1);
612
613 last_timestamp = timestamp;
614 }
615
616 // Remove stream previously added to free the external encoder instance.
617 EXPECT_TRUE(channel->RemoveSendStream(kSsrc));
618}
619
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200620void WebRtcVideoEngineTest::AssignDefaultAptRtxTypes() {
621 std::vector<VideoCodec> engine_codecs = engine_.codecs();
622 RTC_DCHECK(!engine_codecs.empty());
623 for (const cricket::VideoCodec& codec : engine_codecs) {
624 if (codec.name == "rtx") {
625 int associated_payload_type;
626 if (codec.GetParam(kCodecParamAssociatedPayloadType,
627 &associated_payload_type)) {
628 default_apt_rtx_types_[associated_payload_type] = codec.id;
629 }
630 }
631 }
632}
633
634void WebRtcVideoEngineTest::AssignDefaultCodec() {
635 std::vector<VideoCodec> engine_codecs = engine_.codecs();
636 RTC_DCHECK(!engine_codecs.empty());
637 bool codec_set = false;
638 for (const cricket::VideoCodec& codec : engine_codecs) {
639 if (!codec_set && codec.name != "rtx" && codec.name != "red" &&
640 codec.name != "ulpfec") {
641 default_codec_ = codec;
642 codec_set = true;
643 }
644 }
645
646 RTC_DCHECK(codec_set);
647}
648
Oleh Prypina40f8242017-12-21 13:32:23 +0100649size_t WebRtcVideoEngineTest::GetEngineCodecIndex(
650 const std::string& name) const {
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +0100651 const std::vector<cricket::VideoCodec> codecs = engine_.codecs();
652 for (size_t i = 0; i < codecs.size(); ++i) {
653 const cricket::VideoCodec engine_codec = codecs[i];
Niels Möller039743e2018-10-23 10:07:25 +0200654 if (!absl::EqualsIgnoreCase(name, engine_codec.name))
Magnus Jedvert8deb8182017-10-05 13:13:32 +0200655 continue;
656 // The tests only use H264 Constrained Baseline. Make sure we don't return
657 // an internal H264 codec from the engine with a different H264 profile.
Niels Möller039743e2018-10-23 10:07:25 +0200658 if (absl::EqualsIgnoreCase(name.c_str(), kH264CodecName)) {
Danil Chapovalov00c71832018-06-15 15:58:38 +0200659 const absl::optional<webrtc::H264::ProfileLevelId> profile_level_id =
Magnus Jedvert8deb8182017-10-05 13:13:32 +0200660 webrtc::H264::ParseSdpProfileLevelId(engine_codec.params);
661 if (profile_level_id->profile !=
662 webrtc::H264::kProfileConstrainedBaseline) {
663 continue;
664 }
665 }
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +0100666 return i;
magjed509e4fe2016-11-18 01:34:11 -0800667 }
668 // This point should never be reached.
669 ADD_FAILURE() << "Unrecognized codec name: " << name;
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +0100670 return -1;
671}
672
673cricket::VideoCodec WebRtcVideoEngineTest::GetEngineCodec(
674 const std::string& name) const {
675 return engine_.codecs()[GetEngineCodecIndex(name)];
magjed509e4fe2016-11-18 01:34:11 -0800676}
677
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200678VideoMediaChannel*
679WebRtcVideoEngineTest::SetSendParamsWithAllSupportedCodecs() {
Sebastian Jansson84848f22018-11-16 10:40:36 +0100680 VideoMediaChannel* channel = engine_.CreateMediaChannel(
Benjamin Wrightbfb444c2018-10-15 10:20:24 -0700681 call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200682 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -0800683 // We need to look up the codec in the engine to get the correct payload type.
Anders Carlsson67537952018-05-03 11:28:29 +0200684 for (const webrtc::SdpVideoFormat& format :
685 encoder_factory_->GetSupportedFormats()) {
686 cricket::VideoCodec engine_codec = GetEngineCodec(format.name);
Steve Anton2c9ebef2019-01-28 17:27:58 -0800687 if (!absl::c_linear_search(parameters.codecs, engine_codec)) {
Anders Carlsson67537952018-05-03 11:28:29 +0200688 parameters.codecs.push_back(engine_codec);
689 }
690 }
magjed509e4fe2016-11-18 01:34:11 -0800691
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200692 EXPECT_TRUE(channel->SetSendParameters(parameters));
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000693
694 return channel;
695}
696
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200697VideoMediaChannel* WebRtcVideoEngineTest::SetRecvParamsWithSupportedCodecs(
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000698 const std::vector<VideoCodec>& codecs) {
Sebastian Jansson84848f22018-11-16 10:40:36 +0100699 VideoMediaChannel* channel = engine_.CreateMediaChannel(
Benjamin Wrightbfb444c2018-10-15 10:20:24 -0700700 call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200701 cricket::VideoRecvParameters parameters;
702 parameters.codecs = codecs;
703 EXPECT_TRUE(channel->SetRecvParameters(parameters));
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000704
705 return channel;
706}
707
Elad Alon157540a2019-02-08 23:37:52 +0100708void WebRtcVideoEngineTest::ExpectRtpCapabilitySupport(const char* uri,
709 bool supported) const {
710 const RtpCapabilities capabilities = engine_.GetCapabilities();
711 if (supported) {
712 EXPECT_THAT(capabilities.header_extensions,
713 testing::Contains(testing::Field(&RtpExtension::uri, uri)));
714 } else {
715 EXPECT_THAT(
716 capabilities.header_extensions,
717 testing::Each(testing::Field(&RtpExtension::uri, testing::StrNe(uri))));
718 }
719}
720
eladalonf1841382017-06-12 01:16:46 -0700721TEST_F(WebRtcVideoEngineTest, UsesSimulcastAdapterForVp8Factories) {
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200722 encoder_factory_->AddSupportedVideoCodecType("VP8");
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000723
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200724 std::unique_ptr<VideoMediaChannel> channel(
725 SetSendParamsWithAllSupportedCodecs());
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000726
Peter Boström0c4e06b2015-10-07 12:23:21 +0200727 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000728
Yves Gerey665174f2018-06-19 15:03:05 +0200729 EXPECT_TRUE(channel->AddSendStream(CreateSimStreamParams("cname", ssrcs)));
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000730 EXPECT_TRUE(channel->SetSend(true));
731
Niels Möller805a27e2019-01-21 12:21:27 +0100732 webrtc::test::FrameForwarder frame_forwarder;
733 cricket::FakeFrameSource frame_source(1280, 720,
734 rtc::kNumMicrosecsPerSec / 60);
735 EXPECT_TRUE(channel->SetVideoSend(ssrcs.front(), nullptr, &frame_forwarder));
736 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
pbos@webrtc.org86196c42015-02-16 21:02:00 +0000737
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200738 ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(2));
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000739
740 // Verify that encoders are configured for simulcast through adapter
741 // (increasing resolution and only configured to send one stream each).
742 int prev_width = -1;
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200743 for (size_t i = 0; i < encoder_factory_->encoders().size(); ++i) {
744 ASSERT_TRUE(encoder_factory_->encoders()[i]->WaitForInitEncode());
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000745 webrtc::VideoCodec codec_settings =
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200746 encoder_factory_->encoders()[i]->GetCodecSettings();
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000747 EXPECT_EQ(0, codec_settings.numberOfSimulcastStreams);
748 EXPECT_GT(codec_settings.width, prev_width);
749 prev_width = codec_settings.width;
750 }
pbos@webrtc.org86196c42015-02-16 21:02:00 +0000751
Niels Möllerff40b142018-04-09 08:49:14 +0200752 EXPECT_TRUE(channel->SetVideoSend(ssrcs.front(), nullptr, nullptr));
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000753
754 channel.reset();
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200755 ASSERT_EQ(0u, encoder_factory_->encoders().size());
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000756}
757
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200758TEST_F(WebRtcVideoEngineTest, ChannelWithH264CanChangeToVp8) {
759 encoder_factory_->AddSupportedVideoCodecType("VP8");
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200760 encoder_factory_->AddSupportedVideoCodecType("H264");
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000761
Niels Möllerd0f0f682019-01-14 09:09:53 +0100762 // Frame source.
763 webrtc::test::FrameForwarder frame_forwarder;
764 cricket::FakeFrameSource frame_source(1280, 720,
765 rtc::kNumMicrosecsPerSec / 30);
Niels Möller4db138e2018-04-19 09:04:13 +0200766
Sebastian Jansson84848f22018-11-16 10:40:36 +0100767 std::unique_ptr<VideoMediaChannel> channel(engine_.CreateMediaChannel(
Benjamin Wrightbfb444c2018-10-15 10:20:24 -0700768 call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions()));
Anders Carlsson67537952018-05-03 11:28:29 +0200769 cricket::VideoSendParameters parameters;
770 parameters.codecs.push_back(GetEngineCodec("H264"));
771 EXPECT_TRUE(channel->SetSendParameters(parameters));
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000772
773 EXPECT_TRUE(
774 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
Niels Möllerd0f0f682019-01-14 09:09:53 +0100775 EXPECT_TRUE(channel->SetVideoSend(kSsrc, nullptr, &frame_forwarder));
Niels Möller4db138e2018-04-19 09:04:13 +0200776 // Sending one frame will have allocate the encoder.
Niels Möllerd0f0f682019-01-14 09:09:53 +0100777 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
Niels Möller4db138e2018-04-19 09:04:13 +0200778
779 ASSERT_EQ_WAIT(1u, encoder_factory_->encoders().size(), kTimeout);
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000780
Anders Carlsson67537952018-05-03 11:28:29 +0200781 cricket::VideoSendParameters new_parameters;
782 new_parameters.codecs.push_back(GetEngineCodec("VP8"));
783 EXPECT_TRUE(channel->SetSendParameters(new_parameters));
Niels Möller4db138e2018-04-19 09:04:13 +0200784
785 // Sending one frame will switch encoder.
Niels Möllerd0f0f682019-01-14 09:09:53 +0100786 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
Niels Möller4db138e2018-04-19 09:04:13 +0200787
Anders Carlsson8a150d92018-05-14 12:40:04 +0200788 EXPECT_EQ_WAIT(1u, encoder_factory_->encoders().size(), kTimeout);
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000789}
790
eladalonf1841382017-06-12 01:16:46 -0700791TEST_F(WebRtcVideoEngineTest,
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000792 UsesSimulcastAdapterForVp8WithCombinedVP8AndH264Factory) {
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200793 encoder_factory_->AddSupportedVideoCodecType("VP8");
794 encoder_factory_->AddSupportedVideoCodecType("H264");
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000795
Sebastian Jansson84848f22018-11-16 10:40:36 +0100796 std::unique_ptr<VideoMediaChannel> channel(engine_.CreateMediaChannel(
Benjamin Wrightbfb444c2018-10-15 10:20:24 -0700797 call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions()));
magjed509e4fe2016-11-18 01:34:11 -0800798 cricket::VideoSendParameters parameters;
799 parameters.codecs.push_back(GetEngineCodec("VP8"));
800 EXPECT_TRUE(channel->SetSendParameters(parameters));
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000801
Peter Boström0c4e06b2015-10-07 12:23:21 +0200802 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000803
Yves Gerey665174f2018-06-19 15:03:05 +0200804 EXPECT_TRUE(channel->AddSendStream(CreateSimStreamParams("cname", ssrcs)));
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000805 EXPECT_TRUE(channel->SetSend(true));
806
807 // Send a fake frame, or else the media engine will configure the simulcast
808 // encoder adapter at a low-enough size that it'll only create a single
809 // encoder layer.
Niels Möller805a27e2019-01-21 12:21:27 +0100810 webrtc::test::FrameForwarder frame_forwarder;
811 cricket::FakeFrameSource frame_source(1280, 720,
812 rtc::kNumMicrosecsPerSec / 30);
813 EXPECT_TRUE(channel->SetVideoSend(ssrcs.front(), nullptr, &frame_forwarder));
814 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000815
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200816 ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(2));
817 ASSERT_TRUE(encoder_factory_->encoders()[0]->WaitForInitEncode());
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000818 EXPECT_EQ(webrtc::kVideoCodecVP8,
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200819 encoder_factory_->encoders()[0]->GetCodecSettings().codecType);
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000820
821 channel.reset();
822 // Make sure DestroyVideoEncoder was called on the factory.
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200823 EXPECT_EQ(0u, encoder_factory_->encoders().size());
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000824}
825
eladalonf1841382017-06-12 01:16:46 -0700826TEST_F(WebRtcVideoEngineTest,
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000827 DestroysNonSimulcastEncoderFromCombinedVP8AndH264Factory) {
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200828 encoder_factory_->AddSupportedVideoCodecType("VP8");
829 encoder_factory_->AddSupportedVideoCodecType("H264");
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000830
Sebastian Jansson84848f22018-11-16 10:40:36 +0100831 std::unique_ptr<VideoMediaChannel> channel(engine_.CreateMediaChannel(
Benjamin Wrightbfb444c2018-10-15 10:20:24 -0700832 call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions()));
magjed509e4fe2016-11-18 01:34:11 -0800833 cricket::VideoSendParameters parameters;
834 parameters.codecs.push_back(GetEngineCodec("H264"));
835 EXPECT_TRUE(channel->SetSendParameters(parameters));
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000836
837 EXPECT_TRUE(
838 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
Per21d45d22016-10-30 21:37:57 +0100839
840 // Send a frame of 720p. This should trigger a "real" encoder initialization.
Niels Möller805a27e2019-01-21 12:21:27 +0100841 webrtc::test::FrameForwarder frame_forwarder;
842 cricket::FakeFrameSource frame_source(1280, 720,
843 rtc::kNumMicrosecsPerSec / 30);
844 EXPECT_TRUE(channel->SetVideoSend(kSsrc, nullptr, &frame_forwarder));
845 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
Niels Möller4db138e2018-04-19 09:04:13 +0200846 ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(1));
847 ASSERT_EQ(1u, encoder_factory_->encoders().size());
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200848 ASSERT_TRUE(encoder_factory_->encoders()[0]->WaitForInitEncode());
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000849 EXPECT_EQ(webrtc::kVideoCodecH264,
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200850 encoder_factory_->encoders()[0]->GetCodecSettings().codecType);
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000851
852 channel.reset();
853 // Make sure DestroyVideoEncoder was called on the factory.
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200854 ASSERT_EQ(0u, encoder_factory_->encoders().size());
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000855}
856
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200857TEST_F(WebRtcVideoEngineTest, SimulcastEnabledForH264BehindFieldTrial) {
858 webrtc::test::ScopedFieldTrials override_field_trials_(
859 "WebRTC-H264Simulcast/Enabled/");
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200860 encoder_factory_->AddSupportedVideoCodecType("H264");
noahricfdac5162015-08-27 01:59:29 -0700861
Sebastian Jansson84848f22018-11-16 10:40:36 +0100862 std::unique_ptr<VideoMediaChannel> channel(engine_.CreateMediaChannel(
Benjamin Wrightbfb444c2018-10-15 10:20:24 -0700863 call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions()));
Anders Carlsson67537952018-05-03 11:28:29 +0200864 cricket::VideoSendParameters parameters;
865 parameters.codecs.push_back(GetEngineCodec("H264"));
866 EXPECT_TRUE(channel->SetSendParameters(parameters));
noahricfdac5162015-08-27 01:59:29 -0700867
Peter Boström0c4e06b2015-10-07 12:23:21 +0200868 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
noahricfdac5162015-08-27 01:59:29 -0700869 EXPECT_TRUE(
870 channel->AddSendStream(cricket::CreateSimStreamParams("cname", ssrcs)));
Peter Boströmce23bee2016-02-02 14:14:30 +0100871
872 // Send a frame of 720p. This should trigger a "real" encoder initialization.
Niels Möller805a27e2019-01-21 12:21:27 +0100873 webrtc::test::FrameForwarder frame_forwarder;
874 cricket::FakeFrameSource frame_source(1280, 720,
875 rtc::kNumMicrosecsPerSec / 30);
876 EXPECT_TRUE(channel->SetVideoSend(ssrcs[0], nullptr, &frame_forwarder));
877 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
Peter Boströmce23bee2016-02-02 14:14:30 +0100878
Niels Möller4db138e2018-04-19 09:04:13 +0200879 ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(1));
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200880 ASSERT_EQ(1u, encoder_factory_->encoders().size());
881 FakeWebRtcVideoEncoder* encoder = encoder_factory_->encoders()[0];
882 ASSERT_TRUE(encoder_factory_->encoders()[0]->WaitForInitEncode());
noahricfdac5162015-08-27 01:59:29 -0700883 EXPECT_EQ(webrtc::kVideoCodecH264, encoder->GetCodecSettings().codecType);
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200884 EXPECT_LT(1u, encoder->GetCodecSettings().numberOfSimulcastStreams);
Niels Möllerff40b142018-04-09 08:49:14 +0200885 EXPECT_TRUE(channel->SetVideoSend(ssrcs[0], nullptr, nullptr));
noahricfdac5162015-08-27 01:59:29 -0700886}
887
brandtrffc61182016-11-28 06:02:22 -0800888// Test that the FlexFEC field trial properly alters the output of
eladalonf1841382017-06-12 01:16:46 -0700889// WebRtcVideoEngine::codecs(), for an existing |engine_| object.
brandtrffc61182016-11-28 06:02:22 -0800890//
891// TODO(brandtr): Remove this test, when the FlexFEC field trial is gone.
eladalonf1841382017-06-12 01:16:46 -0700892TEST_F(WebRtcVideoEngineTest,
brandtrffc61182016-11-28 06:02:22 -0800893 Flexfec03SupportedAsInternalCodecBehindFieldTrial) {
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200894 encoder_factory_->AddSupportedVideoCodecType("VP8");
895
Steve Anton2c9ebef2019-01-28 17:27:58 -0800896 auto flexfec = Field("name", &VideoCodec::name, "flexfec-03");
brandtrffc61182016-11-28 06:02:22 -0800897
898 // FlexFEC is not active without field trial.
Steve Anton2c9ebef2019-01-28 17:27:58 -0800899 EXPECT_THAT(engine_.codecs(), Not(Contains(flexfec)));
brandtrffc61182016-11-28 06:02:22 -0800900
901 // FlexFEC is active with field trial.
902 webrtc::test::ScopedFieldTrials override_field_trials_(
brandtr340e3fd2017-02-28 15:43:10 -0800903 "WebRTC-FlexFEC-03-Advertised/Enabled/");
Steve Anton2c9ebef2019-01-28 17:27:58 -0800904 EXPECT_THAT(engine_.codecs(), Contains(flexfec));
brandtrffc61182016-11-28 06:02:22 -0800905}
906
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200907// Test that codecs are added in the order they are reported from the factory.
908TEST_F(WebRtcVideoEngineTest, ReportSupportedCodecs) {
909 encoder_factory_->AddSupportedVideoCodecType("VP8");
910 const char* kFakeCodecName = "FakeCodec";
911 encoder_factory_->AddSupportedVideoCodecType(kFakeCodecName);
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000912
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200913 // The last reported codec should appear after the first codec in the vector.
Oleh Prypina40f8242017-12-21 13:32:23 +0100914 const size_t vp8_index = GetEngineCodecIndex("VP8");
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200915 const size_t fake_codec_index = GetEngineCodecIndex(kFakeCodecName);
916 EXPECT_LT(vp8_index, fake_codec_index);
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000917}
918
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200919// Test that a codec that was added after the engine was initialized
brandtrffc61182016-11-28 06:02:22 -0800920// does show up in the codec list after it was added.
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200921TEST_F(WebRtcVideoEngineTest, ReportSupportedAddedCodec) {
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +0100922 const char* kFakeExternalCodecName1 = "FakeExternalCodec1";
923 const char* kFakeExternalCodecName2 = "FakeExternalCodec2";
Magnus Jedvert154ee1f2017-11-15 19:27:11 +0100924
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +0100925 // Set up external encoder factory with first codec, and initialize engine.
926 encoder_factory_->AddSupportedVideoCodecType(kFakeExternalCodecName1);
927
brandtrffc61182016-11-28 06:02:22 -0800928 std::vector<cricket::VideoCodec> codecs_before(engine_.codecs());
brandtrffc61182016-11-28 06:02:22 -0800929
930 // Add second codec.
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +0100931 encoder_factory_->AddSupportedVideoCodecType(kFakeExternalCodecName2);
brandtrffc61182016-11-28 06:02:22 -0800932 std::vector<cricket::VideoCodec> codecs_after(engine_.codecs());
Sami Kalliomäkie9a18b22018-07-13 10:28:21 +0200933 // The codec itself and RTX should have been added.
934 EXPECT_EQ(codecs_before.size() + 2, codecs_after.size());
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +0100935
936 // Check that both fake codecs are present and that the second fake codec
937 // appears after the first fake codec.
Oleh Prypina40f8242017-12-21 13:32:23 +0100938 const size_t fake_codec_index1 = GetEngineCodecIndex(kFakeExternalCodecName1);
939 const size_t fake_codec_index2 = GetEngineCodecIndex(kFakeExternalCodecName2);
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +0100940 EXPECT_LT(fake_codec_index1, fake_codec_index2);
brandtrffc61182016-11-28 06:02:22 -0800941}
942
Sami Kalliomäkie9a18b22018-07-13 10:28:21 +0200943TEST_F(WebRtcVideoEngineTest, ReportRtxForExternalCodec) {
944 const char* kFakeCodecName = "FakeCodec";
945 encoder_factory_->AddSupportedVideoCodecType(kFakeCodecName);
946
947 const size_t fake_codec_index = GetEngineCodecIndex(kFakeCodecName);
948 EXPECT_EQ("rtx", engine_.codecs().at(fake_codec_index + 1).name);
949}
950
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200951TEST_F(WebRtcVideoEngineTest, RegisterDecodersIfSupported) {
952 encoder_factory_->AddSupportedVideoCodecType("VP8");
Anders Carlsson67537952018-05-03 11:28:29 +0200953 decoder_factory_->AddSupportedVideoCodecType(webrtc::SdpVideoFormat("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200954 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -0800955 parameters.codecs.push_back(GetEngineCodec("VP8"));
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000956
kwiberg686a8ef2016-02-26 03:00:35 -0800957 std::unique_ptr<VideoMediaChannel> channel(
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200958 SetRecvParamsWithSupportedCodecs(parameters.codecs));
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000959
960 EXPECT_TRUE(
961 channel->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200962 ASSERT_EQ(1u, decoder_factory_->decoders().size());
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000963
964 // Setting codecs of the same type should not reallocate the decoder.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200965 EXPECT_TRUE(channel->SetRecvParameters(parameters));
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200966 EXPECT_EQ(1, decoder_factory_->GetNumCreatedDecoders());
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000967
968 // Remove stream previously added to free the external decoder instance.
969 EXPECT_TRUE(channel->RemoveRecvStream(kSsrc));
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200970 EXPECT_EQ(0u, decoder_factory_->decoders().size());
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000971}
972
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200973// Verifies that we can set up decoders.
974TEST_F(WebRtcVideoEngineTest, RegisterH264DecoderIfSupported) {
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000975 // TODO(pbos): Do not assume that encoder/decoder support is symmetric. We
976 // can't even query the WebRtcVideoDecoderFactory for supported codecs.
977 // For now we add a FakeWebRtcVideoEncoderFactory to add H264 to supported
978 // codecs.
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200979 encoder_factory_->AddSupportedVideoCodecType("H264");
Anders Carlsson67537952018-05-03 11:28:29 +0200980 decoder_factory_->AddSupportedVideoCodecType(webrtc::SdpVideoFormat("H264"));
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000981 std::vector<cricket::VideoCodec> codecs;
magjed509e4fe2016-11-18 01:34:11 -0800982 codecs.push_back(GetEngineCodec("H264"));
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000983
kwiberg686a8ef2016-02-26 03:00:35 -0800984 std::unique_ptr<VideoMediaChannel> channel(
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200985 SetRecvParamsWithSupportedCodecs(codecs));
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000986
987 EXPECT_TRUE(
988 channel->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200989 ASSERT_EQ(1u, decoder_factory_->decoders().size());
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000990}
991
Jonas Oreland49ac5952018-09-26 16:04:32 +0200992// Tests when GetSources is called with non-existing ssrc, it will return an
993// empty list of RtpSource without crashing.
994TEST_F(WebRtcVideoEngineTest, GetSourcesWithNonExistingSsrc) {
995 // Setup an recv stream with |kSsrc|.
996 encoder_factory_->AddSupportedVideoCodecType("VP8");
997 decoder_factory_->AddSupportedVideoCodecType(webrtc::SdpVideoFormat("VP8"));
998 cricket::VideoRecvParameters parameters;
999 parameters.codecs.push_back(GetEngineCodec("VP8"));
1000 std::unique_ptr<VideoMediaChannel> channel(
1001 SetRecvParamsWithSupportedCodecs(parameters.codecs));
1002
1003 EXPECT_TRUE(
1004 channel->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
1005
1006 // Call GetSources with |kSsrc + 1| which doesn't exist.
1007 std::vector<webrtc::RtpSource> sources = channel->GetSources(kSsrc + 1);
1008 EXPECT_EQ(0u, sources.size());
1009}
1010
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001011TEST(WebRtcVideoEngineNewVideoCodecFactoryTest, NullFactories) {
1012 std::unique_ptr<webrtc::VideoEncoderFactory> encoder_factory;
1013 std::unique_ptr<webrtc::VideoDecoderFactory> decoder_factory;
Jiawei Ouc2ebe212018-11-08 10:02:56 -08001014 std::unique_ptr<webrtc::VideoBitrateAllocatorFactory> rate_allocator_factory;
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001015 WebRtcVideoEngine engine(std::move(encoder_factory),
Jiawei Ouc2ebe212018-11-08 10:02:56 -08001016 std::move(decoder_factory),
1017 std::move(rate_allocator_factory));
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001018 EXPECT_EQ(0u, engine.codecs().size());
1019}
1020
1021TEST(WebRtcVideoEngineNewVideoCodecFactoryTest, EmptyFactories) {
1022 // |engine| take ownership of the factories.
Emircan Uysalerdbcac7f2017-10-30 23:10:12 -07001023 webrtc::MockVideoEncoderFactory* encoder_factory =
1024 new webrtc::MockVideoEncoderFactory();
1025 webrtc::MockVideoDecoderFactory* decoder_factory =
1026 new webrtc::MockVideoDecoderFactory();
Jiawei Ouc2ebe212018-11-08 10:02:56 -08001027 webrtc::MockVideoBitrateAllocatorFactory* rate_allocator_factory =
1028 new webrtc::MockVideoBitrateAllocatorFactory();
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001029 WebRtcVideoEngine engine(
1030 (std::unique_ptr<webrtc::VideoEncoderFactory>(encoder_factory)),
Jiawei Ouc2ebe212018-11-08 10:02:56 -08001031 (std::unique_ptr<webrtc::VideoDecoderFactory>(decoder_factory)),
1032 (std::unique_ptr<webrtc::VideoBitrateAllocatorFactory>(
1033 rate_allocator_factory)));
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001034 EXPECT_CALL(*encoder_factory, GetSupportedFormats());
1035 EXPECT_EQ(0u, engine.codecs().size());
1036 EXPECT_CALL(*encoder_factory, Die());
1037 EXPECT_CALL(*decoder_factory, Die());
Jiawei Ouc2ebe212018-11-08 10:02:56 -08001038 EXPECT_CALL(*rate_allocator_factory, Die());
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001039}
1040
1041// Test full behavior in the video engine when video codec factories of the new
1042// type are injected supporting the single codec Vp8. Check the returned codecs
1043// from the engine and that we will create a Vp8 encoder and decoder using the
1044// new factories.
1045TEST(WebRtcVideoEngineNewVideoCodecFactoryTest, Vp8) {
1046 // |engine| take ownership of the factories.
Emircan Uysalerdbcac7f2017-10-30 23:10:12 -07001047 webrtc::MockVideoEncoderFactory* encoder_factory =
1048 new webrtc::MockVideoEncoderFactory();
1049 webrtc::MockVideoDecoderFactory* decoder_factory =
1050 new webrtc::MockVideoDecoderFactory();
Jiawei Ouc2ebe212018-11-08 10:02:56 -08001051 webrtc::MockVideoBitrateAllocatorFactory* rate_allocator_factory =
1052 new webrtc::MockVideoBitrateAllocatorFactory();
1053 EXPECT_CALL(*rate_allocator_factory,
1054 CreateVideoBitrateAllocatorProxy(Field(
1055 &webrtc::VideoCodec::codecType, webrtc::kVideoCodecVP8)))
1056 .WillOnce(testing::Return(new webrtc::MockVideoBitrateAllocator()));
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001057 WebRtcVideoEngine engine(
1058 (std::unique_ptr<webrtc::VideoEncoderFactory>(encoder_factory)),
Jiawei Ouc2ebe212018-11-08 10:02:56 -08001059 (std::unique_ptr<webrtc::VideoDecoderFactory>(decoder_factory)),
1060 (std::unique_ptr<webrtc::VideoBitrateAllocatorFactory>(
1061 rate_allocator_factory)));
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001062 const webrtc::SdpVideoFormat vp8_format("VP8");
1063 const std::vector<webrtc::SdpVideoFormat> supported_formats = {vp8_format};
1064 EXPECT_CALL(*encoder_factory, GetSupportedFormats())
1065 .WillRepeatedly(testing::Return(supported_formats));
1066
1067 // Verify the codecs from the engine.
1068 const std::vector<VideoCodec> engine_codecs = engine.codecs();
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +01001069 // Verify default codecs has been added correctly.
1070 EXPECT_EQ(5u, engine_codecs.size());
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001071 EXPECT_EQ("VP8", engine_codecs.at(0).name);
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +01001072
1073 // RTX codec for VP8.
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001074 EXPECT_EQ("rtx", engine_codecs.at(1).name);
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +01001075 int vp8_associated_payload;
1076 EXPECT_TRUE(engine_codecs.at(1).GetParam(kCodecParamAssociatedPayloadType,
1077 &vp8_associated_payload));
1078 EXPECT_EQ(vp8_associated_payload, engine_codecs.at(0).id);
1079
1080 EXPECT_EQ(kRedCodecName, engine_codecs.at(2).name);
1081
1082 // RTX codec for RED.
1083 EXPECT_EQ("rtx", engine_codecs.at(3).name);
1084 int red_associated_payload;
1085 EXPECT_TRUE(engine_codecs.at(3).GetParam(kCodecParamAssociatedPayloadType,
1086 &red_associated_payload));
1087 EXPECT_EQ(red_associated_payload, engine_codecs.at(2).id);
1088
1089 EXPECT_EQ(kUlpfecCodecName, engine_codecs.at(4).name);
1090
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001091 int associated_payload_type;
1092 EXPECT_TRUE(engine_codecs.at(1).GetParam(
1093 cricket::kCodecParamAssociatedPayloadType, &associated_payload_type));
1094 EXPECT_EQ(engine_codecs.at(0).id, associated_payload_type);
1095 // Verify default parameters has been added to the VP8 codec.
1096 VerifyCodecHasDefaultFeedbackParams(engine_codecs.at(0));
1097
1098 // Mock encoder creation. |engine| take ownership of the encoder.
Mirta Dvornicic1ec2a162018-12-10 09:47:34 +00001099 webrtc::VideoEncoderFactory::CodecInfo codec_info;
1100 codec_info.is_hardware_accelerated = false;
1101 codec_info.has_internal_source = false;
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001102 const webrtc::SdpVideoFormat format("VP8");
Mirta Dvornicic1ec2a162018-12-10 09:47:34 +00001103 EXPECT_CALL(*encoder_factory, QueryVideoEncoder(format))
1104 .WillRepeatedly(testing::Return(codec_info));
Anders Carlsson67537952018-05-03 11:28:29 +02001105 FakeWebRtcVideoEncoder* const encoder = new FakeWebRtcVideoEncoder(nullptr);
Niels Möllerc572ff32018-11-07 08:43:50 +01001106 rtc::Event encoder_created;
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001107 EXPECT_CALL(*encoder_factory, CreateVideoEncoderProxy(format))
Niels Möller4db138e2018-04-19 09:04:13 +02001108 .WillOnce(
1109 ::testing::DoAll(::testing::InvokeWithoutArgs(
1110 [&encoder_created]() { encoder_created.Set(); }),
1111 ::testing::Return(encoder)));
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001112
1113 // Mock decoder creation. |engine| take ownership of the decoder.
Anders Carlsson67537952018-05-03 11:28:29 +02001114 FakeWebRtcVideoDecoder* const decoder = new FakeWebRtcVideoDecoder(nullptr);
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001115 EXPECT_CALL(*decoder_factory, CreateVideoDecoderProxy(format))
1116 .WillOnce(testing::Return(decoder));
1117
1118 // Create a call.
1119 webrtc::RtcEventLogNullImpl event_log;
1120 std::unique_ptr<webrtc::Call> call(
1121 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
1122
1123 // Create send channel.
1124 const int send_ssrc = 123;
Sebastian Jansson84848f22018-11-16 10:40:36 +01001125 std::unique_ptr<VideoMediaChannel> send_channel(engine.CreateMediaChannel(
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07001126 call.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions()));
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001127 cricket::VideoSendParameters send_parameters;
1128 send_parameters.codecs.push_back(engine_codecs.at(0));
1129 EXPECT_TRUE(send_channel->SetSendParameters(send_parameters));
1130 send_channel->OnReadyToSend(true);
1131 EXPECT_TRUE(
1132 send_channel->AddSendStream(StreamParams::CreateLegacy(send_ssrc)));
1133 EXPECT_TRUE(send_channel->SetSend(true));
1134
Niels Möller4db138e2018-04-19 09:04:13 +02001135 // Set capturer.
Niels Möller805a27e2019-01-21 12:21:27 +01001136 webrtc::test::FrameForwarder frame_forwarder;
1137 cricket::FakeFrameSource frame_source(1280, 720,
1138 rtc::kNumMicrosecsPerSec / 30);
1139 EXPECT_TRUE(send_channel->SetVideoSend(send_ssrc, nullptr, &frame_forwarder));
Niels Möller4db138e2018-04-19 09:04:13 +02001140 // Sending one frame will allocate the encoder.
Niels Möller805a27e2019-01-21 12:21:27 +01001141 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
Niels Möller4db138e2018-04-19 09:04:13 +02001142 encoder_created.Wait(kTimeout);
1143
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001144 // Create recv channel.
1145 const int recv_ssrc = 321;
Sebastian Jansson84848f22018-11-16 10:40:36 +01001146 std::unique_ptr<VideoMediaChannel> recv_channel(engine.CreateMediaChannel(
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07001147 call.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions()));
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001148 cricket::VideoRecvParameters recv_parameters;
1149 recv_parameters.codecs.push_back(engine_codecs.at(0));
1150 EXPECT_TRUE(recv_channel->SetRecvParameters(recv_parameters));
1151 EXPECT_TRUE(recv_channel->AddRecvStream(
1152 cricket::StreamParams::CreateLegacy(recv_ssrc)));
1153
1154 // Remove streams previously added to free the encoder and decoder instance.
1155 EXPECT_CALL(*encoder_factory, Die());
1156 EXPECT_CALL(*decoder_factory, Die());
Jiawei Ouc2ebe212018-11-08 10:02:56 -08001157 EXPECT_CALL(*rate_allocator_factory, Die());
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001158 EXPECT_TRUE(send_channel->RemoveSendStream(send_ssrc));
1159 EXPECT_TRUE(recv_channel->RemoveRecvStream(recv_ssrc));
1160}
1161
Magnus Jedvert7501b1c2017-11-09 13:43:42 +01001162// Test behavior when decoder factory fails to create a decoder (returns null).
1163TEST(WebRtcVideoEngineNewVideoCodecFactoryTest, NullDecoder) {
1164 // |engine| take ownership of the factories.
1165 webrtc::MockVideoEncoderFactory* encoder_factory =
Jiawei Ouc2ebe212018-11-08 10:02:56 -08001166 new webrtc::MockVideoEncoderFactory();
Magnus Jedvert7501b1c2017-11-09 13:43:42 +01001167 webrtc::MockVideoDecoderFactory* decoder_factory =
Jiawei Ouc2ebe212018-11-08 10:02:56 -08001168 new webrtc::MockVideoDecoderFactory();
1169 webrtc::MockVideoBitrateAllocatorFactory* rate_allocator_factory =
1170 new webrtc::MockVideoBitrateAllocatorFactory();
Magnus Jedvert7501b1c2017-11-09 13:43:42 +01001171 WebRtcVideoEngine engine(
1172 (std::unique_ptr<webrtc::VideoEncoderFactory>(encoder_factory)),
Jiawei Ouc2ebe212018-11-08 10:02:56 -08001173 (std::unique_ptr<webrtc::VideoDecoderFactory>(decoder_factory)),
1174 (std::unique_ptr<webrtc::VideoBitrateAllocatorFactory>(
1175 rate_allocator_factory)));
Magnus Jedvert7501b1c2017-11-09 13:43:42 +01001176 const webrtc::SdpVideoFormat vp8_format("VP8");
1177 const std::vector<webrtc::SdpVideoFormat> supported_formats = {vp8_format};
1178 EXPECT_CALL(*encoder_factory, GetSupportedFormats())
1179 .WillRepeatedly(testing::Return(supported_formats));
1180
1181 // Decoder creation fails.
1182 EXPECT_CALL(*decoder_factory, CreateVideoDecoderProxy(testing::_))
1183 .WillOnce(testing::Return(nullptr));
1184
1185 // Create a call.
1186 webrtc::RtcEventLogNullImpl event_log;
1187 std::unique_ptr<webrtc::Call> call(
1188 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
1189
1190 // Create recv channel.
1191 const int recv_ssrc = 321;
Sebastian Jansson84848f22018-11-16 10:40:36 +01001192 std::unique_ptr<VideoMediaChannel> recv_channel(engine.CreateMediaChannel(
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07001193 call.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions()));
Magnus Jedvert7501b1c2017-11-09 13:43:42 +01001194 cricket::VideoRecvParameters recv_parameters;
1195 recv_parameters.codecs.push_back(engine.codecs().front());
1196 EXPECT_TRUE(recv_channel->SetRecvParameters(recv_parameters));
1197 EXPECT_TRUE(recv_channel->AddRecvStream(
1198 cricket::StreamParams::CreateLegacy(recv_ssrc)));
1199
1200 // Remove streams previously added to free the encoder and decoder instance.
1201 EXPECT_TRUE(recv_channel->RemoveRecvStream(recv_ssrc));
1202}
1203
eladalonf1841382017-06-12 01:16:46 -07001204TEST_F(WebRtcVideoEngineTest, DISABLED_RecreatesEncoderOnContentTypeChange) {
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001205 encoder_factory_->AddSupportedVideoCodecType("VP8");
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001206 std::unique_ptr<FakeCall> fake_call(new FakeCall());
Anders Carlsson5f2bb622018-05-14 09:48:06 +02001207 std::unique_ptr<VideoMediaChannel> channel(
1208 SetSendParamsWithAllSupportedCodecs());
sprangf24a0642017-02-28 13:23:26 -08001209 ASSERT_TRUE(
1210 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
1211 cricket::VideoCodec codec = GetEngineCodec("VP8");
1212 cricket::VideoSendParameters parameters;
1213 parameters.codecs.push_back(codec);
1214 channel->OnReadyToSend(true);
1215 channel->SetSend(true);
1216 ASSERT_TRUE(channel->SetSendParameters(parameters));
1217
Niels Möller805a27e2019-01-21 12:21:27 +01001218 webrtc::test::FrameForwarder frame_forwarder;
1219 cricket::FakeFrameSource frame_source(1280, 720,
1220 rtc::kNumMicrosecsPerSec / 30);
sprangf24a0642017-02-28 13:23:26 -08001221 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01001222 EXPECT_TRUE(channel->SetVideoSend(kSsrc, &options, &frame_forwarder));
sprangf24a0642017-02-28 13:23:26 -08001223
Niels Möller805a27e2019-01-21 12:21:27 +01001224 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001225 ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(1));
Niels Möllere3cf3d02018-06-13 11:52:16 +02001226 EXPECT_EQ(webrtc::VideoCodecMode::kRealtimeVideo,
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001227 encoder_factory_->encoders().back()->GetCodecSettings().mode);
sprangf24a0642017-02-28 13:23:26 -08001228
Niels Möller805a27e2019-01-21 12:21:27 +01001229 EXPECT_TRUE(channel->SetVideoSend(kSsrc, &options, &frame_forwarder));
1230 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
sprangf24a0642017-02-28 13:23:26 -08001231 // No change in content type, keep current encoder.
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001232 EXPECT_EQ(1, encoder_factory_->GetNumCreatedEncoders());
sprangf24a0642017-02-28 13:23:26 -08001233
1234 options.is_screencast.emplace(true);
Niels Möller805a27e2019-01-21 12:21:27 +01001235 EXPECT_TRUE(channel->SetVideoSend(kSsrc, &options, &frame_forwarder));
1236 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
sprangf24a0642017-02-28 13:23:26 -08001237 // Change to screen content, recreate encoder. For the simulcast encoder
1238 // adapter case, this will result in two calls since InitEncode triggers a
1239 // a new instance.
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001240 ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(2));
Niels Möllere3cf3d02018-06-13 11:52:16 +02001241 EXPECT_EQ(webrtc::VideoCodecMode::kScreensharing,
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001242 encoder_factory_->encoders().back()->GetCodecSettings().mode);
sprangf24a0642017-02-28 13:23:26 -08001243
Niels Möller805a27e2019-01-21 12:21:27 +01001244 EXPECT_TRUE(channel->SetVideoSend(kSsrc, &options, &frame_forwarder));
1245 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
sprangf24a0642017-02-28 13:23:26 -08001246 // Still screen content, no need to update encoder.
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001247 EXPECT_EQ(2, encoder_factory_->GetNumCreatedEncoders());
sprangf24a0642017-02-28 13:23:26 -08001248
1249 options.is_screencast.emplace(false);
1250 options.video_noise_reduction.emplace(false);
Niels Möller805a27e2019-01-21 12:21:27 +01001251 EXPECT_TRUE(channel->SetVideoSend(kSsrc, &options, &frame_forwarder));
sprangf24a0642017-02-28 13:23:26 -08001252 // Change back to regular video content, update encoder. Also change
1253 // a non |is_screencast| option just to verify it doesn't affect recreation.
Niels Möller805a27e2019-01-21 12:21:27 +01001254 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001255 ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(3));
Niels Möllere3cf3d02018-06-13 11:52:16 +02001256 EXPECT_EQ(webrtc::VideoCodecMode::kRealtimeVideo,
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001257 encoder_factory_->encoders().back()->GetCodecSettings().mode);
sprangf24a0642017-02-28 13:23:26 -08001258
1259 // Remove stream previously added to free the external encoder instance.
1260 EXPECT_TRUE(channel->RemoveSendStream(kSsrc));
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001261 EXPECT_EQ(0u, encoder_factory_->encoders().size());
sprangf24a0642017-02-28 13:23:26 -08001262}
1263
Niels Möller6557d0c2018-04-11 15:18:34 +02001264class WebRtcVideoChannelBaseTest : public testing::Test {
1265 protected:
1266 WebRtcVideoChannelBaseTest()
Jonas Oreland49ac5952018-09-26 16:04:32 +02001267 : engine_(webrtc::CreateBuiltinVideoEncoderFactory(),
Jiawei Ouc2ebe212018-11-08 10:02:56 -08001268 webrtc::CreateBuiltinVideoDecoderFactory(),
1269 webrtc::CreateBuiltinVideoBitrateAllocatorFactory()) {}
Niels Möller6557d0c2018-04-11 15:18:34 +02001270
1271 virtual void SetUp() {
Jonas Oreland49ac5952018-09-26 16:04:32 +02001272 // One testcase calls SetUp in a loop, only create call_ once.
1273 if (!call_) {
1274 call_.reset(webrtc::Call::Create(webrtc::Call::Config(&event_log_)));
1275 }
Niels Möller6557d0c2018-04-11 15:18:34 +02001276 cricket::MediaConfig media_config;
1277 // Disabling cpu overuse detection actually disables quality scaling too; it
1278 // implies DegradationPreference kMaintainResolution. Automatic scaling
1279 // needs to be disabled, otherwise, tests which check the size of received
1280 // frames become flaky.
1281 media_config.video.enable_cpu_adaptation = false;
Sebastian Jansson84848f22018-11-16 10:40:36 +01001282 channel_.reset(
1283 static_cast<cricket::WebRtcVideoChannel*>(engine_.CreateMediaChannel(
1284 call_.get(), media_config, cricket::VideoOptions(),
1285 webrtc::CryptoOptions())));
Niels Möller6557d0c2018-04-11 15:18:34 +02001286 channel_->OnReadyToSend(true);
1287 EXPECT_TRUE(channel_.get() != NULL);
1288 network_interface_.SetDestination(channel_.get());
Anton Sukhanov98a462c2018-10-17 13:15:42 -07001289 channel_->SetInterface(&network_interface_, /*media_transport=*/nullptr);
Niels Möller6557d0c2018-04-11 15:18:34 +02001290 cricket::VideoRecvParameters parameters;
1291 parameters.codecs = engine_.codecs();
1292 channel_->SetRecvParameters(parameters);
1293 EXPECT_TRUE(channel_->AddSendStream(DefaultSendStreamParams()));
Niels Möller805a27e2019-01-21 12:21:27 +01001294 frame_forwarder_ = absl::make_unique<webrtc::test::FrameForwarder>();
1295 frame_source_ = absl::make_unique<cricket::FakeFrameSource>(
1296 640, 480, rtc::kNumMicrosecsPerSec / kFramerate);
1297 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, nullptr, frame_forwarder_.get()));
Niels Möller6557d0c2018-04-11 15:18:34 +02001298 }
1299
1300 // Utility method to setup an additional stream to send and receive video.
1301 // Used to test send and recv between two streams.
1302 void SetUpSecondStream() {
1303 SetUpSecondStreamWithNoRecv();
1304 // Setup recv for second stream.
1305 EXPECT_TRUE(channel_->AddRecvStream(
1306 cricket::StreamParams::CreateLegacy(kSsrc + 2)));
1307 // Make the second renderer available for use by a new stream.
1308 EXPECT_TRUE(channel_->SetSink(kSsrc + 2, &renderer2_));
1309 }
1310 // Setup an additional stream just to send video. Defer add recv stream.
1311 // This is required if you want to test unsignalled recv of video rtp packets.
1312 void SetUpSecondStreamWithNoRecv() {
1313 // SetUp() already added kSsrc make sure duplicate SSRCs cant be added.
Yves Gerey665174f2018-06-19 15:03:05 +02001314 EXPECT_TRUE(
1315 channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
Niels Möller6557d0c2018-04-11 15:18:34 +02001316 EXPECT_TRUE(channel_->SetSink(kSsrc, &renderer_));
Yves Gerey665174f2018-06-19 15:03:05 +02001317 EXPECT_FALSE(
1318 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
Niels Möller6557d0c2018-04-11 15:18:34 +02001319 EXPECT_TRUE(channel_->AddSendStream(
1320 cricket::StreamParams::CreateLegacy(kSsrc + 2)));
1321 // We dont add recv for the second stream.
1322
1323 // Setup the receive and renderer for second stream after send.
Niels Möller805a27e2019-01-21 12:21:27 +01001324 frame_forwarder_2_ = absl::make_unique<webrtc::test::FrameForwarder>();
Yves Gerey665174f2018-06-19 15:03:05 +02001325 EXPECT_TRUE(
Niels Möller805a27e2019-01-21 12:21:27 +01001326 channel_->SetVideoSend(kSsrc + 2, nullptr, frame_forwarder_2_.get()));
Niels Möller6557d0c2018-04-11 15:18:34 +02001327 }
Yves Gerey665174f2018-06-19 15:03:05 +02001328 virtual void TearDown() { channel_.reset(); }
1329 bool SetDefaultCodec() { return SetOneCodec(DefaultCodec()); }
Niels Möller6557d0c2018-04-11 15:18:34 +02001330
1331 bool SetOneCodec(const cricket::VideoCodec& codec) {
Niels Möller805a27e2019-01-21 12:21:27 +01001332 frame_source_ = absl::make_unique<cricket::FakeFrameSource>(
1333 kVideoWidth, kVideoHeight, rtc::kNumMicrosecsPerSec / kFramerate);
Niels Möller6557d0c2018-04-11 15:18:34 +02001334
1335 bool sending = channel_->sending();
1336 bool success = SetSend(false);
1337 if (success) {
1338 cricket::VideoSendParameters parameters;
1339 parameters.codecs.push_back(codec);
1340 success = channel_->SetSendParameters(parameters);
1341 }
1342 if (success) {
1343 success = SetSend(sending);
1344 }
1345 return success;
1346 }
Yves Gerey665174f2018-06-19 15:03:05 +02001347 bool SetSend(bool send) { return channel_->SetSend(send); }
Niels Möller805a27e2019-01-21 12:21:27 +01001348 void SendFrame() {
1349 if (frame_forwarder_2_) {
1350 frame_forwarder_2_->IncomingCapturedFrame(frame_source_->GetFrame());
Niels Möller6557d0c2018-04-11 15:18:34 +02001351 }
Niels Möller805a27e2019-01-21 12:21:27 +01001352 frame_forwarder_->IncomingCapturedFrame(frame_source_->GetFrame());
Niels Möller6557d0c2018-04-11 15:18:34 +02001353 }
1354 bool WaitAndSendFrame(int wait_ms) {
1355 bool ret = rtc::Thread::Current()->ProcessMessages(wait_ms);
Niels Möller805a27e2019-01-21 12:21:27 +01001356 SendFrame();
Niels Möller6557d0c2018-04-11 15:18:34 +02001357 return ret;
1358 }
Yves Gerey665174f2018-06-19 15:03:05 +02001359 int NumRtpBytes() { return network_interface_.NumRtpBytes(); }
Niels Möller6557d0c2018-04-11 15:18:34 +02001360 int NumRtpBytes(uint32_t ssrc) {
1361 return network_interface_.NumRtpBytes(ssrc);
1362 }
Yves Gerey665174f2018-06-19 15:03:05 +02001363 int NumRtpPackets() { return network_interface_.NumRtpPackets(); }
Niels Möller6557d0c2018-04-11 15:18:34 +02001364 int NumRtpPackets(uint32_t ssrc) {
1365 return network_interface_.NumRtpPackets(ssrc);
1366 }
Yves Gerey665174f2018-06-19 15:03:05 +02001367 int NumSentSsrcs() { return network_interface_.NumSentSsrcs(); }
Niels Möller6557d0c2018-04-11 15:18:34 +02001368 const rtc::CopyOnWriteBuffer* GetRtpPacket(int index) {
1369 return network_interface_.GetRtpPacket(index);
1370 }
1371 static int GetPayloadType(const rtc::CopyOnWriteBuffer* p) {
Åsa Persson23cd45a2018-07-03 10:40:40 +02001372 webrtc::RTPHeader header;
1373 EXPECT_TRUE(ParseRtpPacket(p, &header));
1374 return header.payloadType;
Niels Möller6557d0c2018-04-11 15:18:34 +02001375 }
Åsa Persson23cd45a2018-07-03 10:40:40 +02001376
Niels Möller6557d0c2018-04-11 15:18:34 +02001377 static bool ParseRtpPacket(const rtc::CopyOnWriteBuffer* p,
Åsa Persson23cd45a2018-07-03 10:40:40 +02001378 webrtc::RTPHeader* header) {
1379 std::unique_ptr<webrtc::RtpHeaderParser> parser(
1380 webrtc::RtpHeaderParser::Create());
1381 return parser->Parse(p->cdata(), p->size(), header);
Niels Möller6557d0c2018-04-11 15:18:34 +02001382 }
1383
1384 // Tests that we can send and receive frames.
1385 void SendAndReceive(const cricket::VideoCodec& codec) {
1386 EXPECT_TRUE(SetOneCodec(codec));
1387 EXPECT_TRUE(SetSend(true));
1388 EXPECT_TRUE(channel_->SetSink(kDefaultReceiveSsrc, &renderer_));
1389 EXPECT_EQ(0, renderer_.num_rendered_frames());
Niels Möller805a27e2019-01-21 12:21:27 +01001390 SendFrame();
Niels Möller6557d0c2018-04-11 15:18:34 +02001391 EXPECT_FRAME_WAIT(1, kVideoWidth, kVideoHeight, kTimeout);
1392 std::unique_ptr<const rtc::CopyOnWriteBuffer> p(GetRtpPacket(0));
1393 EXPECT_EQ(codec.id, GetPayloadType(p.get()));
1394 }
1395
1396 void SendReceiveManyAndGetStats(const cricket::VideoCodec& codec,
Yves Gerey665174f2018-06-19 15:03:05 +02001397 int duration_sec,
1398 int fps) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001399 EXPECT_TRUE(SetOneCodec(codec));
1400 EXPECT_TRUE(SetSend(true));
1401 EXPECT_TRUE(channel_->SetSink(kDefaultReceiveSsrc, &renderer_));
1402 EXPECT_EQ(0, renderer_.num_rendered_frames());
1403 for (int i = 0; i < duration_sec; ++i) {
1404 for (int frame = 1; frame <= fps; ++frame) {
1405 EXPECT_TRUE(WaitAndSendFrame(1000 / fps));
1406 EXPECT_FRAME_WAIT(frame + i * fps, kVideoWidth, kVideoHeight, kTimeout);
1407 }
1408 }
1409 std::unique_ptr<const rtc::CopyOnWriteBuffer> p(GetRtpPacket(0));
1410 EXPECT_EQ(codec.id, GetPayloadType(p.get()));
1411 }
1412
Niels Möller6557d0c2018-04-11 15:18:34 +02001413 cricket::VideoSenderInfo GetSenderStats(size_t i) {
1414 cricket::VideoMediaInfo info;
1415 EXPECT_TRUE(channel_->GetStats(&info));
1416 return info.senders[i];
1417 }
1418
1419 cricket::VideoReceiverInfo GetReceiverStats(size_t i) {
1420 cricket::VideoMediaInfo info;
1421 EXPECT_TRUE(channel_->GetStats(&info));
1422 return info.receivers[i];
1423 }
1424
1425 // Two streams one channel tests.
1426
1427 // Tests that we can send and receive frames.
1428 void TwoStreamsSendAndReceive(const cricket::VideoCodec& codec) {
1429 SetUpSecondStream();
1430 // Test sending and receiving on first stream.
1431 SendAndReceive(codec);
1432 // Test sending and receiving on second stream.
1433 EXPECT_EQ_WAIT(1, renderer2_.num_rendered_frames(), kTimeout);
1434 EXPECT_GT(NumRtpPackets(), 0);
1435 EXPECT_EQ(1, renderer2_.num_rendered_frames());
1436 }
1437
1438 cricket::VideoCodec GetEngineCodec(const std::string& name) {
1439 for (const cricket::VideoCodec& engine_codec : engine_.codecs()) {
Niels Möller039743e2018-10-23 10:07:25 +02001440 if (absl::EqualsIgnoreCase(name, engine_codec.name))
Niels Möller6557d0c2018-04-11 15:18:34 +02001441 return engine_codec;
1442 }
1443 // This point should never be reached.
1444 ADD_FAILURE() << "Unrecognized codec name: " << name;
1445 return cricket::VideoCodec();
1446 }
1447
1448 cricket::VideoCodec DefaultCodec() { return GetEngineCodec("VP8"); }
1449
1450 cricket::StreamParams DefaultSendStreamParams() {
1451 return cricket::StreamParams::CreateLegacy(kSsrc);
1452 }
1453
1454 webrtc::RtcEventLogNullImpl event_log_;
Jonas Oreland49ac5952018-09-26 16:04:32 +02001455 std::unique_ptr<webrtc::Call> call_;
Niels Möller6557d0c2018-04-11 15:18:34 +02001456 WebRtcVideoEngine engine_;
Niels Möller805a27e2019-01-21 12:21:27 +01001457
1458 std::unique_ptr<cricket::FakeFrameSource> frame_source_;
1459 std::unique_ptr<webrtc::test::FrameForwarder> frame_forwarder_;
1460 std::unique_ptr<webrtc::test::FrameForwarder> frame_forwarder_2_;
1461
Niels Möller6557d0c2018-04-11 15:18:34 +02001462 std::unique_ptr<WebRtcVideoChannel> channel_;
1463 cricket::FakeNetworkInterface network_interface_;
1464 cricket::FakeVideoRenderer renderer_;
1465
1466 // Used by test cases where 2 streams are run on the same channel.
1467 cricket::FakeVideoRenderer renderer2_;
1468};
1469
1470// Test that SetSend works.
srtee0c2eea2017-12-15 17:44:33 +01001471TEST_F(WebRtcVideoChannelBaseTest, SetSend) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001472 EXPECT_FALSE(channel_->sending());
Niels Möller805a27e2019-01-21 12:21:27 +01001473 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, nullptr, frame_forwarder_.get()));
Niels Möller6557d0c2018-04-11 15:18:34 +02001474 EXPECT_TRUE(SetOneCodec(DefaultCodec()));
1475 EXPECT_FALSE(channel_->sending());
1476 EXPECT_TRUE(SetSend(true));
1477 EXPECT_TRUE(channel_->sending());
Niels Möller805a27e2019-01-21 12:21:27 +01001478 SendFrame();
Niels Möller6557d0c2018-04-11 15:18:34 +02001479 EXPECT_TRUE_WAIT(NumRtpPackets() > 0, kTimeout);
1480 EXPECT_TRUE(SetSend(false));
1481 EXPECT_FALSE(channel_->sending());
srtee0c2eea2017-12-15 17:44:33 +01001482}
Niels Möller6557d0c2018-04-11 15:18:34 +02001483
1484// Test that SetSend fails without codecs being set.
srtee0c2eea2017-12-15 17:44:33 +01001485TEST_F(WebRtcVideoChannelBaseTest, SetSendWithoutCodecs) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001486 EXPECT_FALSE(channel_->sending());
1487 EXPECT_FALSE(SetSend(true));
1488 EXPECT_FALSE(channel_->sending());
srtee0c2eea2017-12-15 17:44:33 +01001489}
Niels Möller6557d0c2018-04-11 15:18:34 +02001490
1491// Test that we properly set the send and recv buffer sizes by the time
1492// SetSend is called.
srtee0c2eea2017-12-15 17:44:33 +01001493TEST_F(WebRtcVideoChannelBaseTest, SetSendSetsTransportBufferSizes) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001494 EXPECT_TRUE(SetOneCodec(DefaultCodec()));
1495 EXPECT_TRUE(SetSend(true));
1496 EXPECT_EQ(64 * 1024, network_interface_.sendbuf_size());
Johannes Krond38a2b82018-10-23 11:31:19 +02001497 EXPECT_EQ(256 * 1024, network_interface_.recvbuf_size());
Erik Språng820ebd02018-08-20 17:14:25 +02001498}
1499
Niels Möller6557d0c2018-04-11 15:18:34 +02001500// Test that stats work properly for a 1-1 call.
srtee0c2eea2017-12-15 17:44:33 +01001501TEST_F(WebRtcVideoChannelBaseTest, GetStats) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001502 const int kDurationSec = 3;
1503 const int kFps = 10;
1504 SendReceiveManyAndGetStats(DefaultCodec(), kDurationSec, kFps);
1505
1506 cricket::VideoMediaInfo info;
1507 EXPECT_TRUE(channel_->GetStats(&info));
1508
1509 ASSERT_EQ(1U, info.senders.size());
1510 // TODO(whyuan): bytes_sent and bytes_rcvd are different. Are both payload?
1511 // For webrtc, bytes_sent does not include the RTP header length.
1512 EXPECT_GT(info.senders[0].bytes_sent, 0);
1513 EXPECT_EQ(NumRtpPackets(), info.senders[0].packets_sent);
1514 EXPECT_EQ(0.0, info.senders[0].fraction_lost);
1515 ASSERT_TRUE(info.senders[0].codec_payload_type);
1516 EXPECT_EQ(DefaultCodec().id, *info.senders[0].codec_payload_type);
1517 EXPECT_EQ(0, info.senders[0].firs_rcvd);
1518 EXPECT_EQ(0, info.senders[0].plis_rcvd);
1519 EXPECT_EQ(0, info.senders[0].nacks_rcvd);
1520 EXPECT_EQ(kVideoWidth, info.senders[0].send_frame_width);
1521 EXPECT_EQ(kVideoHeight, info.senders[0].send_frame_height);
1522 EXPECT_GT(info.senders[0].framerate_input, 0);
1523 EXPECT_GT(info.senders[0].framerate_sent, 0);
1524
1525 EXPECT_EQ(1U, info.send_codecs.count(DefaultCodec().id));
1526 EXPECT_EQ(DefaultCodec().ToCodecParameters(),
1527 info.send_codecs[DefaultCodec().id]);
1528
1529 ASSERT_EQ(1U, info.receivers.size());
1530 EXPECT_EQ(1U, info.senders[0].ssrcs().size());
1531 EXPECT_EQ(1U, info.receivers[0].ssrcs().size());
1532 EXPECT_EQ(info.senders[0].ssrcs()[0], info.receivers[0].ssrcs()[0]);
1533 ASSERT_TRUE(info.receivers[0].codec_payload_type);
1534 EXPECT_EQ(DefaultCodec().id, *info.receivers[0].codec_payload_type);
1535 EXPECT_EQ(NumRtpBytes(), info.receivers[0].bytes_rcvd);
1536 EXPECT_EQ(NumRtpPackets(), info.receivers[0].packets_rcvd);
1537 EXPECT_EQ(0.0, info.receivers[0].fraction_lost);
1538 EXPECT_EQ(0, info.receivers[0].packets_lost);
1539 // TODO(asapersson): Not set for webrtc. Handle missing stats.
1540 // EXPECT_EQ(0, info.receivers[0].packets_concealed);
1541 EXPECT_EQ(0, info.receivers[0].firs_sent);
1542 EXPECT_EQ(0, info.receivers[0].plis_sent);
1543 EXPECT_EQ(0, info.receivers[0].nacks_sent);
1544 EXPECT_EQ(kVideoWidth, info.receivers[0].frame_width);
1545 EXPECT_EQ(kVideoHeight, info.receivers[0].frame_height);
1546 EXPECT_GT(info.receivers[0].framerate_rcvd, 0);
1547 EXPECT_GT(info.receivers[0].framerate_decoded, 0);
1548 EXPECT_GT(info.receivers[0].framerate_output, 0);
1549
1550 EXPECT_EQ(1U, info.receive_codecs.count(DefaultCodec().id));
1551 EXPECT_EQ(DefaultCodec().ToCodecParameters(),
1552 info.receive_codecs[DefaultCodec().id]);
srtee0c2eea2017-12-15 17:44:33 +01001553}
Niels Möller6557d0c2018-04-11 15:18:34 +02001554
1555// Test that stats work properly for a conf call with multiple recv streams.
srtee0c2eea2017-12-15 17:44:33 +01001556TEST_F(WebRtcVideoChannelBaseTest, GetStatsMultipleRecvStreams) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001557 cricket::FakeVideoRenderer renderer1, renderer2;
1558 EXPECT_TRUE(SetOneCodec(DefaultCodec()));
1559 cricket::VideoSendParameters parameters;
1560 parameters.codecs.push_back(DefaultCodec());
1561 parameters.conference_mode = true;
1562 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1563 EXPECT_TRUE(SetSend(true));
Yves Gerey665174f2018-06-19 15:03:05 +02001564 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
1565 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
Niels Möller6557d0c2018-04-11 15:18:34 +02001566 EXPECT_TRUE(channel_->SetSink(1, &renderer1));
1567 EXPECT_TRUE(channel_->SetSink(2, &renderer2));
1568 EXPECT_EQ(0, renderer1.num_rendered_frames());
1569 EXPECT_EQ(0, renderer2.num_rendered_frames());
1570 std::vector<uint32_t> ssrcs;
1571 ssrcs.push_back(1);
1572 ssrcs.push_back(2);
1573 network_interface_.SetConferenceMode(true, ssrcs);
Niels Möller805a27e2019-01-21 12:21:27 +01001574 SendFrame();
Niels Möller6557d0c2018-04-11 15:18:34 +02001575 EXPECT_FRAME_ON_RENDERER_WAIT(renderer1, 1, kVideoWidth, kVideoHeight,
1576 kTimeout);
1577 EXPECT_FRAME_ON_RENDERER_WAIT(renderer2, 1, kVideoWidth, kVideoHeight,
1578 kTimeout);
1579
1580 EXPECT_TRUE(channel_->SetSend(false));
1581
1582 cricket::VideoMediaInfo info;
1583 EXPECT_TRUE(channel_->GetStats(&info));
1584 ASSERT_EQ(1U, info.senders.size());
1585 // TODO(whyuan): bytes_sent and bytes_rcvd are different. Are both payload?
1586 // For webrtc, bytes_sent does not include the RTP header length.
1587 EXPECT_GT(GetSenderStats(0).bytes_sent, 0);
1588 EXPECT_EQ_WAIT(NumRtpPackets(), GetSenderStats(0).packets_sent, kTimeout);
1589 EXPECT_EQ(kVideoWidth, GetSenderStats(0).send_frame_width);
1590 EXPECT_EQ(kVideoHeight, GetSenderStats(0).send_frame_height);
1591
1592 ASSERT_EQ(2U, info.receivers.size());
1593 for (size_t i = 0; i < info.receivers.size(); ++i) {
1594 EXPECT_EQ(1U, GetReceiverStats(i).ssrcs().size());
1595 EXPECT_EQ(i + 1, GetReceiverStats(i).ssrcs()[0]);
1596 EXPECT_EQ_WAIT(NumRtpBytes(), GetReceiverStats(i).bytes_rcvd, kTimeout);
Yves Gerey665174f2018-06-19 15:03:05 +02001597 EXPECT_EQ_WAIT(NumRtpPackets(), GetReceiverStats(i).packets_rcvd, kTimeout);
Niels Möller6557d0c2018-04-11 15:18:34 +02001598 EXPECT_EQ_WAIT(kVideoWidth, GetReceiverStats(i).frame_width, kTimeout);
1599 EXPECT_EQ_WAIT(kVideoHeight, GetReceiverStats(i).frame_height, kTimeout);
1600 }
srtee0c2eea2017-12-15 17:44:33 +01001601}
Niels Möller6557d0c2018-04-11 15:18:34 +02001602
1603// Test that stats work properly for a conf call with multiple send streams.
srtee0c2eea2017-12-15 17:44:33 +01001604TEST_F(WebRtcVideoChannelBaseTest, GetStatsMultipleSendStreams) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001605 // Normal setup; note that we set the SSRC explicitly to ensure that
1606 // it will come first in the senders map.
1607 EXPECT_TRUE(SetOneCodec(DefaultCodec()));
1608 cricket::VideoSendParameters parameters;
1609 parameters.codecs.push_back(DefaultCodec());
1610 parameters.conference_mode = true;
1611 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Yves Gerey665174f2018-06-19 15:03:05 +02001612 EXPECT_TRUE(
1613 channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
Niels Möller6557d0c2018-04-11 15:18:34 +02001614 EXPECT_TRUE(channel_->SetSink(kSsrc, &renderer_));
1615 EXPECT_TRUE(SetSend(true));
Niels Möller805a27e2019-01-21 12:21:27 +01001616 SendFrame();
Niels Möller6557d0c2018-04-11 15:18:34 +02001617 EXPECT_TRUE_WAIT(NumRtpPackets() > 0, kTimeout);
1618 EXPECT_FRAME_WAIT(1, kVideoWidth, kVideoHeight, kTimeout);
1619
1620 // Add an additional capturer, and hook up a renderer to receive it.
1621 cricket::FakeVideoRenderer renderer2;
Niels Möller805a27e2019-01-21 12:21:27 +01001622 webrtc::test::FrameForwarder frame_forwarder;
Niels Möller6557d0c2018-04-11 15:18:34 +02001623 const int kTestWidth = 160;
1624 const int kTestHeight = 120;
Niels Möller805a27e2019-01-21 12:21:27 +01001625 cricket::FakeFrameSource frame_source(kTestWidth, kTestHeight,
1626 rtc::kNumMicrosecsPerSec / 5);
Yves Gerey665174f2018-06-19 15:03:05 +02001627 EXPECT_TRUE(
1628 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(5678)));
Niels Möller805a27e2019-01-21 12:21:27 +01001629 EXPECT_TRUE(channel_->SetVideoSend(5678, nullptr, &frame_forwarder));
Yves Gerey665174f2018-06-19 15:03:05 +02001630 EXPECT_TRUE(
1631 channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(5678)));
Niels Möller6557d0c2018-04-11 15:18:34 +02001632 EXPECT_TRUE(channel_->SetSink(5678, &renderer2));
Niels Möller805a27e2019-01-21 12:21:27 +01001633 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
Yves Gerey665174f2018-06-19 15:03:05 +02001634 EXPECT_FRAME_ON_RENDERER_WAIT(renderer2, 1, kTestWidth, kTestHeight,
1635 kTimeout);
Niels Möller6557d0c2018-04-11 15:18:34 +02001636
1637 // Get stats, and make sure they are correct for two senders. We wait until
1638 // the number of expected packets have been sent to avoid races where we
1639 // check stats before it has been updated.
1640 cricket::VideoMediaInfo info;
1641 for (uint32_t i = 0; i < kTimeout; ++i) {
1642 rtc::Thread::Current()->ProcessMessages(1);
1643 EXPECT_TRUE(channel_->GetStats(&info));
1644 ASSERT_EQ(2U, info.senders.size());
1645 if (info.senders[0].packets_sent + info.senders[1].packets_sent ==
1646 NumRtpPackets()) {
1647 // Stats have been updated for both sent frames, expectations can be
1648 // checked now.
1649 break;
1650 }
1651 }
1652 EXPECT_EQ(NumRtpPackets(),
1653 info.senders[0].packets_sent + info.senders[1].packets_sent)
1654 << "Timed out while waiting for packet counts for all sent packets.";
1655 EXPECT_EQ(1U, info.senders[0].ssrcs().size());
1656 EXPECT_EQ(1234U, info.senders[0].ssrcs()[0]);
1657 EXPECT_EQ(kVideoWidth, info.senders[0].send_frame_width);
1658 EXPECT_EQ(kVideoHeight, info.senders[0].send_frame_height);
1659 EXPECT_EQ(1U, info.senders[1].ssrcs().size());
1660 EXPECT_EQ(5678U, info.senders[1].ssrcs()[0]);
1661 EXPECT_EQ(kTestWidth, info.senders[1].send_frame_width);
1662 EXPECT_EQ(kTestHeight, info.senders[1].send_frame_height);
1663 // The capturer must be unregistered here as it runs out of it's scope next.
1664 channel_->SetVideoSend(5678, nullptr, nullptr);
srtee0c2eea2017-12-15 17:44:33 +01001665}
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +00001666
Niels Möller6557d0c2018-04-11 15:18:34 +02001667// Test that we can set the bandwidth.
srtee0c2eea2017-12-15 17:44:33 +01001668TEST_F(WebRtcVideoChannelBaseTest, SetSendBandwidth) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001669 cricket::VideoSendParameters parameters;
1670 parameters.codecs.push_back(DefaultCodec());
1671 parameters.max_bandwidth_bps = -1; // <= 0 means unlimited.
1672 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1673 parameters.max_bandwidth_bps = 128 * 1024;
1674 EXPECT_TRUE(channel_->SetSendParameters(parameters));
srtee0c2eea2017-12-15 17:44:33 +01001675}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001676
Niels Möller6557d0c2018-04-11 15:18:34 +02001677// Test that we can set the SSRC for the default send source.
srtee0c2eea2017-12-15 17:44:33 +01001678TEST_F(WebRtcVideoChannelBaseTest, SetSendSsrc) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001679 EXPECT_TRUE(SetDefaultCodec());
1680 EXPECT_TRUE(SetSend(true));
Niels Möller805a27e2019-01-21 12:21:27 +01001681 SendFrame();
Niels Möller6557d0c2018-04-11 15:18:34 +02001682 EXPECT_TRUE_WAIT(NumRtpPackets() > 0, kTimeout);
Åsa Persson23cd45a2018-07-03 10:40:40 +02001683 webrtc::RTPHeader header;
Niels Möller6557d0c2018-04-11 15:18:34 +02001684 std::unique_ptr<const rtc::CopyOnWriteBuffer> p(GetRtpPacket(0));
Åsa Persson23cd45a2018-07-03 10:40:40 +02001685 EXPECT_TRUE(ParseRtpPacket(p.get(), &header));
1686 EXPECT_EQ(kSsrc, header.ssrc);
1687
Niels Möller6557d0c2018-04-11 15:18:34 +02001688 // Packets are being paced out, so these can mismatch between the first and
1689 // second call to NumRtpPackets until pending packets are paced out.
Åsa Persson23cd45a2018-07-03 10:40:40 +02001690 EXPECT_EQ_WAIT(NumRtpPackets(), NumRtpPackets(header.ssrc), kTimeout);
1691 EXPECT_EQ_WAIT(NumRtpBytes(), NumRtpBytes(header.ssrc), kTimeout);
Niels Möller6557d0c2018-04-11 15:18:34 +02001692 EXPECT_EQ(1, NumSentSsrcs());
1693 EXPECT_EQ(0, NumRtpPackets(kSsrc - 1));
1694 EXPECT_EQ(0, NumRtpBytes(kSsrc - 1));
srtee0c2eea2017-12-15 17:44:33 +01001695}
Niels Möller6557d0c2018-04-11 15:18:34 +02001696
1697// Test that we can set the SSRC even after codecs are set.
srtee0c2eea2017-12-15 17:44:33 +01001698TEST_F(WebRtcVideoChannelBaseTest, SetSendSsrcAfterSetCodecs) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001699 // Remove stream added in Setup.
1700 EXPECT_TRUE(channel_->RemoveSendStream(kSsrc));
1701 EXPECT_TRUE(SetDefaultCodec());
Niels Möller6557d0c2018-04-11 15:18:34 +02001702 EXPECT_TRUE(
Yves Gerey665174f2018-06-19 15:03:05 +02001703 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(999)));
Niels Möller805a27e2019-01-21 12:21:27 +01001704 EXPECT_TRUE(channel_->SetVideoSend(999u, nullptr, frame_forwarder_.get()));
Niels Möller6557d0c2018-04-11 15:18:34 +02001705 EXPECT_TRUE(SetSend(true));
1706 EXPECT_TRUE(WaitAndSendFrame(0));
1707 EXPECT_TRUE_WAIT(NumRtpPackets() > 0, kTimeout);
Åsa Persson23cd45a2018-07-03 10:40:40 +02001708 webrtc::RTPHeader header;
Niels Möller6557d0c2018-04-11 15:18:34 +02001709 std::unique_ptr<const rtc::CopyOnWriteBuffer> p(GetRtpPacket(0));
Åsa Persson23cd45a2018-07-03 10:40:40 +02001710 EXPECT_TRUE(ParseRtpPacket(p.get(), &header));
1711 EXPECT_EQ(999u, header.ssrc);
Niels Möller6557d0c2018-04-11 15:18:34 +02001712 // Packets are being paced out, so these can mismatch between the first and
1713 // second call to NumRtpPackets until pending packets are paced out.
Åsa Persson23cd45a2018-07-03 10:40:40 +02001714 EXPECT_EQ_WAIT(NumRtpPackets(), NumRtpPackets(header.ssrc), kTimeout);
1715 EXPECT_EQ_WAIT(NumRtpBytes(), NumRtpBytes(header.ssrc), kTimeout);
Niels Möller6557d0c2018-04-11 15:18:34 +02001716 EXPECT_EQ(1, NumSentSsrcs());
1717 EXPECT_EQ(0, NumRtpPackets(kSsrc));
1718 EXPECT_EQ(0, NumRtpBytes(kSsrc));
srtee0c2eea2017-12-15 17:44:33 +01001719}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001720
Niels Möller6557d0c2018-04-11 15:18:34 +02001721// Test that we can set the default video renderer before and after
1722// media is received.
srtee0c2eea2017-12-15 17:44:33 +01001723TEST_F(WebRtcVideoChannelBaseTest, SetSink) {
Yves Gerey665174f2018-06-19 15:03:05 +02001724 uint8_t data1[] = {0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
1725 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
Niels Möller6557d0c2018-04-11 15:18:34 +02001726
1727 rtc::CopyOnWriteBuffer packet1(data1, sizeof(data1));
1728 rtc::SetBE32(packet1.data() + 8, kSsrc);
1729 channel_->SetSink(kDefaultReceiveSsrc, NULL);
1730 EXPECT_TRUE(SetDefaultCodec());
1731 EXPECT_TRUE(SetSend(true));
1732 EXPECT_EQ(0, renderer_.num_rendered_frames());
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07001733 channel_->OnPacketReceived(packet1, /* packet_time_us */ -1);
Niels Möller6557d0c2018-04-11 15:18:34 +02001734 EXPECT_TRUE(channel_->SetSink(kDefaultReceiveSsrc, &renderer_));
Niels Möller805a27e2019-01-21 12:21:27 +01001735 SendFrame();
Niels Möller6557d0c2018-04-11 15:18:34 +02001736 EXPECT_FRAME_WAIT(1, kVideoWidth, kVideoHeight, kTimeout);
srtee0c2eea2017-12-15 17:44:33 +01001737}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001738
Niels Möller6557d0c2018-04-11 15:18:34 +02001739// Tests setting up and configuring a send stream.
srtee0c2eea2017-12-15 17:44:33 +01001740TEST_F(WebRtcVideoChannelBaseTest, AddRemoveSendStreams) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001741 EXPECT_TRUE(SetOneCodec(DefaultCodec()));
1742 EXPECT_TRUE(SetSend(true));
1743 EXPECT_TRUE(channel_->SetSink(kDefaultReceiveSsrc, &renderer_));
Niels Möller805a27e2019-01-21 12:21:27 +01001744 SendFrame();
Niels Möller6557d0c2018-04-11 15:18:34 +02001745 EXPECT_FRAME_WAIT(1, kVideoWidth, kVideoHeight, kTimeout);
1746 EXPECT_GT(NumRtpPackets(), 0);
Åsa Persson23cd45a2018-07-03 10:40:40 +02001747 webrtc::RTPHeader header;
Niels Möller6557d0c2018-04-11 15:18:34 +02001748 size_t last_packet = NumRtpPackets() - 1;
Yves Gerey665174f2018-06-19 15:03:05 +02001749 std::unique_ptr<const rtc::CopyOnWriteBuffer> p(
1750 GetRtpPacket(static_cast<int>(last_packet)));
Åsa Persson23cd45a2018-07-03 10:40:40 +02001751 EXPECT_TRUE(ParseRtpPacket(p.get(), &header));
1752 EXPECT_EQ(kSsrc, header.ssrc);
Niels Möller6557d0c2018-04-11 15:18:34 +02001753
1754 // Remove the send stream that was added during Setup.
1755 EXPECT_TRUE(channel_->RemoveSendStream(kSsrc));
1756 int rtp_packets = NumRtpPackets();
1757
Niels Möller6557d0c2018-04-11 15:18:34 +02001758 EXPECT_TRUE(
Yves Gerey665174f2018-06-19 15:03:05 +02001759 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(789u)));
Niels Möller805a27e2019-01-21 12:21:27 +01001760 EXPECT_TRUE(channel_->SetVideoSend(789u, nullptr, frame_forwarder_.get()));
Niels Möller6557d0c2018-04-11 15:18:34 +02001761 EXPECT_EQ(rtp_packets, NumRtpPackets());
1762 // Wait 30ms to guarantee the engine does not drop the frame.
1763 EXPECT_TRUE(WaitAndSendFrame(30));
1764 EXPECT_TRUE_WAIT(NumRtpPackets() > rtp_packets, kTimeout);
1765
1766 last_packet = NumRtpPackets() - 1;
1767 p.reset(GetRtpPacket(static_cast<int>(last_packet)));
Åsa Persson23cd45a2018-07-03 10:40:40 +02001768 EXPECT_TRUE(ParseRtpPacket(p.get(), &header));
1769 EXPECT_EQ(789u, header.ssrc);
srtee0c2eea2017-12-15 17:44:33 +01001770}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001771
Niels Möller6557d0c2018-04-11 15:18:34 +02001772// Tests the behavior of incoming streams in a conference scenario.
srtee0c2eea2017-12-15 17:44:33 +01001773TEST_F(WebRtcVideoChannelBaseTest, SimulateConference) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001774 cricket::FakeVideoRenderer renderer1, renderer2;
1775 EXPECT_TRUE(SetDefaultCodec());
1776 cricket::VideoSendParameters parameters;
1777 parameters.codecs.push_back(DefaultCodec());
1778 parameters.conference_mode = true;
1779 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1780 EXPECT_TRUE(SetSend(true));
Yves Gerey665174f2018-06-19 15:03:05 +02001781 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
1782 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
Niels Möller6557d0c2018-04-11 15:18:34 +02001783 EXPECT_TRUE(channel_->SetSink(1, &renderer1));
1784 EXPECT_TRUE(channel_->SetSink(2, &renderer2));
1785 EXPECT_EQ(0, renderer1.num_rendered_frames());
1786 EXPECT_EQ(0, renderer2.num_rendered_frames());
1787 std::vector<uint32_t> ssrcs;
1788 ssrcs.push_back(1);
1789 ssrcs.push_back(2);
1790 network_interface_.SetConferenceMode(true, ssrcs);
Niels Möller805a27e2019-01-21 12:21:27 +01001791 SendFrame();
Niels Möller6557d0c2018-04-11 15:18:34 +02001792 EXPECT_FRAME_ON_RENDERER_WAIT(renderer1, 1, kVideoWidth, kVideoHeight,
1793 kTimeout);
1794 EXPECT_FRAME_ON_RENDERER_WAIT(renderer2, 1, kVideoWidth, kVideoHeight,
1795 kTimeout);
1796
1797 std::unique_ptr<const rtc::CopyOnWriteBuffer> p(GetRtpPacket(0));
1798 EXPECT_EQ(DefaultCodec().id, GetPayloadType(p.get()));
1799 EXPECT_EQ(kVideoWidth, renderer1.width());
1800 EXPECT_EQ(kVideoHeight, renderer1.height());
1801 EXPECT_EQ(kVideoWidth, renderer2.width());
1802 EXPECT_EQ(kVideoHeight, renderer2.height());
1803 EXPECT_TRUE(channel_->RemoveRecvStream(2));
1804 EXPECT_TRUE(channel_->RemoveRecvStream(1));
srtee0c2eea2017-12-15 17:44:33 +01001805}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001806
Niels Möller6557d0c2018-04-11 15:18:34 +02001807// Tests that we can add and remove capturers and frames are sent out properly
srtee0c2eea2017-12-15 17:44:33 +01001808TEST_F(WebRtcVideoChannelBaseTest, DISABLED_AddRemoveCapturer) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001809 using cricket::VideoCodec;
1810 using cricket::VideoOptions;
1811 using cricket::VideoFormat;
1812 using cricket::FOURCC_I420;
1813
1814 VideoCodec codec = DefaultCodec();
1815 const int time_between_send_ms = VideoFormat::FpsToInterval(kFramerate);
1816 EXPECT_TRUE(SetOneCodec(codec));
1817 EXPECT_TRUE(SetSend(true));
1818 EXPECT_TRUE(channel_->SetSink(kDefaultReceiveSsrc, &renderer_));
1819 EXPECT_EQ(0, renderer_.num_rendered_frames());
Niels Möller805a27e2019-01-21 12:21:27 +01001820 SendFrame();
Niels Möller6557d0c2018-04-11 15:18:34 +02001821 EXPECT_FRAME_WAIT(1, kVideoWidth, kVideoHeight, kTimeout);
Niels Möller805a27e2019-01-21 12:21:27 +01001822
1823 webrtc::test::FrameForwarder frame_forwarder;
1824 cricket::FakeFrameSource frame_source(480, 360, rtc::kNumMicrosecsPerSec / 30,
1825 rtc::kNumMicrosecsPerSec / 30);
Niels Möller6557d0c2018-04-11 15:18:34 +02001826
1827 // TODO(nisse): This testcase fails if we don't configure
1828 // screencast. It's unclear why, I see nothing obvious in this
1829 // test which is related to screencast logic.
1830 VideoOptions video_options;
1831 video_options.is_screencast = true;
1832 channel_->SetVideoSend(kSsrc, &video_options, nullptr);
1833
Niels Möller6557d0c2018-04-11 15:18:34 +02001834 int captured_frames = 1;
1835 for (int iterations = 0; iterations < 2; ++iterations) {
Niels Möller805a27e2019-01-21 12:21:27 +01001836 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, nullptr, &frame_forwarder));
Niels Möller6557d0c2018-04-11 15:18:34 +02001837 rtc::Thread::Current()->ProcessMessages(time_between_send_ms);
Niels Möller805a27e2019-01-21 12:21:27 +01001838 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
1839
Niels Möller6557d0c2018-04-11 15:18:34 +02001840 ++captured_frames;
1841 // Wait until frame of right size is captured.
1842 EXPECT_TRUE_WAIT(renderer_.num_rendered_frames() >= captured_frames &&
Niels Möller805a27e2019-01-21 12:21:27 +01001843 480 == renderer_.width() &&
1844 360 == renderer_.height() && !renderer_.black_frame(),
Yves Gerey665174f2018-06-19 15:03:05 +02001845 kTimeout);
Niels Möller6557d0c2018-04-11 15:18:34 +02001846 EXPECT_GE(renderer_.num_rendered_frames(), captured_frames);
Niels Möller805a27e2019-01-21 12:21:27 +01001847 EXPECT_EQ(480, renderer_.width());
1848 EXPECT_EQ(360, renderer_.height());
Niels Möller6557d0c2018-04-11 15:18:34 +02001849 captured_frames = renderer_.num_rendered_frames() + 1;
1850 EXPECT_FALSE(renderer_.black_frame());
1851 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, nullptr, nullptr));
1852 // Make sure a black frame is generated within the specified timeout.
1853 // The black frame should be the resolution of the previous frame to
1854 // prevent expensive encoder reconfigurations.
1855 EXPECT_TRUE_WAIT(renderer_.num_rendered_frames() >= captured_frames &&
Niels Möller805a27e2019-01-21 12:21:27 +01001856 480 == renderer_.width() &&
1857 360 == renderer_.height() && renderer_.black_frame(),
Yves Gerey665174f2018-06-19 15:03:05 +02001858 kTimeout);
Niels Möller6557d0c2018-04-11 15:18:34 +02001859 EXPECT_GE(renderer_.num_rendered_frames(), captured_frames);
Niels Möller805a27e2019-01-21 12:21:27 +01001860 EXPECT_EQ(480, renderer_.width());
1861 EXPECT_EQ(360, renderer_.height());
Niels Möller6557d0c2018-04-11 15:18:34 +02001862 EXPECT_TRUE(renderer_.black_frame());
1863
1864 // The black frame has the same timestamp as the next frame since it's
1865 // timestamp is set to the last frame's timestamp + interval. WebRTC will
1866 // not render a frame with the same timestamp so capture another frame
1867 // with the frame capturer to increment the next frame's timestamp.
Niels Möller805a27e2019-01-21 12:21:27 +01001868 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
Niels Möller6557d0c2018-04-11 15:18:34 +02001869 }
srtee0c2eea2017-12-15 17:44:33 +01001870}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001871
Niels Möller6557d0c2018-04-11 15:18:34 +02001872// Tests that if SetVideoSend is called with a NULL capturer after the
1873// capturer was already removed, the application doesn't crash (and no black
1874// frame is sent).
srtee0c2eea2017-12-15 17:44:33 +01001875TEST_F(WebRtcVideoChannelBaseTest, RemoveCapturerWithoutAdd) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001876 EXPECT_TRUE(SetOneCodec(DefaultCodec()));
1877 EXPECT_TRUE(SetSend(true));
1878 EXPECT_TRUE(channel_->SetSink(kDefaultReceiveSsrc, &renderer_));
1879 EXPECT_EQ(0, renderer_.num_rendered_frames());
Niels Möller805a27e2019-01-21 12:21:27 +01001880 SendFrame();
Niels Möller6557d0c2018-04-11 15:18:34 +02001881 EXPECT_FRAME_WAIT(1, kVideoWidth, kVideoHeight, kTimeout);
1882 // Wait for one frame so they don't get dropped because we send frames too
1883 // tightly.
1884 rtc::Thread::Current()->ProcessMessages(30);
1885 // Remove the capturer.
1886 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, nullptr, nullptr));
1887
1888 // No capturer was added, so this SetVideoSend shouldn't do anything.
1889 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, nullptr, nullptr));
1890 rtc::Thread::Current()->ProcessMessages(300);
1891 // Verify no more frames were sent.
1892 EXPECT_EQ(1, renderer_.num_rendered_frames());
srtee0c2eea2017-12-15 17:44:33 +01001893}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001894
Niels Möller6557d0c2018-04-11 15:18:34 +02001895// Tests that we can add and remove capturer as unique sources.
srtee0c2eea2017-12-15 17:44:33 +01001896TEST_F(WebRtcVideoChannelBaseTest, AddRemoveCapturerMultipleSources) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001897 // WebRTC implementation will drop frames if pushed to quickly. Wait the
1898 // interval time to avoid that.
1899 // WebRTC implementation will drop frames if pushed to quickly. Wait the
1900 // interval time to avoid that.
1901 // Set up the stream associated with the engine.
Yves Gerey665174f2018-06-19 15:03:05 +02001902 EXPECT_TRUE(
1903 channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
Niels Möller6557d0c2018-04-11 15:18:34 +02001904 EXPECT_TRUE(channel_->SetSink(kSsrc, &renderer_));
1905 cricket::VideoFormat capture_format(
1906 kVideoWidth, kVideoHeight,
1907 cricket::VideoFormat::FpsToInterval(kFramerate), cricket::FOURCC_I420);
1908 // Set up additional stream 1.
1909 cricket::FakeVideoRenderer renderer1;
1910 EXPECT_FALSE(channel_->SetSink(1, &renderer1));
Yves Gerey665174f2018-06-19 15:03:05 +02001911 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
Niels Möller6557d0c2018-04-11 15:18:34 +02001912 EXPECT_TRUE(channel_->SetSink(1, &renderer1));
Yves Gerey665174f2018-06-19 15:03:05 +02001913 EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(1)));
Niels Möller805a27e2019-01-21 12:21:27 +01001914
1915 webrtc::test::FrameForwarder frame_forwarder1;
1916 cricket::FakeFrameSource frame_source(kVideoWidth, kVideoHeight,
1917 rtc::kNumMicrosecsPerSec / kFramerate);
1918
Niels Möller6557d0c2018-04-11 15:18:34 +02001919 // Set up additional stream 2.
1920 cricket::FakeVideoRenderer renderer2;
1921 EXPECT_FALSE(channel_->SetSink(2, &renderer2));
Yves Gerey665174f2018-06-19 15:03:05 +02001922 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
Niels Möller6557d0c2018-04-11 15:18:34 +02001923 EXPECT_TRUE(channel_->SetSink(2, &renderer2));
Yves Gerey665174f2018-06-19 15:03:05 +02001924 EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
Niels Möller805a27e2019-01-21 12:21:27 +01001925 webrtc::test::FrameForwarder frame_forwarder2;
1926
Niels Möller6557d0c2018-04-11 15:18:34 +02001927 // State for all the streams.
1928 EXPECT_TRUE(SetOneCodec(DefaultCodec()));
1929 // A limitation in the lmi implementation requires that SetVideoSend() is
1930 // called after SetOneCodec().
1931 // TODO(hellner): this seems like an unnecessary constraint, fix it.
Niels Möller805a27e2019-01-21 12:21:27 +01001932 EXPECT_TRUE(channel_->SetVideoSend(1, nullptr, &frame_forwarder1));
1933 EXPECT_TRUE(channel_->SetVideoSend(2, nullptr, &frame_forwarder2));
Niels Möller6557d0c2018-04-11 15:18:34 +02001934 EXPECT_TRUE(SetSend(true));
1935 // Test capturer associated with engine.
1936 const int kTestWidth = 160;
1937 const int kTestHeight = 120;
Niels Möller805a27e2019-01-21 12:21:27 +01001938 frame_forwarder1.IncomingCapturedFrame(frame_source.GetFrame(
1939 kTestWidth, kTestHeight, webrtc::VideoRotation::kVideoRotation_0,
1940 rtc::kNumMicrosecsPerSec / kFramerate));
Yves Gerey665174f2018-06-19 15:03:05 +02001941 EXPECT_FRAME_ON_RENDERER_WAIT(renderer1, 1, kTestWidth, kTestHeight,
1942 kTimeout);
Niels Möller6557d0c2018-04-11 15:18:34 +02001943 // Capture a frame with additional capturer2, frames should be received
Niels Möller805a27e2019-01-21 12:21:27 +01001944 frame_forwarder2.IncomingCapturedFrame(frame_source.GetFrame(
1945 kTestWidth, kTestHeight, webrtc::VideoRotation::kVideoRotation_0,
1946 rtc::kNumMicrosecsPerSec / kFramerate));
Yves Gerey665174f2018-06-19 15:03:05 +02001947 EXPECT_FRAME_ON_RENDERER_WAIT(renderer2, 1, kTestWidth, kTestHeight,
1948 kTimeout);
Niels Möller6557d0c2018-04-11 15:18:34 +02001949 // Successfully remove the capturer.
1950 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, nullptr, nullptr));
1951 // The capturers must be unregistered here as it runs out of it's scope
1952 // next.
1953 EXPECT_TRUE(channel_->SetVideoSend(1, nullptr, nullptr));
1954 EXPECT_TRUE(channel_->SetVideoSend(2, nullptr, nullptr));
srtee0c2eea2017-12-15 17:44:33 +01001955}
Niels Möller6557d0c2018-04-11 15:18:34 +02001956
1957// Tests empty StreamParams is rejected.
srtee0c2eea2017-12-15 17:44:33 +01001958TEST_F(WebRtcVideoChannelBaseTest, RejectEmptyStreamParams) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001959 // Remove the send stream that was added during Setup.
1960 EXPECT_TRUE(channel_->RemoveSendStream(kSsrc));
1961
1962 cricket::StreamParams empty;
1963 EXPECT_FALSE(channel_->AddSendStream(empty));
Yves Gerey665174f2018-06-19 15:03:05 +02001964 EXPECT_TRUE(
1965 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(789u)));
srtee0c2eea2017-12-15 17:44:33 +01001966}
Niels Möller6557d0c2018-04-11 15:18:34 +02001967
1968// Test that multiple send streams can be created and deleted properly.
srtee0c2eea2017-12-15 17:44:33 +01001969TEST_F(WebRtcVideoChannelBaseTest, MultipleSendStreams) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001970 // Remove stream added in Setup. I.e. remove stream corresponding to default
1971 // channel.
1972 EXPECT_TRUE(channel_->RemoveSendStream(kSsrc));
Yves Gerey665174f2018-06-19 15:03:05 +02001973 const unsigned int kSsrcsSize = sizeof(kSsrcs4) / sizeof(kSsrcs4[0]);
Niels Möller6557d0c2018-04-11 15:18:34 +02001974 for (unsigned int i = 0; i < kSsrcsSize; ++i) {
1975 EXPECT_TRUE(channel_->AddSendStream(
1976 cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
1977 }
1978 // Delete one of the non default channel streams, let the destructor delete
1979 // the remaining ones.
1980 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcs4[kSsrcsSize - 1]));
1981 // Stream should already be deleted.
1982 EXPECT_FALSE(channel_->RemoveSendStream(kSsrcs4[kSsrcsSize - 1]));
srtee0c2eea2017-12-15 17:44:33 +01001983}
pbos@webrtc.orgc4175b92014-09-03 15:25:49 +00001984
eladalonf1841382017-06-12 01:16:46 -07001985TEST_F(WebRtcVideoChannelBaseTest, SendAndReceiveVp8Vga) {
magjed509e4fe2016-11-18 01:34:11 -08001986 SendAndReceive(GetEngineCodec("VP8"));
pbos@webrtc.org9359cb32014-07-23 15:44:48 +00001987}
1988
eladalonf1841382017-06-12 01:16:46 -07001989TEST_F(WebRtcVideoChannelBaseTest, SendAndReceiveVp8Qvga) {
magjed509e4fe2016-11-18 01:34:11 -08001990 SendAndReceive(GetEngineCodec("VP8"));
pbos@webrtc.org9359cb32014-07-23 15:44:48 +00001991}
1992
eladalonf1841382017-06-12 01:16:46 -07001993TEST_F(WebRtcVideoChannelBaseTest, SendAndReceiveVp8SvcQqvga) {
magjed509e4fe2016-11-18 01:34:11 -08001994 SendAndReceive(GetEngineCodec("VP8"));
pbos@webrtc.org9359cb32014-07-23 15:44:48 +00001995}
1996
eladalonf1841382017-06-12 01:16:46 -07001997TEST_F(WebRtcVideoChannelBaseTest, TwoStreamsSendAndReceive) {
Peter Boströmd1f584b2016-04-20 16:31:53 +02001998 // Set a high bitrate to not be downscaled by VP8 due to low initial start
1999 // bitrates. This currently happens at <250k, and two streams sharing 300k
2000 // initially will use QVGA instead of VGA.
2001 // TODO(pbos): Set up the quality scaler so that both senders reliably start
2002 // at QVGA, then verify that instead.
magjed509e4fe2016-11-18 01:34:11 -08002003 cricket::VideoCodec codec = GetEngineCodec("VP8");
Peter Boströmd1f584b2016-04-20 16:31:53 +02002004 codec.params[kCodecParamStartBitrate] = "1000000";
Niels Möller6557d0c2018-04-11 15:18:34 +02002005 TwoStreamsSendAndReceive(codec);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002006}
2007
eladalonf1841382017-06-12 01:16:46 -07002008class WebRtcVideoChannelTest : public WebRtcVideoEngineTest {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002009 public:
eladalonf1841382017-06-12 01:16:46 -07002010 WebRtcVideoChannelTest() : WebRtcVideoChannelTest("") {}
2011 explicit WebRtcVideoChannelTest(const char* field_trials)
Niels Möller805a27e2019-01-21 12:21:27 +01002012 : WebRtcVideoEngineTest(field_trials),
2013 frame_source_(1280, 720, rtc::kNumMicrosecsPerSec / 30),
2014 last_ssrc_(0) {}
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002015 void SetUp() override {
Anders Carlsson5f2bb622018-05-14 09:48:06 +02002016 encoder_factory_->AddSupportedVideoCodecType("VP8");
2017 encoder_factory_->AddSupportedVideoCodecType("VP9");
2018#if defined(WEBRTC_USE_H264)
2019 encoder_factory_->AddSupportedVideoCodecType("H264");
2020#endif
2021
Sebastian Jansson8f83b422018-02-21 13:07:13 +01002022 fake_call_.reset(new FakeCall());
Sebastian Jansson84848f22018-11-16 10:40:36 +01002023 channel_.reset(engine_.CreateMediaChannel(fake_call_.get(),
2024 GetMediaConfig(), VideoOptions(),
2025 webrtc::CryptoOptions()));
Sergey Ulanove2b15012016-11-22 16:08:30 -08002026 channel_->OnReadyToSend(true);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002027 last_ssrc_ = 123;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002028 send_parameters_.codecs = engine_.codecs();
2029 recv_parameters_.codecs = engine_.codecs();
2030 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002031 }
2032
2033 protected:
2034 FakeVideoSendStream* AddSendStream() {
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002035 return AddSendStream(StreamParams::CreateLegacy(++last_ssrc_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002036 }
2037
2038 FakeVideoSendStream* AddSendStream(const StreamParams& sp) {
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002039 size_t num_streams = fake_call_->GetVideoSendStreams().size();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002040 EXPECT_TRUE(channel_->AddSendStream(sp));
2041 std::vector<FakeVideoSendStream*> streams =
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002042 fake_call_->GetVideoSendStreams();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002043 EXPECT_EQ(num_streams + 1, streams.size());
2044 return streams[streams.size() - 1];
2045 }
2046
2047 std::vector<FakeVideoSendStream*> GetFakeSendStreams() {
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002048 return fake_call_->GetVideoSendStreams();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002049 }
2050
2051 FakeVideoReceiveStream* AddRecvStream() {
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002052 return AddRecvStream(StreamParams::CreateLegacy(++last_ssrc_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002053 }
2054
2055 FakeVideoReceiveStream* AddRecvStream(const StreamParams& sp) {
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002056 size_t num_streams = fake_call_->GetVideoReceiveStreams().size();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002057 EXPECT_TRUE(channel_->AddRecvStream(sp));
2058 std::vector<FakeVideoReceiveStream*> streams =
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002059 fake_call_->GetVideoReceiveStreams();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002060 EXPECT_EQ(num_streams + 1, streams.size());
2061 return streams[streams.size() - 1];
2062 }
2063
pbos@webrtc.org00873182014-11-25 14:03:34 +00002064 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps,
2065 int expected_min_bitrate_bps,
2066 const char* start_bitrate_kbps,
2067 int expected_start_bitrate_bps,
2068 const char* max_bitrate_kbps,
2069 int expected_max_bitrate_bps) {
Sebastian Jansson8f83b422018-02-21 13:07:13 +01002070 ExpectSetBitrateParameters(expected_min_bitrate_bps,
2071 expected_start_bitrate_bps,
2072 expected_max_bitrate_bps);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002073 auto& codecs = send_parameters_.codecs;
2074 codecs.clear();
magjed509e4fe2016-11-18 01:34:11 -08002075 codecs.push_back(GetEngineCodec("VP8"));
pbos@webrtc.org00873182014-11-25 14:03:34 +00002076 codecs[0].params[kCodecParamMinBitrate] = min_bitrate_kbps;
2077 codecs[0].params[kCodecParamStartBitrate] = start_bitrate_kbps;
2078 codecs[0].params[kCodecParamMaxBitrate] = max_bitrate_kbps;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002079 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Sebastian Jansson8f83b422018-02-21 13:07:13 +01002080 }
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002081
Sebastian Jansson8f83b422018-02-21 13:07:13 +01002082 void ExpectSetBitrateParameters(int min_bitrate_bps,
2083 int start_bitrate_bps,
2084 int max_bitrate_bps) {
2085 EXPECT_CALL(
2086 *fake_call_->GetMockTransportControllerSend(),
2087 SetSdpBitrateParameters(AllOf(
2088 Field(&BitrateConstraints::min_bitrate_bps, min_bitrate_bps),
2089 Field(&BitrateConstraints::start_bitrate_bps, start_bitrate_bps),
2090 Field(&BitrateConstraints::max_bitrate_bps, max_bitrate_bps))));
2091 }
2092
2093 void ExpectSetMaxBitrate(int max_bitrate_bps) {
2094 EXPECT_CALL(*fake_call_->GetMockTransportControllerSend(),
2095 SetSdpBitrateParameters(Field(
2096 &BitrateConstraints::max_bitrate_bps, max_bitrate_bps)));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002097 }
2098
Johannes Kron9190b822018-10-29 11:22:05 +01002099 void TestExtmapAllowMixedCaller(bool extmap_allow_mixed) {
2100 // For a caller, the answer will be applied in set remote description
2101 // where SetSendParameters() is called.
2102 EXPECT_TRUE(
2103 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
2104 send_parameters_.extmap_allow_mixed = extmap_allow_mixed;
2105 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2106 const webrtc::VideoSendStream::Config& config =
2107 fake_call_->GetVideoSendStreams()[0]->GetConfig();
2108 EXPECT_EQ(extmap_allow_mixed, config.rtp.extmap_allow_mixed);
2109 }
2110
2111 void TestExtmapAllowMixedCallee(bool extmap_allow_mixed) {
2112 // For a callee, the answer will be applied in set local description
2113 // where SetExtmapAllowMixed() and AddSendStream() are called.
2114 channel_->SetExtmapAllowMixed(extmap_allow_mixed);
2115 EXPECT_TRUE(
2116 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
2117 const webrtc::VideoSendStream::Config& config =
2118 fake_call_->GetVideoSendStreams()[0]->GetConfig();
2119 EXPECT_EQ(extmap_allow_mixed, config.rtp.extmap_allow_mixed);
2120 }
2121
isheriff6f8d6862016-05-26 11:24:55 -07002122 void TestSetSendRtpHeaderExtensions(const std::string& ext_uri) {
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002123 // Enable extension.
2124 const int id = 1;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002125 cricket::VideoSendParameters parameters = send_parameters_;
isheriff6f8d6862016-05-26 11:24:55 -07002126 parameters.extensions.push_back(RtpExtension(ext_uri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002127 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002128 FakeVideoSendStream* send_stream =
2129 AddSendStream(cricket::StreamParams::CreateLegacy(123));
2130
2131 // Verify the send extension id.
2132 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
2133 EXPECT_EQ(id, send_stream->GetConfig().rtp.extensions[0].id);
isheriff6f8d6862016-05-26 11:24:55 -07002134 EXPECT_EQ(ext_uri, send_stream->GetConfig().rtp.extensions[0].uri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002135 // Verify call with same set of extensions returns true.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002136 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002137 // Verify that SetSendRtpHeaderExtensions doesn't implicitly add them for
2138 // receivers.
2139 EXPECT_TRUE(AddRecvStream(cricket::StreamParams::CreateLegacy(123))
2140 ->GetConfig()
2141 .rtp.extensions.empty());
2142
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00002143 // Verify that existing RTP header extensions can be removed.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002144 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Fredrik Solenberg709ed672015-09-15 12:26:33 +02002145 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
2146 send_stream = fake_call_->GetVideoSendStreams()[0];
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00002147 EXPECT_TRUE(send_stream->GetConfig().rtp.extensions.empty());
2148
2149 // Verify that adding receive RTP header extensions adds them for existing
2150 // streams.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002151 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Fredrik Solenberg709ed672015-09-15 12:26:33 +02002152 send_stream = fake_call_->GetVideoSendStreams()[0];
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00002153 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
2154 EXPECT_EQ(id, send_stream->GetConfig().rtp.extensions[0].id);
isheriff6f8d6862016-05-26 11:24:55 -07002155 EXPECT_EQ(ext_uri, send_stream->GetConfig().rtp.extensions[0].uri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002156 }
2157
isheriff6f8d6862016-05-26 11:24:55 -07002158 void TestSetRecvRtpHeaderExtensions(const std::string& ext_uri) {
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002159 // Enable extension.
2160 const int id = 1;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002161 cricket::VideoRecvParameters parameters = recv_parameters_;
isheriff6f8d6862016-05-26 11:24:55 -07002162 parameters.extensions.push_back(RtpExtension(ext_uri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002163 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002164
2165 FakeVideoReceiveStream* recv_stream =
2166 AddRecvStream(cricket::StreamParams::CreateLegacy(123));
2167
2168 // Verify the recv extension id.
2169 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.extensions.size());
2170 EXPECT_EQ(id, recv_stream->GetConfig().rtp.extensions[0].id);
isheriff6f8d6862016-05-26 11:24:55 -07002171 EXPECT_EQ(ext_uri, recv_stream->GetConfig().rtp.extensions[0].uri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002172 // Verify call with same set of extensions returns true.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002173 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00002174
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002175 // Verify that SetRecvRtpHeaderExtensions doesn't implicitly add them for
2176 // senders.
2177 EXPECT_TRUE(AddSendStream(cricket::StreamParams::CreateLegacy(123))
2178 ->GetConfig()
2179 .rtp.extensions.empty());
2180
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00002181 // Verify that existing RTP header extensions can be removed.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002182 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
Fredrik Solenberg709ed672015-09-15 12:26:33 +02002183 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
2184 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00002185 EXPECT_TRUE(recv_stream->GetConfig().rtp.extensions.empty());
2186
2187 // Verify that adding receive RTP header extensions adds them for existing
2188 // streams.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002189 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
Fredrik Solenberg709ed672015-09-15 12:26:33 +02002190 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00002191 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.extensions.size());
2192 EXPECT_EQ(id, recv_stream->GetConfig().rtp.extensions[0].id);
isheriff6f8d6862016-05-26 11:24:55 -07002193 EXPECT_EQ(ext_uri, recv_stream->GetConfig().rtp.extensions[0].uri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002194 }
2195
Stefan Holmerbbaf3632015-10-29 18:53:23 +01002196 void TestExtensionFilter(const std::vector<std::string>& extensions,
2197 const std::string& expected_extension) {
2198 cricket::VideoSendParameters parameters = send_parameters_;
2199 int expected_id = -1;
2200 int id = 1;
2201 for (const std::string& extension : extensions) {
2202 if (extension == expected_extension)
2203 expected_id = id;
isheriff6f8d6862016-05-26 11:24:55 -07002204 parameters.extensions.push_back(RtpExtension(extension, id++));
Stefan Holmerbbaf3632015-10-29 18:53:23 +01002205 }
2206 EXPECT_TRUE(channel_->SetSendParameters(parameters));
2207 FakeVideoSendStream* send_stream =
2208 AddSendStream(cricket::StreamParams::CreateLegacy(123));
2209
2210 // Verify that only one of them has been set, and that it is the one with
2211 // highest priority (transport sequence number).
2212 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
2213 EXPECT_EQ(expected_id, send_stream->GetConfig().rtp.extensions[0].id);
2214 EXPECT_EQ(expected_extension,
isheriff6f8d6862016-05-26 11:24:55 -07002215 send_stream->GetConfig().rtp.extensions[0].uri);
Stefan Holmerbbaf3632015-10-29 18:53:23 +01002216 }
2217
asapersson3c81a1a2017-06-14 05:52:21 -07002218 void TestDegradationPreference(bool resolution_scaling_enabled,
2219 bool fps_scaling_enabled);
2220
Erik Språngefbde372015-04-29 16:21:28 +02002221 void TestCpuAdaptation(bool enable_overuse, bool is_screenshare);
Peter Boström3548dd22015-05-22 18:48:36 +02002222 void TestReceiverLocalSsrcConfiguration(bool receiver_first);
magjed509e4fe2016-11-18 01:34:11 -08002223 void TestReceiveUnsignaledSsrcPacket(uint8_t payload_type,
2224 bool expect_created_receive_stream);
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002225
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002226 FakeVideoSendStream* SetDenoisingOption(
nisse05103312016-03-16 02:22:50 -07002227 uint32_t ssrc,
Niels Möller805a27e2019-01-21 12:21:27 +01002228 webrtc::test::FrameForwarder* frame_forwarder,
nisse0db023a2016-03-01 04:29:59 -08002229 bool enabled) {
nisse05103312016-03-16 02:22:50 -07002230 cricket::VideoOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002231 options.video_noise_reduction = enabled;
Niels Möller805a27e2019-01-21 12:21:27 +01002232 EXPECT_TRUE(channel_->SetVideoSend(ssrc, &options, frame_forwarder));
nisse0db023a2016-03-01 04:29:59 -08002233 // Options only take effect on the next frame.
Niels Möller805a27e2019-01-21 12:21:27 +01002234 frame_forwarder->IncomingCapturedFrame(frame_source_.GetFrame());
nisse0db023a2016-03-01 04:29:59 -08002235
Erik Språng143cec12015-04-28 10:01:41 +02002236 return fake_call_->GetVideoSendStreams().back();
2237 }
2238
Peter Boström2feafdb2015-09-09 14:32:14 +02002239 FakeVideoSendStream* SetUpSimulcast(bool enabled, bool with_rtx) {
2240 const int kRtxSsrcOffset = 0xDEADBEEF;
Erik Språng143cec12015-04-28 10:01:41 +02002241 last_ssrc_ += 3;
Peter Boström2feafdb2015-09-09 14:32:14 +02002242 std::vector<uint32_t> ssrcs;
2243 std::vector<uint32_t> rtx_ssrcs;
2244 uint32_t num_streams = enabled ? 3 : 1;
2245 for (uint32_t i = 0; i < num_streams; ++i) {
2246 uint32_t ssrc = last_ssrc_ + i;
2247 ssrcs.push_back(ssrc);
2248 if (with_rtx) {
2249 rtx_ssrcs.push_back(ssrc + kRtxSsrcOffset);
2250 }
Erik Språng143cec12015-04-28 10:01:41 +02002251 }
Peter Boström2feafdb2015-09-09 14:32:14 +02002252 if (with_rtx) {
2253 return AddSendStream(
2254 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
2255 }
2256 return AddSendStream(CreateSimStreamParams("cname", ssrcs));
Erik Språng143cec12015-04-28 10:01:41 +02002257 }
2258
perkjfa10b552016-10-02 23:45:26 -07002259 int GetMaxEncoderBitrate() {
skvladdc1c62c2016-03-16 19:07:43 -07002260 std::vector<FakeVideoSendStream*> streams =
2261 fake_call_->GetVideoSendStreams();
perkjfa10b552016-10-02 23:45:26 -07002262 EXPECT_EQ(1u, streams.size());
skvladdc1c62c2016-03-16 19:07:43 -07002263 FakeVideoSendStream* stream = streams[streams.size() - 1];
Mirko Bonadeif859e552018-05-30 15:31:29 +02002264 EXPECT_EQ(1u, stream->GetEncoderConfig().number_of_streams);
perkjfa10b552016-10-02 23:45:26 -07002265 return stream->GetVideoStreams()[0].max_bitrate_bps;
skvladdc1c62c2016-03-16 19:07:43 -07002266 }
2267
perkjfa10b552016-10-02 23:45:26 -07002268 void SetAndExpectMaxBitrate(int global_max,
skvladdc1c62c2016-03-16 19:07:43 -07002269 int stream_max,
2270 int expected_encoder_bitrate) {
2271 VideoSendParameters limited_send_params = send_parameters_;
2272 limited_send_params.max_bandwidth_bps = global_max;
2273 EXPECT_TRUE(channel_->SetSendParameters(limited_send_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07002274 webrtc::RtpParameters parameters =
2275 channel_->GetRtpSendParameters(last_ssrc_);
skvladdc1c62c2016-03-16 19:07:43 -07002276 EXPECT_EQ(1UL, parameters.encodings.size());
Oskar Sundbom78807582017-11-16 11:09:55 +01002277 parameters.encodings[0].max_bitrate_bps = stream_max;
Zach Steinba37b4b2018-01-23 15:02:36 -08002278 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
skvladdc1c62c2016-03-16 19:07:43 -07002279 // Read back the parameteres and verify they have the correct value
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07002280 parameters = channel_->GetRtpSendParameters(last_ssrc_);
skvladdc1c62c2016-03-16 19:07:43 -07002281 EXPECT_EQ(1UL, parameters.encodings.size());
Oskar Sundbom78807582017-11-16 11:09:55 +01002282 EXPECT_EQ(stream_max, parameters.encodings[0].max_bitrate_bps);
skvladdc1c62c2016-03-16 19:07:43 -07002283 // Verify that the new value propagated down to the encoder
perkjfa10b552016-10-02 23:45:26 -07002284 EXPECT_EQ(expected_encoder_bitrate, GetMaxEncoderBitrate());
skvladdc1c62c2016-03-16 19:07:43 -07002285 }
2286
Åsa Persson55659812018-06-18 17:51:32 +02002287 // Values from kSimulcastConfigs in simulcast.cc.
2288 const std::vector<webrtc::VideoStream> GetSimulcastBitrates720p() const {
2289 std::vector<webrtc::VideoStream> layers(3);
2290 layers[0].min_bitrate_bps = 30000;
2291 layers[0].target_bitrate_bps = 150000;
2292 layers[0].max_bitrate_bps = 200000;
2293 layers[1].min_bitrate_bps = 150000;
2294 layers[1].target_bitrate_bps = 500000;
2295 layers[1].max_bitrate_bps = 700000;
2296 layers[2].min_bitrate_bps = 600000;
2297 layers[2].target_bitrate_bps = 2500000;
2298 layers[2].max_bitrate_bps = 2500000;
2299 return layers;
2300 }
2301
Niels Möller805a27e2019-01-21 12:21:27 +01002302 cricket::FakeFrameSource frame_source_;
kwiberg686a8ef2016-02-26 03:00:35 -08002303 std::unique_ptr<FakeCall> fake_call_;
2304 std::unique_ptr<VideoMediaChannel> channel_;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002305 cricket::VideoSendParameters send_parameters_;
2306 cricket::VideoRecvParameters recv_parameters_;
Peter Boström0c4e06b2015-10-07 12:23:21 +02002307 uint32_t last_ssrc_;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002308};
2309
eladalonf1841382017-06-12 01:16:46 -07002310TEST_F(WebRtcVideoChannelTest, SetsSyncGroupFromSyncLabel) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02002311 const uint32_t kVideoSsrc = 123;
pbos8fc7fa72015-07-15 08:02:58 -07002312 const std::string kSyncLabel = "AvSyncLabel";
2313
2314 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kVideoSsrc);
Seth Hampson845e8782018-03-02 11:34:10 -08002315 sp.set_stream_ids({kSyncLabel});
pbos8fc7fa72015-07-15 08:02:58 -07002316 EXPECT_TRUE(channel_->AddRecvStream(sp));
2317
Mirko Bonadeif859e552018-05-30 15:31:29 +02002318 EXPECT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
pbos8fc7fa72015-07-15 08:02:58 -07002319 EXPECT_EQ(kSyncLabel,
2320 fake_call_->GetVideoReceiveStreams()[0]->GetConfig().sync_group)
2321 << "SyncGroup should be set based on sync_label";
2322}
2323
eladalonf1841382017-06-12 01:16:46 -07002324TEST_F(WebRtcVideoChannelTest, RecvStreamWithSimAndRtx) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002325 cricket::VideoSendParameters parameters;
2326 parameters.codecs = engine_.codecs();
2327 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002328 EXPECT_TRUE(channel_->SetSend(true));
nisse4b4dc862016-02-17 05:25:36 -08002329 parameters.conference_mode = true;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002330 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002331
2332 // Send side.
Peter Boström0c4e06b2015-10-07 12:23:21 +02002333 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
2334 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002335 FakeVideoSendStream* send_stream = AddSendStream(
2336 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
2337
2338 ASSERT_EQ(rtx_ssrcs.size(), send_stream->GetConfig().rtp.rtx.ssrcs.size());
2339 for (size_t i = 0; i < rtx_ssrcs.size(); ++i)
2340 EXPECT_EQ(rtx_ssrcs[i], send_stream->GetConfig().rtp.rtx.ssrcs[i]);
2341
2342 // Receiver side.
2343 FakeVideoReceiveStream* recv_stream = AddRecvStream(
2344 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
nisse26e3abb2017-08-25 04:44:25 -07002345 EXPECT_FALSE(
2346 recv_stream->GetConfig().rtp.rtx_associated_payload_types.empty());
nisseca5706d2017-09-11 02:32:16 -07002347 EXPECT_TRUE(VerifyRtxReceiveAssociations(recv_stream->GetConfig()))
Peter Boströmd8b01092016-05-12 16:44:36 +02002348 << "RTX should be mapped for all decoders/payload types.";
nisseca5706d2017-09-11 02:32:16 -07002349 EXPECT_TRUE(HasRtxReceiveAssociation(recv_stream->GetConfig(),
Yves Gerey665174f2018-06-19 15:03:05 +02002350 GetEngineCodec("red").id))
nisseca5706d2017-09-11 02:32:16 -07002351 << "RTX should be mapped for the RED payload type";
2352
brandtr14742122017-01-27 04:53:07 -08002353 EXPECT_EQ(rtx_ssrcs[0], recv_stream->GetConfig().rtp.rtx_ssrc);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002354}
2355
eladalonf1841382017-06-12 01:16:46 -07002356TEST_F(WebRtcVideoChannelTest, RecvStreamWithRtx) {
pbos@webrtc.orge322a172014-06-13 11:47:28 +00002357 // Setup one channel with an associated RTX stream.
2358 cricket::StreamParams params =
2359 cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
2360 params.AddFidSsrc(kSsrcs1[0], kRtxSsrcs1[0]);
2361 FakeVideoReceiveStream* recv_stream = AddRecvStream(params);
brandtr14742122017-01-27 04:53:07 -08002362 EXPECT_EQ(kRtxSsrcs1[0], recv_stream->GetConfig().rtp.rtx_ssrc);
nisseca5706d2017-09-11 02:32:16 -07002363
2364 EXPECT_TRUE(VerifyRtxReceiveAssociations(recv_stream->GetConfig()))
2365 << "RTX should be mapped for all decoders/payload types.";
2366 EXPECT_TRUE(HasRtxReceiveAssociation(recv_stream->GetConfig(),
Yves Gerey665174f2018-06-19 15:03:05 +02002367 GetEngineCodec("red").id))
nisseca5706d2017-09-11 02:32:16 -07002368 << "RTX should be mapped for the RED payload type";
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002369}
2370
eladalonf1841382017-06-12 01:16:46 -07002371TEST_F(WebRtcVideoChannelTest, RecvStreamNoRtx) {
pbos@webrtc.orge322a172014-06-13 11:47:28 +00002372 // Setup one channel without an associated RTX stream.
2373 cricket::StreamParams params =
2374 cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
2375 FakeVideoReceiveStream* recv_stream = AddRecvStream(params);
brandtr14742122017-01-27 04:53:07 -08002376 ASSERT_EQ(0U, recv_stream->GetConfig().rtp.rtx_ssrc);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002377}
2378
Johannes Kron9190b822018-10-29 11:22:05 +01002379// Test propagation of extmap allow mixed setting.
2380TEST_F(WebRtcVideoChannelTest, SetExtmapAllowMixedAsCaller) {
2381 TestExtmapAllowMixedCaller(/*extmap_allow_mixed=*/true);
2382}
2383TEST_F(WebRtcVideoChannelTest, SetExtmapAllowMixedDisabledAsCaller) {
2384 TestExtmapAllowMixedCaller(/*extmap_allow_mixed=*/false);
2385}
2386TEST_F(WebRtcVideoChannelTest, SetExtmapAllowMixedAsCallee) {
2387 TestExtmapAllowMixedCallee(/*extmap_allow_mixed=*/true);
2388}
2389TEST_F(WebRtcVideoChannelTest, SetExtmapAllowMixedDisabledAsCallee) {
2390 TestExtmapAllowMixedCallee(/*extmap_allow_mixed=*/false);
2391}
2392
eladalonf1841382017-06-12 01:16:46 -07002393TEST_F(WebRtcVideoChannelTest, NoHeaderExtesionsByDefault) {
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002394 FakeVideoSendStream* send_stream =
2395 AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcs1[0]));
2396 ASSERT_TRUE(send_stream->GetConfig().rtp.extensions.empty());
2397
2398 FakeVideoReceiveStream* recv_stream =
2399 AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrcs1[0]));
2400 ASSERT_TRUE(recv_stream->GetConfig().rtp.extensions.empty());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002401}
2402
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002403// Test support for RTP timestamp offset header extension.
eladalonf1841382017-06-12 01:16:46 -07002404TEST_F(WebRtcVideoChannelTest, SendRtpTimestampOffsetHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002405 TestSetSendRtpHeaderExtensions(RtpExtension::kTimestampOffsetUri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002406}
isheriff6f8d6862016-05-26 11:24:55 -07002407
eladalonf1841382017-06-12 01:16:46 -07002408TEST_F(WebRtcVideoChannelTest, RecvRtpTimestampOffsetHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002409 TestSetRecvRtpHeaderExtensions(RtpExtension::kTimestampOffsetUri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002410}
2411
2412// Test support for absolute send time header extension.
eladalonf1841382017-06-12 01:16:46 -07002413TEST_F(WebRtcVideoChannelTest, SendAbsoluteSendTimeHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002414 TestSetSendRtpHeaderExtensions(RtpExtension::kAbsSendTimeUri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002415}
isheriff6f8d6862016-05-26 11:24:55 -07002416
eladalonf1841382017-06-12 01:16:46 -07002417TEST_F(WebRtcVideoChannelTest, RecvAbsoluteSendTimeHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002418 TestSetRecvRtpHeaderExtensions(RtpExtension::kAbsSendTimeUri);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002419}
2420
eladalonf1841382017-06-12 01:16:46 -07002421TEST_F(WebRtcVideoChannelTest, FiltersExtensionsPicksTransportSeqNum) {
Stefan Holmerbbaf3632015-10-29 18:53:23 +01002422 // Enable three redundant extensions.
2423 std::vector<std::string> extensions;
isheriff6f8d6862016-05-26 11:24:55 -07002424 extensions.push_back(RtpExtension::kAbsSendTimeUri);
2425 extensions.push_back(RtpExtension::kTimestampOffsetUri);
2426 extensions.push_back(RtpExtension::kTransportSequenceNumberUri);
2427 TestExtensionFilter(extensions, RtpExtension::kTransportSequenceNumberUri);
Stefan Holmerbbaf3632015-10-29 18:53:23 +01002428}
2429
eladalonf1841382017-06-12 01:16:46 -07002430TEST_F(WebRtcVideoChannelTest, FiltersExtensionsPicksAbsSendTime) {
Stefan Holmerbbaf3632015-10-29 18:53:23 +01002431 // Enable two redundant extensions.
2432 std::vector<std::string> extensions;
isheriff6f8d6862016-05-26 11:24:55 -07002433 extensions.push_back(RtpExtension::kAbsSendTimeUri);
2434 extensions.push_back(RtpExtension::kTimestampOffsetUri);
2435 TestExtensionFilter(extensions, RtpExtension::kAbsSendTimeUri);
Stefan Holmerbbaf3632015-10-29 18:53:23 +01002436}
2437
stefanc1aeaf02015-10-15 07:26:07 -07002438// Test support for transport sequence number header extension.
eladalonf1841382017-06-12 01:16:46 -07002439TEST_F(WebRtcVideoChannelTest, SendTransportSequenceNumberHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002440 TestSetSendRtpHeaderExtensions(RtpExtension::kTransportSequenceNumberUri);
stefanc1aeaf02015-10-15 07:26:07 -07002441}
eladalonf1841382017-06-12 01:16:46 -07002442TEST_F(WebRtcVideoChannelTest, RecvTransportSequenceNumberHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002443 TestSetRecvRtpHeaderExtensions(RtpExtension::kTransportSequenceNumberUri);
stefanc1aeaf02015-10-15 07:26:07 -07002444}
2445
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -07002446// Test support for video rotation header extension.
eladalonf1841382017-06-12 01:16:46 -07002447TEST_F(WebRtcVideoChannelTest, SendVideoRotationHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002448 TestSetSendRtpHeaderExtensions(RtpExtension::kVideoRotationUri);
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -07002449}
eladalonf1841382017-06-12 01:16:46 -07002450TEST_F(WebRtcVideoChannelTest, RecvVideoRotationHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002451 TestSetRecvRtpHeaderExtensions(RtpExtension::kVideoRotationUri);
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -07002452}
2453
eladalonf1841382017-06-12 01:16:46 -07002454TEST_F(WebRtcVideoChannelTest, IdenticalSendExtensionsDoesntRecreateStream) {
Stefan Holmerbbaf3632015-10-29 18:53:23 +01002455 const int kAbsSendTimeId = 1;
2456 const int kVideoRotationId = 2;
isheriff6f8d6862016-05-26 11:24:55 -07002457 send_parameters_.extensions.push_back(
2458 RtpExtension(RtpExtension::kAbsSendTimeUri, kAbsSendTimeId));
2459 send_parameters_.extensions.push_back(
2460 RtpExtension(RtpExtension::kVideoRotationUri, kVideoRotationId));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00002461
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002462 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00002463 FakeVideoSendStream* send_stream =
2464 AddSendStream(cricket::StreamParams::CreateLegacy(123));
2465
2466 EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());
Stefan Holmerbbaf3632015-10-29 18:53:23 +01002467 ASSERT_EQ(2u, send_stream->GetConfig().rtp.extensions.size());
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00002468
2469 // Setting the same extensions (even if in different order) shouldn't
2470 // reallocate the stream.
Steve Anton2c9ebef2019-01-28 17:27:58 -08002471 absl::c_reverse(send_parameters_.extensions);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002472 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00002473
2474 EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());
2475
2476 // Setting different extensions should recreate the stream.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002477 send_parameters_.extensions.resize(1);
2478 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00002479
2480 EXPECT_EQ(2, fake_call_->GetNumCreatedSendStreams());
2481}
2482
eladalonf1841382017-06-12 01:16:46 -07002483TEST_F(WebRtcVideoChannelTest, IdenticalRecvExtensionsDoesntRecreateStream) {
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00002484 const int kTOffsetId = 1;
2485 const int kAbsSendTimeId = 2;
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -07002486 const int kVideoRotationId = 3;
isheriff6f8d6862016-05-26 11:24:55 -07002487 recv_parameters_.extensions.push_back(
2488 RtpExtension(RtpExtension::kAbsSendTimeUri, kAbsSendTimeId));
2489 recv_parameters_.extensions.push_back(
2490 RtpExtension(RtpExtension::kTimestampOffsetUri, kTOffsetId));
2491 recv_parameters_.extensions.push_back(
2492 RtpExtension(RtpExtension::kVideoRotationUri, kVideoRotationId));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00002493
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002494 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
Peter Boström54be3e02015-05-25 15:04:24 +02002495 FakeVideoReceiveStream* recv_stream =
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00002496 AddRecvStream(cricket::StreamParams::CreateLegacy(123));
2497
2498 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
Peter Boström54be3e02015-05-25 15:04:24 +02002499 ASSERT_EQ(3u, recv_stream->GetConfig().rtp.extensions.size());
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00002500
2501 // Setting the same extensions (even if in different order) shouldn't
2502 // reallocate the stream.
Steve Anton2c9ebef2019-01-28 17:27:58 -08002503 absl::c_reverse(recv_parameters_.extensions);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002504 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00002505
2506 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
2507
2508 // Setting different extensions should recreate the stream.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002509 recv_parameters_.extensions.resize(1);
2510 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00002511
2512 EXPECT_EQ(2, fake_call_->GetNumCreatedReceiveStreams());
2513}
2514
eladalonf1841382017-06-12 01:16:46 -07002515TEST_F(WebRtcVideoChannelTest,
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002516 SetSendRtpHeaderExtensionsExcludeUnsupportedExtensions) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002517 const int kUnsupportedId = 1;
2518 const int kTOffsetId = 2;
2519
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002520 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002521 RtpExtension(kUnsupportedExtensionName, kUnsupportedId));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002522 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002523 RtpExtension(RtpExtension::kTimestampOffsetUri, kTOffsetId));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002524 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002525 FakeVideoSendStream* send_stream =
2526 AddSendStream(cricket::StreamParams::CreateLegacy(123));
2527
2528 // Only timestamp offset extension is set to send stream,
2529 // unsupported rtp extension is ignored.
2530 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
isheriff6f8d6862016-05-26 11:24:55 -07002531 EXPECT_STREQ(RtpExtension::kTimestampOffsetUri,
2532 send_stream->GetConfig().rtp.extensions[0].uri.c_str());
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002533}
2534
eladalonf1841382017-06-12 01:16:46 -07002535TEST_F(WebRtcVideoChannelTest,
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002536 SetRecvRtpHeaderExtensionsExcludeUnsupportedExtensions) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002537 const int kUnsupportedId = 1;
2538 const int kTOffsetId = 2;
2539
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002540 recv_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002541 RtpExtension(kUnsupportedExtensionName, kUnsupportedId));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002542 recv_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002543 RtpExtension(RtpExtension::kTimestampOffsetUri, kTOffsetId));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002544 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002545 FakeVideoReceiveStream* recv_stream =
2546 AddRecvStream(cricket::StreamParams::CreateLegacy(123));
2547
2548 // Only timestamp offset extension is set to receive stream,
2549 // unsupported rtp extension is ignored.
2550 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.extensions.size());
isheriff6f8d6862016-05-26 11:24:55 -07002551 EXPECT_STREQ(RtpExtension::kTimestampOffsetUri,
2552 recv_stream->GetConfig().rtp.extensions[0].uri.c_str());
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002553}
2554
eladalonf1841382017-06-12 01:16:46 -07002555TEST_F(WebRtcVideoChannelTest, SetSendRtpHeaderExtensionsRejectsIncorrectIds) {
Peter Boström23914fe2015-03-31 15:08:04 +02002556 const int kIncorrectIds[] = {-2, -1, 0, 15, 16};
pkasting@chromium.orge7a4a122015-01-28 21:36:55 +00002557 for (size_t i = 0; i < arraysize(kIncorrectIds); ++i) {
isheriff6f8d6862016-05-26 11:24:55 -07002558 send_parameters_.extensions.push_back(
2559 RtpExtension(RtpExtension::kTimestampOffsetUri, kIncorrectIds[i]));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002560 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_))
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002561 << "Bad extension id '" << kIncorrectIds[i] << "' accepted.";
2562 }
2563}
2564
eladalonf1841382017-06-12 01:16:46 -07002565TEST_F(WebRtcVideoChannelTest, SetRecvRtpHeaderExtensionsRejectsIncorrectIds) {
Peter Boström23914fe2015-03-31 15:08:04 +02002566 const int kIncorrectIds[] = {-2, -1, 0, 15, 16};
pkasting@chromium.orge7a4a122015-01-28 21:36:55 +00002567 for (size_t i = 0; i < arraysize(kIncorrectIds); ++i) {
isheriff6f8d6862016-05-26 11:24:55 -07002568 recv_parameters_.extensions.push_back(
2569 RtpExtension(RtpExtension::kTimestampOffsetUri, kIncorrectIds[i]));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002570 EXPECT_FALSE(channel_->SetRecvParameters(recv_parameters_))
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002571 << "Bad extension id '" << kIncorrectIds[i] << "' accepted.";
2572 }
2573}
2574
eladalonf1841382017-06-12 01:16:46 -07002575TEST_F(WebRtcVideoChannelTest, SetSendRtpHeaderExtensionsRejectsDuplicateIds) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002576 const int id = 1;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002577 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002578 RtpExtension(RtpExtension::kTimestampOffsetUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002579 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002580 RtpExtension(RtpExtension::kAbsSendTimeUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002581 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002582
2583 // Duplicate entries are also not supported.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002584 send_parameters_.extensions.clear();
2585 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002586 RtpExtension(RtpExtension::kTimestampOffsetUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002587 send_parameters_.extensions.push_back(send_parameters_.extensions.back());
2588 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002589}
2590
eladalonf1841382017-06-12 01:16:46 -07002591TEST_F(WebRtcVideoChannelTest, SetRecvRtpHeaderExtensionsRejectsDuplicateIds) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002592 const int id = 1;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002593 recv_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002594 RtpExtension(RtpExtension::kTimestampOffsetUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002595 recv_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002596 RtpExtension(RtpExtension::kAbsSendTimeUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002597 EXPECT_FALSE(channel_->SetRecvParameters(recv_parameters_));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002598
2599 // Duplicate entries are also not supported.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002600 recv_parameters_.extensions.clear();
2601 recv_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002602 RtpExtension(RtpExtension::kTimestampOffsetUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002603 recv_parameters_.extensions.push_back(recv_parameters_.extensions.back());
2604 EXPECT_FALSE(channel_->SetRecvParameters(recv_parameters_));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002605}
2606
eladalonf1841382017-06-12 01:16:46 -07002607TEST_F(WebRtcVideoChannelTest, AddRecvStreamOnlyUsesOneReceiveStream) {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002608 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002609 EXPECT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002610}
2611
eladalonf1841382017-06-12 01:16:46 -07002612TEST_F(WebRtcVideoChannelTest, RtcpIsCompoundByDefault) {
Peter Boströmd7da1202015-06-05 14:09:38 +02002613 FakeVideoReceiveStream* stream = AddRecvStream();
pbosda903ea2015-10-02 02:36:56 -07002614 EXPECT_EQ(webrtc::RtcpMode::kCompound, stream->GetConfig().rtp.rtcp_mode);
Peter Boströmd7da1202015-06-05 14:09:38 +02002615}
2616
eladalonf1841382017-06-12 01:16:46 -07002617TEST_F(WebRtcVideoChannelTest, RembIsEnabledByDefault) {
pbos@webrtc.org257e1302014-07-25 19:01:32 +00002618 FakeVideoReceiveStream* stream = AddRecvStream();
2619 EXPECT_TRUE(stream->GetConfig().rtp.remb);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002620}
2621
eladalonf1841382017-06-12 01:16:46 -07002622TEST_F(WebRtcVideoChannelTest, TransportCcIsEnabledByDefault) {
stefan43edf0f2015-11-20 18:05:48 -08002623 FakeVideoReceiveStream* stream = AddRecvStream();
2624 EXPECT_TRUE(stream->GetConfig().rtp.transport_cc);
2625}
2626
eladalonf1841382017-06-12 01:16:46 -07002627TEST_F(WebRtcVideoChannelTest, RembCanBeEnabledAndDisabled) {
pbos@webrtc.org257e1302014-07-25 19:01:32 +00002628 FakeVideoReceiveStream* stream = AddRecvStream();
2629 EXPECT_TRUE(stream->GetConfig().rtp.remb);
2630
Peter Boström126c03e2015-05-11 12:48:12 +02002631 // Verify that REMB is turned off when send(!) codecs without REMB are set.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002632 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002633 parameters.codecs.push_back(RemoveFeedbackParams(GetEngineCodec("VP8")));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002634 EXPECT_TRUE(parameters.codecs[0].feedback_params.params().empty());
2635 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002636 stream = fake_call_->GetVideoReceiveStreams()[0];
pbos@webrtc.org257e1302014-07-25 19:01:32 +00002637 EXPECT_FALSE(stream->GetConfig().rtp.remb);
2638
2639 // Verify that REMB is turned on when setting default codecs since the
2640 // default codecs have REMB enabled.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002641 parameters.codecs = engine_.codecs();
2642 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002643 stream = fake_call_->GetVideoReceiveStreams()[0];
pbos@webrtc.org257e1302014-07-25 19:01:32 +00002644 EXPECT_TRUE(stream->GetConfig().rtp.remb);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002645}
2646
eladalonf1841382017-06-12 01:16:46 -07002647TEST_F(WebRtcVideoChannelTest, TransportCcCanBeEnabledAndDisabled) {
stefan43edf0f2015-11-20 18:05:48 -08002648 FakeVideoReceiveStream* stream = AddRecvStream();
2649 EXPECT_TRUE(stream->GetConfig().rtp.transport_cc);
2650
2651 // Verify that transport cc feedback is turned off when send(!) codecs without
2652 // transport cc feedback are set.
2653 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002654 parameters.codecs.push_back(RemoveFeedbackParams(GetEngineCodec("VP8")));
stefan43edf0f2015-11-20 18:05:48 -08002655 EXPECT_TRUE(parameters.codecs[0].feedback_params.params().empty());
2656 EXPECT_TRUE(channel_->SetSendParameters(parameters));
2657 stream = fake_call_->GetVideoReceiveStreams()[0];
2658 EXPECT_FALSE(stream->GetConfig().rtp.transport_cc);
2659
2660 // Verify that transport cc feedback is turned on when setting default codecs
2661 // since the default codecs have transport cc feedback enabled.
2662 parameters.codecs = engine_.codecs();
2663 EXPECT_TRUE(channel_->SetSendParameters(parameters));
2664 stream = fake_call_->GetVideoReceiveStreams()[0];
2665 EXPECT_TRUE(stream->GetConfig().rtp.transport_cc);
2666}
2667
eladalonf1841382017-06-12 01:16:46 -07002668TEST_F(WebRtcVideoChannelTest, NackIsEnabledByDefault) {
Anders Carlsson5f2bb622018-05-14 09:48:06 +02002669 AssignDefaultCodec();
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +00002670 VerifyCodecHasDefaultFeedbackParams(default_codec_);
2671
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002672 cricket::VideoSendParameters parameters;
2673 parameters.codecs = engine_.codecs();
2674 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org19864742014-05-30 07:35:47 +00002675 EXPECT_TRUE(channel_->SetSend(true));
2676
2677 // Send side.
2678 FakeVideoSendStream* send_stream =
2679 AddSendStream(cricket::StreamParams::CreateLegacy(1));
2680 EXPECT_GT(send_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
2681
2682 // Receiver side.
2683 FakeVideoReceiveStream* recv_stream =
2684 AddRecvStream(cricket::StreamParams::CreateLegacy(1));
2685 EXPECT_GT(recv_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
2686
2687 // Nack history size should match between sender and receiver.
2688 EXPECT_EQ(send_stream->GetConfig().rtp.nack.rtp_history_ms,
2689 recv_stream->GetConfig().rtp.nack.rtp_history_ms);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002690}
2691
eladalonf1841382017-06-12 01:16:46 -07002692TEST_F(WebRtcVideoChannelTest, NackCanBeEnabledAndDisabled) {
Peter Boström67c9df72015-05-11 14:34:58 +02002693 FakeVideoSendStream* send_stream = AddSendStream();
Peter Boström3548dd22015-05-22 18:48:36 +02002694 FakeVideoReceiveStream* recv_stream = AddRecvStream();
Peter Boström67c9df72015-05-11 14:34:58 +02002695
2696 EXPECT_GT(recv_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
2697 EXPECT_GT(send_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
2698
2699 // Verify that NACK is turned off when send(!) codecs without NACK are set.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002700 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002701 parameters.codecs.push_back(RemoveFeedbackParams(GetEngineCodec("VP8")));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002702 EXPECT_TRUE(parameters.codecs[0].feedback_params.params().empty());
2703 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Peter Boström67c9df72015-05-11 14:34:58 +02002704 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
2705 EXPECT_EQ(0, recv_stream->GetConfig().rtp.nack.rtp_history_ms);
2706 send_stream = fake_call_->GetVideoSendStreams()[0];
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +00002707 EXPECT_EQ(0, send_stream->GetConfig().rtp.nack.rtp_history_ms);
2708
Peter Boström67c9df72015-05-11 14:34:58 +02002709 // Verify that NACK is turned on when setting default codecs since the
2710 // default codecs have NACK enabled.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002711 parameters.codecs = engine_.codecs();
2712 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Peter Boström67c9df72015-05-11 14:34:58 +02002713 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
2714 EXPECT_GT(recv_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
2715 send_stream = fake_call_->GetVideoSendStreams()[0];
2716 EXPECT_GT(send_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +00002717}
2718
Peter Boströme7ba0862016-03-12 00:02:28 +01002719// This test verifies that new frame sizes reconfigures encoders even though not
2720// (yet) sending. The purpose of this is to permit encoding as quickly as
2721// possible once we start sending. Likely the frames being input are from the
2722// same source that will be sent later, which just means that we're ready
2723// earlier.
eladalonf1841382017-06-12 01:16:46 -07002724TEST_F(WebRtcVideoChannelTest, ReconfiguresEncodersWhenNotSending) {
Peter Boströme7ba0862016-03-12 00:02:28 +01002725 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002726 parameters.codecs.push_back(GetEngineCodec("VP8"));
Peter Boströme7ba0862016-03-12 00:02:28 +01002727 ASSERT_TRUE(channel_->SetSendParameters(parameters));
2728 channel_->SetSend(false);
2729
2730 FakeVideoSendStream* stream = AddSendStream();
2731
perkjfa10b552016-10-02 23:45:26 -07002732 // No frames entered.
Peter Boströme7ba0862016-03-12 00:02:28 +01002733 std::vector<webrtc::VideoStream> streams = stream->GetVideoStreams();
Danil Chapovalov350531e2018-06-08 11:04:04 +00002734 EXPECT_EQ(0u, streams[0].width);
2735 EXPECT_EQ(0u, streams[0].height);
Peter Boströme7ba0862016-03-12 00:02:28 +01002736
Niels Möller805a27e2019-01-21 12:21:27 +01002737 webrtc::test::FrameForwarder frame_forwarder;
2738 cricket::FakeFrameSource frame_source(1280, 720,
2739 rtc::kNumMicrosecsPerSec / 30);
2740
2741 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));
2742 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
Peter Boströme7ba0862016-03-12 00:02:28 +01002743
2744 // Frame entered, should be reconfigured to new dimensions.
2745 streams = stream->GetVideoStreams();
Niels Möller805a27e2019-01-21 12:21:27 +01002746 EXPECT_EQ(rtc::checked_cast<size_t>(1280), streams[0].width);
2747 EXPECT_EQ(rtc::checked_cast<size_t>(720), streams[0].height);
Peter Boströme7ba0862016-03-12 00:02:28 +01002748
Niels Möllerff40b142018-04-09 08:49:14 +02002749 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
Peter Boströme7ba0862016-03-12 00:02:28 +01002750}
2751
eladalonf1841382017-06-12 01:16:46 -07002752TEST_F(WebRtcVideoChannelTest, UsesCorrectSettingsForScreencast) {
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00002753 static const int kScreenshareMinBitrateKbps = 800;
magjed509e4fe2016-11-18 01:34:11 -08002754 cricket::VideoCodec codec = GetEngineCodec("VP8");
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002755 cricket::VideoSendParameters parameters;
2756 parameters.codecs.push_back(codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002757 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00002758 AddSendStream();
2759
Niels Möller805a27e2019-01-21 12:21:27 +01002760 webrtc::test::FrameForwarder frame_forwarder;
2761 cricket::FakeFrameSource frame_source(1280, 720,
2762 rtc::kNumMicrosecsPerSec / 30);
nisse05103312016-03-16 02:22:50 -07002763 VideoOptions min_bitrate_options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002764 min_bitrate_options.screencast_min_bitrate_kbps = kScreenshareMinBitrateKbps;
Niels Möller805a27e2019-01-21 12:21:27 +01002765 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &min_bitrate_options,
2766 &frame_forwarder));
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00002767
2768 EXPECT_TRUE(channel_->SetSend(true));
2769
Niels Möller805a27e2019-01-21 12:21:27 +01002770 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00002771 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
2772 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
2773
2774 EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());
2775
2776 // Verify non-screencast settings.
perkj26091b12016-09-01 01:17:40 -07002777 webrtc::VideoEncoderConfig encoder_config =
2778 send_stream->GetEncoderConfig().Copy();
Erik Språng143cec12015-04-28 10:01:41 +02002779 EXPECT_EQ(webrtc::VideoEncoderConfig::ContentType::kRealtimeVideo,
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00002780 encoder_config.content_type);
perkjfa10b552016-10-02 23:45:26 -07002781 std::vector<webrtc::VideoStream> streams = send_stream->GetVideoStreams();
Niels Möller805a27e2019-01-21 12:21:27 +01002782 EXPECT_EQ(rtc::checked_cast<size_t>(1280), streams.front().width);
2783 EXPECT_EQ(rtc::checked_cast<size_t>(720), streams.front().height);
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00002784 EXPECT_EQ(0, encoder_config.min_transmit_bitrate_bps)
2785 << "Non-screenshare shouldn't use min-transmit bitrate.";
2786
Niels Möllerff40b142018-04-09 08:49:14 +02002787 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
perkjd533aec2017-01-13 05:57:25 -08002788 EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());
nisse05103312016-03-16 02:22:50 -07002789 VideoOptions screencast_options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002790 screencast_options.is_screencast = true;
Niels Möller805a27e2019-01-21 12:21:27 +01002791 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &screencast_options,
2792 &frame_forwarder));
2793 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
sprangf24a0642017-02-28 13:23:26 -08002794 // Send stream recreated after option change.
2795 ASSERT_EQ(2, fake_call_->GetNumCreatedSendStreams());
2796 send_stream = fake_call_->GetVideoSendStreams().front();
2797 EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00002798
2799 // Verify screencast settings.
perkj26091b12016-09-01 01:17:40 -07002800 encoder_config = send_stream->GetEncoderConfig().Copy();
Erik Språng143cec12015-04-28 10:01:41 +02002801 EXPECT_EQ(webrtc::VideoEncoderConfig::ContentType::kScreen,
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00002802 encoder_config.content_type);
2803 EXPECT_EQ(kScreenshareMinBitrateKbps * 1000,
2804 encoder_config.min_transmit_bitrate_bps);
2805
perkjfa10b552016-10-02 23:45:26 -07002806 streams = send_stream->GetVideoStreams();
Niels Möller805a27e2019-01-21 12:21:27 +01002807 EXPECT_EQ(rtc::checked_cast<size_t>(1280), streams.front().width);
2808 EXPECT_EQ(rtc::checked_cast<size_t>(720), streams.front().height);
Sergey Silkina796a7e2018-03-01 15:11:29 +01002809 EXPECT_FALSE(streams[0].num_temporal_layers.has_value());
Niels Möllerff40b142018-04-09 08:49:14 +02002810 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002811}
2812
eladalonf1841382017-06-12 01:16:46 -07002813TEST_F(WebRtcVideoChannelTest,
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002814 ConferenceModeScreencastConfiguresTemporalLayer) {
Rasmus Brandt195d1d72018-05-09 11:28:01 +02002815 static const int kConferenceScreencastTemporalBitrateBps = 200 * 1000;
nisse4b4dc862016-02-17 05:25:36 -08002816 send_parameters_.conference_mode = true;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002817 channel_->SetSendParameters(send_parameters_);
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002818
2819 AddSendStream();
nisse05103312016-03-16 02:22:50 -07002820 VideoOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002821 options.is_screencast = true;
Niels Möller805a27e2019-01-21 12:21:27 +01002822 webrtc::test::FrameForwarder frame_forwarder;
2823 cricket::FakeFrameSource frame_source(1280, 720,
2824 rtc::kNumMicrosecsPerSec / 30);
2825 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002826 EXPECT_TRUE(channel_->SetSend(true));
2827
Niels Möller805a27e2019-01-21 12:21:27 +01002828 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002829 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
2830 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
2831
perkj26091b12016-09-01 01:17:40 -07002832 webrtc::VideoEncoderConfig encoder_config =
2833 send_stream->GetEncoderConfig().Copy();
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002834
2835 // Verify screencast settings.
perkj26091b12016-09-01 01:17:40 -07002836 encoder_config = send_stream->GetEncoderConfig().Copy();
Erik Språng143cec12015-04-28 10:01:41 +02002837 EXPECT_EQ(webrtc::VideoEncoderConfig::ContentType::kScreen,
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002838 encoder_config.content_type);
perkjfa10b552016-10-02 23:45:26 -07002839
2840 std::vector<webrtc::VideoStream> streams = send_stream->GetVideoStreams();
2841 ASSERT_EQ(1u, streams.size());
Sergey Silkina796a7e2018-03-01 15:11:29 +01002842 ASSERT_EQ(2u, streams[0].num_temporal_layers);
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002843 EXPECT_EQ(kConferenceScreencastTemporalBitrateBps,
Sergey Silkina796a7e2018-03-01 15:11:29 +01002844 streams[0].target_bitrate_bps);
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00002845
Niels Möllerff40b142018-04-09 08:49:14 +02002846 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002847}
2848
eladalonf1841382017-06-12 01:16:46 -07002849TEST_F(WebRtcVideoChannelTest, SuspendBelowMinBitrateDisabledByDefault) {
pbos@webrtc.org5ff71ab2014-07-23 07:28:56 +00002850 FakeVideoSendStream* stream = AddSendStream();
2851 EXPECT_FALSE(stream->GetConfig().suspend_below_min_bitrate);
2852}
2853
eladalonf1841382017-06-12 01:16:46 -07002854TEST_F(WebRtcVideoChannelTest, SetMediaConfigSuspendBelowMinBitrate) {
kthelgason2bc68642017-02-07 07:02:22 -08002855 MediaConfig media_config = GetMediaConfig();
nisse0db023a2016-03-01 04:29:59 -08002856 media_config.video.suspend_below_min_bitrate = true;
2857
Sebastian Jansson84848f22018-11-16 10:40:36 +01002858 channel_.reset(engine_.CreateMediaChannel(
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07002859 fake_call_.get(), media_config, VideoOptions(), webrtc::CryptoOptions()));
Sergey Ulanove2b15012016-11-22 16:08:30 -08002860 channel_->OnReadyToSend(true);
nisse0db023a2016-03-01 04:29:59 -08002861
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002862 channel_->SetSendParameters(send_parameters_);
pbos@webrtc.org5ff71ab2014-07-23 07:28:56 +00002863
2864 FakeVideoSendStream* stream = AddSendStream();
2865 EXPECT_TRUE(stream->GetConfig().suspend_below_min_bitrate);
2866
nisse0db023a2016-03-01 04:29:59 -08002867 media_config.video.suspend_below_min_bitrate = false;
Sebastian Jansson84848f22018-11-16 10:40:36 +01002868 channel_.reset(engine_.CreateMediaChannel(
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07002869 fake_call_.get(), media_config, VideoOptions(), webrtc::CryptoOptions()));
Sergey Ulanove2b15012016-11-22 16:08:30 -08002870 channel_->OnReadyToSend(true);
nisse0db023a2016-03-01 04:29:59 -08002871
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002872 channel_->SetSendParameters(send_parameters_);
pbos@webrtc.org5ff71ab2014-07-23 07:28:56 +00002873
nisse0db023a2016-03-01 04:29:59 -08002874 stream = AddSendStream();
pbos@webrtc.org5ff71ab2014-07-23 07:28:56 +00002875 EXPECT_FALSE(stream->GetConfig().suspend_below_min_bitrate);
2876}
2877
eladalonf1841382017-06-12 01:16:46 -07002878TEST_F(WebRtcVideoChannelTest, Vp8DenoisingEnabledByDefault) {
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00002879 FakeVideoSendStream* stream = AddSendStream();
2880 webrtc::VideoCodecVP8 vp8_settings;
2881 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
2882 EXPECT_TRUE(vp8_settings.denoisingOn);
2883}
2884
eladalonf1841382017-06-12 01:16:46 -07002885TEST_F(WebRtcVideoChannelTest, VerifyVp8SpecificSettings) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002886 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002887 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002888 ASSERT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00002889
Peter Boström2feafdb2015-09-09 14:32:14 +02002890 // Single-stream settings should apply with RTX as well (verifies that we
2891 // check number of regular SSRCs and not StreamParams::ssrcs which contains
2892 // both RTX and regular SSRCs).
2893 FakeVideoSendStream* stream = SetUpSimulcast(false, true);
Erik Språng143cec12015-04-28 10:01:41 +02002894
Niels Möller805a27e2019-01-21 12:21:27 +01002895 webrtc::test::FrameForwarder frame_forwarder;
2896 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));
Erik Språng143cec12015-04-28 10:01:41 +02002897 channel_->SetSend(true);
2898
Niels Möller805a27e2019-01-21 12:21:27 +01002899 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Erik Språng143cec12015-04-28 10:01:41 +02002900
pbos4cba4eb2015-10-26 11:18:18 -07002901 webrtc::VideoCodecVP8 vp8_settings;
2902 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
2903 EXPECT_TRUE(vp8_settings.denoisingOn)
2904 << "VP8 denoising should be on by default.";
2905
Niels Möller805a27e2019-01-21 12:21:27 +01002906 stream = SetDenoisingOption(last_ssrc_, &frame_forwarder, false);
Erik Språng143cec12015-04-28 10:01:41 +02002907
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00002908 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
2909 EXPECT_FALSE(vp8_settings.denoisingOn);
Erik Språng143cec12015-04-28 10:01:41 +02002910 EXPECT_TRUE(vp8_settings.automaticResizeOn);
2911 EXPECT_TRUE(vp8_settings.frameDroppingOn);
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00002912
Niels Möller805a27e2019-01-21 12:21:27 +01002913 stream = SetDenoisingOption(last_ssrc_, &frame_forwarder, true);
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00002914
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00002915 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
2916 EXPECT_TRUE(vp8_settings.denoisingOn);
Erik Språng143cec12015-04-28 10:01:41 +02002917 EXPECT_TRUE(vp8_settings.automaticResizeOn);
2918 EXPECT_TRUE(vp8_settings.frameDroppingOn);
2919
Niels Möllerff40b142018-04-09 08:49:14 +02002920 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
Peter Boström2feafdb2015-09-09 14:32:14 +02002921 stream = SetUpSimulcast(true, false);
Niels Möller805a27e2019-01-21 12:21:27 +01002922 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));
Erik Språng143cec12015-04-28 10:01:41 +02002923 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01002924 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Erik Språng143cec12015-04-28 10:01:41 +02002925
Mirko Bonadeif859e552018-05-30 15:31:29 +02002926 EXPECT_EQ(3u, stream->GetVideoStreams().size());
Erik Språng143cec12015-04-28 10:01:41 +02002927 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
2928 // Autmatic resize off when using simulcast.
2929 EXPECT_FALSE(vp8_settings.automaticResizeOn);
2930 EXPECT_TRUE(vp8_settings.frameDroppingOn);
2931
2932 // In screen-share mode, denoising is forced off and simulcast disabled.
nisse05103312016-03-16 02:22:50 -07002933 VideoOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002934 options.is_screencast = true;
Niels Möller805a27e2019-01-21 12:21:27 +01002935 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
Niels Möller60653ba2016-03-02 11:41:36 +01002936
Niels Möller805a27e2019-01-21 12:21:27 +01002937 stream = SetDenoisingOption(last_ssrc_, &frame_forwarder, false);
Erik Språng143cec12015-04-28 10:01:41 +02002938
Mirko Bonadeif859e552018-05-30 15:31:29 +02002939 EXPECT_EQ(1u, stream->GetVideoStreams().size());
Erik Språng143cec12015-04-28 10:01:41 +02002940 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
2941 EXPECT_FALSE(vp8_settings.denoisingOn);
2942 // Resizing and frame dropping always off for screen sharing.
2943 EXPECT_FALSE(vp8_settings.automaticResizeOn);
2944 EXPECT_FALSE(vp8_settings.frameDroppingOn);
2945
Niels Möller805a27e2019-01-21 12:21:27 +01002946 stream = SetDenoisingOption(last_ssrc_, &frame_forwarder, true);
Erik Språng143cec12015-04-28 10:01:41 +02002947
2948 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
2949 EXPECT_FALSE(vp8_settings.denoisingOn);
2950 EXPECT_FALSE(vp8_settings.automaticResizeOn);
2951 EXPECT_FALSE(vp8_settings.frameDroppingOn);
2952
Niels Möllerff40b142018-04-09 08:49:14 +02002953 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
Erik Språng143cec12015-04-28 10:01:41 +02002954}
2955
deadbeef119760a2016-04-04 11:43:27 -07002956// Test that setting the same options doesn't result in the encoder being
2957// reconfigured.
eladalonf1841382017-06-12 01:16:46 -07002958TEST_F(WebRtcVideoChannelTest, SetIdenticalOptionsDoesntReconfigureEncoder) {
deadbeef119760a2016-04-04 11:43:27 -07002959 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01002960 webrtc::test::FrameForwarder frame_forwarder;
deadbeef119760a2016-04-04 11:43:27 -07002961
perkjfa10b552016-10-02 23:45:26 -07002962 AddSendStream();
perkjfa10b552016-10-02 23:45:26 -07002963 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002964 parameters.codecs.push_back(GetEngineCodec("VP8"));
perkjfa10b552016-10-02 23:45:26 -07002965 ASSERT_TRUE(channel_->SetSendParameters(parameters));
2966 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
2967
Niels Möller805a27e2019-01-21 12:21:27 +01002968 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
2969 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
2970 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
perkjfa10b552016-10-02 23:45:26 -07002971 // Expect 1 reconfigurations at this point from the initial configuration.
2972 EXPECT_EQ(1, send_stream->num_encoder_reconfigurations());
deadbeef119760a2016-04-04 11:43:27 -07002973
2974 // Set the options one more time and expect no additional reconfigurations.
Niels Möller805a27e2019-01-21 12:21:27 +01002975 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
perkjfa10b552016-10-02 23:45:26 -07002976 EXPECT_EQ(1, send_stream->num_encoder_reconfigurations());
2977
2978 // Change |options| and expect 2 reconfigurations.
Oskar Sundbom78807582017-11-16 11:09:55 +01002979 options.video_noise_reduction = true;
Niels Möller805a27e2019-01-21 12:21:27 +01002980 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
deadbeef119760a2016-04-04 11:43:27 -07002981 EXPECT_EQ(2, send_stream->num_encoder_reconfigurations());
2982
Niels Möllerff40b142018-04-09 08:49:14 +02002983 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
deadbeef119760a2016-04-04 11:43:27 -07002984}
2985
eladalonf1841382017-06-12 01:16:46 -07002986class Vp9SettingsTest : public WebRtcVideoChannelTest {
Erik Språng143cec12015-04-28 10:01:41 +02002987 public:
asaperssonc5dabdd2016-03-21 04:15:50 -07002988 Vp9SettingsTest() : Vp9SettingsTest("") {}
2989 explicit Vp9SettingsTest(const char* field_trials)
eladalonf1841382017-06-12 01:16:46 -07002990 : WebRtcVideoChannelTest(field_trials) {
Magnus Jedvert02e7a192017-09-23 17:21:32 +02002991 encoder_factory_->AddSupportedVideoCodecType("VP9");
Erik Språng143cec12015-04-28 10:01:41 +02002992 }
2993 virtual ~Vp9SettingsTest() {}
2994
2995 protected:
Erik Språng143cec12015-04-28 10:01:41 +02002996 void TearDown() override {
2997 // Remove references to encoder_factory_ since this will be destroyed
2998 // before channel_ and engine_.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002999 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
Erik Språng143cec12015-04-28 10:01:41 +02003000 }
Erik Språng143cec12015-04-28 10:01:41 +02003001};
3002
3003TEST_F(Vp9SettingsTest, VerifyVp9SpecificSettings) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003004 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08003005 parameters.codecs.push_back(GetEngineCodec("VP9"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003006 ASSERT_TRUE(channel_->SetSendParameters(parameters));
Erik Språng143cec12015-04-28 10:01:41 +02003007
Peter Boström2feafdb2015-09-09 14:32:14 +02003008 FakeVideoSendStream* stream = SetUpSimulcast(false, false);
Erik Språng143cec12015-04-28 10:01:41 +02003009
Niels Möller805a27e2019-01-21 12:21:27 +01003010 webrtc::test::FrameForwarder frame_forwarder;
3011 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));
Erik Språng143cec12015-04-28 10:01:41 +02003012 channel_->SetSend(true);
3013
Niels Möller805a27e2019-01-21 12:21:27 +01003014 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Erik Språng143cec12015-04-28 10:01:41 +02003015
pbos4cba4eb2015-10-26 11:18:18 -07003016 webrtc::VideoCodecVP9 vp9_settings;
3017 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
jianja5e8aa62017-03-27 10:09:00 -07003018 EXPECT_TRUE(vp9_settings.denoisingOn)
3019 << "VP9 denoising should be on by default.";
pbos4cba4eb2015-10-26 11:18:18 -07003020
Niels Möller805a27e2019-01-21 12:21:27 +01003021 stream = SetDenoisingOption(last_ssrc_, &frame_forwarder, false);
Erik Språng143cec12015-04-28 10:01:41 +02003022
Erik Språng143cec12015-04-28 10:01:41 +02003023 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
3024 EXPECT_FALSE(vp9_settings.denoisingOn);
3025 // Frame dropping always on for real time video.
3026 EXPECT_TRUE(vp9_settings.frameDroppingOn);
3027
Niels Möller805a27e2019-01-21 12:21:27 +01003028 stream = SetDenoisingOption(last_ssrc_, &frame_forwarder, true);
Erik Språng143cec12015-04-28 10:01:41 +02003029
3030 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
3031 EXPECT_TRUE(vp9_settings.denoisingOn);
3032 EXPECT_TRUE(vp9_settings.frameDroppingOn);
3033
3034 // In screen-share mode, denoising is forced off.
nisse05103312016-03-16 02:22:50 -07003035 VideoOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01003036 options.is_screencast = true;
Niels Möller805a27e2019-01-21 12:21:27 +01003037 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
perkj2d5f0912016-02-29 00:04:41 -08003038
Niels Möller805a27e2019-01-21 12:21:27 +01003039 stream = SetDenoisingOption(last_ssrc_, &frame_forwarder, false);
Erik Språng143cec12015-04-28 10:01:41 +02003040
3041 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
3042 EXPECT_FALSE(vp9_settings.denoisingOn);
Sergey Silkinbe71a1e2018-05-17 16:46:43 +02003043 // Frame dropping always on for screen sharing.
3044 EXPECT_TRUE(vp9_settings.frameDroppingOn);
Erik Språng143cec12015-04-28 10:01:41 +02003045
Niels Möller805a27e2019-01-21 12:21:27 +01003046 stream = SetDenoisingOption(last_ssrc_, &frame_forwarder, false);
Erik Språng143cec12015-04-28 10:01:41 +02003047
3048 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
3049 EXPECT_FALSE(vp9_settings.denoisingOn);
Sergey Silkinbe71a1e2018-05-17 16:46:43 +02003050 EXPECT_TRUE(vp9_settings.frameDroppingOn);
Erik Språng143cec12015-04-28 10:01:41 +02003051
Niels Möllerff40b142018-04-09 08:49:14 +02003052 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003053}
3054
Sergey Silkinf18072e2018-03-14 10:35:35 +01003055TEST_F(Vp9SettingsTest, MultipleSsrcsEnablesSvc) {
3056 cricket::VideoSendParameters parameters;
3057 parameters.codecs.push_back(GetEngineCodec("VP9"));
3058 ASSERT_TRUE(channel_->SetSendParameters(parameters));
3059
3060 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
3061
3062 FakeVideoSendStream* stream =
3063 AddSendStream(CreateSimStreamParams("cname", ssrcs));
3064
3065 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
Sergey Silkinf18072e2018-03-14 10:35:35 +01003066
Niels Möller805a27e2019-01-21 12:21:27 +01003067 webrtc::test::FrameForwarder frame_forwarder;
3068 EXPECT_TRUE(channel_->SetVideoSend(ssrcs[0], nullptr, &frame_forwarder));
Sergey Silkinf18072e2018-03-14 10:35:35 +01003069 channel_->SetSend(true);
3070
Niels Möller805a27e2019-01-21 12:21:27 +01003071 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Sergey Silkinf18072e2018-03-14 10:35:35 +01003072
3073 webrtc::VideoCodecVP9 vp9_settings;
3074 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
3075
3076 const size_t kNumSpatialLayers = ssrcs.size();
3077 const size_t kNumTemporalLayers = 3;
3078 EXPECT_EQ(vp9_settings.numberOfSpatialLayers, kNumSpatialLayers);
3079 EXPECT_EQ(vp9_settings.numberOfTemporalLayers, kNumTemporalLayers);
3080
Niels Möllerff40b142018-04-09 08:49:14 +02003081 EXPECT_TRUE(channel_->SetVideoSend(ssrcs[0], nullptr, nullptr));
Sergey Silkinf18072e2018-03-14 10:35:35 +01003082}
3083
Ilya Nikolaevskiy33d2a912019-04-02 11:05:03 +02003084TEST_F(Vp9SettingsTest, SvcModeCreatesSingleRtpStream) {
3085 cricket::VideoSendParameters parameters;
3086 parameters.codecs.push_back(GetEngineCodec("VP9"));
3087 ASSERT_TRUE(channel_->SetSendParameters(parameters));
3088
3089 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
3090
3091 FakeVideoSendStream* stream =
3092 AddSendStream(CreateSimStreamParams("cname", ssrcs));
3093
3094 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
3095
3096 // Despite 3 ssrcs provided, single layer is used.
3097 EXPECT_EQ(1u, config.rtp.ssrcs.size());
3098
3099 webrtc::test::FrameForwarder frame_forwarder;
3100 EXPECT_TRUE(channel_->SetVideoSend(ssrcs[0], nullptr, &frame_forwarder));
3101 channel_->SetSend(true);
3102
3103 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
3104
3105 webrtc::VideoCodecVP9 vp9_settings;
3106 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
3107
3108 const size_t kNumSpatialLayers = ssrcs.size();
3109 EXPECT_EQ(vp9_settings.numberOfSpatialLayers, kNumSpatialLayers);
3110
3111 EXPECT_TRUE(channel_->SetVideoSend(ssrcs[0], nullptr, nullptr));
3112}
3113
Sergey Silkin8b9b5f92018-12-10 09:28:53 +01003114TEST_F(Vp9SettingsTest, AllEncodingParametersCopied) {
3115 cricket::VideoSendParameters send_parameters;
3116 send_parameters.codecs.push_back(GetEngineCodec("VP9"));
3117 ASSERT_TRUE(channel_->SetSendParameters(send_parameters));
3118
3119 const size_t kNumSpatialLayers = 3;
3120 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
3121
3122 FakeVideoSendStream* stream =
3123 AddSendStream(CreateSimStreamParams("cname", ssrcs));
3124
3125 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(ssrcs[0]);
3126 ASSERT_EQ(kNumSpatialLayers, parameters.encodings.size());
3127 ASSERT_TRUE(parameters.encodings[0].active);
3128 ASSERT_TRUE(parameters.encodings[1].active);
3129 ASSERT_TRUE(parameters.encodings[2].active);
3130 // Invert value to verify copying.
3131 parameters.encodings[1].active = false;
3132 EXPECT_TRUE(channel_->SetRtpSendParameters(ssrcs[0], parameters).ok());
3133
3134 webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
3135
3136 // number_of_streams should be 1 since all spatial layers are sent on the
3137 // same SSRC. But encoding parameters of all layers is supposed to be copied
3138 // and stored in simulcast_layers[].
3139 EXPECT_EQ(1u, encoder_config.number_of_streams);
3140 EXPECT_EQ(encoder_config.simulcast_layers.size(), kNumSpatialLayers);
3141 EXPECT_TRUE(encoder_config.simulcast_layers[0].active);
3142 EXPECT_FALSE(encoder_config.simulcast_layers[1].active);
3143 EXPECT_TRUE(encoder_config.simulcast_layers[2].active);
3144}
3145
asaperssonc5dabdd2016-03-21 04:15:50 -07003146class Vp9SettingsTestWithFieldTrial : public Vp9SettingsTest {
3147 public:
brandtr468da7c2016-11-22 02:16:47 -08003148 explicit Vp9SettingsTestWithFieldTrial(const char* field_trials)
asaperssonc5dabdd2016-03-21 04:15:50 -07003149 : Vp9SettingsTest(field_trials) {}
3150
3151 protected:
3152 void VerifySettings(int num_spatial_layers, int num_temporal_layers) {
3153 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08003154 parameters.codecs.push_back(GetEngineCodec("VP9"));
asaperssonc5dabdd2016-03-21 04:15:50 -07003155 ASSERT_TRUE(channel_->SetSendParameters(parameters));
3156
3157 FakeVideoSendStream* stream = SetUpSimulcast(false, false);
3158
Niels Möller805a27e2019-01-21 12:21:27 +01003159 webrtc::test::FrameForwarder frame_forwarder;
3160 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));
asaperssonc5dabdd2016-03-21 04:15:50 -07003161 channel_->SetSend(true);
3162
Niels Möller805a27e2019-01-21 12:21:27 +01003163 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
asaperssonc5dabdd2016-03-21 04:15:50 -07003164
3165 webrtc::VideoCodecVP9 vp9_settings;
3166 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
3167 EXPECT_EQ(num_spatial_layers, vp9_settings.numberOfSpatialLayers);
3168 EXPECT_EQ(num_temporal_layers, vp9_settings.numberOfTemporalLayers);
3169
Niels Möllerff40b142018-04-09 08:49:14 +02003170 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
asaperssonc5dabdd2016-03-21 04:15:50 -07003171 }
3172};
3173
3174class Vp9SettingsTestWithNoFlag : public Vp9SettingsTestWithFieldTrial {
3175 public:
3176 Vp9SettingsTestWithNoFlag() : Vp9SettingsTestWithFieldTrial("") {}
3177};
3178
3179TEST_F(Vp9SettingsTestWithNoFlag, VerifySettings) {
3180 const int kNumSpatialLayers = 1;
3181 const int kNumTemporalLayers = 1;
3182 VerifySettings(kNumSpatialLayers, kNumTemporalLayers);
3183}
3184
3185class Vp9SettingsTestWithInvalidFlag : public Vp9SettingsTestWithFieldTrial {
3186 public:
3187 Vp9SettingsTestWithInvalidFlag()
3188 : Vp9SettingsTestWithFieldTrial("WebRTC-SupportVP9SVC/Default/") {}
3189};
3190
3191TEST_F(Vp9SettingsTestWithInvalidFlag, VerifySettings) {
3192 const int kNumSpatialLayers = 1;
3193 const int kNumTemporalLayers = 1;
3194 VerifySettings(kNumSpatialLayers, kNumTemporalLayers);
3195}
3196
3197class Vp9SettingsTestWith2SL3TLFlag : public Vp9SettingsTestWithFieldTrial {
3198 public:
3199 Vp9SettingsTestWith2SL3TLFlag()
3200 : Vp9SettingsTestWithFieldTrial(
3201 "WebRTC-SupportVP9SVC/EnabledByFlag_2SL3TL/") {}
3202};
3203
3204TEST_F(Vp9SettingsTestWith2SL3TLFlag, VerifySettings) {
3205 const int kNumSpatialLayers = 2;
3206 const int kNumTemporalLayers = 3;
3207 VerifySettings(kNumSpatialLayers, kNumTemporalLayers);
3208}
3209
Åsa Persson45bbc8a2017-11-13 10:16:47 +01003210TEST_F(WebRtcVideoChannelTest, VerifyMinBitrate) {
3211 std::vector<webrtc::VideoStream> streams = AddSendStream()->GetVideoStreams();
3212 ASSERT_EQ(1u, streams.size());
3213 EXPECT_EQ(cricket::kMinVideoBitrateBps, streams[0].min_bitrate_bps);
3214}
3215
3216TEST_F(WebRtcVideoChannelTest, VerifyMinBitrateWithForcedFallbackFieldTrial) {
3217 webrtc::test::ScopedFieldTrials override_field_trials_(
3218 "WebRTC-VP8-Forced-Fallback-Encoder-v2/Enabled-1,2,34567/");
3219 std::vector<webrtc::VideoStream> streams = AddSendStream()->GetVideoStreams();
3220 ASSERT_EQ(1u, streams.size());
3221 EXPECT_EQ(34567, streams[0].min_bitrate_bps);
3222}
3223
asapersson3c81a1a2017-06-14 05:52:21 -07003224TEST_F(WebRtcVideoChannelTest,
3225 BalancedDegradationPreferenceNotSupportedWithoutFieldtrial) {
3226 webrtc::test::ScopedFieldTrials override_field_trials_(
3227 "WebRTC-Video-BalancedDegradation/Disabled/");
3228 const bool kResolutionScalingEnabled = true;
3229 const bool kFpsScalingEnabled = false;
3230 TestDegradationPreference(kResolutionScalingEnabled, kFpsScalingEnabled);
3231}
3232
3233TEST_F(WebRtcVideoChannelTest,
3234 BalancedDegradationPreferenceSupportedBehindFieldtrial) {
3235 webrtc::test::ScopedFieldTrials override_field_trials_(
3236 "WebRTC-Video-BalancedDegradation/Enabled/");
3237 const bool kResolutionScalingEnabled = true;
3238 const bool kFpsScalingEnabled = true;
3239 TestDegradationPreference(kResolutionScalingEnabled, kFpsScalingEnabled);
3240}
3241
eladalonf1841382017-06-12 01:16:46 -07003242TEST_F(WebRtcVideoChannelTest, AdaptsOnOveruse) {
Erik Språngefbde372015-04-29 16:21:28 +02003243 TestCpuAdaptation(true, false);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003244}
3245
eladalonf1841382017-06-12 01:16:46 -07003246TEST_F(WebRtcVideoChannelTest, DoesNotAdaptOnOveruseWhenDisabled) {
Erik Språngefbde372015-04-29 16:21:28 +02003247 TestCpuAdaptation(false, false);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003248}
3249
Niels Möller3de32e62019-01-18 08:42:18 +01003250TEST_F(WebRtcVideoChannelTest, DoesNotAdaptWhenScreeensharing) {
3251 TestCpuAdaptation(false, true);
3252}
3253
eladalonf1841382017-06-12 01:16:46 -07003254TEST_F(WebRtcVideoChannelTest, DoesNotAdaptOnOveruseWhenScreensharing) {
Erik Språngefbde372015-04-29 16:21:28 +02003255 TestCpuAdaptation(true, true);
3256}
3257
eladalonf1841382017-06-12 01:16:46 -07003258TEST_F(WebRtcVideoChannelTest, PreviousAdaptationDoesNotApplyToScreenshare) {
magjed509e4fe2016-11-18 01:34:11 -08003259 cricket::VideoCodec codec = GetEngineCodec("VP8");
Per766ad3b2016-04-05 15:23:49 +02003260 cricket::VideoSendParameters parameters;
3261 parameters.codecs.push_back(codec);
3262
kthelgason2bc68642017-02-07 07:02:22 -08003263 MediaConfig media_config = GetMediaConfig();
Niels Möller1d7ecd22018-01-18 15:25:12 +01003264 media_config.video.enable_cpu_adaptation = true;
Sebastian Jansson84848f22018-11-16 10:40:36 +01003265 channel_.reset(engine_.CreateMediaChannel(
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07003266 fake_call_.get(), media_config, VideoOptions(), webrtc::CryptoOptions()));
Sergey Ulanove2b15012016-11-22 16:08:30 -08003267 channel_->OnReadyToSend(true);
Per766ad3b2016-04-05 15:23:49 +02003268 ASSERT_TRUE(channel_->SetSendParameters(parameters));
3269
3270 AddSendStream();
Niels Möller805a27e2019-01-21 12:21:27 +01003271 webrtc::test::FrameForwarder frame_forwarder;
Per766ad3b2016-04-05 15:23:49 +02003272
Per766ad3b2016-04-05 15:23:49 +02003273 ASSERT_TRUE(channel_->SetSend(true));
3274 cricket::VideoOptions camera_options;
Oskar Sundbom78807582017-11-16 11:09:55 +01003275 camera_options.is_screencast = false;
Niels Möller805a27e2019-01-21 12:21:27 +01003276 channel_->SetVideoSend(last_ssrc_, &camera_options, &frame_forwarder);
Per766ad3b2016-04-05 15:23:49 +02003277
3278 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
3279 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
Per766ad3b2016-04-05 15:23:49 +02003280
Niels Möllerdcc70292019-01-15 16:32:38 +01003281 EXPECT_TRUE(send_stream->resolution_scaling_enabled());
3282 // Dont' expect anything on framerate_scaling_enabled, since the default is
3283 // transitioning from MAINTAIN_FRAMERATE to BALANCED.
Per766ad3b2016-04-05 15:23:49 +02003284
Niels Möllerdcc70292019-01-15 16:32:38 +01003285 // Switch to screen share. Expect no resolution scaling.
Per766ad3b2016-04-05 15:23:49 +02003286 cricket::VideoOptions screenshare_options;
Oskar Sundbom78807582017-11-16 11:09:55 +01003287 screenshare_options.is_screencast = true;
Niels Möller805a27e2019-01-21 12:21:27 +01003288 channel_->SetVideoSend(last_ssrc_, &screenshare_options, &frame_forwarder);
sprangf24a0642017-02-28 13:23:26 -08003289 ASSERT_EQ(2, fake_call_->GetNumCreatedSendStreams());
3290 send_stream = fake_call_->GetVideoSendStreams().front();
Niels Möllerdcc70292019-01-15 16:32:38 +01003291 EXPECT_FALSE(send_stream->resolution_scaling_enabled());
Per766ad3b2016-04-05 15:23:49 +02003292
Niels Möllerdcc70292019-01-15 16:32:38 +01003293 // Switch back to the normal capturer. Expect resolution scaling to be
3294 // reenabled.
Niels Möller805a27e2019-01-21 12:21:27 +01003295 channel_->SetVideoSend(last_ssrc_, &camera_options, &frame_forwarder);
3296 send_stream = fake_call_->GetVideoSendStreams().front();
sprangf24a0642017-02-28 13:23:26 -08003297 ASSERT_EQ(3, fake_call_->GetNumCreatedSendStreams());
3298 send_stream = fake_call_->GetVideoSendStreams().front();
Niels Möllerdcc70292019-01-15 16:32:38 +01003299 EXPECT_TRUE(send_stream->resolution_scaling_enabled());
Per766ad3b2016-04-05 15:23:49 +02003300
Niels Möllerff40b142018-04-09 08:49:14 +02003301 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
Per766ad3b2016-04-05 15:23:49 +02003302}
3303
asapersson3c81a1a2017-06-14 05:52:21 -07003304// TODO(asapersson): Remove this test when the balanced field trial is removed.
3305void WebRtcVideoChannelTest::TestDegradationPreference(
3306 bool resolution_scaling_enabled,
3307 bool fps_scaling_enabled) {
3308 cricket::VideoCodec codec = GetEngineCodec("VP8");
3309 cricket::VideoSendParameters parameters;
3310 parameters.codecs.push_back(codec);
3311
3312 MediaConfig media_config = GetMediaConfig();
Niels Möller1d7ecd22018-01-18 15:25:12 +01003313 media_config.video.enable_cpu_adaptation = true;
Sebastian Jansson84848f22018-11-16 10:40:36 +01003314 channel_.reset(engine_.CreateMediaChannel(
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07003315 fake_call_.get(), media_config, VideoOptions(), webrtc::CryptoOptions()));
asapersson3c81a1a2017-06-14 05:52:21 -07003316 channel_->OnReadyToSend(true);
3317
3318 EXPECT_TRUE(channel_->SetSendParameters(parameters));
3319
3320 AddSendStream();
3321
Niels Möller805a27e2019-01-21 12:21:27 +01003322 webrtc::test::FrameForwarder frame_forwarder;
asapersson3c81a1a2017-06-14 05:52:21 -07003323 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01003324 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
asapersson3c81a1a2017-06-14 05:52:21 -07003325
3326 EXPECT_TRUE(channel_->SetSend(true));
3327
3328 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
3329 EXPECT_EQ(resolution_scaling_enabled,
3330 send_stream->resolution_scaling_enabled());
3331 EXPECT_EQ(fps_scaling_enabled, send_stream->framerate_scaling_enabled());
3332
Niels Möllerff40b142018-04-09 08:49:14 +02003333 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
asapersson3c81a1a2017-06-14 05:52:21 -07003334}
3335
eladalonf1841382017-06-12 01:16:46 -07003336void WebRtcVideoChannelTest::TestCpuAdaptation(bool enable_overuse,
3337 bool is_screenshare) {
magjed509e4fe2016-11-18 01:34:11 -08003338 cricket::VideoCodec codec = GetEngineCodec("VP8");
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003339 cricket::VideoSendParameters parameters;
3340 parameters.codecs.push_back(codec);
nisse51542be2016-02-12 02:27:06 -08003341
kthelgason2bc68642017-02-07 07:02:22 -08003342 MediaConfig media_config = GetMediaConfig();
3343 if (enable_overuse) {
Niels Möller1d7ecd22018-01-18 15:25:12 +01003344 media_config.video.enable_cpu_adaptation = true;
pbos@webrtc.org42684be2014-10-03 11:25:45 +00003345 }
Sebastian Jansson84848f22018-11-16 10:40:36 +01003346 channel_.reset(engine_.CreateMediaChannel(
Benjamin Wrightbfb444c2018-10-15 10:20:24 -07003347 fake_call_.get(), media_config, VideoOptions(), webrtc::CryptoOptions()));
Sergey Ulanove2b15012016-11-22 16:08:30 -08003348 channel_->OnReadyToSend(true);
nisse51542be2016-02-12 02:27:06 -08003349
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003350 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00003351
3352 AddSendStream();
3353
Niels Möller805a27e2019-01-21 12:21:27 +01003354 webrtc::test::FrameForwarder frame_forwarder;
nisse05103312016-03-16 02:22:50 -07003355 VideoOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01003356 options.is_screencast = is_screenshare;
Niels Möller805a27e2019-01-21 12:21:27 +01003357 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00003358
3359 EXPECT_TRUE(channel_->SetSend(true));
3360
solenberge5269742015-09-08 05:13:22 -07003361 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
perkj2d5f0912016-02-29 00:04:41 -08003362
sprangc5d62e22017-04-02 23:53:04 -07003363 if (!enable_overuse) {
perkj803d97f2016-11-01 11:45:46 -07003364 EXPECT_FALSE(send_stream->resolution_scaling_enabled());
sprangc5d62e22017-04-02 23:53:04 -07003365 EXPECT_FALSE(send_stream->framerate_scaling_enabled());
Niels Möller805a27e2019-01-21 12:21:27 +01003366 } else if (is_screenshare) {
sprangc5d62e22017-04-02 23:53:04 -07003367 EXPECT_FALSE(send_stream->resolution_scaling_enabled());
3368 EXPECT_TRUE(send_stream->framerate_scaling_enabled());
3369 } else {
3370 EXPECT_TRUE(send_stream->resolution_scaling_enabled());
3371 EXPECT_FALSE(send_stream->framerate_scaling_enabled());
3372 }
Niels Möllerff40b142018-04-09 08:49:14 +02003373 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003374}
3375
eladalonf1841382017-06-12 01:16:46 -07003376TEST_F(WebRtcVideoChannelTest, EstimatesNtpStartTimeCorrectly) {
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00003377 // Start at last timestamp to verify that wraparounds are estimated correctly.
3378 static const uint32_t kInitialTimestamp = 0xFFFFFFFFu;
3379 static const int64_t kInitialNtpTimeMs = 1247891230;
3380 static const int kFrameOffsetMs = 20;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003381 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003382
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00003383 FakeVideoReceiveStream* stream = AddRecvStream();
3384 cricket::FakeVideoRenderer renderer;
nisse08582ff2016-02-04 01:24:52 -08003385 EXPECT_TRUE(channel_->SetSink(last_ssrc_, &renderer));
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00003386
Artem Titov1ebfb6a2019-01-03 23:49:37 +01003387 webrtc::VideoFrame video_frame =
3388 webrtc::VideoFrame::Builder()
3389 .set_video_frame_buffer(CreateBlackFrameBuffer(4, 4))
3390 .set_timestamp_rtp(kInitialTimestamp)
3391 .set_timestamp_us(0)
3392 .set_rotation(webrtc::kVideoRotation_0)
3393 .build();
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00003394 // Initial NTP time is not available on the first frame, but should still be
3395 // able to be estimated.
nisseeb83a1a2016-03-21 01:27:56 -07003396 stream->InjectFrame(video_frame);
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00003397
3398 EXPECT_EQ(1, renderer.num_rendered_frames());
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00003399
3400 // This timestamp is kInitialTimestamp (-1) + kFrameOffsetMs * 90, which
3401 // triggers a constant-overflow warning, hence we're calculating it explicitly
3402 // here.
Ilya Nikolaevskiy9c38c472018-09-03 16:11:42 +02003403 fake_clock_.AdvanceTimeMicros(kFrameOffsetMs * rtc::kNumMicrosecsPerMillisec);
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00003404 video_frame.set_timestamp(kFrameOffsetMs * 90 - 1);
3405 video_frame.set_ntp_time_ms(kInitialNtpTimeMs + kFrameOffsetMs);
nisseeb83a1a2016-03-21 01:27:56 -07003406 stream->InjectFrame(video_frame);
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00003407
3408 EXPECT_EQ(2, renderer.num_rendered_frames());
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00003409
3410 // Verify that NTP time has been correctly deduced.
3411 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00003412 ASSERT_TRUE(channel_->GetStats(&info));
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00003413 ASSERT_EQ(1u, info.receivers.size());
3414 EXPECT_EQ(kInitialNtpTimeMs, info.receivers[0].capture_start_ntp_time_ms);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003415}
3416
eladalonf1841382017-06-12 01:16:46 -07003417TEST_F(WebRtcVideoChannelTest, SetDefaultSendCodecs) {
Anders Carlsson5f2bb622018-05-14 09:48:06 +02003418 AssignDefaultAptRtxTypes();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003419 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003420
3421 VideoCodec codec;
3422 EXPECT_TRUE(channel_->GetSendCodec(&codec));
pbos@webrtc.org9fbb7172014-06-13 09:34:13 +00003423 EXPECT_TRUE(codec.Matches(engine_.codecs()[0]));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003424
3425 // Using a RTX setup to verify that the default RTX payload type is good.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003426 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
3427 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003428 FakeVideoSendStream* stream = AddSendStream(
3429 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
perkj26091b12016-09-01 01:17:40 -07003430 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003431
3432 // Make sure NACK and FEC are enabled on the correct payload types.
3433 EXPECT_EQ(1000, config.rtp.nack.rtp_history_ms);
magjed509e4fe2016-11-18 01:34:11 -08003434 EXPECT_EQ(GetEngineCodec("ulpfec").id, config.rtp.ulpfec.ulpfec_payload_type);
3435 EXPECT_EQ(GetEngineCodec("red").id, config.rtp.ulpfec.red_payload_type);
pbos@webrtc.org269605c2014-06-26 08:49:03 +00003436
3437 EXPECT_EQ(1u, config.rtp.rtx.ssrcs.size());
3438 EXPECT_EQ(kRtxSsrcs1[0], config.rtp.rtx.ssrcs[0]);
Shao Changbine62202f2015-04-21 20:24:50 +08003439 VerifySendStreamHasRtxTypes(config, default_apt_rtx_types_);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003440 // TODO(juberti): Check RTCP, PLI, TMMBR.
3441}
3442
brandtr31bd2242017-05-19 05:47:46 -07003443// The following four tests ensures that FlexFEC is not activated by default
3444// when the field trials are not enabled.
3445// TODO(brandtr): Remove or update these tests when FlexFEC _is_ enabled by
3446// default.
Yves Gerey665174f2018-06-19 15:03:05 +02003447TEST_F(WebRtcVideoChannelTest, FlexfecSendCodecWithoutSsrcNotExposedByDefault) {
brandtr468da7c2016-11-22 02:16:47 -08003448 FakeVideoSendStream* stream = AddSendStream();
3449 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
3450
brandtr3d200bd2017-01-16 06:59:19 -08003451 EXPECT_EQ(-1, config.rtp.flexfec.payload_type);
brandtr31bd2242017-05-19 05:47:46 -07003452 EXPECT_EQ(0U, config.rtp.flexfec.ssrc);
3453 EXPECT_TRUE(config.rtp.flexfec.protected_media_ssrcs.empty());
brandtr468da7c2016-11-22 02:16:47 -08003454}
3455
eladalonf1841382017-06-12 01:16:46 -07003456TEST_F(WebRtcVideoChannelTest, FlexfecSendCodecWithSsrcNotExposedByDefault) {
brandtr468da7c2016-11-22 02:16:47 -08003457 FakeVideoSendStream* stream = AddSendStream(
3458 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
3459 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
3460
brandtr3d200bd2017-01-16 06:59:19 -08003461 EXPECT_EQ(-1, config.rtp.flexfec.payload_type);
brandtr31bd2242017-05-19 05:47:46 -07003462 EXPECT_EQ(0U, config.rtp.flexfec.ssrc);
3463 EXPECT_TRUE(config.rtp.flexfec.protected_media_ssrcs.empty());
3464}
3465
Yves Gerey665174f2018-06-19 15:03:05 +02003466TEST_F(WebRtcVideoChannelTest, FlexfecRecvCodecWithoutSsrcNotExposedByDefault) {
brandtr31bd2242017-05-19 05:47:46 -07003467 AddRecvStream();
3468
3469 const std::vector<FakeFlexfecReceiveStream*>& streams =
3470 fake_call_->GetFlexfecReceiveStreams();
3471 EXPECT_TRUE(streams.empty());
3472}
3473
eladalonf1841382017-06-12 01:16:46 -07003474TEST_F(WebRtcVideoChannelTest, FlexfecRecvCodecWithSsrcNotExposedByDefault) {
brandtr31bd2242017-05-19 05:47:46 -07003475 AddRecvStream(
3476 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
3477
3478 const std::vector<FakeFlexfecReceiveStream*>& streams =
3479 fake_call_->GetFlexfecReceiveStreams();
3480 EXPECT_TRUE(streams.empty());
brandtr468da7c2016-11-22 02:16:47 -08003481}
3482
3483// TODO(brandtr): When FlexFEC is no longer behind a field trial, merge all
3484// tests that use this test fixture into the corresponding "non-field trial"
3485// tests.
eladalonf1841382017-06-12 01:16:46 -07003486class WebRtcVideoChannelFlexfecRecvTest : public WebRtcVideoChannelTest {
brandtr468da7c2016-11-22 02:16:47 -08003487 public:
eladalonf1841382017-06-12 01:16:46 -07003488 WebRtcVideoChannelFlexfecRecvTest()
3489 : WebRtcVideoChannelTest("WebRTC-FlexFEC-03-Advertised/Enabled/") {}
brandtr468da7c2016-11-22 02:16:47 -08003490};
3491
eladalonf1841382017-06-12 01:16:46 -07003492TEST_F(WebRtcVideoChannelFlexfecRecvTest,
brandtr36e7d702017-01-13 07:15:54 -08003493 DefaultFlexfecCodecHasTransportCcAndRembFeedbackParam) {
3494 EXPECT_TRUE(cricket::HasTransportCc(GetEngineCodec("flexfec-03")));
3495 EXPECT_TRUE(cricket::HasRemb(GetEngineCodec("flexfec-03")));
3496}
3497
eladalonf1841382017-06-12 01:16:46 -07003498TEST_F(WebRtcVideoChannelFlexfecRecvTest, SetDefaultRecvCodecsWithoutSsrc) {
brandtr31bd2242017-05-19 05:47:46 -07003499 AddRecvStream();
3500
3501 const std::vector<FakeFlexfecReceiveStream*>& streams =
3502 fake_call_->GetFlexfecReceiveStreams();
3503 EXPECT_TRUE(streams.empty());
Rasmus Brandt60bb6fe2018-02-05 09:51:47 +01003504
3505 const std::vector<FakeVideoReceiveStream*>& video_streams =
3506 fake_call_->GetVideoReceiveStreams();
3507 ASSERT_EQ(1U, video_streams.size());
3508 const FakeVideoReceiveStream& video_stream = *video_streams.front();
3509 EXPECT_EQ(0, video_stream.GetNumAddedSecondarySinks());
3510 EXPECT_EQ(0, video_stream.GetNumRemovedSecondarySinks());
brandtr31bd2242017-05-19 05:47:46 -07003511}
3512
eladalonf1841382017-06-12 01:16:46 -07003513TEST_F(WebRtcVideoChannelFlexfecRecvTest, SetDefaultRecvCodecsWithSsrc) {
brandtr31bd2242017-05-19 05:47:46 -07003514 AddRecvStream(
3515 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
3516
3517 const std::vector<FakeFlexfecReceiveStream*>& streams =
3518 fake_call_->GetFlexfecReceiveStreams();
3519 ASSERT_EQ(1U, streams.size());
3520 const FakeFlexfecReceiveStream* stream = streams.front();
3521 const webrtc::FlexfecReceiveStream::Config& config = stream->GetConfig();
3522 EXPECT_EQ(GetEngineCodec("flexfec-03").id, config.payload_type);
3523 EXPECT_EQ(kFlexfecSsrc, config.remote_ssrc);
3524 ASSERT_EQ(1U, config.protected_media_ssrcs.size());
3525 EXPECT_EQ(kSsrcs1[0], config.protected_media_ssrcs[0]);
brandtr7cd28b92017-09-22 00:26:25 -07003526
3527 const std::vector<FakeVideoReceiveStream*>& video_streams =
3528 fake_call_->GetVideoReceiveStreams();
3529 ASSERT_EQ(1U, video_streams.size());
Rasmus Brandt60bb6fe2018-02-05 09:51:47 +01003530 const FakeVideoReceiveStream& video_stream = *video_streams.front();
3531 EXPECT_EQ(1, video_stream.GetNumAddedSecondarySinks());
brandtr7cd28b92017-09-22 00:26:25 -07003532 const webrtc::VideoReceiveStream::Config& video_config =
Rasmus Brandt60bb6fe2018-02-05 09:51:47 +01003533 video_stream.GetConfig();
brandtr7cd28b92017-09-22 00:26:25 -07003534 EXPECT_TRUE(video_config.rtp.protected_by_flexfec);
brandtr31bd2242017-05-19 05:47:46 -07003535}
3536
eladalonf1841382017-06-12 01:16:46 -07003537TEST_F(WebRtcVideoChannelFlexfecRecvTest,
brandtr11fb4722017-05-30 01:31:37 -07003538 EnablingFlexfecDoesNotRecreateVideoReceiveStream) {
3539 cricket::VideoRecvParameters recv_parameters;
3540 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
3541 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
3542
3543 AddRecvStream(
3544 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
3545 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
Rasmus Brandt60bb6fe2018-02-05 09:51:47 +01003546 const std::vector<FakeVideoReceiveStream*>& video_streams =
3547 fake_call_->GetVideoReceiveStreams();
3548 ASSERT_EQ(1U, video_streams.size());
3549 const FakeVideoReceiveStream& video_stream = *video_streams.front();
3550 EXPECT_EQ(0, video_stream.GetNumAddedSecondarySinks());
3551 EXPECT_EQ(0, video_stream.GetNumRemovedSecondarySinks());
brandtr11fb4722017-05-30 01:31:37 -07003552
3553 // Enable FlexFEC.
3554 recv_parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
3555 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
3556 EXPECT_EQ(2, fake_call_->GetNumCreatedReceiveStreams())
3557 << "Enabling FlexFEC should create FlexfecReceiveStream.";
3558 EXPECT_EQ(1U, fake_call_->GetVideoReceiveStreams().size())
3559 << "Enabling FlexFEC should not create VideoReceiveStream.";
3560 EXPECT_EQ(1U, fake_call_->GetFlexfecReceiveStreams().size())
3561 << "Enabling FlexFEC should create a single FlexfecReceiveStream.";
Rasmus Brandt60bb6fe2018-02-05 09:51:47 +01003562 EXPECT_EQ(1, video_stream.GetNumAddedSecondarySinks());
3563 EXPECT_EQ(0, video_stream.GetNumRemovedSecondarySinks());
brandtr11fb4722017-05-30 01:31:37 -07003564}
3565
eladalonf1841382017-06-12 01:16:46 -07003566TEST_F(WebRtcVideoChannelFlexfecRecvTest,
brandtr11fb4722017-05-30 01:31:37 -07003567 DisablingFlexfecDoesNotRecreateVideoReceiveStream) {
3568 cricket::VideoRecvParameters recv_parameters;
3569 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
3570 recv_parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
3571 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
3572
3573 AddRecvStream(
3574 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
3575 EXPECT_EQ(2, fake_call_->GetNumCreatedReceiveStreams());
brandtr11fb4722017-05-30 01:31:37 -07003576 EXPECT_EQ(1U, fake_call_->GetFlexfecReceiveStreams().size());
Rasmus Brandt60bb6fe2018-02-05 09:51:47 +01003577 const std::vector<FakeVideoReceiveStream*>& video_streams =
3578 fake_call_->GetVideoReceiveStreams();
3579 ASSERT_EQ(1U, video_streams.size());
3580 const FakeVideoReceiveStream& video_stream = *video_streams.front();
3581 EXPECT_EQ(1, video_stream.GetNumAddedSecondarySinks());
3582 EXPECT_EQ(0, video_stream.GetNumRemovedSecondarySinks());
brandtr11fb4722017-05-30 01:31:37 -07003583
3584 // Disable FlexFEC.
3585 recv_parameters.codecs.clear();
3586 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
3587 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
3588 EXPECT_EQ(2, fake_call_->GetNumCreatedReceiveStreams())
3589 << "Disabling FlexFEC should not recreate VideoReceiveStream.";
3590 EXPECT_EQ(1U, fake_call_->GetVideoReceiveStreams().size())
3591 << "Disabling FlexFEC should not destroy VideoReceiveStream.";
3592 EXPECT_TRUE(fake_call_->GetFlexfecReceiveStreams().empty())
3593 << "Disabling FlexFEC should destroy FlexfecReceiveStream.";
Rasmus Brandt60bb6fe2018-02-05 09:51:47 +01003594 EXPECT_EQ(1, video_stream.GetNumAddedSecondarySinks());
3595 EXPECT_EQ(1, video_stream.GetNumRemovedSecondarySinks());
brandtr11fb4722017-05-30 01:31:37 -07003596}
3597
brandtr31bd2242017-05-19 05:47:46 -07003598// TODO(brandtr): When FlexFEC is no longer behind a field trial, merge all
3599// tests that use this test fixture into the corresponding "non-field trial"
3600// tests.
eladalonf1841382017-06-12 01:16:46 -07003601class WebRtcVideoChannelFlexfecSendRecvTest : public WebRtcVideoChannelTest {
brandtr31bd2242017-05-19 05:47:46 -07003602 public:
eladalonf1841382017-06-12 01:16:46 -07003603 WebRtcVideoChannelFlexfecSendRecvTest()
3604 : WebRtcVideoChannelTest(
brandtr31bd2242017-05-19 05:47:46 -07003605 "WebRTC-FlexFEC-03-Advertised/Enabled/WebRTC-FlexFEC-03/Enabled/") {
3606 }
3607};
3608
Yves Gerey665174f2018-06-19 15:03:05 +02003609TEST_F(WebRtcVideoChannelFlexfecSendRecvTest, SetDefaultSendCodecsWithoutSsrc) {
brandtr468da7c2016-11-22 02:16:47 -08003610 FakeVideoSendStream* stream = AddSendStream();
3611 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
3612
brandtr3d200bd2017-01-16 06:59:19 -08003613 EXPECT_EQ(GetEngineCodec("flexfec-03").id, config.rtp.flexfec.payload_type);
3614 EXPECT_EQ(0U, config.rtp.flexfec.ssrc);
3615 EXPECT_TRUE(config.rtp.flexfec.protected_media_ssrcs.empty());
brandtr468da7c2016-11-22 02:16:47 -08003616}
3617
eladalonf1841382017-06-12 01:16:46 -07003618TEST_F(WebRtcVideoChannelFlexfecSendRecvTest, SetDefaultSendCodecsWithSsrc) {
brandtr468da7c2016-11-22 02:16:47 -08003619 FakeVideoSendStream* stream = AddSendStream(
3620 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
3621 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
3622
brandtr3d200bd2017-01-16 06:59:19 -08003623 EXPECT_EQ(GetEngineCodec("flexfec-03").id, config.rtp.flexfec.payload_type);
3624 EXPECT_EQ(kFlexfecSsrc, config.rtp.flexfec.ssrc);
3625 ASSERT_EQ(1U, config.rtp.flexfec.protected_media_ssrcs.size());
3626 EXPECT_EQ(kSsrcs1[0], config.rtp.flexfec.protected_media_ssrcs[0]);
brandtr468da7c2016-11-22 02:16:47 -08003627}
3628
eladalonf1841382017-06-12 01:16:46 -07003629TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithoutFec) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003630 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08003631 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003632 ASSERT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003633
3634 FakeVideoSendStream* stream = AddSendStream();
perkj26091b12016-09-01 01:17:40 -07003635 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003636
brandtrb5f2c3f2016-10-04 23:28:39 -07003637 EXPECT_EQ(-1, config.rtp.ulpfec.ulpfec_payload_type);
3638 EXPECT_EQ(-1, config.rtp.ulpfec.red_payload_type);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003639}
3640
eladalonf1841382017-06-12 01:16:46 -07003641TEST_F(WebRtcVideoChannelFlexfecSendRecvTest, SetSendCodecsWithoutFec) {
brandtr468da7c2016-11-22 02:16:47 -08003642 cricket::VideoSendParameters parameters;
3643 parameters.codecs.push_back(GetEngineCodec("VP8"));
3644 ASSERT_TRUE(channel_->SetSendParameters(parameters));
3645
3646 FakeVideoSendStream* stream = AddSendStream();
3647 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
3648
brandtr3d200bd2017-01-16 06:59:19 -08003649 EXPECT_EQ(-1, config.rtp.flexfec.payload_type);
brandtr468da7c2016-11-22 02:16:47 -08003650}
3651
eladalonf1841382017-06-12 01:16:46 -07003652TEST_F(WebRtcVideoChannelFlexfecRecvTest, SetRecvCodecsWithFec) {
brandtr9c3d4c42017-01-23 06:59:13 -08003653 AddRecvStream(
3654 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
brandtr9c3d4c42017-01-23 06:59:13 -08003655
3656 cricket::VideoRecvParameters recv_parameters;
3657 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
3658 recv_parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
3659 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
brandtr9d58d942017-02-03 04:43:41 -08003660
3661 const std::vector<FakeFlexfecReceiveStream*>& flexfec_streams =
3662 fake_call_->GetFlexfecReceiveStreams();
3663 ASSERT_EQ(1U, flexfec_streams.size());
3664 const FakeFlexfecReceiveStream* flexfec_stream = flexfec_streams.front();
3665 const webrtc::FlexfecReceiveStream::Config& flexfec_stream_config =
3666 flexfec_stream->GetConfig();
brandtr9c3d4c42017-01-23 06:59:13 -08003667 EXPECT_EQ(GetEngineCodec("flexfec-03").id,
brandtr9d58d942017-02-03 04:43:41 -08003668 flexfec_stream_config.payload_type);
3669 EXPECT_EQ(kFlexfecSsrc, flexfec_stream_config.remote_ssrc);
3670 ASSERT_EQ(1U, flexfec_stream_config.protected_media_ssrcs.size());
3671 EXPECT_EQ(kSsrcs1[0], flexfec_stream_config.protected_media_ssrcs[0]);
3672 const std::vector<FakeVideoReceiveStream*>& video_streams =
3673 fake_call_->GetVideoReceiveStreams();
3674 const FakeVideoReceiveStream* video_stream = video_streams.front();
3675 const webrtc::VideoReceiveStream::Config& video_stream_config =
3676 video_stream->GetConfig();
3677 EXPECT_EQ(video_stream_config.rtp.local_ssrc,
3678 flexfec_stream_config.local_ssrc);
3679 EXPECT_EQ(video_stream_config.rtp.rtcp_mode, flexfec_stream_config.rtcp_mode);
3680 EXPECT_EQ(video_stream_config.rtcp_send_transport,
3681 flexfec_stream_config.rtcp_send_transport);
3682 // TODO(brandtr): Update this EXPECT when we set |transport_cc| in a
3683 // spec-compliant way.
3684 EXPECT_EQ(video_stream_config.rtp.transport_cc,
3685 flexfec_stream_config.transport_cc);
3686 EXPECT_EQ(video_stream_config.rtp.rtcp_mode, flexfec_stream_config.rtcp_mode);
3687 EXPECT_EQ(video_stream_config.rtp.extensions,
3688 flexfec_stream_config.rtp_header_extensions);
brandtr9c3d4c42017-01-23 06:59:13 -08003689}
3690
brandtr31bd2242017-05-19 05:47:46 -07003691// We should not send FlexFEC, even if we advertise it, unless the right
3692// field trial is set.
3693// TODO(brandtr): Remove when FlexFEC is enabled by default.
eladalonf1841382017-06-12 01:16:46 -07003694TEST_F(WebRtcVideoChannelFlexfecRecvTest,
brandtr31bd2242017-05-19 05:47:46 -07003695 SetSendCodecsWithoutSsrcWithFecDoesNotEnableFec) {
3696 cricket::VideoSendParameters parameters;
3697 parameters.codecs.push_back(GetEngineCodec("VP8"));
3698 parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
3699 ASSERT_TRUE(channel_->SetSendParameters(parameters));
3700
3701 FakeVideoSendStream* stream = AddSendStream();
3702 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
3703
3704 EXPECT_EQ(-1, config.rtp.flexfec.payload_type);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003705 EXPECT_EQ(0u, config.rtp.flexfec.ssrc);
brandtr31bd2242017-05-19 05:47:46 -07003706 EXPECT_TRUE(config.rtp.flexfec.protected_media_ssrcs.empty());
3707}
3708
eladalonf1841382017-06-12 01:16:46 -07003709TEST_F(WebRtcVideoChannelFlexfecRecvTest,
brandtr31bd2242017-05-19 05:47:46 -07003710 SetSendCodecsWithSsrcWithFecDoesNotEnableFec) {
3711 cricket::VideoSendParameters parameters;
3712 parameters.codecs.push_back(GetEngineCodec("VP8"));
3713 parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
3714 ASSERT_TRUE(channel_->SetSendParameters(parameters));
3715
3716 FakeVideoSendStream* stream = AddSendStream(
3717 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
3718 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
3719
3720 EXPECT_EQ(-1, config.rtp.flexfec.payload_type);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003721 EXPECT_EQ(0u, config.rtp.flexfec.ssrc);
brandtr31bd2242017-05-19 05:47:46 -07003722 EXPECT_TRUE(config.rtp.flexfec.protected_media_ssrcs.empty());
3723}
3724
eladalonf1841382017-06-12 01:16:46 -07003725TEST_F(WebRtcVideoChannelTest,
pbos@webrtc.org269605c2014-06-26 08:49:03 +00003726 SetSendCodecRejectsRtxWithoutAssociatedPayloadType) {
magjed509e4fe2016-11-18 01:34:11 -08003727 const int kUnusedPayloadType = 127;
3728 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType));
3729
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003730 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08003731 cricket::VideoCodec rtx_codec(kUnusedPayloadType, "rtx");
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003732 parameters.codecs.push_back(rtx_codec);
3733 EXPECT_FALSE(channel_->SetSendParameters(parameters))
pbos@webrtc.org269605c2014-06-26 08:49:03 +00003734 << "RTX codec without associated payload type should be rejected.";
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003735}
3736
eladalonf1841382017-06-12 01:16:46 -07003737TEST_F(WebRtcVideoChannelTest,
pbos@webrtc.org269605c2014-06-26 08:49:03 +00003738 SetSendCodecRejectsRtxWithoutMatchingVideoCodec) {
magjed509e4fe2016-11-18 01:34:11 -08003739 const int kUnusedPayloadType1 = 126;
3740 const int kUnusedPayloadType2 = 127;
3741 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType1));
3742 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType2));
3743 {
3744 cricket::VideoCodec rtx_codec = cricket::VideoCodec::CreateRtxCodec(
3745 kUnusedPayloadType1, GetEngineCodec("VP8").id);
3746 cricket::VideoSendParameters parameters;
3747 parameters.codecs.push_back(GetEngineCodec("VP8"));
3748 parameters.codecs.push_back(rtx_codec);
3749 ASSERT_TRUE(channel_->SetSendParameters(parameters));
3750 }
3751 {
3752 cricket::VideoCodec rtx_codec = cricket::VideoCodec::CreateRtxCodec(
3753 kUnusedPayloadType1, kUnusedPayloadType2);
3754 cricket::VideoSendParameters parameters;
3755 parameters.codecs.push_back(GetEngineCodec("VP8"));
3756 parameters.codecs.push_back(rtx_codec);
3757 EXPECT_FALSE(channel_->SetSendParameters(parameters))
3758 << "RTX without matching video codec should be rejected.";
3759 }
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003760}
3761
eladalonf1841382017-06-12 01:16:46 -07003762TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithChangedRtxPayloadType) {
brandtr14742122017-01-27 04:53:07 -08003763 const int kUnusedPayloadType1 = 126;
3764 const int kUnusedPayloadType2 = 127;
3765 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType1));
3766 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType2));
3767
3768 // SSRCs for RTX.
3769 cricket::StreamParams params =
3770 cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
3771 params.AddFidSsrc(kSsrcs1[0], kRtxSsrcs1[0]);
3772 AddSendStream(params);
3773
3774 // Original payload type for RTX.
3775 cricket::VideoSendParameters parameters;
3776 parameters.codecs.push_back(GetEngineCodec("VP8"));
3777 cricket::VideoCodec rtx_codec(kUnusedPayloadType1, "rtx");
3778 rtx_codec.SetParam("apt", GetEngineCodec("VP8").id);
3779 parameters.codecs.push_back(rtx_codec);
3780 EXPECT_TRUE(channel_->SetSendParameters(parameters));
3781 ASSERT_EQ(1U, fake_call_->GetVideoSendStreams().size());
3782 const webrtc::VideoSendStream::Config& config_before =
3783 fake_call_->GetVideoSendStreams()[0]->GetConfig();
3784 EXPECT_EQ(kUnusedPayloadType1, config_before.rtp.rtx.payload_type);
3785 ASSERT_EQ(1U, config_before.rtp.rtx.ssrcs.size());
3786 EXPECT_EQ(kRtxSsrcs1[0], config_before.rtp.rtx.ssrcs[0]);
3787
3788 // Change payload type for RTX.
3789 parameters.codecs[1].id = kUnusedPayloadType2;
3790 EXPECT_TRUE(channel_->SetSendParameters(parameters));
3791 ASSERT_EQ(1U, fake_call_->GetVideoSendStreams().size());
3792 const webrtc::VideoSendStream::Config& config_after =
3793 fake_call_->GetVideoSendStreams()[0]->GetConfig();
3794 EXPECT_EQ(kUnusedPayloadType2, config_after.rtp.rtx.payload_type);
3795 ASSERT_EQ(1U, config_after.rtp.rtx.ssrcs.size());
3796 EXPECT_EQ(kRtxSsrcs1[0], config_after.rtp.rtx.ssrcs[0]);
3797}
3798
eladalonf1841382017-06-12 01:16:46 -07003799TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithoutFecDisablesFec) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003800 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08003801 parameters.codecs.push_back(GetEngineCodec("VP8"));
3802 parameters.codecs.push_back(GetEngineCodec("ulpfec"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003803 ASSERT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org269605c2014-06-26 08:49:03 +00003804
3805 FakeVideoSendStream* stream = AddSendStream();
perkj26091b12016-09-01 01:17:40 -07003806 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
pbos@webrtc.org269605c2014-06-26 08:49:03 +00003807
magjed509e4fe2016-11-18 01:34:11 -08003808 EXPECT_EQ(GetEngineCodec("ulpfec").id, config.rtp.ulpfec.ulpfec_payload_type);
pbos@webrtc.org269605c2014-06-26 08:49:03 +00003809
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003810 parameters.codecs.pop_back();
3811 ASSERT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00003812 stream = fake_call_->GetVideoSendStreams()[0];
brandtr468da7c2016-11-22 02:16:47 -08003813 ASSERT_TRUE(stream != nullptr);
perkj26091b12016-09-01 01:17:40 -07003814 config = stream->GetConfig().Copy();
brandtrb5f2c3f2016-10-04 23:28:39 -07003815 EXPECT_EQ(-1, config.rtp.ulpfec.ulpfec_payload_type)
brandtr468da7c2016-11-22 02:16:47 -08003816 << "SetSendCodec without ULPFEC should disable current ULPFEC.";
3817}
3818
eladalonf1841382017-06-12 01:16:46 -07003819TEST_F(WebRtcVideoChannelFlexfecSendRecvTest,
brandtr31bd2242017-05-19 05:47:46 -07003820 SetSendCodecsWithoutFecDisablesFec) {
brandtr468da7c2016-11-22 02:16:47 -08003821 cricket::VideoSendParameters parameters;
3822 parameters.codecs.push_back(GetEngineCodec("VP8"));
3823 parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
3824 ASSERT_TRUE(channel_->SetSendParameters(parameters));
3825
3826 FakeVideoSendStream* stream = AddSendStream(
3827 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
3828 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
3829
brandtr3d200bd2017-01-16 06:59:19 -08003830 EXPECT_EQ(GetEngineCodec("flexfec-03").id, config.rtp.flexfec.payload_type);
3831 EXPECT_EQ(kFlexfecSsrc, config.rtp.flexfec.ssrc);
brandtr468da7c2016-11-22 02:16:47 -08003832 ASSERT_EQ(1U, config.rtp.flexfec.protected_media_ssrcs.size());
3833 EXPECT_EQ(kSsrcs1[0], config.rtp.flexfec.protected_media_ssrcs[0]);
3834
3835 parameters.codecs.pop_back();
3836 ASSERT_TRUE(channel_->SetSendParameters(parameters));
3837 stream = fake_call_->GetVideoSendStreams()[0];
3838 ASSERT_TRUE(stream != nullptr);
3839 config = stream->GetConfig().Copy();
brandtr3d200bd2017-01-16 06:59:19 -08003840 EXPECT_EQ(-1, config.rtp.flexfec.payload_type)
brandtr468da7c2016-11-22 02:16:47 -08003841 << "SetSendCodec without FlexFEC should disable current FlexFEC.";
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003842}
3843
eladalonf1841382017-06-12 01:16:46 -07003844TEST_F(WebRtcVideoChannelTest, SetSendCodecsChangesExistingStreams) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003845 cricket::VideoSendParameters parameters;
perkj26752742016-10-24 01:21:16 -07003846 cricket::VideoCodec codec(100, "VP8");
3847 codec.SetParam(kCodecParamMaxQuantization, kDefaultQpMax);
3848 parameters.codecs.push_back(codec);
perkjfa10b552016-10-02 23:45:26 -07003849
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003850 ASSERT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org86196c42015-02-16 21:02:00 +00003851 channel_->SetSend(true);
pbos@webrtc.org38ce7d02014-07-16 08:01:38 +00003852
pbos@webrtc.org86196c42015-02-16 21:02:00 +00003853 FakeVideoSendStream* stream = AddSendStream();
Niels Möller805a27e2019-01-21 12:21:27 +01003854 webrtc::test::FrameForwarder frame_forwarder;
3855 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));
pbos@webrtc.org86196c42015-02-16 21:02:00 +00003856
3857 std::vector<webrtc::VideoStream> streams = stream->GetVideoStreams();
perkjfa10b552016-10-02 23:45:26 -07003858 EXPECT_EQ(kDefaultQpMax, streams[0].max_qp);
pbos@webrtc.org38ce7d02014-07-16 08:01:38 +00003859
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003860 parameters.codecs.clear();
perkj26752742016-10-24 01:21:16 -07003861 codec.SetParam(kCodecParamMaxQuantization, kDefaultQpMax + 1);
3862 parameters.codecs.push_back(codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003863 ASSERT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00003864 streams = fake_call_->GetVideoSendStreams()[0]->GetVideoStreams();
perkjfa10b552016-10-02 23:45:26 -07003865 EXPECT_EQ(kDefaultQpMax + 1, streams[0].max_qp);
Niels Möllerff40b142018-04-09 08:49:14 +02003866 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003867}
3868
eladalonf1841382017-06-12 01:16:46 -07003869TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithBitrates) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00003870 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
3871 200000);
3872}
3873
eladalonf1841382017-06-12 01:16:46 -07003874TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithHighMaxBitrate) {
pbos@webrtc.orga5f6fb52015-03-23 22:29:39 +00003875 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
3876 std::vector<webrtc::VideoStream> streams = AddSendStream()->GetVideoStreams();
3877 ASSERT_EQ(1u, streams.size());
3878 EXPECT_EQ(10000000, streams[0].max_bitrate_bps);
3879}
3880
eladalonf1841382017-06-12 01:16:46 -07003881TEST_F(WebRtcVideoChannelTest,
pbos@webrtc.org00873182014-11-25 14:03:34 +00003882 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
Sebastian Jansson8f83b422018-02-21 13:07:13 +01003883 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
pbos@webrtc.org00873182014-11-25 14:03:34 +00003884}
3885
eladalonf1841382017-06-12 01:16:46 -07003886TEST_F(WebRtcVideoChannelTest, SetSendCodecsCapsMinAndStartBitrate) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00003887 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003888}
3889
eladalonf1841382017-06-12 01:16:46 -07003890TEST_F(WebRtcVideoChannelTest, SetSendCodecsRejectsMaxLessThanMinBitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003891 send_parameters_.codecs[0].params[kCodecParamMinBitrate] = "300";
3892 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "200";
3893 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003894}
3895
Taylor Brandstetter58f2bd92016-04-26 17:15:23 -07003896// Test that when both the codec-specific bitrate params and max_bandwidth_bps
3897// are present in the same send parameters, the settings are combined correctly.
eladalonf1841382017-06-12 01:16:46 -07003898TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithBitratesAndMaxSendBandwidth) {
Taylor Brandstetter58f2bd92016-04-26 17:15:23 -07003899 send_parameters_.codecs[0].params[kCodecParamMinBitrate] = "100";
3900 send_parameters_.codecs[0].params[kCodecParamStartBitrate] = "200";
3901 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "300";
3902 send_parameters_.max_bandwidth_bps = 400000;
Taylor Brandstetter58f2bd92016-04-26 17:15:23 -07003903 // We expect max_bandwidth_bps to take priority, if set.
Sebastian Jansson8f83b422018-02-21 13:07:13 +01003904 ExpectSetBitrateParameters(100000, 200000, 400000);
3905 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
3906 // Since the codec isn't changing, start_bitrate_bps should be -1.
3907 ExpectSetBitrateParameters(100000, -1, 350000);
Taylor Brandstetter58f2bd92016-04-26 17:15:23 -07003908
3909 // Decrease max_bandwidth_bps.
3910 send_parameters_.max_bandwidth_bps = 350000;
3911 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Taylor Brandstetter58f2bd92016-04-26 17:15:23 -07003912
3913 // Now try again with the values flipped around.
3914 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "400";
3915 send_parameters_.max_bandwidth_bps = 300000;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01003916 ExpectSetBitrateParameters(100000, 200000, 300000);
Taylor Brandstetter58f2bd92016-04-26 17:15:23 -07003917 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Taylor Brandstetter58f2bd92016-04-26 17:15:23 -07003918
3919 // If we change the codec max, max_bandwidth_bps should still apply.
3920 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "350";
Sebastian Jansson8f83b422018-02-21 13:07:13 +01003921 ExpectSetBitrateParameters(100000, 200000, 300000);
Taylor Brandstetter58f2bd92016-04-26 17:15:23 -07003922 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Taylor Brandstetter58f2bd92016-04-26 17:15:23 -07003923}
3924
Piotr (Peter) Slatala946b9682019-03-18 10:25:02 -07003925// Test that when both the codec-specific bitrate params and max_bandwidth_bps
3926// are present in the same send parameters, the settings are combined correctly.
3927TEST_F(WebRtcVideoChannelTest,
3928 SetSendCodecsWithBitratesAndMaxSendBandwidthForMediaTransport) {
3929 // Same as SetSendCodecsWithBitratesAndMaxSendBandwidth but with Media
3930 // Transport.
3931 webrtc::MediaTransportSettings settings;
3932 settings.is_caller = true;
3933 webrtc::FakeMediaTransport fake_media_transport(settings);
3934 std::unique_ptr<cricket::FakeNetworkInterface> network_interface(
3935 new cricket::FakeNetworkInterface);
3936 channel_->SetInterface(network_interface.get(), &fake_media_transport);
3937
3938 send_parameters_.codecs[0].params[kCodecParamMinBitrate] = "100";
3939 send_parameters_.codecs[0].params[kCodecParamStartBitrate] = "200";
3940 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "300";
3941 send_parameters_.max_bandwidth_bps = 400000;
3942 {
3943 // We expect max_bandwidth_bps to take priority, if set.
3944 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
3945 ASSERT_EQ(1u,
3946 fake_media_transport.target_rate_constraints_in_order().size());
3947 const webrtc::MediaTransportTargetRateConstraints& constraint =
3948 fake_media_transport.target_rate_constraints_in_order()[0];
3949 ASSERT_EQ(webrtc::DataRate::bps(100000), constraint.min_bitrate);
3950 ASSERT_EQ(webrtc::DataRate::bps(200000), constraint.starting_bitrate);
3951 ASSERT_EQ(webrtc::DataRate::bps(400000), constraint.max_bitrate);
3952 }
3953
3954 {
3955 // Decrease max_bandwidth_bps.
3956 send_parameters_.max_bandwidth_bps = 350000;
3957 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
3958 ASSERT_EQ(2u,
3959 fake_media_transport.target_rate_constraints_in_order().size());
3960 const webrtc::MediaTransportTargetRateConstraints& constraint =
3961 fake_media_transport.target_rate_constraints_in_order()[1];
3962
3963 // Since the codec isn't changing, start_bitrate_bps should be 0.
3964 ASSERT_EQ(webrtc::DataRate::bps(100000), constraint.min_bitrate);
3965 ASSERT_EQ(absl::nullopt, constraint.starting_bitrate);
3966 ASSERT_EQ(webrtc::DataRate::bps(350000), constraint.max_bitrate);
3967 }
3968
3969 {
3970 // Now try again with the values flipped around.
3971 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "400";
3972 send_parameters_.max_bandwidth_bps = 300000;
3973 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
3974 ASSERT_EQ(3u,
3975 fake_media_transport.target_rate_constraints_in_order().size());
3976 const webrtc::MediaTransportTargetRateConstraints& constraint =
3977 fake_media_transport.target_rate_constraints_in_order()[2];
3978
3979 ASSERT_EQ(webrtc::DataRate::bps(100000), constraint.min_bitrate);
3980 ASSERT_EQ(webrtc::DataRate::bps(200000), constraint.starting_bitrate);
3981 ASSERT_EQ(webrtc::DataRate::bps(300000), constraint.max_bitrate);
3982 }
3983
3984 {
3985 // Now try again with the values flipped around.
3986 // If we change the codec max, max_bandwidth_bps should still apply.
3987 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "350";
3988 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
3989 ASSERT_EQ(4u,
3990 fake_media_transport.target_rate_constraints_in_order().size());
3991 const webrtc::MediaTransportTargetRateConstraints& constraint =
3992 fake_media_transport.target_rate_constraints_in_order()[3];
3993
3994 ASSERT_EQ(webrtc::DataRate::bps(100000), constraint.min_bitrate);
3995 ASSERT_EQ(webrtc::DataRate::bps(200000), constraint.starting_bitrate);
3996 ASSERT_EQ(webrtc::DataRate::bps(300000), constraint.max_bitrate);
3997 }
3998}
3999
Yves Gerey665174f2018-06-19 15:03:05 +02004000TEST_F(WebRtcVideoChannelTest, SetMaxSendBandwidthShouldPreserveOtherBitrates) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00004001 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
4002 200000);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004003 send_parameters_.max_bandwidth_bps = 300000;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01004004 // Setting max bitrate should keep previous min bitrate.
4005 // Setting max bitrate should not reset start bitrate.
4006 ExpectSetBitrateParameters(100000, -1, 300000);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004007 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.org00873182014-11-25 14:03:34 +00004008}
4009
eladalonf1841382017-06-12 01:16:46 -07004010TEST_F(WebRtcVideoChannelTest, SetMaxSendBandwidthShouldBeRemovable) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004011 send_parameters_.max_bandwidth_bps = 300000;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01004012 ExpectSetMaxBitrate(300000);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004013 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos5c7760a2017-03-10 11:23:12 -08004014 // -1 means to disable max bitrate (set infinite).
4015 send_parameters_.max_bandwidth_bps = -1;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01004016 ExpectSetMaxBitrate(-1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004017 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004018}
4019
eladalonf1841382017-06-12 01:16:46 -07004020TEST_F(WebRtcVideoChannelTest, SetMaxSendBandwidthAndAddSendStream) {
perkjfa10b552016-10-02 23:45:26 -07004021 send_parameters_.max_bandwidth_bps = 99999;
4022 FakeVideoSendStream* stream = AddSendStream();
Sebastian Jansson8f83b422018-02-21 13:07:13 +01004023 ExpectSetMaxBitrate(send_parameters_.max_bandwidth_bps);
perkjfa10b552016-10-02 23:45:26 -07004024 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
perkjfa10b552016-10-02 23:45:26 -07004025 ASSERT_EQ(1u, stream->GetVideoStreams().size());
4026 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
4027 stream->GetVideoStreams()[0].max_bitrate_bps);
4028
4029 send_parameters_.max_bandwidth_bps = 77777;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01004030 ExpectSetMaxBitrate(send_parameters_.max_bandwidth_bps);
perkjfa10b552016-10-02 23:45:26 -07004031 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
4032 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
perkjfa10b552016-10-02 23:45:26 -07004033 stream->GetVideoStreams()[0].max_bitrate_bps);
4034}
4035
Seth Hampsonfeec91e2018-07-13 10:41:10 -07004036// Tests that when the codec specific max bitrate and VideoSendParameters
4037// max_bandwidth_bps are used, that it sets the VideoStream's max bitrate
4038// appropriately.
4039TEST_F(WebRtcVideoChannelTest,
4040 MaxBitratePrioritizesVideoSendParametersOverCodecMaxBitrate) {
4041 send_parameters_.codecs[0].params[kCodecParamMinBitrate] = "100";
4042 send_parameters_.codecs[0].params[kCodecParamStartBitrate] = "200";
4043 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "300";
4044 send_parameters_.max_bandwidth_bps = -1;
4045 AddSendStream();
4046 ExpectSetMaxBitrate(300000);
4047 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
4048
4049 std::vector<FakeVideoSendStream*> video_send_streams = GetFakeSendStreams();
4050 ASSERT_EQ(1u, video_send_streams.size());
4051 FakeVideoSendStream* video_send_stream = video_send_streams[0];
4052 ASSERT_EQ(1u, video_send_streams[0]->GetVideoStreams().size());
4053 // First the max bitrate is set based upon the codec param.
4054 EXPECT_EQ(300000,
4055 video_send_streams[0]->GetVideoStreams()[0].max_bitrate_bps);
4056
4057 // The VideoSendParameters max bitrate overrides the codec's.
4058 send_parameters_.max_bandwidth_bps = 500000;
4059 ExpectSetMaxBitrate(send_parameters_.max_bandwidth_bps);
4060 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
4061 ASSERT_EQ(1u, video_send_stream->GetVideoStreams().size());
4062 EXPECT_EQ(500000, video_send_stream->GetVideoStreams()[0].max_bitrate_bps);
4063}
4064
4065// Tests that when the codec specific max bitrate and RtpParameters
4066// max_bitrate_bps are used, that it sets the VideoStream's max bitrate
4067// appropriately.
4068TEST_F(WebRtcVideoChannelTest,
4069 MaxBitratePrioritizesRtpParametersOverCodecMaxBitrate) {
4070 send_parameters_.codecs[0].params[kCodecParamMinBitrate] = "100";
4071 send_parameters_.codecs[0].params[kCodecParamStartBitrate] = "200";
4072 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "300";
4073 send_parameters_.max_bandwidth_bps = -1;
4074 AddSendStream();
4075 ExpectSetMaxBitrate(300000);
4076 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
4077
4078 std::vector<FakeVideoSendStream*> video_send_streams = GetFakeSendStreams();
4079 ASSERT_EQ(1u, video_send_streams.size());
4080 FakeVideoSendStream* video_send_stream = video_send_streams[0];
4081 ASSERT_EQ(1u, video_send_stream->GetVideoStreams().size());
4082 // First the max bitrate is set based upon the codec param.
4083 EXPECT_EQ(300000, video_send_stream->GetVideoStreams()[0].max_bitrate_bps);
4084
4085 // The RtpParameter max bitrate overrides the codec's.
4086 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
4087 ASSERT_EQ(1u, parameters.encodings.size());
4088 parameters.encodings[0].max_bitrate_bps = 500000;
4089 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
4090 ASSERT_EQ(1u, video_send_stream->GetVideoStreams().size());
4091 EXPECT_EQ(parameters.encodings[0].max_bitrate_bps,
4092 video_send_stream->GetVideoStreams()[0].max_bitrate_bps);
4093}
4094
Åsa Persson55659812018-06-18 17:51:32 +02004095TEST_F(WebRtcVideoChannelTest,
4096 MaxBitrateIsMinimumOfMaxSendBandwidthAndMaxEncodingBitrate) {
4097 send_parameters_.max_bandwidth_bps = 99999;
4098 FakeVideoSendStream* stream = AddSendStream();
4099 ExpectSetMaxBitrate(send_parameters_.max_bandwidth_bps);
4100 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
4101 ASSERT_EQ(1u, stream->GetVideoStreams().size());
4102 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
4103 stream->GetVideoStreams()[0].max_bitrate_bps);
4104
4105 // Get and set the rtp encoding parameters.
4106 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
4107 EXPECT_EQ(1u, parameters.encodings.size());
4108
4109 parameters.encodings[0].max_bitrate_bps = 99999 - 1;
4110 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
4111 EXPECT_EQ(parameters.encodings[0].max_bitrate_bps,
4112 stream->GetVideoStreams()[0].max_bitrate_bps);
4113
4114 parameters.encodings[0].max_bitrate_bps = 99999 + 1;
4115 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
4116 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
4117 stream->GetVideoStreams()[0].max_bitrate_bps);
4118}
4119
eladalonf1841382017-06-12 01:16:46 -07004120TEST_F(WebRtcVideoChannelTest, SetMaxSendBitrateCanIncreaseSenderBitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004121 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004122 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004123 ASSERT_TRUE(channel_->SetSendParameters(parameters));
Peter Boströmdfd53fe2015-03-27 15:58:11 +01004124 channel_->SetSend(true);
4125
4126 FakeVideoSendStream* stream = AddSendStream();
4127
Niels Möller805a27e2019-01-21 12:21:27 +01004128 webrtc::test::FrameForwarder frame_forwarder;
4129 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));
Peter Boström3afc8c42016-01-27 16:45:21 +01004130
Peter Boströmdfd53fe2015-03-27 15:58:11 +01004131 std::vector<webrtc::VideoStream> streams = stream->GetVideoStreams();
4132 int initial_max_bitrate_bps = streams[0].max_bitrate_bps;
4133 EXPECT_GT(initial_max_bitrate_bps, 0);
4134
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004135 parameters.max_bandwidth_bps = initial_max_bitrate_bps * 2;
4136 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Peter Boström3afc8c42016-01-27 16:45:21 +01004137 // Insert a frame to update the encoder config.
Niels Möller805a27e2019-01-21 12:21:27 +01004138 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Peter Boströmdfd53fe2015-03-27 15:58:11 +01004139 streams = stream->GetVideoStreams();
4140 EXPECT_EQ(initial_max_bitrate_bps * 2, streams[0].max_bitrate_bps);
Niels Möllerff40b142018-04-09 08:49:14 +02004141 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
Peter Boströmdfd53fe2015-03-27 15:58:11 +01004142}
4143
eladalonf1841382017-06-12 01:16:46 -07004144TEST_F(WebRtcVideoChannelTest,
Peter Boströmdfd53fe2015-03-27 15:58:11 +01004145 SetMaxSendBitrateCanIncreaseSimulcastSenderBitrate) {
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));
Peter Boströmdfd53fe2015-03-27 15:58:11 +01004149 channel_->SetSend(true);
4150
4151 FakeVideoSendStream* stream = AddSendStream(
4152 cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kSsrcs3)));
4153
4154 // Send a frame to make sure this scales up to >1 stream (simulcast).
Niels Möller805a27e2019-01-21 12:21:27 +01004155 webrtc::test::FrameForwarder frame_forwarder;
4156 EXPECT_TRUE(channel_->SetVideoSend(kSsrcs3[0], nullptr, &frame_forwarder));
4157 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Peter Boströmdfd53fe2015-03-27 15:58:11 +01004158
4159 std::vector<webrtc::VideoStream> streams = stream->GetVideoStreams();
4160 ASSERT_GT(streams.size(), 1u)
4161 << "Without simulcast this test doesn't make sense.";
pbosbe16f792015-10-16 12:49:39 -07004162 int initial_max_bitrate_bps = GetTotalMaxBitrateBps(streams);
Peter Boströmdfd53fe2015-03-27 15:58:11 +01004163 EXPECT_GT(initial_max_bitrate_bps, 0);
4164
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004165 parameters.max_bandwidth_bps = initial_max_bitrate_bps * 2;
4166 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Peter Boström3afc8c42016-01-27 16:45:21 +01004167 // Insert a frame to update the encoder config.
Niels Möller805a27e2019-01-21 12:21:27 +01004168 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Peter Boströmdfd53fe2015-03-27 15:58:11 +01004169 streams = stream->GetVideoStreams();
pbosbe16f792015-10-16 12:49:39 -07004170 int increased_max_bitrate_bps = GetTotalMaxBitrateBps(streams);
Peter Boströmdfd53fe2015-03-27 15:58:11 +01004171 EXPECT_EQ(initial_max_bitrate_bps * 2, increased_max_bitrate_bps);
4172
Niels Möllerff40b142018-04-09 08:49:14 +02004173 EXPECT_TRUE(channel_->SetVideoSend(kSsrcs3[0], nullptr, nullptr));
Peter Boströmdfd53fe2015-03-27 15:58:11 +01004174}
4175
eladalonf1841382017-06-12 01:16:46 -07004176TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithMaxQuantization) {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004177 static const char* kMaxQuantization = "21";
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004178 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004179 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004180 parameters.codecs[0].params[kCodecParamMaxQuantization] = kMaxQuantization;
4181 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Mirko Bonadeif859e552018-05-30 15:31:29 +02004182 EXPECT_EQ(atoi(kMaxQuantization),
pbos@webrtc.org6ae48c62014-06-06 10:49:19 +00004183 AddSendStream()->GetVideoStreams().back().max_qp);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004184
4185 VideoCodec codec;
4186 EXPECT_TRUE(channel_->GetSendCodec(&codec));
4187 EXPECT_EQ(kMaxQuantization, codec.params[kCodecParamMaxQuantization]);
4188}
4189
eladalonf1841382017-06-12 01:16:46 -07004190TEST_F(WebRtcVideoChannelTest, SetSendCodecsRejectBadPayloadTypes) {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004191 // TODO(pbos): Should we only allow the dynamic range?
pkasting@chromium.orge7a4a122015-01-28 21:36:55 +00004192 static const int kIncorrectPayloads[] = {-2, -1, 128, 129};
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004193 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004194 parameters.codecs.push_back(GetEngineCodec("VP8"));
pkasting@chromium.orge7a4a122015-01-28 21:36:55 +00004195 for (size_t i = 0; i < arraysize(kIncorrectPayloads); ++i) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004196 parameters.codecs[0].id = kIncorrectPayloads[i];
4197 EXPECT_FALSE(channel_->SetSendParameters(parameters))
pkasting@chromium.orgd3245462015-02-23 21:28:22 +00004198 << "Bad payload type '" << kIncorrectPayloads[i] << "' accepted.";
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004199 }
4200}
4201
eladalonf1841382017-06-12 01:16:46 -07004202TEST_F(WebRtcVideoChannelTest, SetSendCodecsAcceptAllValidPayloadTypes) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004203 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004204 parameters.codecs.push_back(GetEngineCodec("VP8"));
magjedf823ede2016-11-12 09:53:04 -08004205 for (int payload_type = 96; payload_type <= 127; ++payload_type) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004206 parameters.codecs[0].id = payload_type;
4207 EXPECT_TRUE(channel_->SetSendParameters(parameters))
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004208 << "Payload type '" << payload_type << "' rejected.";
4209 }
4210}
4211
deadbeef67cf2c12016-04-13 10:07:16 -07004212// Test that setting the a different set of codecs but with an identical front
4213// codec doesn't result in the stream being recreated.
4214// This may happen when a subsequent negotiation includes fewer codecs, as a
4215// result of one of the codecs being rejected.
eladalonf1841382017-06-12 01:16:46 -07004216TEST_F(WebRtcVideoChannelTest,
deadbeef67cf2c12016-04-13 10:07:16 -07004217 SetSendCodecsIdenticalFirstCodecDoesntRecreateStream) {
4218 cricket::VideoSendParameters parameters1;
magjed509e4fe2016-11-18 01:34:11 -08004219 parameters1.codecs.push_back(GetEngineCodec("VP8"));
4220 parameters1.codecs.push_back(GetEngineCodec("VP9"));
deadbeef67cf2c12016-04-13 10:07:16 -07004221 EXPECT_TRUE(channel_->SetSendParameters(parameters1));
4222
4223 AddSendStream();
4224 EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());
4225
4226 cricket::VideoSendParameters parameters2;
magjed509e4fe2016-11-18 01:34:11 -08004227 parameters2.codecs.push_back(GetEngineCodec("VP8"));
deadbeef67cf2c12016-04-13 10:07:16 -07004228 EXPECT_TRUE(channel_->SetSendParameters(parameters2));
4229 EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());
4230}
4231
eladalonf1841382017-06-12 01:16:46 -07004232TEST_F(WebRtcVideoChannelTest, SetRecvCodecsWithOnlyVp8) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004233 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004234 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004235 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004236}
4237
pbos@webrtc.orge322a172014-06-13 11:47:28 +00004238// Test that we set our inbound RTX codecs properly.
eladalonf1841382017-06-12 01:16:46 -07004239TEST_F(WebRtcVideoChannelTest, SetRecvCodecsWithRtx) {
magjed509e4fe2016-11-18 01:34:11 -08004240 const int kUnusedPayloadType1 = 126;
4241 const int kUnusedPayloadType2 = 127;
4242 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType1));
4243 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType2));
4244
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004245 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004246 parameters.codecs.push_back(GetEngineCodec("VP8"));
4247 cricket::VideoCodec rtx_codec(kUnusedPayloadType1, "rtx");
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004248 parameters.codecs.push_back(rtx_codec);
4249 EXPECT_FALSE(channel_->SetRecvParameters(parameters))
pbos@webrtc.orge322a172014-06-13 11:47:28 +00004250 << "RTX codec without associated payload should be rejected.";
4251
magjed509e4fe2016-11-18 01:34:11 -08004252 parameters.codecs[1].SetParam("apt", kUnusedPayloadType2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004253 EXPECT_FALSE(channel_->SetRecvParameters(parameters))
pbos@webrtc.orge322a172014-06-13 11:47:28 +00004254 << "RTX codec with invalid associated payload type should be rejected.";
4255
magjed509e4fe2016-11-18 01:34:11 -08004256 parameters.codecs[1].SetParam("apt", GetEngineCodec("VP8").id);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004257 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orge322a172014-06-13 11:47:28 +00004258
magjed509e4fe2016-11-18 01:34:11 -08004259 cricket::VideoCodec rtx_codec2(kUnusedPayloadType2, "rtx");
pbos@webrtc.orge322a172014-06-13 11:47:28 +00004260 rtx_codec2.SetParam("apt", rtx_codec.id);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004261 parameters.codecs.push_back(rtx_codec2);
pbos@webrtc.orge322a172014-06-13 11:47:28 +00004262
Yves Gerey665174f2018-06-19 15:03:05 +02004263 EXPECT_FALSE(channel_->SetRecvParameters(parameters))
4264 << "RTX codec with another RTX as associated payload type should be "
4265 "rejected.";
pbos@webrtc.orge322a172014-06-13 11:47:28 +00004266}
4267
eladalonf1841382017-06-12 01:16:46 -07004268TEST_F(WebRtcVideoChannelTest, SetRecvCodecsWithChangedRtxPayloadType) {
brandtr14742122017-01-27 04:53:07 -08004269 const int kUnusedPayloadType1 = 126;
4270 const int kUnusedPayloadType2 = 127;
4271 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType1));
4272 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType2));
4273
4274 // SSRCs for RTX.
4275 cricket::StreamParams params =
4276 cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
4277 params.AddFidSsrc(kSsrcs1[0], kRtxSsrcs1[0]);
4278 AddRecvStream(params);
4279
4280 // Original payload type for RTX.
4281 cricket::VideoRecvParameters parameters;
4282 parameters.codecs.push_back(GetEngineCodec("VP8"));
4283 cricket::VideoCodec rtx_codec(kUnusedPayloadType1, "rtx");
4284 rtx_codec.SetParam("apt", GetEngineCodec("VP8").id);
4285 parameters.codecs.push_back(rtx_codec);
4286 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
4287 ASSERT_EQ(1U, fake_call_->GetVideoReceiveStreams().size());
4288 const webrtc::VideoReceiveStream::Config& config_before =
4289 fake_call_->GetVideoReceiveStreams()[0]->GetConfig();
nisse26e3abb2017-08-25 04:44:25 -07004290 EXPECT_EQ(1U, config_before.rtp.rtx_associated_payload_types.size());
4291 const int* payload_type_before = FindKeyByValue(
4292 config_before.rtp.rtx_associated_payload_types, GetEngineCodec("VP8").id);
4293 ASSERT_NE(payload_type_before, nullptr);
4294 EXPECT_EQ(kUnusedPayloadType1, *payload_type_before);
brandtr14742122017-01-27 04:53:07 -08004295 EXPECT_EQ(kRtxSsrcs1[0], config_before.rtp.rtx_ssrc);
4296
4297 // Change payload type for RTX.
4298 parameters.codecs[1].id = kUnusedPayloadType2;
4299 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
4300 ASSERT_EQ(1U, fake_call_->GetVideoReceiveStreams().size());
4301 const webrtc::VideoReceiveStream::Config& config_after =
4302 fake_call_->GetVideoReceiveStreams()[0]->GetConfig();
nisse26e3abb2017-08-25 04:44:25 -07004303 EXPECT_EQ(1U, config_after.rtp.rtx_associated_payload_types.size());
4304 const int* payload_type_after = FindKeyByValue(
4305 config_after.rtp.rtx_associated_payload_types, GetEngineCodec("VP8").id);
4306 ASSERT_NE(payload_type_after, nullptr);
4307 EXPECT_EQ(kUnusedPayloadType2, *payload_type_after);
brandtr14742122017-01-27 04:53:07 -08004308 EXPECT_EQ(kRtxSsrcs1[0], config_after.rtp.rtx_ssrc);
4309}
4310
eladalonf1841382017-06-12 01:16:46 -07004311TEST_F(WebRtcVideoChannelTest, SetRecvCodecsDifferentPayloadType) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004312 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004313 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004314 parameters.codecs[0].id = 99;
4315 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004316}
4317
eladalonf1841382017-06-12 01:16:46 -07004318TEST_F(WebRtcVideoChannelTest, SetRecvCodecsAcceptDefaultCodecs) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004319 cricket::VideoRecvParameters parameters;
4320 parameters.codecs = engine_.codecs();
4321 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgccbed3b2014-07-11 13:02:54 +00004322
4323 FakeVideoReceiveStream* stream = AddRecvStream();
Tommi733b5472016-06-10 17:58:01 +02004324 const webrtc::VideoReceiveStream::Config& config = stream->GetConfig();
Niels Möllercb7e1d22018-09-11 15:56:04 +02004325 EXPECT_EQ(engine_.codecs()[0].name, config.decoders[0].video_format.name);
pbos@webrtc.org776e6f22014-10-29 15:28:39 +00004326 EXPECT_EQ(engine_.codecs()[0].id, config.decoders[0].payload_type);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004327}
4328
eladalonf1841382017-06-12 01:16:46 -07004329TEST_F(WebRtcVideoChannelTest, SetRecvCodecsRejectUnsupportedCodec) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004330 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004331 parameters.codecs.push_back(GetEngineCodec("VP8"));
perkj26752742016-10-24 01:21:16 -07004332 parameters.codecs.push_back(VideoCodec(101, "WTF3"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004333 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004334}
4335
eladalonf1841382017-06-12 01:16:46 -07004336TEST_F(WebRtcVideoChannelTest, SetRecvCodecsAcceptsMultipleVideoCodecs) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004337 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004338 parameters.codecs.push_back(GetEngineCodec("VP8"));
4339 parameters.codecs.push_back(GetEngineCodec("VP9"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004340 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004341}
4342
eladalonf1841382017-06-12 01:16:46 -07004343TEST_F(WebRtcVideoChannelTest, SetRecvCodecsWithoutFecDisablesFec) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004344 cricket::VideoSendParameters send_parameters;
magjed509e4fe2016-11-18 01:34:11 -08004345 send_parameters.codecs.push_back(GetEngineCodec("VP8"));
4346 send_parameters.codecs.push_back(GetEngineCodec("red"));
4347 send_parameters.codecs.push_back(GetEngineCodec("ulpfec"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004348 ASSERT_TRUE(channel_->SetSendParameters(send_parameters));
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00004349
4350 FakeVideoReceiveStream* stream = AddRecvStream();
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00004351
magjed509e4fe2016-11-18 01:34:11 -08004352 EXPECT_EQ(GetEngineCodec("ulpfec").id,
nisse3b3622f2017-09-26 02:49:21 -07004353 stream->GetConfig().rtp.ulpfec_payload_type);
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00004354
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004355 cricket::VideoRecvParameters recv_parameters;
magjed509e4fe2016-11-18 01:34:11 -08004356 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004357 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00004358 stream = fake_call_->GetVideoReceiveStreams()[0];
brandtr468da7c2016-11-22 02:16:47 -08004359 ASSERT_TRUE(stream != nullptr);
nisse3b3622f2017-09-26 02:49:21 -07004360 EXPECT_EQ(-1, stream->GetConfig().rtp.ulpfec_payload_type)
brandtr468da7c2016-11-22 02:16:47 -08004361 << "SetSendCodec without ULPFEC should disable current ULPFEC.";
4362}
4363
eladalonf1841382017-06-12 01:16:46 -07004364TEST_F(WebRtcVideoChannelFlexfecRecvTest, SetRecvParamsWithoutFecDisablesFec) {
brandtr468da7c2016-11-22 02:16:47 -08004365 AddRecvStream(
4366 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
brandtr9c3d4c42017-01-23 06:59:13 -08004367 const std::vector<FakeFlexfecReceiveStream*>& streams =
brandtr468da7c2016-11-22 02:16:47 -08004368 fake_call_->GetFlexfecReceiveStreams();
4369
4370 ASSERT_EQ(1U, streams.size());
brandtr9c3d4c42017-01-23 06:59:13 -08004371 const FakeFlexfecReceiveStream* stream = streams.front();
4372 EXPECT_EQ(GetEngineCodec("flexfec-03").id, stream->GetConfig().payload_type);
4373 EXPECT_EQ(kFlexfecSsrc, stream->GetConfig().remote_ssrc);
4374 ASSERT_EQ(1U, stream->GetConfig().protected_media_ssrcs.size());
4375 EXPECT_EQ(kSsrcs1[0], stream->GetConfig().protected_media_ssrcs[0]);
brandtr468da7c2016-11-22 02:16:47 -08004376
4377 cricket::VideoRecvParameters recv_parameters;
4378 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
4379 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
4380 EXPECT_TRUE(streams.empty())
4381 << "SetSendCodec without FlexFEC should disable current FlexFEC.";
pbos@webrtc.org269605c2014-06-26 08:49:03 +00004382}
4383
eladalonf1841382017-06-12 01:16:46 -07004384TEST_F(WebRtcVideoChannelTest, SetSendParamsWithFecEnablesFec) {
Stefan Holmer2b1f6512016-05-17 16:33:30 +02004385 FakeVideoReceiveStream* stream = AddRecvStream();
magjed509e4fe2016-11-18 01:34:11 -08004386 EXPECT_EQ(GetEngineCodec("ulpfec").id,
nisse3b3622f2017-09-26 02:49:21 -07004387 stream->GetConfig().rtp.ulpfec_payload_type);
Stefan Holmer2b1f6512016-05-17 16:33:30 +02004388
4389 cricket::VideoRecvParameters recv_parameters;
magjed509e4fe2016-11-18 01:34:11 -08004390 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
4391 recv_parameters.codecs.push_back(GetEngineCodec("red"));
4392 recv_parameters.codecs.push_back(GetEngineCodec("ulpfec"));
Stefan Holmer2b1f6512016-05-17 16:33:30 +02004393 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
4394 stream = fake_call_->GetVideoReceiveStreams()[0];
brandtr468da7c2016-11-22 02:16:47 -08004395 ASSERT_TRUE(stream != nullptr);
magjed509e4fe2016-11-18 01:34:11 -08004396 EXPECT_EQ(GetEngineCodec("ulpfec").id,
nisse3b3622f2017-09-26 02:49:21 -07004397 stream->GetConfig().rtp.ulpfec_payload_type)
brandtr468da7c2016-11-22 02:16:47 -08004398 << "ULPFEC should be enabled on the receive stream.";
Stefan Holmer2b1f6512016-05-17 16:33:30 +02004399
4400 cricket::VideoSendParameters send_parameters;
magjed509e4fe2016-11-18 01:34:11 -08004401 send_parameters.codecs.push_back(GetEngineCodec("VP8"));
4402 send_parameters.codecs.push_back(GetEngineCodec("red"));
4403 send_parameters.codecs.push_back(GetEngineCodec("ulpfec"));
Stefan Holmer2b1f6512016-05-17 16:33:30 +02004404 ASSERT_TRUE(channel_->SetSendParameters(send_parameters));
4405 stream = fake_call_->GetVideoReceiveStreams()[0];
magjed509e4fe2016-11-18 01:34:11 -08004406 EXPECT_EQ(GetEngineCodec("ulpfec").id,
nisse3b3622f2017-09-26 02:49:21 -07004407 stream->GetConfig().rtp.ulpfec_payload_type)
brandtr468da7c2016-11-22 02:16:47 -08004408 << "ULPFEC should be enabled on the receive stream.";
4409}
4410
eladalonf1841382017-06-12 01:16:46 -07004411TEST_F(WebRtcVideoChannelFlexfecSendRecvTest,
brandtr31bd2242017-05-19 05:47:46 -07004412 SetSendRecvParamsWithFecEnablesFec) {
brandtr468da7c2016-11-22 02:16:47 -08004413 AddRecvStream(
4414 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
brandtr9c3d4c42017-01-23 06:59:13 -08004415 const std::vector<FakeFlexfecReceiveStream*>& streams =
brandtr468da7c2016-11-22 02:16:47 -08004416 fake_call_->GetFlexfecReceiveStreams();
4417
4418 cricket::VideoRecvParameters recv_parameters;
4419 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
4420 recv_parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
4421 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
4422 ASSERT_EQ(1U, streams.size());
brandtr9c3d4c42017-01-23 06:59:13 -08004423 const FakeFlexfecReceiveStream* stream_with_recv_params = streams.front();
brandtr468da7c2016-11-22 02:16:47 -08004424 EXPECT_EQ(GetEngineCodec("flexfec-03").id,
brandtr9c3d4c42017-01-23 06:59:13 -08004425 stream_with_recv_params->GetConfig().payload_type);
4426 EXPECT_EQ(kFlexfecSsrc, stream_with_recv_params->GetConfig().remote_ssrc);
brandtr468da7c2016-11-22 02:16:47 -08004427 EXPECT_EQ(1U,
brandtr9c3d4c42017-01-23 06:59:13 -08004428 stream_with_recv_params->GetConfig().protected_media_ssrcs.size());
brandtr468da7c2016-11-22 02:16:47 -08004429 EXPECT_EQ(kSsrcs1[0],
brandtr9c3d4c42017-01-23 06:59:13 -08004430 stream_with_recv_params->GetConfig().protected_media_ssrcs[0]);
brandtr468da7c2016-11-22 02:16:47 -08004431
4432 cricket::VideoSendParameters send_parameters;
4433 send_parameters.codecs.push_back(GetEngineCodec("VP8"));
4434 send_parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
4435 ASSERT_TRUE(channel_->SetSendParameters(send_parameters));
4436 ASSERT_EQ(1U, streams.size());
brandtr9c3d4c42017-01-23 06:59:13 -08004437 const FakeFlexfecReceiveStream* stream_with_send_params = streams.front();
brandtr468da7c2016-11-22 02:16:47 -08004438 EXPECT_EQ(GetEngineCodec("flexfec-03").id,
brandtr9c3d4c42017-01-23 06:59:13 -08004439 stream_with_send_params->GetConfig().payload_type);
4440 EXPECT_EQ(kFlexfecSsrc, stream_with_send_params->GetConfig().remote_ssrc);
brandtr468da7c2016-11-22 02:16:47 -08004441 EXPECT_EQ(1U,
brandtr9c3d4c42017-01-23 06:59:13 -08004442 stream_with_send_params->GetConfig().protected_media_ssrcs.size());
brandtr468da7c2016-11-22 02:16:47 -08004443 EXPECT_EQ(kSsrcs1[0],
brandtr9c3d4c42017-01-23 06:59:13 -08004444 stream_with_send_params->GetConfig().protected_media_ssrcs[0]);
Stefan Holmer2b1f6512016-05-17 16:33:30 +02004445}
4446
eladalonf1841382017-06-12 01:16:46 -07004447TEST_F(WebRtcVideoChannelTest, SetRecvCodecsRejectDuplicateFecPayloads) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004448 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004449 parameters.codecs.push_back(GetEngineCodec("VP8"));
4450 parameters.codecs.push_back(GetEngineCodec("red"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004451 parameters.codecs[1].id = parameters.codecs[0].id;
4452 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004453}
4454
eladalonf1841382017-06-12 01:16:46 -07004455TEST_F(WebRtcVideoChannelFlexfecRecvTest,
brandtr31bd2242017-05-19 05:47:46 -07004456 SetRecvCodecsRejectDuplicateFecPayloads) {
brandtr468da7c2016-11-22 02:16:47 -08004457 cricket::VideoRecvParameters parameters;
4458 parameters.codecs.push_back(GetEngineCodec("VP8"));
4459 parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
4460 parameters.codecs[1].id = parameters.codecs[0].id;
4461 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
4462}
4463
eladalonf1841382017-06-12 01:16:46 -07004464TEST_F(WebRtcVideoChannelTest, SetRecvCodecsRejectDuplicateCodecPayloads) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004465 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004466 parameters.codecs.push_back(GetEngineCodec("VP8"));
4467 parameters.codecs.push_back(GetEngineCodec("VP9"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004468 parameters.codecs[1].id = parameters.codecs[0].id;
4469 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004470}
4471
eladalonf1841382017-06-12 01:16:46 -07004472TEST_F(WebRtcVideoChannelTest,
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004473 SetRecvCodecsAcceptSameCodecOnMultiplePayloadTypes) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004474 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004475 parameters.codecs.push_back(GetEngineCodec("VP8"));
4476 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004477 parameters.codecs[1].id += 1;
4478 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004479}
4480
deadbeef67cf2c12016-04-13 10:07:16 -07004481// Test that setting the same codecs but with a different order
deadbeef874ca3a2015-08-20 17:19:20 -07004482// doesn't result in the stream being recreated.
eladalonf1841382017-06-12 01:16:46 -07004483TEST_F(WebRtcVideoChannelTest,
deadbeef67cf2c12016-04-13 10:07:16 -07004484 SetRecvCodecsDifferentOrderDoesntRecreateStream) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004485 cricket::VideoRecvParameters parameters1;
magjed509e4fe2016-11-18 01:34:11 -08004486 parameters1.codecs.push_back(GetEngineCodec("VP8"));
4487 parameters1.codecs.push_back(GetEngineCodec("red"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004488 EXPECT_TRUE(channel_->SetRecvParameters(parameters1));
deadbeef874ca3a2015-08-20 17:19:20 -07004489
4490 AddRecvStream(cricket::StreamParams::CreateLegacy(123));
4491 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
4492
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004493 cricket::VideoRecvParameters parameters2;
magjed509e4fe2016-11-18 01:34:11 -08004494 parameters2.codecs.push_back(GetEngineCodec("red"));
4495 parameters2.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004496 EXPECT_TRUE(channel_->SetRecvParameters(parameters2));
deadbeef874ca3a2015-08-20 17:19:20 -07004497 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
4498}
4499
eladalonf1841382017-06-12 01:16:46 -07004500TEST_F(WebRtcVideoChannelTest, SendStreamNotSendingByDefault) {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004501 EXPECT_FALSE(AddSendStream()->IsSending());
4502}
4503
eladalonf1841382017-06-12 01:16:46 -07004504TEST_F(WebRtcVideoChannelTest, ReceiveStreamReceivingByDefault) {
pbos@webrtc.org85f42942014-07-22 09:14:58 +00004505 EXPECT_TRUE(AddRecvStream()->IsReceiving());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004506}
4507
eladalonf1841382017-06-12 01:16:46 -07004508TEST_F(WebRtcVideoChannelTest, SetSend) {
pbos@webrtc.org5301b0f2014-07-17 08:51:46 +00004509 FakeVideoSendStream* stream = AddSendStream();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004510 EXPECT_FALSE(stream->IsSending());
4511
4512 // false->true
4513 EXPECT_TRUE(channel_->SetSend(true));
4514 EXPECT_TRUE(stream->IsSending());
4515 // true->true
4516 EXPECT_TRUE(channel_->SetSend(true));
4517 EXPECT_TRUE(stream->IsSending());
4518 // true->false
4519 EXPECT_TRUE(channel_->SetSend(false));
4520 EXPECT_FALSE(stream->IsSending());
4521 // false->false
4522 EXPECT_TRUE(channel_->SetSend(false));
4523 EXPECT_FALSE(stream->IsSending());
4524
4525 EXPECT_TRUE(channel_->SetSend(true));
4526 FakeVideoSendStream* new_stream = AddSendStream();
4527 EXPECT_TRUE(new_stream->IsSending())
4528 << "Send stream created after SetSend(true) not sending initially.";
4529}
4530
pbos@webrtc.orgd8198032014-11-10 14:41:43 +00004531// This test verifies DSCP settings are properly applied on video media channel.
eladalonf1841382017-06-12 01:16:46 -07004532TEST_F(WebRtcVideoChannelTest, TestSetDscpOptions) {
kwiberg686a8ef2016-02-26 03:00:35 -08004533 std::unique_ptr<cricket::FakeNetworkInterface> network_interface(
pbos@webrtc.orgd8198032014-11-10 14:41:43 +00004534 new cricket::FakeNetworkInterface);
nisse51542be2016-02-12 02:27:06 -08004535 MediaConfig config;
Tim Haloun6ca98362018-09-17 17:06:08 -07004536 std::unique_ptr<cricket::WebRtcVideoChannel> channel;
Tim Haloun648d28a2018-10-18 16:52:22 -07004537 webrtc::RtpParameters parameters;
nisse51542be2016-02-12 02:27:06 -08004538
Sebastian Jansson84848f22018-11-16 10:40:36 +01004539 channel.reset(
4540 static_cast<cricket::WebRtcVideoChannel*>(engine_.CreateMediaChannel(
4541 call_.get(), config, VideoOptions(), webrtc::CryptoOptions())));
Anton Sukhanov98a462c2018-10-17 13:15:42 -07004542 channel->SetInterface(network_interface.get(), /*media_transport=*/nullptr);
nisse51542be2016-02-12 02:27:06 -08004543 // Default value when DSCP is disabled should be DSCP_DEFAULT.
pbos@webrtc.orgd8198032014-11-10 14:41:43 +00004544 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface->dscp());
nisse51542be2016-02-12 02:27:06 -08004545
Tim Haloun648d28a2018-10-18 16:52:22 -07004546 // Default value when DSCP is enabled is also DSCP_DEFAULT, until it is set
4547 // through rtp parameters.
nisse51542be2016-02-12 02:27:06 -08004548 config.enable_dscp = true;
Sebastian Jansson84848f22018-11-16 10:40:36 +01004549 channel.reset(
4550 static_cast<cricket::WebRtcVideoChannel*>(engine_.CreateMediaChannel(
4551 call_.get(), config, VideoOptions(), webrtc::CryptoOptions())));
Anton Sukhanov98a462c2018-10-17 13:15:42 -07004552 channel->SetInterface(network_interface.get(), /*media_transport=*/nullptr);
Tim Haloun648d28a2018-10-18 16:52:22 -07004553 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface->dscp());
4554
4555 // Create a send stream to configure
4556 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(kSsrc)));
4557 parameters = channel->GetRtpSendParameters(kSsrc);
4558 ASSERT_FALSE(parameters.encodings.empty());
4559
4560 // Various priorities map to various dscp values.
4561 parameters.encodings[0].network_priority = 4.0;
4562 ASSERT_TRUE(channel->SetRtpSendParameters(kSsrc, parameters).ok());
nisse51542be2016-02-12 02:27:06 -08004563 EXPECT_EQ(rtc::DSCP_AF41, network_interface->dscp());
Tim Haloun648d28a2018-10-18 16:52:22 -07004564 parameters.encodings[0].network_priority = 0.5;
4565 ASSERT_TRUE(channel->SetRtpSendParameters(kSsrc, parameters).ok());
4566 EXPECT_EQ(rtc::DSCP_CS1, network_interface->dscp());
4567
4568 // A bad priority does not change the dscp value.
4569 parameters.encodings[0].network_priority = 0.0;
4570 ASSERT_FALSE(channel->SetRtpSendParameters(kSsrc, parameters).ok());
4571 EXPECT_EQ(rtc::DSCP_CS1, network_interface->dscp());
nisse51542be2016-02-12 02:27:06 -08004572
Tim Haloun6ca98362018-09-17 17:06:08 -07004573 // Packets should also self-identify their dscp in PacketOptions.
4574 const uint8_t kData[10] = {0};
4575 EXPECT_TRUE(static_cast<webrtc::Transport*>(channel.get())
4576 ->SendRtcp(kData, sizeof(kData)));
Tim Haloun648d28a2018-10-18 16:52:22 -07004577 EXPECT_EQ(rtc::DSCP_CS1, network_interface->options().dscp);
Tim Haloun6ca98362018-09-17 17:06:08 -07004578
nisse51542be2016-02-12 02:27:06 -08004579 // Verify that setting the option to false resets the
4580 // DiffServCodePoint.
4581 config.enable_dscp = false;
Sebastian Jansson84848f22018-11-16 10:40:36 +01004582 channel.reset(
4583 static_cast<cricket::WebRtcVideoChannel*>(engine_.CreateMediaChannel(
4584 call_.get(), config, VideoOptions(), webrtc::CryptoOptions())));
Anton Sukhanov98a462c2018-10-17 13:15:42 -07004585 channel->SetInterface(network_interface.get(), /*media_transport=*/nullptr);
nisse51542be2016-02-12 02:27:06 -08004586 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface->dscp());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004587}
4588
deadbeef13871492015-12-09 12:37:51 -08004589// This test verifies that the RTCP reduced size mode is properly applied to
4590// send video streams.
eladalonf1841382017-06-12 01:16:46 -07004591TEST_F(WebRtcVideoChannelTest, TestSetSendRtcpReducedSize) {
deadbeef13871492015-12-09 12:37:51 -08004592 // Create stream, expecting that default mode is "compound".
4593 FakeVideoSendStream* stream1 = AddSendStream();
4594 EXPECT_EQ(webrtc::RtcpMode::kCompound, stream1->GetConfig().rtp.rtcp_mode);
Florent Castellidacec712018-05-24 16:24:21 +02004595 webrtc::RtpParameters rtp_parameters =
4596 channel_->GetRtpSendParameters(last_ssrc_);
4597 EXPECT_FALSE(rtp_parameters.rtcp.reduced_size);
deadbeef13871492015-12-09 12:37:51 -08004598
4599 // Now enable reduced size mode.
4600 send_parameters_.rtcp.reduced_size = true;
4601 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
4602 stream1 = fake_call_->GetVideoSendStreams()[0];
4603 EXPECT_EQ(webrtc::RtcpMode::kReducedSize, stream1->GetConfig().rtp.rtcp_mode);
Florent Castellidacec712018-05-24 16:24:21 +02004604 rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
4605 EXPECT_TRUE(rtp_parameters.rtcp.reduced_size);
deadbeef13871492015-12-09 12:37:51 -08004606
4607 // Create a new stream and ensure it picks up the reduced size mode.
4608 FakeVideoSendStream* stream2 = AddSendStream();
4609 EXPECT_EQ(webrtc::RtcpMode::kReducedSize, stream2->GetConfig().rtp.rtcp_mode);
4610}
4611
4612// This test verifies that the RTCP reduced size mode is properly applied to
4613// receive video streams.
eladalonf1841382017-06-12 01:16:46 -07004614TEST_F(WebRtcVideoChannelTest, TestSetRecvRtcpReducedSize) {
deadbeef13871492015-12-09 12:37:51 -08004615 // Create stream, expecting that default mode is "compound".
4616 FakeVideoReceiveStream* stream1 = AddRecvStream();
4617 EXPECT_EQ(webrtc::RtcpMode::kCompound, stream1->GetConfig().rtp.rtcp_mode);
4618
4619 // Now enable reduced size mode.
Taylor Brandstetter5f0b83b2016-03-18 15:02:07 -07004620 // TODO(deadbeef): Once "recv_parameters" becomes "receiver_parameters",
4621 // the reduced_size flag should come from that.
4622 send_parameters_.rtcp.reduced_size = true;
4623 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
deadbeef13871492015-12-09 12:37:51 -08004624 stream1 = fake_call_->GetVideoReceiveStreams()[0];
4625 EXPECT_EQ(webrtc::RtcpMode::kReducedSize, stream1->GetConfig().rtp.rtcp_mode);
4626
4627 // Create a new stream and ensure it picks up the reduced size mode.
4628 FakeVideoReceiveStream* stream2 = AddRecvStream();
4629 EXPECT_EQ(webrtc::RtcpMode::kReducedSize, stream2->GetConfig().rtp.rtcp_mode);
4630}
4631
eladalonf1841382017-06-12 01:16:46 -07004632TEST_F(WebRtcVideoChannelTest, OnReadyToSendSignalsNetworkState) {
skvlad7a43d252016-03-22 15:32:27 -07004633 EXPECT_EQ(webrtc::kNetworkUp,
4634 fake_call_->GetNetworkState(webrtc::MediaType::VIDEO));
4635 EXPECT_EQ(webrtc::kNetworkUp,
4636 fake_call_->GetNetworkState(webrtc::MediaType::AUDIO));
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00004637
4638 channel_->OnReadyToSend(false);
skvlad7a43d252016-03-22 15:32:27 -07004639 EXPECT_EQ(webrtc::kNetworkDown,
4640 fake_call_->GetNetworkState(webrtc::MediaType::VIDEO));
4641 EXPECT_EQ(webrtc::kNetworkUp,
4642 fake_call_->GetNetworkState(webrtc::MediaType::AUDIO));
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00004643
4644 channel_->OnReadyToSend(true);
skvlad7a43d252016-03-22 15:32:27 -07004645 EXPECT_EQ(webrtc::kNetworkUp,
4646 fake_call_->GetNetworkState(webrtc::MediaType::VIDEO));
4647 EXPECT_EQ(webrtc::kNetworkUp,
4648 fake_call_->GetNetworkState(webrtc::MediaType::AUDIO));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004649}
4650
eladalonf1841382017-06-12 01:16:46 -07004651TEST_F(WebRtcVideoChannelTest, GetStatsReportsSentCodecName) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004652 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004653 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004654 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Peter Boström74d9ed72015-03-26 16:28:31 +01004655
4656 AddSendStream();
4657
4658 cricket::VideoMediaInfo info;
4659 ASSERT_TRUE(channel_->GetStats(&info));
magjed509e4fe2016-11-18 01:34:11 -08004660 EXPECT_EQ("VP8", info.senders[0].codec_name);
Peter Boström74d9ed72015-03-26 16:28:31 +01004661}
4662
eladalonf1841382017-06-12 01:16:46 -07004663TEST_F(WebRtcVideoChannelTest, GetStatsReportsEncoderImplementationName) {
Peter Boströmb7d9a972015-12-18 16:01:11 +01004664 FakeVideoSendStream* stream = AddSendStream();
4665 webrtc::VideoSendStream::Stats stats;
4666 stats.encoder_implementation_name = "encoder_implementation_name";
4667 stream->SetStats(stats);
4668
4669 cricket::VideoMediaInfo info;
4670 ASSERT_TRUE(channel_->GetStats(&info));
4671 EXPECT_EQ(stats.encoder_implementation_name,
4672 info.senders[0].encoder_implementation_name);
4673}
4674
eladalonf1841382017-06-12 01:16:46 -07004675TEST_F(WebRtcVideoChannelTest, GetStatsReportsCpuOveruseMetrics) {
pbos@webrtc.org3e6e2712015-02-26 12:19:31 +00004676 FakeVideoSendStream* stream = AddSendStream();
4677 webrtc::VideoSendStream::Stats stats;
4678 stats.avg_encode_time_ms = 13;
4679 stats.encode_usage_percent = 42;
4680 stream->SetStats(stats);
4681
4682 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00004683 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org3e6e2712015-02-26 12:19:31 +00004684 EXPECT_EQ(stats.avg_encode_time_ms, info.senders[0].avg_encode_ms);
4685 EXPECT_EQ(stats.encode_usage_percent, info.senders[0].encode_usage_percent);
4686}
4687
eladalonf1841382017-06-12 01:16:46 -07004688TEST_F(WebRtcVideoChannelTest, GetStatsReportsFramesEncoded) {
sakal43536c32016-10-24 01:46:43 -07004689 FakeVideoSendStream* stream = AddSendStream();
4690 webrtc::VideoSendStream::Stats stats;
4691 stats.frames_encoded = 13;
4692 stream->SetStats(stats);
4693
4694 cricket::VideoMediaInfo info;
4695 ASSERT_TRUE(channel_->GetStats(&info));
4696 EXPECT_EQ(stats.frames_encoded, info.senders[0].frames_encoded);
4697}
4698
eladalonf1841382017-06-12 01:16:46 -07004699TEST_F(WebRtcVideoChannelTest, GetStatsReportsQpSum) {
sakal87da4042016-10-31 06:53:47 -07004700 FakeVideoSendStream* stream = AddSendStream();
4701 webrtc::VideoSendStream::Stats stats;
Oskar Sundbom78807582017-11-16 11:09:55 +01004702 stats.qp_sum = 13;
sakal87da4042016-10-31 06:53:47 -07004703 stream->SetStats(stats);
4704
4705 cricket::VideoMediaInfo info;
4706 ASSERT_TRUE(channel_->GetStats(&info));
4707 EXPECT_EQ(stats.qp_sum, info.senders[0].qp_sum);
4708}
4709
eladalonf1841382017-06-12 01:16:46 -07004710TEST_F(WebRtcVideoChannelTest, GetStatsReportsUpperResolution) {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00004711 FakeVideoSendStream* stream = AddSendStream();
4712 webrtc::VideoSendStream::Stats stats;
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00004713 stats.substreams[17].width = 123;
4714 stats.substreams[17].height = 40;
4715 stats.substreams[42].width = 80;
4716 stats.substreams[42].height = 31;
4717 stats.substreams[11].width = 20;
4718 stats.substreams[11].height = 90;
pbos@webrtc.org273a4142014-12-01 15:23:21 +00004719 stream->SetStats(stats);
4720
4721 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00004722 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org273a4142014-12-01 15:23:21 +00004723 ASSERT_EQ(1u, info.senders.size());
4724 EXPECT_EQ(123, info.senders[0].send_frame_width);
4725 EXPECT_EQ(90, info.senders[0].send_frame_height);
4726}
4727
eladalonf1841382017-06-12 01:16:46 -07004728TEST_F(WebRtcVideoChannelTest, GetStatsReportsCpuAdaptationStats) {
perkj803d97f2016-11-01 11:45:46 -07004729 FakeVideoSendStream* stream = AddSendStream();
4730 webrtc::VideoSendStream::Stats stats;
4731 stats.number_of_cpu_adapt_changes = 2;
4732 stats.cpu_limited_resolution = true;
4733 stream->SetStats(stats);
pbos@webrtc.org9a4410e2015-02-26 10:03:39 +00004734
pbos@webrtc.org9a4410e2015-02-26 10:03:39 +00004735 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00004736 EXPECT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org9a4410e2015-02-26 10:03:39 +00004737 ASSERT_EQ(1U, info.senders.size());
eladalonf1841382017-06-12 01:16:46 -07004738 EXPECT_EQ(WebRtcVideoChannel::ADAPTREASON_CPU, info.senders[0].adapt_reason);
perkj803d97f2016-11-01 11:45:46 -07004739 EXPECT_EQ(stats.number_of_cpu_adapt_changes, info.senders[0].adapt_changes);
pbos@webrtc.org9a4410e2015-02-26 10:03:39 +00004740}
4741
eladalonf1841382017-06-12 01:16:46 -07004742TEST_F(WebRtcVideoChannelTest, GetStatsReportsAdaptationAndBandwidthStats) {
perkj803d97f2016-11-01 11:45:46 -07004743 FakeVideoSendStream* stream = AddSendStream();
asapersson17821db2015-12-14 02:08:12 -08004744 webrtc::VideoSendStream::Stats stats;
perkj803d97f2016-11-01 11:45:46 -07004745 stats.number_of_cpu_adapt_changes = 2;
4746 stats.cpu_limited_resolution = true;
asapersson17821db2015-12-14 02:08:12 -08004747 stats.bw_limited_resolution = true;
perkj803d97f2016-11-01 11:45:46 -07004748 stream->SetStats(stats);
4749
4750 cricket::VideoMediaInfo info;
asapersson17821db2015-12-14 02:08:12 -08004751 EXPECT_TRUE(channel_->GetStats(&info));
4752 ASSERT_EQ(1U, info.senders.size());
eladalonf1841382017-06-12 01:16:46 -07004753 EXPECT_EQ(WebRtcVideoChannel::ADAPTREASON_CPU |
4754 WebRtcVideoChannel::ADAPTREASON_BANDWIDTH,
asapersson17821db2015-12-14 02:08:12 -08004755 info.senders[0].adapt_reason);
perkj803d97f2016-11-01 11:45:46 -07004756 EXPECT_EQ(stats.number_of_cpu_adapt_changes, info.senders[0].adapt_changes);
asapersson17821db2015-12-14 02:08:12 -08004757}
4758
eladalonf1841382017-06-12 01:16:46 -07004759TEST_F(WebRtcVideoChannelTest,
asapersson17821db2015-12-14 02:08:12 -08004760 GetStatsTranslatesBandwidthLimitedResolutionCorrectly) {
4761 FakeVideoSendStream* stream = AddSendStream();
4762 webrtc::VideoSendStream::Stats stats;
4763 stats.bw_limited_resolution = true;
4764 stream->SetStats(stats);
4765
4766 cricket::VideoMediaInfo info;
4767 EXPECT_TRUE(channel_->GetStats(&info));
4768 ASSERT_EQ(1U, info.senders.size());
eladalonf1841382017-06-12 01:16:46 -07004769 EXPECT_EQ(WebRtcVideoChannel::ADAPTREASON_BANDWIDTH,
asapersson17821db2015-12-14 02:08:12 -08004770 info.senders[0].adapt_reason);
4771}
4772
Yves Gerey665174f2018-06-19 15:03:05 +02004773TEST_F(WebRtcVideoChannelTest, GetStatsTranslatesSendRtcpPacketTypesCorrectly) {
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00004774 FakeVideoSendStream* stream = AddSendStream();
4775 webrtc::VideoSendStream::Stats stats;
4776 stats.substreams[17].rtcp_packet_type_counts.fir_packets = 2;
4777 stats.substreams[17].rtcp_packet_type_counts.nack_packets = 3;
4778 stats.substreams[17].rtcp_packet_type_counts.pli_packets = 4;
4779
4780 stats.substreams[42].rtcp_packet_type_counts.fir_packets = 5;
4781 stats.substreams[42].rtcp_packet_type_counts.nack_packets = 7;
4782 stats.substreams[42].rtcp_packet_type_counts.pli_packets = 9;
4783
4784 stream->SetStats(stats);
4785
4786 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00004787 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00004788 EXPECT_EQ(7, info.senders[0].firs_rcvd);
4789 EXPECT_EQ(10, info.senders[0].nacks_rcvd);
4790 EXPECT_EQ(13, info.senders[0].plis_rcvd);
4791}
4792
eladalonf1841382017-06-12 01:16:46 -07004793TEST_F(WebRtcVideoChannelTest,
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00004794 GetStatsTranslatesReceiveRtcpPacketTypesCorrectly) {
4795 FakeVideoReceiveStream* stream = AddRecvStream();
4796 webrtc::VideoReceiveStream::Stats stats;
4797 stats.rtcp_packet_type_counts.fir_packets = 2;
4798 stats.rtcp_packet_type_counts.nack_packets = 3;
4799 stats.rtcp_packet_type_counts.pli_packets = 4;
4800 stream->SetStats(stats);
4801
4802 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00004803 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00004804 EXPECT_EQ(stats.rtcp_packet_type_counts.fir_packets,
Mirko Bonadeif859e552018-05-30 15:31:29 +02004805 rtc::checked_cast<unsigned int>(info.receivers[0].firs_sent));
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00004806 EXPECT_EQ(stats.rtcp_packet_type_counts.nack_packets,
Mirko Bonadeif859e552018-05-30 15:31:29 +02004807 rtc::checked_cast<unsigned int>(info.receivers[0].nacks_sent));
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00004808 EXPECT_EQ(stats.rtcp_packet_type_counts.pli_packets,
Mirko Bonadeif859e552018-05-30 15:31:29 +02004809 rtc::checked_cast<unsigned int>(info.receivers[0].plis_sent));
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00004810}
4811
eladalonf1841382017-06-12 01:16:46 -07004812TEST_F(WebRtcVideoChannelTest, GetStatsTranslatesDecodeStatsCorrectly) {
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00004813 FakeVideoReceiveStream* stream = AddRecvStream();
4814 webrtc::VideoReceiveStream::Stats stats;
Peter Boströmb7d9a972015-12-18 16:01:11 +01004815 stats.decoder_implementation_name = "decoder_implementation_name";
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00004816 stats.decode_ms = 2;
4817 stats.max_decode_ms = 3;
4818 stats.current_delay_ms = 4;
4819 stats.target_delay_ms = 5;
4820 stats.jitter_buffer_ms = 6;
4821 stats.min_playout_delay_ms = 7;
4822 stats.render_delay_ms = 8;
asapersson26dd92b2016-08-30 00:45:45 -07004823 stats.width = 9;
4824 stats.height = 10;
hbos42f6d2f2017-01-20 03:56:50 -08004825 stats.frame_counts.key_frames = 11;
4826 stats.frame_counts.delta_frames = 12;
hbos50cfe1f2017-01-23 07:21:55 -08004827 stats.frames_rendered = 13;
4828 stats.frames_decoded = 14;
Oskar Sundbom78807582017-11-16 11:09:55 +01004829 stats.qp_sum = 15;
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00004830 stream->SetStats(stats);
4831
4832 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00004833 ASSERT_TRUE(channel_->GetStats(&info));
Peter Boströmb7d9a972015-12-18 16:01:11 +01004834 EXPECT_EQ(stats.decoder_implementation_name,
4835 info.receivers[0].decoder_implementation_name);
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00004836 EXPECT_EQ(stats.decode_ms, info.receivers[0].decode_ms);
4837 EXPECT_EQ(stats.max_decode_ms, info.receivers[0].max_decode_ms);
4838 EXPECT_EQ(stats.current_delay_ms, info.receivers[0].current_delay_ms);
4839 EXPECT_EQ(stats.target_delay_ms, info.receivers[0].target_delay_ms);
4840 EXPECT_EQ(stats.jitter_buffer_ms, info.receivers[0].jitter_buffer_ms);
4841 EXPECT_EQ(stats.min_playout_delay_ms, info.receivers[0].min_playout_delay_ms);
4842 EXPECT_EQ(stats.render_delay_ms, info.receivers[0].render_delay_ms);
asapersson26dd92b2016-08-30 00:45:45 -07004843 EXPECT_EQ(stats.width, info.receivers[0].frame_width);
4844 EXPECT_EQ(stats.height, info.receivers[0].frame_height);
Mirko Bonadeif859e552018-05-30 15:31:29 +02004845 EXPECT_EQ(rtc::checked_cast<unsigned int>(stats.frame_counts.key_frames +
4846 stats.frame_counts.delta_frames),
hbos42f6d2f2017-01-20 03:56:50 -08004847 info.receivers[0].frames_received);
hbos50cfe1f2017-01-23 07:21:55 -08004848 EXPECT_EQ(stats.frames_rendered, info.receivers[0].frames_rendered);
sakale5ba44e2016-10-26 07:09:24 -07004849 EXPECT_EQ(stats.frames_decoded, info.receivers[0].frames_decoded);
sakalcc452e12017-02-09 04:53:45 -08004850 EXPECT_EQ(stats.qp_sum, info.receivers[0].qp_sum);
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00004851}
4852
eladalonf1841382017-06-12 01:16:46 -07004853TEST_F(WebRtcVideoChannelTest, GetStatsTranslatesReceivePacketStatsCorrectly) {
Peter Boström393347f2015-04-22 14:52:45 +02004854 FakeVideoReceiveStream* stream = AddRecvStream();
4855 webrtc::VideoReceiveStream::Stats stats;
4856 stats.rtp_stats.transmitted.payload_bytes = 2;
4857 stats.rtp_stats.transmitted.header_bytes = 3;
4858 stats.rtp_stats.transmitted.padding_bytes = 4;
4859 stats.rtp_stats.transmitted.packets = 5;
srte186d9c32017-08-04 05:03:53 -07004860 stats.rtcp_stats.packets_lost = 6;
Peter Boström393347f2015-04-22 14:52:45 +02004861 stats.rtcp_stats.fraction_lost = 7;
4862 stream->SetStats(stats);
4863
4864 cricket::VideoMediaInfo info;
4865 ASSERT_TRUE(channel_->GetStats(&info));
4866 EXPECT_EQ(stats.rtp_stats.transmitted.payload_bytes +
4867 stats.rtp_stats.transmitted.header_bytes +
4868 stats.rtp_stats.transmitted.padding_bytes,
Mirko Bonadeif859e552018-05-30 15:31:29 +02004869 rtc::checked_cast<size_t>(info.receivers[0].bytes_rcvd));
Peter Boström393347f2015-04-22 14:52:45 +02004870 EXPECT_EQ(stats.rtp_stats.transmitted.packets,
Mirko Bonadeif859e552018-05-30 15:31:29 +02004871 rtc::checked_cast<unsigned int>(info.receivers[0].packets_rcvd));
srte186d9c32017-08-04 05:03:53 -07004872 EXPECT_EQ(stats.rtcp_stats.packets_lost, info.receivers[0].packets_lost);
Mirko Bonadeif859e552018-05-30 15:31:29 +02004873 EXPECT_EQ(rtc::checked_cast<float>(stats.rtcp_stats.fraction_lost) / (1 << 8),
Peter Boström393347f2015-04-22 14:52:45 +02004874 info.receivers[0].fraction_lost);
4875}
4876
eladalonf1841382017-06-12 01:16:46 -07004877TEST_F(WebRtcVideoChannelTest, TranslatesCallStatsCorrectly) {
pbos@webrtc.org2b19f062014-12-11 13:26:09 +00004878 AddSendStream();
4879 AddSendStream();
4880 webrtc::Call::Stats stats;
4881 stats.rtt_ms = 123;
4882 fake_call_->SetStats(stats);
4883
4884 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00004885 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org2b19f062014-12-11 13:26:09 +00004886 ASSERT_EQ(2u, info.senders.size());
4887 EXPECT_EQ(stats.rtt_ms, info.senders[0].rtt_ms);
4888 EXPECT_EQ(stats.rtt_ms, info.senders[1].rtt_ms);
4889}
4890
eladalonf1841382017-06-12 01:16:46 -07004891TEST_F(WebRtcVideoChannelTest, TranslatesSenderBitrateStatsCorrectly) {
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00004892 FakeVideoSendStream* stream = AddSendStream();
4893 webrtc::VideoSendStream::Stats stats;
pbos@webrtc.org891d4832015-02-26 13:15:22 +00004894 stats.target_media_bitrate_bps = 156;
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00004895 stats.media_bitrate_bps = 123;
4896 stats.substreams[17].total_bitrate_bps = 1;
4897 stats.substreams[17].retransmit_bitrate_bps = 2;
4898 stats.substreams[42].total_bitrate_bps = 3;
4899 stats.substreams[42].retransmit_bitrate_bps = 4;
4900 stream->SetStats(stats);
4901
4902 FakeVideoSendStream* stream2 = AddSendStream();
4903 webrtc::VideoSendStream::Stats stats2;
pbos@webrtc.org891d4832015-02-26 13:15:22 +00004904 stats2.target_media_bitrate_bps = 200;
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00004905 stats2.media_bitrate_bps = 321;
4906 stats2.substreams[13].total_bitrate_bps = 5;
4907 stats2.substreams[13].retransmit_bitrate_bps = 6;
4908 stats2.substreams[21].total_bitrate_bps = 7;
4909 stats2.substreams[21].retransmit_bitrate_bps = 8;
4910 stream2->SetStats(stats2);
4911
4912 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00004913 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00004914 ASSERT_EQ(2u, info.senders.size());
stefanf79ade12017-06-02 06:44:03 -07004915 BandwidthEstimationInfo bwe_info;
4916 channel_->FillBitrateInfo(&bwe_info);
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00004917 // Assuming stream and stream2 corresponds to senders[0] and [1] respectively
4918 // is OK as std::maps are sorted and AddSendStream() gives increasing SSRCs.
4919 EXPECT_EQ(stats.media_bitrate_bps, info.senders[0].nominal_bitrate);
4920 EXPECT_EQ(stats2.media_bitrate_bps, info.senders[1].nominal_bitrate);
pbos@webrtc.org891d4832015-02-26 13:15:22 +00004921 EXPECT_EQ(stats.target_media_bitrate_bps + stats2.target_media_bitrate_bps,
stefanf79ade12017-06-02 06:44:03 -07004922 bwe_info.target_enc_bitrate);
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00004923 EXPECT_EQ(stats.media_bitrate_bps + stats2.media_bitrate_bps,
stefanf79ade12017-06-02 06:44:03 -07004924 bwe_info.actual_enc_bitrate);
4925 EXPECT_EQ(1 + 3 + 5 + 7, bwe_info.transmit_bitrate)
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00004926 << "Bandwidth stats should take all streams into account.";
stefanf79ade12017-06-02 06:44:03 -07004927 EXPECT_EQ(2 + 4 + 6 + 8, bwe_info.retransmit_bitrate)
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00004928 << "Bandwidth stats should take all streams into account.";
4929}
4930
eladalonf1841382017-06-12 01:16:46 -07004931TEST_F(WebRtcVideoChannelTest, DefaultReceiveStreamReconfiguresToUseRtx) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004932 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orga2a6fe62015-03-06 15:35:19 +00004933
Peter Boström0c4e06b2015-10-07 12:23:21 +02004934 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
4935 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
pbos@webrtc.orga2a6fe62015-03-06 15:35:19 +00004936
4937 ASSERT_EQ(0u, fake_call_->GetVideoReceiveStreams().size());
4938 const size_t kDataLength = 12;
4939 uint8_t data[kDataLength];
4940 memset(data, 0, sizeof(data));
4941 rtc::SetBE32(&data[8], ssrcs[0]);
jbaucheec21bd2016-03-20 06:15:43 -07004942 rtc::CopyOnWriteBuffer packet(data, kDataLength);
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07004943 channel_->OnPacketReceived(packet, /* packet_time_us */ -1);
pbos@webrtc.orga2a6fe62015-03-06 15:35:19 +00004944
4945 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size())
4946 << "No default receive stream created.";
4947 FakeVideoReceiveStream* recv_stream = fake_call_->GetVideoReceiveStreams()[0];
brandtr14742122017-01-27 04:53:07 -08004948 EXPECT_EQ(0u, recv_stream->GetConfig().rtp.rtx_ssrc)
pbos@webrtc.orga2a6fe62015-03-06 15:35:19 +00004949 << "Default receive stream should not have configured RTX";
4950
4951 EXPECT_TRUE(channel_->AddRecvStream(
4952 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs)));
4953 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size())
brandtr14742122017-01-27 04:53:07 -08004954 << "AddRecvStream should have reconfigured, not added a new receiver.";
pbos@webrtc.orga2a6fe62015-03-06 15:35:19 +00004955 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
nisse26e3abb2017-08-25 04:44:25 -07004956 EXPECT_FALSE(
4957 recv_stream->GetConfig().rtp.rtx_associated_payload_types.empty());
nisseca5706d2017-09-11 02:32:16 -07004958 EXPECT_TRUE(VerifyRtxReceiveAssociations(recv_stream->GetConfig()))
Peter Boströmd8b01092016-05-12 16:44:36 +02004959 << "RTX should be mapped for all decoders/payload types.";
nisseca5706d2017-09-11 02:32:16 -07004960 EXPECT_TRUE(HasRtxReceiveAssociation(recv_stream->GetConfig(),
Yves Gerey665174f2018-06-19 15:03:05 +02004961 GetEngineCodec("red").id))
nisseca5706d2017-09-11 02:32:16 -07004962 << "RTX should be mapped also for the RED payload type";
brandtr14742122017-01-27 04:53:07 -08004963 EXPECT_EQ(rtx_ssrcs[0], recv_stream->GetConfig().rtp.rtx_ssrc);
pbos@webrtc.orga2a6fe62015-03-06 15:35:19 +00004964}
4965
eladalonf1841382017-06-12 01:16:46 -07004966TEST_F(WebRtcVideoChannelTest, RejectsAddingStreamsWithMissingSsrcsForRtx) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004967 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Peter Boströmd4362cd2015-03-25 14:17:23 +01004968
Peter Boström0c4e06b2015-10-07 12:23:21 +02004969 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
4970 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
Peter Boströmd4362cd2015-03-25 14:17:23 +01004971
4972 StreamParams sp =
4973 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs);
4974 sp.ssrcs = ssrcs; // Without RTXs, this is the important part.
4975
4976 EXPECT_FALSE(channel_->AddSendStream(sp));
4977 EXPECT_FALSE(channel_->AddRecvStream(sp));
4978}
4979
eladalonf1841382017-06-12 01:16:46 -07004980TEST_F(WebRtcVideoChannelTest, RejectsAddingStreamsWithOverlappingRtxSsrcs) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004981 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Peter Boströmd6f4c252015-03-26 16:23:04 +01004982
Peter Boström0c4e06b2015-10-07 12:23:21 +02004983 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
4984 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
Peter Boströmd6f4c252015-03-26 16:23:04 +01004985
4986 StreamParams sp =
4987 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs);
4988
4989 EXPECT_TRUE(channel_->AddSendStream(sp));
4990 EXPECT_TRUE(channel_->AddRecvStream(sp));
4991
4992 // The RTX SSRC is already used in previous streams, using it should fail.
4993 sp = cricket::StreamParams::CreateLegacy(rtx_ssrcs[0]);
4994 EXPECT_FALSE(channel_->AddSendStream(sp));
4995 EXPECT_FALSE(channel_->AddRecvStream(sp));
4996
4997 // After removing the original stream this should be fine to add (makes sure
4998 // that RTX ssrcs are not forever taken).
4999 EXPECT_TRUE(channel_->RemoveSendStream(ssrcs[0]));
5000 EXPECT_TRUE(channel_->RemoveRecvStream(ssrcs[0]));
5001 EXPECT_TRUE(channel_->AddSendStream(sp));
5002 EXPECT_TRUE(channel_->AddRecvStream(sp));
5003}
5004
eladalonf1841382017-06-12 01:16:46 -07005005TEST_F(WebRtcVideoChannelTest,
Peter Boströmd6f4c252015-03-26 16:23:04 +01005006 RejectsAddingStreamsWithOverlappingSimulcastSsrcs) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02005007 static const uint32_t kFirstStreamSsrcs[] = {1, 2, 3};
5008 static const uint32_t kOverlappingStreamSsrcs[] = {4, 3, 5};
Fredrik Solenbergb071a192015-09-17 16:42:56 +02005009 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Peter Boströmd6f4c252015-03-26 16:23:04 +01005010
Peter Boströmd6f4c252015-03-26 16:23:04 +01005011 StreamParams sp =
5012 cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kFirstStreamSsrcs));
5013
5014 EXPECT_TRUE(channel_->AddSendStream(sp));
5015 EXPECT_TRUE(channel_->AddRecvStream(sp));
5016
5017 // One of the SSRCs is already used in previous streams, using it should fail.
5018 sp = cricket::CreateSimStreamParams("cname",
5019 MAKE_VECTOR(kOverlappingStreamSsrcs));
5020 EXPECT_FALSE(channel_->AddSendStream(sp));
5021 EXPECT_FALSE(channel_->AddRecvStream(sp));
5022
5023 // After removing the original stream this should be fine to add (makes sure
5024 // that RTX ssrcs are not forever taken).
Peter Boström3548dd22015-05-22 18:48:36 +02005025 EXPECT_TRUE(channel_->RemoveSendStream(kFirstStreamSsrcs[0]));
5026 EXPECT_TRUE(channel_->RemoveRecvStream(kFirstStreamSsrcs[0]));
Peter Boströmd6f4c252015-03-26 16:23:04 +01005027 EXPECT_TRUE(channel_->AddSendStream(sp));
5028 EXPECT_TRUE(channel_->AddRecvStream(sp));
5029}
5030
eladalonf1841382017-06-12 01:16:46 -07005031TEST_F(WebRtcVideoChannelTest, ReportsSsrcGroupsInStats) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02005032 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Peter Boström259bd202015-05-28 13:39:50 +02005033
5034 static const uint32_t kSenderSsrcs[] = {4, 7, 10};
5035 static const uint32_t kSenderRtxSsrcs[] = {5, 8, 11};
5036
5037 StreamParams sender_sp = cricket::CreateSimWithRtxStreamParams(
5038 "cname", MAKE_VECTOR(kSenderSsrcs), MAKE_VECTOR(kSenderRtxSsrcs));
5039
5040 EXPECT_TRUE(channel_->AddSendStream(sender_sp));
5041
5042 static const uint32_t kReceiverSsrcs[] = {3};
5043 static const uint32_t kReceiverRtxSsrcs[] = {2};
5044
5045 StreamParams receiver_sp = cricket::CreateSimWithRtxStreamParams(
5046 "cname", MAKE_VECTOR(kReceiverSsrcs), MAKE_VECTOR(kReceiverRtxSsrcs));
5047 EXPECT_TRUE(channel_->AddRecvStream(receiver_sp));
5048
5049 cricket::VideoMediaInfo info;
5050 ASSERT_TRUE(channel_->GetStats(&info));
5051
5052 ASSERT_EQ(1u, info.senders.size());
5053 ASSERT_EQ(1u, info.receivers.size());
5054
5055 EXPECT_NE(sender_sp.ssrc_groups, receiver_sp.ssrc_groups);
5056 EXPECT_EQ(sender_sp.ssrc_groups, info.senders[0].ssrc_groups);
5057 EXPECT_EQ(receiver_sp.ssrc_groups, info.receivers[0].ssrc_groups);
5058}
5059
eladalonf1841382017-06-12 01:16:46 -07005060TEST_F(WebRtcVideoChannelTest, MapsReceivedPayloadTypeToCodecName) {
pbosf42376c2015-08-28 07:35:32 -07005061 FakeVideoReceiveStream* stream = AddRecvStream();
5062 webrtc::VideoReceiveStream::Stats stats;
5063 cricket::VideoMediaInfo info;
5064
5065 // Report no codec name before receiving.
5066 stream->SetStats(stats);
5067 ASSERT_TRUE(channel_->GetStats(&info));
5068 EXPECT_STREQ("", info.receivers[0].codec_name.c_str());
5069
5070 // Report VP8 if we're receiving it.
magjed509e4fe2016-11-18 01:34:11 -08005071 stats.current_payload_type = GetEngineCodec("VP8").id;
pbosf42376c2015-08-28 07:35:32 -07005072 stream->SetStats(stats);
5073 ASSERT_TRUE(channel_->GetStats(&info));
5074 EXPECT_STREQ(kVp8CodecName, info.receivers[0].codec_name.c_str());
5075
5076 // Report no codec name for unknown playload types.
5077 stats.current_payload_type = 3;
5078 stream->SetStats(stats);
5079 ASSERT_TRUE(channel_->GetStats(&info));
5080 EXPECT_STREQ("", info.receivers[0].codec_name.c_str());
5081}
5082
Seth Hampson5897a6e2018-04-03 11:16:33 -07005083// Tests that when we add a stream without SSRCs, but contains a stream_id
5084// that it is stored and its stream id is later used when the first packet
5085// arrives to properly create a receive stream with a sync label.
5086TEST_F(WebRtcVideoChannelTest, RecvUnsignaledSsrcWithSignaledStreamId) {
5087 const char kSyncLabel[] = "sync_label";
5088 cricket::StreamParams unsignaled_stream;
5089 unsignaled_stream.set_stream_ids({kSyncLabel});
5090 ASSERT_TRUE(channel_->AddRecvStream(unsignaled_stream));
5091 // The stream shouldn't have been created at this point because it doesn't
5092 // have any SSRCs.
Mirko Bonadeif859e552018-05-30 15:31:29 +02005093 EXPECT_EQ(0u, fake_call_->GetVideoReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07005094
5095 // Create and deliver packet.
5096 const size_t kDataLength = 12;
5097 uint8_t data[kDataLength];
5098 memset(data, 0, sizeof(data));
5099 rtc::SetBE32(&data[8], kIncomingUnsignalledSsrc);
5100 rtc::CopyOnWriteBuffer packet(data, kDataLength);
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07005101 channel_->OnPacketReceived(packet, /* packet_time_us */ -1);
Seth Hampson5897a6e2018-04-03 11:16:33 -07005102
5103 // The stream should now be created with the appropriate sync label.
5104 EXPECT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
5105 EXPECT_EQ(kSyncLabel,
5106 fake_call_->GetVideoReceiveStreams()[0]->GetConfig().sync_group);
5107
5108 // Removing the unsignaled stream should clear the cache. This time when
5109 // a default video receive stream is created it won't have a sync_group.
5110 ASSERT_TRUE(channel_->RemoveRecvStream(0));
5111 ASSERT_TRUE(channel_->RemoveRecvStream(kIncomingUnsignalledSsrc));
5112 EXPECT_EQ(0u, fake_call_->GetVideoReceiveStreams().size());
5113
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07005114 channel_->OnPacketReceived(packet, /* packet_time_us */ -1);
Seth Hampson5897a6e2018-04-03 11:16:33 -07005115 EXPECT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
5116 EXPECT_TRUE(
5117 fake_call_->GetVideoReceiveStreams()[0]->GetConfig().sync_group.empty());
5118}
5119
Ruslan Burakov493a6502019-02-27 15:32:48 +01005120// Test BaseMinimumPlayoutDelayMs on receive streams.
5121TEST_F(WebRtcVideoChannelTest, BaseMinimumPlayoutDelayMs) {
5122 // Test that set won't work for non-existing receive streams.
5123 EXPECT_FALSE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrc + 2, 200));
5124 // Test that get won't work for non-existing receive streams.
5125 EXPECT_FALSE(channel_->GetBaseMinimumPlayoutDelayMs(kSsrc + 2));
5126
5127 EXPECT_TRUE(AddRecvStream());
5128 // Test that set works for the existing receive stream.
5129 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(last_ssrc_, 200));
5130 auto* recv_stream = fake_call_->GetVideoReceiveStream(last_ssrc_);
5131 EXPECT_TRUE(recv_stream);
5132 EXPECT_EQ(recv_stream->base_mininum_playout_delay_ms(), 200);
5133 EXPECT_EQ(channel_->GetBaseMinimumPlayoutDelayMs(last_ssrc_).value_or(0),
5134 200);
5135}
5136
5137// Test BaseMinimumPlayoutDelayMs on unsignaled receive streams.
5138TEST_F(WebRtcVideoChannelTest, BaseMinimumPlayoutDelayMsUnsignaledRecvStream) {
5139 absl::optional<int> delay_ms;
5140 const FakeVideoReceiveStream* recv_stream;
5141
5142 // Set default stream with SSRC 0
5143 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(0, 200));
5144 EXPECT_EQ(200, channel_->GetBaseMinimumPlayoutDelayMs(0).value_or(0));
5145
5146 // Spawn an unsignaled stream by sending a packet, it should inherit
5147 // default delay 200.
5148 const size_t kDataLength = 12;
5149 uint8_t data[kDataLength];
5150 memset(data, 0, sizeof(data));
5151 rtc::SetBE32(&data[8], kIncomingUnsignalledSsrc);
5152 rtc::CopyOnWriteBuffer packet(data, kDataLength);
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07005153 channel_->OnPacketReceived(packet, /* packet_time_us */ -1);
Ruslan Burakov493a6502019-02-27 15:32:48 +01005154
5155 recv_stream = fake_call_->GetVideoReceiveStream(kIncomingUnsignalledSsrc);
5156 EXPECT_EQ(recv_stream->base_mininum_playout_delay_ms(), 200);
5157 delay_ms = channel_->GetBaseMinimumPlayoutDelayMs(kIncomingUnsignalledSsrc);
5158 EXPECT_EQ(200, delay_ms.value_or(0));
5159
5160 // Check that now if we change delay for SSRC 0 it will change delay for the
5161 // default receiving stream as well.
5162 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(0, 300));
5163 EXPECT_EQ(300, channel_->GetBaseMinimumPlayoutDelayMs(0).value_or(0));
5164 delay_ms = channel_->GetBaseMinimumPlayoutDelayMs(kIncomingUnsignalledSsrc);
5165 EXPECT_EQ(300, delay_ms.value_or(0));
5166 recv_stream = fake_call_->GetVideoReceiveStream(kIncomingUnsignalledSsrc);
5167 EXPECT_EQ(recv_stream->base_mininum_playout_delay_ms(), 300);
5168}
5169
eladalonf1841382017-06-12 01:16:46 -07005170void WebRtcVideoChannelTest::TestReceiveUnsignaledSsrcPacket(
noahricd10a68e2015-07-10 11:27:55 -07005171 uint8_t payload_type,
5172 bool expect_created_receive_stream) {
magjed509e4fe2016-11-18 01:34:11 -08005173 // kRedRtxPayloadType must currently be unused.
5174 EXPECT_FALSE(FindCodecById(engine_.codecs(), kRedRtxPayloadType));
5175
noahricd10a68e2015-07-10 11:27:55 -07005176 // Add a RED RTX codec.
5177 VideoCodec red_rtx_codec =
magjed509e4fe2016-11-18 01:34:11 -08005178 VideoCodec::CreateRtxCodec(kRedRtxPayloadType, GetEngineCodec("red").id);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02005179 recv_parameters_.codecs.push_back(red_rtx_codec);
5180 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
noahricd10a68e2015-07-10 11:27:55 -07005181
5182 ASSERT_EQ(0u, fake_call_->GetVideoReceiveStreams().size());
5183 const size_t kDataLength = 12;
5184 uint8_t data[kDataLength];
5185 memset(data, 0, sizeof(data));
5186
5187 rtc::Set8(data, 1, payload_type);
5188 rtc::SetBE32(&data[8], kIncomingUnsignalledSsrc);
jbaucheec21bd2016-03-20 06:15:43 -07005189 rtc::CopyOnWriteBuffer packet(data, kDataLength);
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07005190 channel_->OnPacketReceived(packet, /* packet_time_us */ -1);
noahricd10a68e2015-07-10 11:27:55 -07005191
5192 if (expect_created_receive_stream) {
5193 EXPECT_EQ(1u, fake_call_->GetVideoReceiveStreams().size())
5194 << "Should have created a receive stream for payload type: "
5195 << payload_type;
5196 } else {
5197 EXPECT_EQ(0u, fake_call_->GetVideoReceiveStreams().size())
5198 << "Shouldn't have created a receive stream for payload type: "
5199 << payload_type;
5200 }
5201}
5202
Åsa Persson2c7149b2018-10-15 09:36:10 +02005203class WebRtcVideoChannelDiscardUnknownSsrcTest : public WebRtcVideoChannelTest {
5204 public:
5205 WebRtcVideoChannelDiscardUnknownSsrcTest()
5206 : WebRtcVideoChannelTest(
5207 "WebRTC-Video-DiscardPacketsWithUnknownSsrc/Enabled/") {}
5208};
5209
5210TEST_F(WebRtcVideoChannelDiscardUnknownSsrcTest, NoUnsignalledStreamCreated) {
5211 TestReceiveUnsignaledSsrcPacket(GetEngineCodec("VP8").id,
5212 false /* expect_created_receive_stream */);
5213}
5214
eladalonf1841382017-06-12 01:16:46 -07005215TEST_F(WebRtcVideoChannelTest, Vp8PacketCreatesUnsignalledStream) {
magjed509e4fe2016-11-18 01:34:11 -08005216 TestReceiveUnsignaledSsrcPacket(GetEngineCodec("VP8").id,
5217 true /* expect_created_receive_stream */);
noahricd10a68e2015-07-10 11:27:55 -07005218}
5219
eladalonf1841382017-06-12 01:16:46 -07005220TEST_F(WebRtcVideoChannelTest, Vp9PacketCreatesUnsignalledStream) {
magjed509e4fe2016-11-18 01:34:11 -08005221 TestReceiveUnsignaledSsrcPacket(GetEngineCodec("VP9").id,
5222 true /* expect_created_receive_stream */);
noahricd10a68e2015-07-10 11:27:55 -07005223}
5224
eladalonf1841382017-06-12 01:16:46 -07005225TEST_F(WebRtcVideoChannelTest, RtxPacketDoesntCreateUnsignalledStream) {
Anders Carlsson5f2bb622018-05-14 09:48:06 +02005226 AssignDefaultAptRtxTypes();
magjed509e4fe2016-11-18 01:34:11 -08005227 const cricket::VideoCodec vp8 = GetEngineCodec("VP8");
5228 const int rtx_vp8_payload_type = default_apt_rtx_types_[vp8.id];
5229 TestReceiveUnsignaledSsrcPacket(rtx_vp8_payload_type,
5230 false /* expect_created_receive_stream */);
noahricd10a68e2015-07-10 11:27:55 -07005231}
5232
eladalonf1841382017-06-12 01:16:46 -07005233TEST_F(WebRtcVideoChannelTest, UlpfecPacketDoesntCreateUnsignalledStream) {
magjed509e4fe2016-11-18 01:34:11 -08005234 TestReceiveUnsignaledSsrcPacket(GetEngineCodec("ulpfec").id,
5235 false /* expect_created_receive_stream */);
noahricd10a68e2015-07-10 11:27:55 -07005236}
5237
eladalonf1841382017-06-12 01:16:46 -07005238TEST_F(WebRtcVideoChannelFlexfecRecvTest,
brandtr468da7c2016-11-22 02:16:47 -08005239 FlexfecPacketDoesntCreateUnsignalledStream) {
5240 TestReceiveUnsignaledSsrcPacket(GetEngineCodec("flexfec-03").id,
5241 false /* expect_created_receive_stream */);
5242}
5243
eladalonf1841382017-06-12 01:16:46 -07005244TEST_F(WebRtcVideoChannelTest, RedRtxPacketDoesntCreateUnsignalledStream) {
magjed509e4fe2016-11-18 01:34:11 -08005245 TestReceiveUnsignaledSsrcPacket(kRedRtxPayloadType,
5246 false /* expect_created_receive_stream */);
noahricd10a68e2015-07-10 11:27:55 -07005247}
5248
mzanaty8a855d62017-02-17 15:46:43 -08005249// Test that receiving any unsignalled SSRC works even if it changes.
5250// The first unsignalled SSRC received will create a default receive stream.
5251// Any different unsignalled SSRC received will replace the default.
eladalonf1841382017-06-12 01:16:46 -07005252TEST_F(WebRtcVideoChannelTest, ReceiveDifferentUnsignaledSsrc) {
mzanaty8a855d62017-02-17 15:46:43 -08005253 // Allow receiving VP8, VP9, H264 (if enabled).
5254 cricket::VideoRecvParameters parameters;
5255 parameters.codecs.push_back(GetEngineCodec("VP8"));
5256 parameters.codecs.push_back(GetEngineCodec("VP9"));
5257
5258#if defined(WEBRTC_USE_H264)
5259 cricket::VideoCodec H264codec(126, "H264");
5260 parameters.codecs.push_back(H264codec);
5261#endif
5262
5263 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
5264 // No receive streams yet.
5265 ASSERT_EQ(0u, fake_call_->GetVideoReceiveStreams().size());
5266 cricket::FakeVideoRenderer renderer;
5267 EXPECT_TRUE(channel_->SetSink(kDefaultRecvSsrc, &renderer));
5268
5269 // Receive VP8 packet on first SSRC.
5270 uint8_t data[kMinRtpPacketLen];
5271 cricket::RtpHeader rtpHeader;
5272 rtpHeader.payload_type = GetEngineCodec("VP8").id;
5273 rtpHeader.seq_num = rtpHeader.timestamp = 0;
Yves Gerey665174f2018-06-19 15:03:05 +02005274 rtpHeader.ssrc = kIncomingUnsignalledSsrc + 1;
mzanaty8a855d62017-02-17 15:46:43 -08005275 cricket::SetRtpHeader(data, sizeof(data), rtpHeader);
5276 rtc::CopyOnWriteBuffer packet(data, sizeof(data));
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07005277 channel_->OnPacketReceived(packet, /* packet_time_us */ -1);
mzanaty8a855d62017-02-17 15:46:43 -08005278 // VP8 packet should create default receive stream.
5279 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02005280 FakeVideoReceiveStream* recv_stream = fake_call_->GetVideoReceiveStreams()[0];
mzanaty8a855d62017-02-17 15:46:43 -08005281 EXPECT_EQ(rtpHeader.ssrc, recv_stream->GetConfig().rtp.remote_ssrc);
5282 // Verify that the receive stream sinks to a renderer.
Artem Titov1ebfb6a2019-01-03 23:49:37 +01005283 webrtc::VideoFrame video_frame =
5284 webrtc::VideoFrame::Builder()
5285 .set_video_frame_buffer(CreateBlackFrameBuffer(4, 4))
5286 .set_timestamp_rtp(100)
5287 .set_timestamp_us(0)
5288 .set_rotation(webrtc::kVideoRotation_0)
5289 .build();
mzanaty8a855d62017-02-17 15:46:43 -08005290 recv_stream->InjectFrame(video_frame);
5291 EXPECT_EQ(1, renderer.num_rendered_frames());
5292
5293 // Receive VP9 packet on second SSRC.
5294 rtpHeader.payload_type = GetEngineCodec("VP9").id;
Yves Gerey665174f2018-06-19 15:03:05 +02005295 rtpHeader.ssrc = kIncomingUnsignalledSsrc + 2;
mzanaty8a855d62017-02-17 15:46:43 -08005296 cricket::SetRtpHeader(data, sizeof(data), rtpHeader);
5297 rtc::CopyOnWriteBuffer packet2(data, sizeof(data));
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07005298 channel_->OnPacketReceived(packet2, /* packet_time_us */ -1);
mzanaty8a855d62017-02-17 15:46:43 -08005299 // VP9 packet should replace the default receive SSRC.
5300 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
5301 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
5302 EXPECT_EQ(rtpHeader.ssrc, recv_stream->GetConfig().rtp.remote_ssrc);
5303 // Verify that the receive stream sinks to a renderer.
Artem Titov1ebfb6a2019-01-03 23:49:37 +01005304 webrtc::VideoFrame video_frame2 =
5305 webrtc::VideoFrame::Builder()
5306 .set_video_frame_buffer(CreateBlackFrameBuffer(4, 4))
5307 .set_timestamp_rtp(200)
5308 .set_timestamp_us(0)
5309 .set_rotation(webrtc::kVideoRotation_0)
5310 .build();
mzanaty8a855d62017-02-17 15:46:43 -08005311 recv_stream->InjectFrame(video_frame2);
5312 EXPECT_EQ(2, renderer.num_rendered_frames());
5313
5314#if defined(WEBRTC_USE_H264)
5315 // Receive H264 packet on third SSRC.
5316 rtpHeader.payload_type = 126;
Yves Gerey665174f2018-06-19 15:03:05 +02005317 rtpHeader.ssrc = kIncomingUnsignalledSsrc + 3;
mzanaty8a855d62017-02-17 15:46:43 -08005318 cricket::SetRtpHeader(data, sizeof(data), rtpHeader);
5319 rtc::CopyOnWriteBuffer packet3(data, sizeof(data));
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07005320 channel_->OnPacketReceived(packet3, /* packet_time_us */ -1);
mzanaty8a855d62017-02-17 15:46:43 -08005321 // H264 packet should replace the default receive SSRC.
5322 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
5323 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
5324 EXPECT_EQ(rtpHeader.ssrc, recv_stream->GetConfig().rtp.remote_ssrc);
5325 // Verify that the receive stream sinks to a renderer.
Artem Titov1ebfb6a2019-01-03 23:49:37 +01005326 webrtc::VideoFrame video_frame3 =
5327 webrtc::VideoFrame::Builder()
5328 .set_video_frame_buffer(CreateBlackFrameBuffer(4, 4))
5329 .set_timestamp_rtp(300)
5330 .set_timestamp_us(0)
5331 .set_rotation(webrtc::kVideoRotation_0)
5332 .build();
mzanaty8a855d62017-02-17 15:46:43 -08005333 recv_stream->InjectFrame(video_frame3);
5334 EXPECT_EQ(3, renderer.num_rendered_frames());
5335#endif
5336}
5337
brandtr0dc57ea2017-05-29 23:33:31 -07005338// This test verifies that when a new default stream is created for a new
5339// unsignaled SSRC, the new stream does not overwrite any old stream that had
5340// been the default receive stream before being properly signaled.
eladalonf1841382017-06-12 01:16:46 -07005341TEST_F(WebRtcVideoChannelTest,
brandtr0dc57ea2017-05-29 23:33:31 -07005342 NewUnsignaledStreamDoesNotDestroyPreviouslyUnsignaledStream) {
5343 cricket::VideoRecvParameters parameters;
5344 parameters.codecs.push_back(GetEngineCodec("VP8"));
5345 ASSERT_TRUE(channel_->SetRecvParameters(parameters));
5346
5347 // No streams signaled and no packets received, so we should not have any
5348 // stream objects created yet.
5349 EXPECT_EQ(0u, fake_call_->GetVideoReceiveStreams().size());
5350
5351 // Receive packet on an unsignaled SSRC.
5352 uint8_t data[kMinRtpPacketLen];
5353 cricket::RtpHeader rtp_header;
5354 rtp_header.payload_type = GetEngineCodec("VP8").id;
5355 rtp_header.seq_num = rtp_header.timestamp = 0;
5356 rtp_header.ssrc = kSsrcs3[0];
5357 cricket::SetRtpHeader(data, sizeof(data), rtp_header);
5358 rtc::CopyOnWriteBuffer packet(data, sizeof(data));
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07005359 channel_->OnPacketReceived(packet, /* packet_time_us */ -1);
brandtr0dc57ea2017-05-29 23:33:31 -07005360 // Default receive stream should be created.
5361 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
5362 FakeVideoReceiveStream* recv_stream0 =
5363 fake_call_->GetVideoReceiveStreams()[0];
5364 EXPECT_EQ(kSsrcs3[0], recv_stream0->GetConfig().rtp.remote_ssrc);
5365
5366 // Signal the SSRC.
5367 EXPECT_TRUE(
5368 channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrcs3[0])));
5369 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
5370 recv_stream0 = fake_call_->GetVideoReceiveStreams()[0];
5371 EXPECT_EQ(kSsrcs3[0], recv_stream0->GetConfig().rtp.remote_ssrc);
5372
5373 // Receive packet on a different unsignaled SSRC.
5374 rtp_header.ssrc = kSsrcs3[1];
5375 cricket::SetRtpHeader(data, sizeof(data), rtp_header);
5376 packet.SetData(data, sizeof(data));
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07005377 channel_->OnPacketReceived(packet, /* packet_time_us */ -1);
brandtr0dc57ea2017-05-29 23:33:31 -07005378 // New default receive stream should be created, but old stream should remain.
5379 ASSERT_EQ(2u, fake_call_->GetVideoReceiveStreams().size());
5380 EXPECT_EQ(recv_stream0, fake_call_->GetVideoReceiveStreams()[0]);
5381 FakeVideoReceiveStream* recv_stream1 =
5382 fake_call_->GetVideoReceiveStreams()[1];
5383 EXPECT_EQ(kSsrcs3[1], recv_stream1->GetConfig().rtp.remote_ssrc);
5384}
5385
Seth Hampson7c682e02018-05-04 16:28:15 -07005386TEST_F(WebRtcVideoChannelTest, CanSetMaxBitrateForExistingStream) {
skvladdc1c62c2016-03-16 19:07:43 -07005387 AddSendStream();
5388
Niels Möller805a27e2019-01-21 12:21:27 +01005389 webrtc::test::FrameForwarder frame_forwarder;
5390 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));
skvladdc1c62c2016-03-16 19:07:43 -07005391 EXPECT_TRUE(channel_->SetSend(true));
Niels Möller805a27e2019-01-21 12:21:27 +01005392 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
skvladdc1c62c2016-03-16 19:07:43 -07005393
perkjfa10b552016-10-02 23:45:26 -07005394 int default_encoder_bitrate = GetMaxEncoderBitrate();
brandtr468da7c2016-11-22 02:16:47 -08005395 EXPECT_GT(default_encoder_bitrate, 1000);
skvladdc1c62c2016-03-16 19:07:43 -07005396
5397 // TODO(skvlad): Resolve the inconsistency between the interpretation
5398 // of the global bitrate limit for audio and video:
5399 // - Audio: max_bandwidth_bps = 0 - fail the operation,
5400 // max_bandwidth_bps = -1 - remove the bandwidth limit
5401 // - Video: max_bandwidth_bps = 0 - remove the bandwidth limit,
pbos5c7760a2017-03-10 11:23:12 -08005402 // max_bandwidth_bps = -1 - remove the bandwidth limit
skvladdc1c62c2016-03-16 19:07:43 -07005403
perkjfa10b552016-10-02 23:45:26 -07005404 SetAndExpectMaxBitrate(1000, 0, 1000);
5405 SetAndExpectMaxBitrate(1000, 800, 800);
5406 SetAndExpectMaxBitrate(600, 800, 600);
5407 SetAndExpectMaxBitrate(0, 800, 800);
5408 SetAndExpectMaxBitrate(0, 0, default_encoder_bitrate);
skvladdc1c62c2016-03-16 19:07:43 -07005409
Niels Möllerff40b142018-04-09 08:49:14 +02005410 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
skvladdc1c62c2016-03-16 19:07:43 -07005411}
5412
eladalonf1841382017-06-12 01:16:46 -07005413TEST_F(WebRtcVideoChannelTest, CannotSetMaxBitrateForNonexistentStream) {
skvladdc1c62c2016-03-16 19:07:43 -07005414 webrtc::RtpParameters nonexistent_parameters =
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07005415 channel_->GetRtpSendParameters(last_ssrc_);
Mirko Bonadeif859e552018-05-30 15:31:29 +02005416 EXPECT_EQ(0u, nonexistent_parameters.encodings.size());
skvladdc1c62c2016-03-16 19:07:43 -07005417
5418 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07005419 EXPECT_FALSE(
Zach Steinba37b4b2018-01-23 15:02:36 -08005420 channel_->SetRtpSendParameters(last_ssrc_, nonexistent_parameters).ok());
skvladdc1c62c2016-03-16 19:07:43 -07005421}
5422
eladalonf1841382017-06-12 01:16:46 -07005423TEST_F(WebRtcVideoChannelTest,
Seth Hampson7c682e02018-05-04 16:28:15 -07005424 SetLowMaxBitrateOverwritesVideoStreamMinBitrate) {
Åsa Perssonbdee46d2018-06-25 11:28:06 +02005425 FakeVideoSendStream* stream = AddSendStream();
5426
Seth Hampson7c682e02018-05-04 16:28:15 -07005427 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
5428 EXPECT_EQ(1UL, parameters.encodings.size());
5429 EXPECT_FALSE(parameters.encodings[0].max_bitrate_bps.has_value());
5430 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
5431
5432 // Note that this is testing the behavior of the FakeVideoSendStream, which
5433 // also calls to CreateEncoderStreams to get the VideoStreams, so essentially
5434 // we are just testing the behavior of
5435 // EncoderStreamFactory::CreateEncoderStreams.
Åsa Perssonbdee46d2018-06-25 11:28:06 +02005436 ASSERT_EQ(1UL, stream->GetVideoStreams().size());
5437 EXPECT_EQ(kMinVideoBitrateBps, stream->GetVideoStreams()[0].min_bitrate_bps);
Seth Hampson7c682e02018-05-04 16:28:15 -07005438
5439 // Set a low max bitrate & check that VideoStream.min_bitrate_bps is limited
5440 // by this amount.
5441 parameters = channel_->GetRtpSendParameters(last_ssrc_);
5442 int low_max_bitrate_bps = kMinVideoBitrateBps - 1000;
5443 parameters.encodings[0].max_bitrate_bps = low_max_bitrate_bps;
5444 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
5445
Åsa Perssonbdee46d2018-06-25 11:28:06 +02005446 ASSERT_EQ(1UL, stream->GetVideoStreams().size());
5447 EXPECT_EQ(low_max_bitrate_bps, stream->GetVideoStreams()[0].min_bitrate_bps);
5448 EXPECT_EQ(low_max_bitrate_bps, stream->GetVideoStreams()[0].max_bitrate_bps);
5449}
5450
5451TEST_F(WebRtcVideoChannelTest,
5452 SetHighMinBitrateOverwritesVideoStreamMaxBitrate) {
5453 FakeVideoSendStream* stream = AddSendStream();
5454
5455 // Note that this is testing the behavior of the FakeVideoSendStream, which
5456 // also calls to CreateEncoderStreams to get the VideoStreams, so essentially
5457 // we are just testing the behavior of
5458 // EncoderStreamFactory::CreateEncoderStreams.
5459 ASSERT_EQ(1UL, stream->GetVideoStreams().size());
5460 int high_min_bitrate_bps = stream->GetVideoStreams()[0].max_bitrate_bps + 1;
5461
5462 // Set a high min bitrate and check that max_bitrate_bps is adjusted up.
5463 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
5464 EXPECT_EQ(1UL, parameters.encodings.size());
5465 parameters.encodings[0].min_bitrate_bps = high_min_bitrate_bps;
5466 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
5467
5468 ASSERT_EQ(1UL, stream->GetVideoStreams().size());
5469 EXPECT_EQ(high_min_bitrate_bps, stream->GetVideoStreams()[0].min_bitrate_bps);
5470 EXPECT_EQ(high_min_bitrate_bps, stream->GetVideoStreams()[0].max_bitrate_bps);
5471}
5472
5473TEST_F(WebRtcVideoChannelTest,
5474 SetMinBitrateAboveMaxBitrateLimitAdjustsMinBitrateDown) {
5475 send_parameters_.max_bandwidth_bps = 99999;
5476 FakeVideoSendStream* stream = AddSendStream();
5477 ExpectSetMaxBitrate(send_parameters_.max_bandwidth_bps);
5478 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
5479 ASSERT_EQ(1UL, stream->GetVideoStreams().size());
5480 EXPECT_EQ(kMinVideoBitrateBps, stream->GetVideoStreams()[0].min_bitrate_bps);
5481 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
5482 stream->GetVideoStreams()[0].max_bitrate_bps);
5483
5484 // Set min bitrate above global max bitrate and check that min_bitrate_bps is
5485 // adjusted down.
5486 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
5487 EXPECT_EQ(1UL, parameters.encodings.size());
5488 parameters.encodings[0].min_bitrate_bps = 99999 + 1;
5489 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
5490 ASSERT_EQ(1UL, stream->GetVideoStreams().size());
5491 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
5492 stream->GetVideoStreams()[0].min_bitrate_bps);
5493 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
5494 stream->GetVideoStreams()[0].max_bitrate_bps);
Seth Hampson7c682e02018-05-04 16:28:15 -07005495}
5496
Åsa Persson8c1bf952018-09-13 10:42:19 +02005497TEST_F(WebRtcVideoChannelTest, SetMaxFramerateOneStream) {
5498 FakeVideoSendStream* stream = AddSendStream();
5499
5500 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
5501 EXPECT_EQ(1UL, parameters.encodings.size());
5502 EXPECT_FALSE(parameters.encodings[0].max_framerate.has_value());
5503 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
5504
5505 // Note that this is testing the behavior of the FakeVideoSendStream, which
5506 // also calls to CreateEncoderStreams to get the VideoStreams, so essentially
5507 // we are just testing the behavior of
5508 // EncoderStreamFactory::CreateEncoderStreams.
5509 ASSERT_EQ(1UL, stream->GetVideoStreams().size());
5510 EXPECT_EQ(kDefaultVideoMaxFramerate,
5511 stream->GetVideoStreams()[0].max_framerate);
5512
5513 // Set max framerate and check that VideoStream.max_framerate is set.
5514 const int kNewMaxFramerate = kDefaultVideoMaxFramerate - 1;
5515 parameters = channel_->GetRtpSendParameters(last_ssrc_);
5516 parameters.encodings[0].max_framerate = kNewMaxFramerate;
5517 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
5518
5519 ASSERT_EQ(1UL, stream->GetVideoStreams().size());
5520 EXPECT_EQ(kNewMaxFramerate, stream->GetVideoStreams()[0].max_framerate);
5521}
5522
Åsa Persson23eba222018-10-02 14:47:06 +02005523TEST_F(WebRtcVideoChannelTest, SetNumTemporalLayersForSingleStream) {
5524 FakeVideoSendStream* stream = AddSendStream();
5525
5526 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
5527 EXPECT_EQ(1UL, parameters.encodings.size());
5528 EXPECT_FALSE(parameters.encodings[0].num_temporal_layers.has_value());
5529 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
5530
5531 // Note that this is testing the behavior of the FakeVideoSendStream, which
5532 // also calls to CreateEncoderStreams to get the VideoStreams, so essentially
5533 // we are just testing the behavior of
5534 // EncoderStreamFactory::CreateEncoderStreams.
5535 ASSERT_EQ(1UL, stream->GetVideoStreams().size());
5536 EXPECT_FALSE(stream->GetVideoStreams()[0].num_temporal_layers.has_value());
5537
5538 // Set temporal layers and check that VideoStream.num_temporal_layers is set.
5539 parameters = channel_->GetRtpSendParameters(last_ssrc_);
5540 parameters.encodings[0].num_temporal_layers = 2;
5541 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
5542
5543 ASSERT_EQ(1UL, stream->GetVideoStreams().size());
5544 EXPECT_EQ(2UL, stream->GetVideoStreams()[0].num_temporal_layers);
5545}
5546
Seth Hampson7c682e02018-05-04 16:28:15 -07005547TEST_F(WebRtcVideoChannelTest,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07005548 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvladdc1c62c2016-03-16 19:07:43 -07005549 AddSendStream();
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07005550 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
skvladdc1c62c2016-03-16 19:07:43 -07005551 // Two or more encodings should result in failure.
5552 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08005553 EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08005554 // Zero encodings should also fail.
5555 parameters.encodings.clear();
Zach Steinba37b4b2018-01-23 15:02:36 -08005556 EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08005557}
5558
Zach Stein3ca452b2018-01-18 10:01:24 -08005559TEST_F(WebRtcVideoChannelTest,
5560 CannotSetSimulcastRtpSendParametersWithIncorrectNumberOfEncodings) {
5561 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
5562 StreamParams sp = CreateSimStreamParams("cname", ssrcs);
5563 AddSendStream(sp);
5564
5565 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
5566
5567 // Additional encodings should result in failure.
5568 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08005569 EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
Zach Stein3ca452b2018-01-18 10:01:24 -08005570 // Zero encodings should also fail.
5571 parameters.encodings.clear();
Zach Steinba37b4b2018-01-23 15:02:36 -08005572 EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
Zach Stein3ca452b2018-01-18 10:01:24 -08005573}
5574
deadbeeffb2aced2017-01-06 23:05:37 -08005575// Changing the SSRC through RtpParameters is not allowed.
eladalonf1841382017-06-12 01:16:46 -07005576TEST_F(WebRtcVideoChannelTest, CannotSetSsrcInRtpSendParameters) {
deadbeeffb2aced2017-01-06 23:05:37 -08005577 AddSendStream();
5578 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
Oskar Sundbom78807582017-11-16 11:09:55 +01005579 parameters.encodings[0].ssrc = 0xdeadbeef;
Zach Steinba37b4b2018-01-23 15:02:36 -08005580 EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
skvladdc1c62c2016-03-16 19:07:43 -07005581}
5582
Seth Hampson24722b32017-12-22 09:36:42 -08005583// Tests that when RTCRtpEncodingParameters.bitrate_priority gets set to
5584// a value <= 0, setting the parameters returns false.
5585TEST_F(WebRtcVideoChannelTest, SetRtpSendParametersInvalidBitratePriority) {
5586 AddSendStream();
5587 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
5588 EXPECT_EQ(1UL, parameters.encodings.size());
5589 EXPECT_EQ(webrtc::kDefaultBitratePriority,
5590 parameters.encodings[0].bitrate_priority);
5591
5592 parameters.encodings[0].bitrate_priority = 0;
Zach Steinba37b4b2018-01-23 15:02:36 -08005593 EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08005594 parameters.encodings[0].bitrate_priority = -2;
Zach Steinba37b4b2018-01-23 15:02:36 -08005595 EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08005596}
5597
5598// Tests when the the RTCRtpEncodingParameters.bitrate_priority gets set
5599// properly on the VideoChannel and propogates down to the video encoder.
5600TEST_F(WebRtcVideoChannelTest, SetRtpSendParametersPriorityOneStream) {
5601 AddSendStream();
5602 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
5603 EXPECT_EQ(1UL, parameters.encodings.size());
5604 EXPECT_EQ(webrtc::kDefaultBitratePriority,
5605 parameters.encodings[0].bitrate_priority);
5606
5607 // Change the value and set it on the VideoChannel.
5608 double new_bitrate_priority = 2.0;
5609 parameters.encodings[0].bitrate_priority = new_bitrate_priority;
Zach Steinba37b4b2018-01-23 15:02:36 -08005610 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08005611
5612 // Verify that the encoding parameters bitrate_priority is set for the
5613 // VideoChannel.
5614 parameters = channel_->GetRtpSendParameters(last_ssrc_);
5615 EXPECT_EQ(1UL, parameters.encodings.size());
5616 EXPECT_EQ(new_bitrate_priority, parameters.encodings[0].bitrate_priority);
5617
5618 // Verify that the new value propagated down to the encoder.
5619 std::vector<FakeVideoSendStream*> video_send_streams =
5620 fake_call_->GetVideoSendStreams();
5621 EXPECT_EQ(1UL, video_send_streams.size());
5622 FakeVideoSendStream* video_send_stream = video_send_streams.front();
5623 // Check that the WebRtcVideoSendStream updated the VideoEncoderConfig
5624 // appropriately.
5625 EXPECT_EQ(new_bitrate_priority,
5626 video_send_stream->GetEncoderConfig().bitrate_priority);
5627 // Check that the vector of VideoStreams also was propagated correctly. Note
5628 // that this is testing the behavior of the FakeVideoSendStream, which mimics
5629 // the calls to CreateEncoderStreams to get the VideoStreams.
Danil Chapovalov00c71832018-06-15 15:58:38 +02005630 EXPECT_EQ(absl::optional<double>(new_bitrate_priority),
Seth Hampson24722b32017-12-22 09:36:42 -08005631 video_send_stream->GetVideoStreams()[0].bitrate_priority);
5632}
5633
5634// Tests that the RTCRtpEncodingParameters.bitrate_priority is set for the
5635// VideoChannel and the value propogates to the video encoder with all simulcast
5636// streams.
5637TEST_F(WebRtcVideoChannelTest, SetRtpSendParametersPrioritySimulcastStreams) {
5638 // Create the stream params with multiple ssrcs for simulcast.
Åsa Persson31cb8f92018-06-27 10:44:56 +02005639 const size_t kNumSimulcastStreams = 3;
Seth Hampson24722b32017-12-22 09:36:42 -08005640 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
5641 StreamParams stream_params = CreateSimStreamParams("cname", ssrcs);
5642 AddSendStream(stream_params);
5643 uint32_t primary_ssrc = stream_params.first_ssrc();
5644
Niels Möller805a27e2019-01-21 12:21:27 +01005645 // Using the FrameForwarder, we manually send a full size
Tommi85959932018-02-07 19:26:06 +01005646 // frame. This creates multiple VideoStreams for all simulcast layers when
5647 // reconfiguring, and allows us to test this behavior.
Niels Möller805a27e2019-01-21 12:21:27 +01005648 webrtc::test::FrameForwarder frame_forwarder;
Seth Hampson24722b32017-12-22 09:36:42 -08005649 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01005650 EXPECT_TRUE(channel_->SetVideoSend(primary_ssrc, &options, &frame_forwarder));
Seth Hampson24722b32017-12-22 09:36:42 -08005651 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01005652 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame(
5653 1920, 1080, webrtc::VideoRotation::kVideoRotation_0,
5654 rtc::kNumMicrosecsPerSec / 30));
5655
Seth Hampson24722b32017-12-22 09:36:42 -08005656 // Get and set the rtp encoding parameters.
5657 webrtc::RtpParameters parameters =
5658 channel_->GetRtpSendParameters(primary_ssrc);
Åsa Persson31cb8f92018-06-27 10:44:56 +02005659 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
Seth Hampson24722b32017-12-22 09:36:42 -08005660 EXPECT_EQ(webrtc::kDefaultBitratePriority,
5661 parameters.encodings[0].bitrate_priority);
5662 // Change the value and set it on the VideoChannel.
5663 double new_bitrate_priority = 2.0;
5664 parameters.encodings[0].bitrate_priority = new_bitrate_priority;
Zach Steinba37b4b2018-01-23 15:02:36 -08005665 EXPECT_TRUE(channel_->SetRtpSendParameters(primary_ssrc, parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08005666
5667 // Verify that the encoding parameters priority is set on the VideoChannel.
5668 parameters = channel_->GetRtpSendParameters(primary_ssrc);
Åsa Persson31cb8f92018-06-27 10:44:56 +02005669 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
Seth Hampson24722b32017-12-22 09:36:42 -08005670 EXPECT_EQ(new_bitrate_priority, parameters.encodings[0].bitrate_priority);
5671
5672 // Verify that the new value propagated down to the encoder.
5673 std::vector<FakeVideoSendStream*> video_send_streams =
5674 fake_call_->GetVideoSendStreams();
5675 EXPECT_EQ(1UL, video_send_streams.size());
5676 FakeVideoSendStream* video_send_stream = video_send_streams.front();
5677 // Check that the WebRtcVideoSendStream updated the VideoEncoderConfig
5678 // appropriately.
Åsa Persson31cb8f92018-06-27 10:44:56 +02005679 EXPECT_EQ(kNumSimulcastStreams,
Seth Hampson24722b32017-12-22 09:36:42 -08005680 video_send_stream->GetEncoderConfig().number_of_streams);
5681 EXPECT_EQ(new_bitrate_priority,
5682 video_send_stream->GetEncoderConfig().bitrate_priority);
5683 // Check that the vector of VideoStreams also propagated correctly. The
5684 // FakeVideoSendStream calls CreateEncoderStreams, and we are testing that
5685 // these are created appropriately for the simulcast case.
Åsa Persson31cb8f92018-06-27 10:44:56 +02005686 EXPECT_EQ(kNumSimulcastStreams, video_send_stream->GetVideoStreams().size());
Danil Chapovalov00c71832018-06-15 15:58:38 +02005687 EXPECT_EQ(absl::optional<double>(new_bitrate_priority),
Seth Hampson24722b32017-12-22 09:36:42 -08005688 video_send_stream->GetVideoStreams()[0].bitrate_priority);
5689 // Since we are only setting bitrate priority per-sender, the other
5690 // VideoStreams should have a bitrate priority of 0.
Danil Chapovalov00c71832018-06-15 15:58:38 +02005691 EXPECT_EQ(absl::nullopt,
Seth Hampson24722b32017-12-22 09:36:42 -08005692 video_send_stream->GetVideoStreams()[1].bitrate_priority);
Danil Chapovalov00c71832018-06-15 15:58:38 +02005693 EXPECT_EQ(absl::nullopt,
Seth Hampson24722b32017-12-22 09:36:42 -08005694 video_send_stream->GetVideoStreams()[2].bitrate_priority);
Niels Möllerff40b142018-04-09 08:49:14 +02005695 EXPECT_TRUE(channel_->SetVideoSend(primary_ssrc, nullptr, nullptr));
Seth Hampson24722b32017-12-22 09:36:42 -08005696}
5697
Tim Haloun648d28a2018-10-18 16:52:22 -07005698// RTCRtpEncodingParameters.network_priority must be one of a few values
5699// derived from the default priority, corresponding to very-low, low, medium,
5700// or high.
5701TEST_F(WebRtcVideoChannelTest, SetRtpSendParametersInvalidNetworkPriority) {
5702 AddSendStream();
5703 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
5704 EXPECT_EQ(1UL, parameters.encodings.size());
5705 EXPECT_EQ(webrtc::kDefaultBitratePriority,
5706 parameters.encodings[0].network_priority);
5707
5708 double good_values[] = {0.5, 1.0, 2.0, 4.0};
5709 double bad_values[] = {-1.0, 0.0, 0.49, 0.51, 1.1, 3.99, 4.1, 5.0};
5710 for (auto it : good_values) {
5711 parameters.encodings[0].network_priority = it;
5712 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
5713 }
5714 for (auto it : bad_values) {
5715 parameters.encodings[0].network_priority = it;
5716 EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
5717 }
5718}
5719
Florent Castellic1a0bcb2019-01-29 14:26:48 +01005720TEST_F(WebRtcVideoChannelTest,
5721 GetAndSetRtpSendParametersScaleResolutionDownByVP8) {
Rasmus Brandt9387b522019-02-05 14:23:26 +01005722 VideoSendParameters parameters;
5723 parameters.codecs.push_back(VideoCodec(kVp8CodecName));
Florent Castellic1a0bcb2019-01-29 14:26:48 +01005724 ASSERT_TRUE(channel_->SetSendParameters(parameters));
5725 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
5726
5727 webrtc::test::FrameForwarder frame_forwarder;
Rasmus Brandt9387b522019-02-05 14:23:26 +01005728 FakeFrameSource frame_source(1280, 720, rtc::kNumMicrosecsPerSec / 30);
Florent Castellic1a0bcb2019-01-29 14:26:48 +01005729
5730 VideoOptions options;
5731 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
5732 channel_->SetSend(true);
5733
5734 // Try layers in natural order (smallest to largest).
5735 {
5736 auto rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
5737 ASSERT_EQ(3u, rtp_parameters.encodings.size());
5738 rtp_parameters.encodings[0].scale_resolution_down_by = 4.0;
5739 rtp_parameters.encodings[1].scale_resolution_down_by = 2.0;
5740 rtp_parameters.encodings[2].scale_resolution_down_by = 1.0;
5741 auto result = channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
5742 ASSERT_TRUE(result.ok());
5743
5744 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
5745
5746 std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
5747 ASSERT_EQ(3u, video_streams.size());
5748 EXPECT_EQ(320u, video_streams[0].width);
5749 EXPECT_EQ(180u, video_streams[0].height);
5750 EXPECT_EQ(640u, video_streams[1].width);
5751 EXPECT_EQ(360u, video_streams[1].height);
5752 EXPECT_EQ(1280u, video_streams[2].width);
5753 EXPECT_EQ(720u, video_streams[2].height);
5754 }
5755
5756 // Try layers in reverse natural order (largest to smallest).
5757 {
5758 auto rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
5759 ASSERT_EQ(3u, rtp_parameters.encodings.size());
5760 rtp_parameters.encodings[0].scale_resolution_down_by = 1.0;
5761 rtp_parameters.encodings[1].scale_resolution_down_by = 2.0;
5762 rtp_parameters.encodings[2].scale_resolution_down_by = 4.0;
5763 auto result = channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
5764 ASSERT_TRUE(result.ok());
5765
5766 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
5767
5768 std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
5769 ASSERT_EQ(3u, video_streams.size());
5770 EXPECT_EQ(1280u, video_streams[0].width);
5771 EXPECT_EQ(720u, video_streams[0].height);
5772 EXPECT_EQ(640u, video_streams[1].width);
5773 EXPECT_EQ(360u, video_streams[1].height);
5774 EXPECT_EQ(320u, video_streams[2].width);
5775 EXPECT_EQ(180u, video_streams[2].height);
5776 }
5777
5778 // Try layers in mixed order.
5779 {
5780 auto rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
5781 ASSERT_EQ(3u, rtp_parameters.encodings.size());
5782 rtp_parameters.encodings[0].scale_resolution_down_by = 10.0;
5783 rtp_parameters.encodings[1].scale_resolution_down_by = 2.0;
5784 rtp_parameters.encodings[2].scale_resolution_down_by = 4.0;
5785 auto result = channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
5786 ASSERT_TRUE(result.ok());
5787
5788 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
5789
5790 std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
5791 ASSERT_EQ(3u, video_streams.size());
5792 EXPECT_EQ(128u, video_streams[0].width);
5793 EXPECT_EQ(72u, video_streams[0].height);
5794 EXPECT_EQ(640u, video_streams[1].width);
5795 EXPECT_EQ(360u, video_streams[1].height);
5796 EXPECT_EQ(320u, video_streams[2].width);
5797 EXPECT_EQ(180u, video_streams[2].height);
5798 }
5799
5800 // Try with a missing scale setting, defaults to 1.0 if any other is set.
5801 {
5802 auto rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
5803 ASSERT_EQ(3u, rtp_parameters.encodings.size());
5804 rtp_parameters.encodings[0].scale_resolution_down_by = 1.0;
5805 rtp_parameters.encodings[1].scale_resolution_down_by.reset();
5806 rtp_parameters.encodings[2].scale_resolution_down_by = 4.0;
5807 auto result = channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
5808 ASSERT_TRUE(result.ok());
5809
5810 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
5811
5812 std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
5813 ASSERT_EQ(3u, video_streams.size());
5814 EXPECT_EQ(1280u, video_streams[0].width);
5815 EXPECT_EQ(720u, video_streams[0].height);
5816 EXPECT_EQ(1280u, video_streams[1].width);
5817 EXPECT_EQ(720u, video_streams[1].height);
5818 EXPECT_EQ(320u, video_streams[2].width);
5819 EXPECT_EQ(180u, video_streams[2].height);
5820 }
5821
5822 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
5823}
5824
5825TEST_F(WebRtcVideoChannelTest,
Rasmus Brandt9387b522019-02-05 14:23:26 +01005826 GetAndSetRtpSendParametersScaleResolutionDownByVP8WithOddResolution) {
5827 // Ensure that the top layer has width and height divisible by 2^3,
5828 // so that the bottom layer has width and height divisible by 2.
5829 // TODO(bugs.webrtc.org/8785): Remove this field trial when we fully trust
5830 // the number of simulcast layers set by the app.
5831 webrtc::test::ScopedFieldTrials field_trial(
5832 "WebRTC-NormalizeSimulcastResolution/Enabled-3/");
5833
5834 // Set up WebRtcVideoChannel for 3-layer VP8 simulcast.
5835 VideoSendParameters parameters;
5836 parameters.codecs.push_back(VideoCodec(kVp8CodecName));
5837 ASSERT_TRUE(channel_->SetSendParameters(parameters));
5838 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
5839 webrtc::test::FrameForwarder frame_forwarder;
5840 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, /*options=*/nullptr,
5841 &frame_forwarder));
5842 channel_->SetSend(true);
5843
5844 // Set |scale_resolution_down_by|'s.
5845 auto rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
5846 ASSERT_EQ(rtp_parameters.encodings.size(), 3u);
5847 rtp_parameters.encodings[0].scale_resolution_down_by = 1.0;
5848 rtp_parameters.encodings[1].scale_resolution_down_by = 2.0;
5849 rtp_parameters.encodings[2].scale_resolution_down_by = 4.0;
5850 const auto result =
5851 channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
5852 ASSERT_TRUE(result.ok());
5853
5854 // Use a capture resolution whose width and height are not divisible by 2^3.
5855 // (See field trial set at the top of the test.)
5856 FakeFrameSource frame_source(2007, 1207, rtc::kNumMicrosecsPerSec / 30);
5857 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
5858
5859 // Ensure the scaling is correct.
5860 const auto video_streams = stream->GetVideoStreams();
5861 ASSERT_EQ(video_streams.size(), 3u);
5862 // Ensure that we round the capture resolution down for the top layer...
5863 EXPECT_EQ(video_streams[0].width, 2000u);
5864 EXPECT_EQ(video_streams[0].height, 1200u);
5865 EXPECT_EQ(video_streams[1].width, 1000u);
5866 EXPECT_EQ(video_streams[1].height, 600u);
5867 // ...and that the bottom layer has a width/height divisible by 2.
5868 EXPECT_EQ(video_streams[2].width, 500u);
5869 EXPECT_EQ(video_streams[2].height, 300u);
5870
5871 // Tear down.
5872 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
5873}
5874
5875TEST_F(WebRtcVideoChannelTest,
Florent Castellic1a0bcb2019-01-29 14:26:48 +01005876 GetAndSetRtpSendParametersScaleResolutionDownByH264) {
Rasmus Brandt9387b522019-02-05 14:23:26 +01005877 encoder_factory_->AddSupportedVideoCodecType(kH264CodecName);
5878 VideoSendParameters parameters;
5879 parameters.codecs.push_back(VideoCodec(kH264CodecName));
Florent Castellic1a0bcb2019-01-29 14:26:48 +01005880 ASSERT_TRUE(channel_->SetSendParameters(parameters));
5881 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
5882
5883 webrtc::test::FrameForwarder frame_forwarder;
Rasmus Brandt9387b522019-02-05 14:23:26 +01005884 FakeFrameSource frame_source(1280, 720, rtc::kNumMicrosecsPerSec / 30);
Florent Castellic1a0bcb2019-01-29 14:26:48 +01005885
5886 VideoOptions options;
5887 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
5888 channel_->SetSend(true);
5889
5890 // Try layers in natural order (smallest to largest).
5891 {
5892 auto rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
5893 ASSERT_EQ(3u, rtp_parameters.encodings.size());
5894 rtp_parameters.encodings[0].scale_resolution_down_by = 4.0;
5895 rtp_parameters.encodings[1].scale_resolution_down_by = 2.0;
5896 rtp_parameters.encodings[2].scale_resolution_down_by = 1.0;
5897 auto result = channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
5898 ASSERT_TRUE(result.ok());
5899
5900 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
5901
5902 std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
5903 ASSERT_EQ(3u, video_streams.size());
5904 EXPECT_EQ(320u, video_streams[0].width);
5905 EXPECT_EQ(180u, video_streams[0].height);
5906 EXPECT_EQ(640u, video_streams[1].width);
5907 EXPECT_EQ(360u, video_streams[1].height);
5908 EXPECT_EQ(1280u, video_streams[2].width);
5909 EXPECT_EQ(720u, video_streams[2].height);
5910 }
5911
5912 // Try layers in reverse natural order (largest to smallest).
5913 {
5914 auto rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
5915 ASSERT_EQ(3u, rtp_parameters.encodings.size());
5916 rtp_parameters.encodings[0].scale_resolution_down_by = 1.0;
5917 rtp_parameters.encodings[1].scale_resolution_down_by = 2.0;
5918 rtp_parameters.encodings[2].scale_resolution_down_by = 4.0;
5919 auto result = channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
5920 ASSERT_TRUE(result.ok());
5921
5922 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
5923
5924 std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
5925 ASSERT_EQ(3u, video_streams.size());
5926 EXPECT_EQ(1280u, video_streams[0].width);
5927 EXPECT_EQ(720u, video_streams[0].height);
5928 EXPECT_EQ(640u, video_streams[1].width);
5929 EXPECT_EQ(360u, video_streams[1].height);
5930 EXPECT_EQ(320u, video_streams[2].width);
5931 EXPECT_EQ(180u, video_streams[2].height);
5932 }
5933
5934 // Try layers in mixed order.
5935 {
5936 auto rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
5937 ASSERT_EQ(3u, rtp_parameters.encodings.size());
5938 rtp_parameters.encodings[0].scale_resolution_down_by = 10.0;
5939 rtp_parameters.encodings[1].scale_resolution_down_by = 2.0;
5940 rtp_parameters.encodings[2].scale_resolution_down_by = 4.0;
5941 auto result = channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
5942 ASSERT_TRUE(result.ok());
5943
5944 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
5945
5946 std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
5947 ASSERT_EQ(3u, video_streams.size());
5948 EXPECT_EQ(128u, video_streams[0].width);
5949 EXPECT_EQ(72u, video_streams[0].height);
5950 EXPECT_EQ(640u, video_streams[1].width);
5951 EXPECT_EQ(360u, video_streams[1].height);
5952 EXPECT_EQ(320u, video_streams[2].width);
5953 EXPECT_EQ(180u, video_streams[2].height);
5954 }
5955
5956 // Try with a missing scale setting, defaults to 1.0 if any other is set.
5957 {
5958 auto rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
5959 ASSERT_EQ(3u, rtp_parameters.encodings.size());
5960 rtp_parameters.encodings[0].scale_resolution_down_by = 1.0;
5961 rtp_parameters.encodings[1].scale_resolution_down_by.reset();
5962 rtp_parameters.encodings[2].scale_resolution_down_by = 4.0;
5963 auto result = channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
5964 ASSERT_TRUE(result.ok());
5965
5966 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
5967
5968 std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
5969 ASSERT_EQ(3u, video_streams.size());
5970 EXPECT_EQ(1280u, video_streams[0].width);
5971 EXPECT_EQ(720u, video_streams[0].height);
5972 EXPECT_EQ(1280u, video_streams[1].width);
5973 EXPECT_EQ(720u, video_streams[1].height);
5974 EXPECT_EQ(320u, video_streams[2].width);
5975 EXPECT_EQ(180u, video_streams[2].height);
5976 }
5977 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
5978}
5979
Rasmus Brandt9387b522019-02-05 14:23:26 +01005980TEST_F(WebRtcVideoChannelTest,
5981 GetAndSetRtpSendParametersScaleResolutionDownByH264WithOddResolution) {
5982 // Ensure that the top layer has width and height divisible by 2^3,
5983 // so that the bottom layer has width and height divisible by 2.
5984 // TODO(bugs.webrtc.org/8785): Remove this field trial when we fully trust
5985 // the number of simulcast layers set by the app.
5986 webrtc::test::ScopedFieldTrials field_trial(
5987 "WebRTC-NormalizeSimulcastResolution/Enabled-3/");
5988
5989 // Set up WebRtcVideoChannel for 3-layer H264 simulcast.
5990 encoder_factory_->AddSupportedVideoCodecType(kH264CodecName);
5991 VideoSendParameters parameters;
5992 parameters.codecs.push_back(VideoCodec(kH264CodecName));
5993 ASSERT_TRUE(channel_->SetSendParameters(parameters));
5994 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
5995 webrtc::test::FrameForwarder frame_forwarder;
5996 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, /*options=*/nullptr,
5997 &frame_forwarder));
5998 channel_->SetSend(true);
5999
6000 // Set |scale_resolution_down_by|'s.
6001 auto rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
6002 ASSERT_EQ(rtp_parameters.encodings.size(), 3u);
6003 rtp_parameters.encodings[0].scale_resolution_down_by = 1.0;
6004 rtp_parameters.encodings[1].scale_resolution_down_by = 2.0;
6005 rtp_parameters.encodings[2].scale_resolution_down_by = 4.0;
6006 const auto result =
6007 channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
6008 ASSERT_TRUE(result.ok());
6009
6010 // Use a capture resolution whose width and height are not divisible by 2^3.
6011 // (See field trial set at the top of the test.)
6012 FakeFrameSource frame_source(2007, 1207, rtc::kNumMicrosecsPerSec / 30);
6013 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
6014
6015 // Ensure the scaling is correct.
6016 const auto video_streams = stream->GetVideoStreams();
6017 ASSERT_EQ(video_streams.size(), 3u);
6018 // Ensure that we round the capture resolution down for the top layer...
6019 EXPECT_EQ(video_streams[0].width, 2000u);
6020 EXPECT_EQ(video_streams[0].height, 1200u);
6021 EXPECT_EQ(video_streams[1].width, 1000u);
6022 EXPECT_EQ(video_streams[1].height, 600u);
6023 // ...and that the bottom layer has a width/height divisible by 2.
6024 EXPECT_EQ(video_streams[2].width, 500u);
6025 EXPECT_EQ(video_streams[2].height, 300u);
6026
6027 // Tear down.
6028 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
6029}
6030
Åsa Persson8c1bf952018-09-13 10:42:19 +02006031TEST_F(WebRtcVideoChannelTest, GetAndSetRtpSendParametersMaxFramerate) {
6032 const size_t kNumSimulcastStreams = 3;
6033 SetUpSimulcast(true, false);
6034
6035 // Get and set the rtp encoding parameters.
6036 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6037 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6038 for (const auto& encoding : parameters.encodings) {
6039 EXPECT_FALSE(encoding.max_framerate);
6040 }
6041
6042 // Change the value and set it on the VideoChannel.
6043 parameters.encodings[0].max_framerate = 10;
6044 parameters.encodings[1].max_framerate = 20;
6045 parameters.encodings[2].max_framerate = 25;
6046 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6047
6048 // Verify that the bitrates are set on the VideoChannel.
6049 parameters = channel_->GetRtpSendParameters(last_ssrc_);
6050 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6051 EXPECT_EQ(10, parameters.encodings[0].max_framerate);
6052 EXPECT_EQ(20, parameters.encodings[1].max_framerate);
6053 EXPECT_EQ(25, parameters.encodings[2].max_framerate);
6054}
6055
Åsa Persson23eba222018-10-02 14:47:06 +02006056TEST_F(WebRtcVideoChannelTest,
6057 SetRtpSendParametersNumTemporalLayersFailsForInvalidRange) {
6058 const size_t kNumSimulcastStreams = 3;
6059 SetUpSimulcast(true, false);
6060
6061 // Get and set the rtp encoding parameters.
6062 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6063 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6064
6065 // Num temporal layers should be in the range [1, kMaxTemporalStreams].
6066 parameters.encodings[0].num_temporal_layers = 0;
6067 EXPECT_EQ(webrtc::RTCErrorType::INVALID_RANGE,
6068 channel_->SetRtpSendParameters(last_ssrc_, parameters).type());
6069 parameters.encodings[0].num_temporal_layers = webrtc::kMaxTemporalStreams + 1;
6070 EXPECT_EQ(webrtc::RTCErrorType::INVALID_RANGE,
6071 channel_->SetRtpSendParameters(last_ssrc_, parameters).type());
6072}
6073
6074TEST_F(WebRtcVideoChannelTest,
6075 SetRtpSendParametersNumTemporalLayersFailsForInvalidModification) {
6076 const size_t kNumSimulcastStreams = 3;
6077 SetUpSimulcast(true, false);
6078
6079 // Get and set the rtp encoding parameters.
6080 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6081 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6082
6083 // No/all layers should be set.
6084 parameters.encodings[0].num_temporal_layers = 1;
6085 EXPECT_EQ(webrtc::RTCErrorType::INVALID_MODIFICATION,
6086 channel_->SetRtpSendParameters(last_ssrc_, parameters).type());
6087
6088 // Different values not supported.
6089 parameters.encodings[0].num_temporal_layers = 1;
6090 parameters.encodings[1].num_temporal_layers = 2;
6091 parameters.encodings[2].num_temporal_layers = 2;
6092 EXPECT_EQ(webrtc::RTCErrorType::INVALID_MODIFICATION,
6093 channel_->SetRtpSendParameters(last_ssrc_, parameters).type());
6094}
6095
6096TEST_F(WebRtcVideoChannelTest, GetAndSetRtpSendParametersNumTemporalLayers) {
6097 const size_t kNumSimulcastStreams = 3;
6098 SetUpSimulcast(true, false);
6099
6100 // Get and set the rtp encoding parameters.
6101 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6102 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6103 for (const auto& encoding : parameters.encodings)
6104 EXPECT_FALSE(encoding.num_temporal_layers);
6105
6106 // Change the value and set it on the VideoChannel.
6107 parameters.encodings[0].num_temporal_layers = 3;
6108 parameters.encodings[1].num_temporal_layers = 3;
6109 parameters.encodings[2].num_temporal_layers = 3;
6110 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6111
6112 // Verify that the number of temporal layers are set on the VideoChannel.
6113 parameters = channel_->GetRtpSendParameters(last_ssrc_);
6114 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6115 EXPECT_EQ(3, parameters.encodings[0].num_temporal_layers);
6116 EXPECT_EQ(3, parameters.encodings[1].num_temporal_layers);
6117 EXPECT_EQ(3, parameters.encodings[2].num_temporal_layers);
6118}
6119
6120TEST_F(WebRtcVideoChannelTest, NumTemporalLayersPropagatedToEncoder) {
6121 const size_t kNumSimulcastStreams = 3;
6122 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
6123
6124 // Send a full size frame so all simulcast layers are used when reconfiguring.
Niels Möller805a27e2019-01-21 12:21:27 +01006125 webrtc::test::FrameForwarder frame_forwarder;
Åsa Persson23eba222018-10-02 14:47:06 +02006126 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01006127 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
Åsa Persson23eba222018-10-02 14:47:06 +02006128 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01006129 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Åsa Persson23eba222018-10-02 14:47:06 +02006130
6131 // Get and set the rtp encoding parameters.
6132 // Change the value and set it on the VideoChannel.
6133 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6134 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6135 parameters.encodings[0].num_temporal_layers = 2;
6136 parameters.encodings[1].num_temporal_layers = 2;
6137 parameters.encodings[2].num_temporal_layers = 2;
6138 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6139
6140 // Verify that the new value is propagated down to the encoder.
6141 // Check that WebRtcVideoSendStream updates VideoEncoderConfig correctly.
6142 EXPECT_EQ(2, stream->num_encoder_reconfigurations());
6143 webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
6144 EXPECT_EQ(kNumSimulcastStreams, encoder_config.number_of_streams);
6145 EXPECT_EQ(kNumSimulcastStreams, encoder_config.simulcast_layers.size());
6146 EXPECT_EQ(2UL, encoder_config.simulcast_layers[0].num_temporal_layers);
6147 EXPECT_EQ(2UL, encoder_config.simulcast_layers[1].num_temporal_layers);
6148 EXPECT_EQ(2UL, encoder_config.simulcast_layers[2].num_temporal_layers);
6149
6150 // FakeVideoSendStream calls CreateEncoderStreams, test that the vector of
6151 // VideoStreams are created appropriately for the simulcast case.
6152 EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
6153 EXPECT_EQ(2UL, stream->GetVideoStreams()[0].num_temporal_layers);
6154 EXPECT_EQ(2UL, stream->GetVideoStreams()[1].num_temporal_layers);
6155 EXPECT_EQ(2UL, stream->GetVideoStreams()[2].num_temporal_layers);
6156
6157 // No parameter changed, encoder should not be reconfigured.
6158 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6159 EXPECT_EQ(2, stream->num_encoder_reconfigurations());
6160
6161 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
6162}
6163
6164TEST_F(WebRtcVideoChannelTest,
6165 DefaultValuePropagatedToEncoderForUnsetNumTemporalLayers) {
6166 const size_t kDefaultNumTemporalLayers = 3;
6167 const size_t kNumSimulcastStreams = 3;
6168 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
6169
6170 // Send a full size frame so all simulcast layers are used when reconfiguring.
Niels Möller805a27e2019-01-21 12:21:27 +01006171 webrtc::test::FrameForwarder frame_forwarder;
Åsa Persson23eba222018-10-02 14:47:06 +02006172 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01006173 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
Åsa Persson23eba222018-10-02 14:47:06 +02006174 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01006175 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Åsa Persson23eba222018-10-02 14:47:06 +02006176
6177 // Change rtp encoding parameters, num_temporal_layers not changed.
6178 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6179 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6180 parameters.encodings[0].min_bitrate_bps = 33000;
6181 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6182
6183 // Verify that no value is propagated down to the encoder.
6184 webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
6185 EXPECT_EQ(kNumSimulcastStreams, encoder_config.number_of_streams);
6186 EXPECT_EQ(kNumSimulcastStreams, encoder_config.simulcast_layers.size());
6187 EXPECT_FALSE(encoder_config.simulcast_layers[0].num_temporal_layers);
6188 EXPECT_FALSE(encoder_config.simulcast_layers[1].num_temporal_layers);
6189 EXPECT_FALSE(encoder_config.simulcast_layers[2].num_temporal_layers);
6190
6191 // FakeVideoSendStream calls CreateEncoderStreams, test that the vector of
6192 // VideoStreams are created appropriately for the simulcast case.
6193 EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
6194 EXPECT_EQ(kDefaultNumTemporalLayers,
6195 stream->GetVideoStreams()[0].num_temporal_layers);
6196 EXPECT_EQ(kDefaultNumTemporalLayers,
6197 stream->GetVideoStreams()[1].num_temporal_layers);
6198 EXPECT_EQ(kDefaultNumTemporalLayers,
6199 stream->GetVideoStreams()[2].num_temporal_layers);
6200
6201 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
6202}
6203
Åsa Persson8c1bf952018-09-13 10:42:19 +02006204TEST_F(WebRtcVideoChannelTest, MaxSimulcastFrameratePropagatedToEncoder) {
6205 const size_t kNumSimulcastStreams = 3;
6206 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
6207
6208 // Send a full size frame so all simulcast layers are used when reconfiguring.
Niels Möller805a27e2019-01-21 12:21:27 +01006209 webrtc::test::FrameForwarder frame_forwarder;
Åsa Persson8c1bf952018-09-13 10:42:19 +02006210 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01006211 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
Åsa Persson8c1bf952018-09-13 10:42:19 +02006212 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01006213 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Åsa Persson8c1bf952018-09-13 10:42:19 +02006214
6215 // Get and set the rtp encoding parameters.
6216 // Change the value and set it on the VideoChannel.
6217 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6218 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6219 parameters.encodings[0].max_framerate = 15;
6220 parameters.encodings[1].max_framerate = 25;
6221 parameters.encodings[2].max_framerate = 20;
6222 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6223
6224 // Verify that the new value propagated down to the encoder.
6225 // Check that WebRtcVideoSendStream updates VideoEncoderConfig correctly.
6226 EXPECT_EQ(2, stream->num_encoder_reconfigurations());
6227 webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
6228 EXPECT_EQ(kNumSimulcastStreams, encoder_config.number_of_streams);
6229 EXPECT_EQ(kNumSimulcastStreams, encoder_config.simulcast_layers.size());
6230 EXPECT_EQ(15, encoder_config.simulcast_layers[0].max_framerate);
6231 EXPECT_EQ(25, encoder_config.simulcast_layers[1].max_framerate);
6232 EXPECT_EQ(20, encoder_config.simulcast_layers[2].max_framerate);
6233
6234 // FakeVideoSendStream calls CreateEncoderStreams, test that the vector of
6235 // VideoStreams are created appropriately for the simulcast case.
6236 // Currently the maximum |max_framerate| is used.
6237 EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
6238 EXPECT_EQ(25, stream->GetVideoStreams()[0].max_framerate);
6239 EXPECT_EQ(25, stream->GetVideoStreams()[1].max_framerate);
6240 EXPECT_EQ(25, stream->GetVideoStreams()[2].max_framerate);
6241
6242 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
6243}
6244
6245TEST_F(WebRtcVideoChannelTest,
6246 DefaultValuePropagatedToEncoderForUnsetFramerate) {
6247 const size_t kNumSimulcastStreams = 3;
6248 const std::vector<webrtc::VideoStream> kDefault = GetSimulcastBitrates720p();
6249 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
6250
6251 // Send a full size frame so all simulcast layers are used when reconfiguring.
Niels Möller805a27e2019-01-21 12:21:27 +01006252 webrtc::test::FrameForwarder frame_forwarder;
Åsa Persson8c1bf952018-09-13 10:42:19 +02006253 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01006254 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
Åsa Persson8c1bf952018-09-13 10:42:19 +02006255 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01006256 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Åsa Persson8c1bf952018-09-13 10:42:19 +02006257
6258 // Get and set the rtp encoding parameters.
6259 // Change the value and set it on the VideoChannel.
6260 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6261 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6262 parameters.encodings[0].max_framerate = 15;
6263 parameters.encodings[2].max_framerate = 20;
6264 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6265
6266 // Verify that the new value propagated down to the encoder.
6267 // Check that WebRtcVideoSendStream updates VideoEncoderConfig correctly.
6268 webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
6269 EXPECT_EQ(kNumSimulcastStreams, encoder_config.number_of_streams);
6270 EXPECT_EQ(kNumSimulcastStreams, encoder_config.simulcast_layers.size());
6271 EXPECT_EQ(15, encoder_config.simulcast_layers[0].max_framerate);
6272 EXPECT_EQ(-1, encoder_config.simulcast_layers[1].max_framerate);
6273 EXPECT_EQ(20, encoder_config.simulcast_layers[2].max_framerate);
6274
6275 // FakeVideoSendStream calls CreateEncoderStreams, test that the vector of
6276 // VideoStreams are created appropriately for the simulcast case.
6277 // The maximum |max_framerate| is used, kDefaultVideoMaxFramerate: 60.
6278 EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
6279 EXPECT_EQ(kDefaultVideoMaxFramerate,
6280 stream->GetVideoStreams()[0].max_framerate);
6281 EXPECT_EQ(kDefaultVideoMaxFramerate,
6282 stream->GetVideoStreams()[1].max_framerate);
6283 EXPECT_EQ(kDefaultVideoMaxFramerate,
6284 stream->GetVideoStreams()[2].max_framerate);
6285
6286 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
6287}
6288
Åsa Persson55659812018-06-18 17:51:32 +02006289TEST_F(WebRtcVideoChannelTest, GetAndSetRtpSendParametersMinAndMaxBitrate) {
6290 const size_t kNumSimulcastStreams = 3;
6291 SetUpSimulcast(true, false);
6292
6293 // Get and set the rtp encoding parameters.
6294 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6295 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6296 for (const auto& encoding : parameters.encodings) {
6297 EXPECT_FALSE(encoding.min_bitrate_bps);
6298 EXPECT_FALSE(encoding.max_bitrate_bps);
6299 }
6300
6301 // Change the value and set it on the VideoChannel.
6302 parameters.encodings[0].min_bitrate_bps = 100000;
6303 parameters.encodings[0].max_bitrate_bps = 200000;
6304 parameters.encodings[1].min_bitrate_bps = 300000;
6305 parameters.encodings[1].max_bitrate_bps = 400000;
6306 parameters.encodings[2].min_bitrate_bps = 500000;
6307 parameters.encodings[2].max_bitrate_bps = 600000;
6308 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6309
6310 // Verify that the bitrates are set on the VideoChannel.
6311 parameters = channel_->GetRtpSendParameters(last_ssrc_);
6312 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6313 EXPECT_EQ(100000, parameters.encodings[0].min_bitrate_bps);
6314 EXPECT_EQ(200000, parameters.encodings[0].max_bitrate_bps);
6315 EXPECT_EQ(300000, parameters.encodings[1].min_bitrate_bps);
6316 EXPECT_EQ(400000, parameters.encodings[1].max_bitrate_bps);
6317 EXPECT_EQ(500000, parameters.encodings[2].min_bitrate_bps);
6318 EXPECT_EQ(600000, parameters.encodings[2].max_bitrate_bps);
6319}
6320
6321TEST_F(WebRtcVideoChannelTest, SetRtpSendParametersFailsWithIncorrectBitrate) {
6322 const size_t kNumSimulcastStreams = 3;
6323 SetUpSimulcast(true, false);
6324
6325 // Get and set the rtp encoding parameters.
6326 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6327 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6328
6329 // Max bitrate lower than min bitrate should fail.
6330 parameters.encodings[2].min_bitrate_bps = 100000;
6331 parameters.encodings[2].max_bitrate_bps = 100000 - 1;
6332 EXPECT_EQ(webrtc::RTCErrorType::INVALID_RANGE,
6333 channel_->SetRtpSendParameters(last_ssrc_, parameters).type());
6334}
6335
6336// Test that min and max bitrate values set via RtpParameters are correctly
6337// propagated to the underlying encoder, and that the target is set to 3/4 of
6338// the maximum (3/4 was chosen because it's similar to the simulcast defaults
6339// that are used if no min/max are specified).
6340TEST_F(WebRtcVideoChannelTest, MinAndMaxSimulcastBitratePropagatedToEncoder) {
6341 const size_t kNumSimulcastStreams = 3;
6342 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
6343
6344 // Send a full size frame so all simulcast layers are used when reconfiguring.
Niels Möller805a27e2019-01-21 12:21:27 +01006345 webrtc::test::FrameForwarder frame_forwarder;
Åsa Persson55659812018-06-18 17:51:32 +02006346 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01006347 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
Åsa Persson55659812018-06-18 17:51:32 +02006348 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01006349 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Åsa Persson55659812018-06-18 17:51:32 +02006350
6351 // Get and set the rtp encoding parameters.
6352 // Change the value and set it on the VideoChannel.
6353 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6354 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6355 parameters.encodings[0].min_bitrate_bps = 100000;
6356 parameters.encodings[0].max_bitrate_bps = 200000;
6357 parameters.encodings[1].min_bitrate_bps = 300000;
6358 parameters.encodings[1].max_bitrate_bps = 400000;
6359 parameters.encodings[2].min_bitrate_bps = 500000;
6360 parameters.encodings[2].max_bitrate_bps = 600000;
6361 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6362
6363 // Verify that the new value propagated down to the encoder.
6364 // Check that WebRtcVideoSendStream updates VideoEncoderConfig correctly.
6365 EXPECT_EQ(2, stream->num_encoder_reconfigurations());
6366 webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
6367 EXPECT_EQ(kNumSimulcastStreams, encoder_config.number_of_streams);
6368 EXPECT_EQ(kNumSimulcastStreams, encoder_config.simulcast_layers.size());
6369 EXPECT_EQ(100000, encoder_config.simulcast_layers[0].min_bitrate_bps);
6370 EXPECT_EQ(200000, encoder_config.simulcast_layers[0].max_bitrate_bps);
6371 EXPECT_EQ(300000, encoder_config.simulcast_layers[1].min_bitrate_bps);
6372 EXPECT_EQ(400000, encoder_config.simulcast_layers[1].max_bitrate_bps);
6373 EXPECT_EQ(500000, encoder_config.simulcast_layers[2].min_bitrate_bps);
6374 EXPECT_EQ(600000, encoder_config.simulcast_layers[2].max_bitrate_bps);
6375
6376 // FakeVideoSendStream calls CreateEncoderStreams, test that the vector of
6377 // VideoStreams are created appropriately for the simulcast case.
6378 EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
6379 // Target bitrate: 200000 * 3 / 4 = 150000.
6380 EXPECT_EQ(100000, stream->GetVideoStreams()[0].min_bitrate_bps);
6381 EXPECT_EQ(150000, stream->GetVideoStreams()[0].target_bitrate_bps);
6382 EXPECT_EQ(200000, stream->GetVideoStreams()[0].max_bitrate_bps);
6383 // Target bitrate: 400000 * 3 / 4 = 300000.
6384 EXPECT_EQ(300000, stream->GetVideoStreams()[1].min_bitrate_bps);
6385 EXPECT_EQ(300000, stream->GetVideoStreams()[1].target_bitrate_bps);
6386 EXPECT_EQ(400000, stream->GetVideoStreams()[1].max_bitrate_bps);
6387 // Target bitrate: 600000 * 3 / 4 = 450000, less than min -> max.
6388 EXPECT_EQ(500000, stream->GetVideoStreams()[2].min_bitrate_bps);
6389 EXPECT_EQ(600000, stream->GetVideoStreams()[2].target_bitrate_bps);
6390 EXPECT_EQ(600000, stream->GetVideoStreams()[2].max_bitrate_bps);
6391
6392 // No parameter changed, encoder should not be reconfigured.
6393 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6394 EXPECT_EQ(2, stream->num_encoder_reconfigurations());
6395
6396 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
6397}
6398
6399// Test to only specify the min or max bitrate value for a layer via
6400// RtpParameters. The unspecified min/max and target value should be set to the
6401// simulcast default that is used if no min/max are specified.
6402TEST_F(WebRtcVideoChannelTest, MinOrMaxSimulcastBitratePropagatedToEncoder) {
6403 const size_t kNumSimulcastStreams = 3;
6404 const std::vector<webrtc::VideoStream> kDefault = GetSimulcastBitrates720p();
6405 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
6406
6407 // Send a full size frame so all simulcast layers are used when reconfiguring.
Niels Möller805a27e2019-01-21 12:21:27 +01006408 webrtc::test::FrameForwarder frame_forwarder;
Åsa Persson55659812018-06-18 17:51:32 +02006409 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01006410 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
Åsa Persson55659812018-06-18 17:51:32 +02006411 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01006412 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Åsa Persson55659812018-06-18 17:51:32 +02006413
6414 // Get and set the rtp encoding parameters.
6415 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6416 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6417
6418 // Change the value and set it on the VideoChannel.
6419 // Layer 0: only configure min bitrate.
6420 const int kMinBpsLayer0 = kDefault[0].min_bitrate_bps + 1;
6421 parameters.encodings[0].min_bitrate_bps = kMinBpsLayer0;
6422 // Layer 1: only configure max bitrate.
6423 const int kMaxBpsLayer1 = kDefault[1].max_bitrate_bps - 1;
6424 parameters.encodings[1].max_bitrate_bps = kMaxBpsLayer1;
6425 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6426
6427 // Verify that the new value propagated down to the encoder.
6428 // Check that WebRtcVideoSendStream updates VideoEncoderConfig correctly.
6429 webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
6430 EXPECT_EQ(kNumSimulcastStreams, encoder_config.number_of_streams);
6431 EXPECT_EQ(kNumSimulcastStreams, encoder_config.simulcast_layers.size());
6432 EXPECT_EQ(kMinBpsLayer0, encoder_config.simulcast_layers[0].min_bitrate_bps);
6433 EXPECT_EQ(-1, encoder_config.simulcast_layers[0].max_bitrate_bps);
6434 EXPECT_EQ(-1, encoder_config.simulcast_layers[1].min_bitrate_bps);
6435 EXPECT_EQ(kMaxBpsLayer1, encoder_config.simulcast_layers[1].max_bitrate_bps);
6436 EXPECT_EQ(-1, encoder_config.simulcast_layers[2].min_bitrate_bps);
6437 EXPECT_EQ(-1, encoder_config.simulcast_layers[2].max_bitrate_bps);
6438
6439 // FakeVideoSendStream calls CreateEncoderStreams, test that the vector of
6440 // VideoStreams are created appropriately for the simulcast case.
6441 EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
6442 // Layer 0: min configured bitrate should overwrite min default.
6443 EXPECT_EQ(kMinBpsLayer0, stream->GetVideoStreams()[0].min_bitrate_bps);
6444 EXPECT_EQ(kDefault[0].target_bitrate_bps,
6445 stream->GetVideoStreams()[0].target_bitrate_bps);
6446 EXPECT_EQ(kDefault[0].max_bitrate_bps,
6447 stream->GetVideoStreams()[0].max_bitrate_bps);
6448 // Layer 1: max configured bitrate should overwrite max default.
6449 EXPECT_EQ(kDefault[1].min_bitrate_bps,
6450 stream->GetVideoStreams()[1].min_bitrate_bps);
6451 EXPECT_EQ(kDefault[1].target_bitrate_bps,
6452 stream->GetVideoStreams()[1].target_bitrate_bps);
6453 EXPECT_EQ(kMaxBpsLayer1, stream->GetVideoStreams()[1].max_bitrate_bps);
6454 // Layer 2: min and max bitrate not configured, default expected.
6455 EXPECT_EQ(kDefault[2].min_bitrate_bps,
6456 stream->GetVideoStreams()[2].min_bitrate_bps);
6457 EXPECT_EQ(kDefault[2].target_bitrate_bps,
6458 stream->GetVideoStreams()[2].target_bitrate_bps);
6459 EXPECT_EQ(kDefault[2].max_bitrate_bps,
6460 stream->GetVideoStreams()[2].max_bitrate_bps);
6461
6462 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
6463}
6464
6465// Test that specifying the min (or max) bitrate value for a layer via
6466// RtpParameters above (or below) the simulcast default max (or min) adjusts the
6467// unspecified values accordingly.
6468TEST_F(WebRtcVideoChannelTest, SetMinAndMaxSimulcastBitrateAboveBelowDefault) {
6469 const size_t kNumSimulcastStreams = 3;
6470 const std::vector<webrtc::VideoStream> kDefault = GetSimulcastBitrates720p();
6471 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
6472
6473 // Send a full size frame so all simulcast layers are used when reconfiguring.
Niels Möller805a27e2019-01-21 12:21:27 +01006474 webrtc::test::FrameForwarder frame_forwarder;
Åsa Persson55659812018-06-18 17:51:32 +02006475 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01006476 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
Åsa Persson55659812018-06-18 17:51:32 +02006477 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01006478 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Åsa Persson55659812018-06-18 17:51:32 +02006479
6480 // Get and set the rtp encoding parameters.
6481 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6482 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6483
6484 // Change the value and set it on the VideoChannel.
6485 // For layer 0, set the min bitrate above the default max.
6486 const int kMinBpsLayer0 = kDefault[0].max_bitrate_bps + 1;
6487 parameters.encodings[0].min_bitrate_bps = kMinBpsLayer0;
6488 // For layer 1, set the max bitrate below the default min.
6489 const int kMaxBpsLayer1 = kDefault[1].min_bitrate_bps - 1;
6490 parameters.encodings[1].max_bitrate_bps = kMaxBpsLayer1;
6491 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6492
6493 // Verify that the new value propagated down to the encoder.
6494 // FakeVideoSendStream calls CreateEncoderStreams, test that the vector of
6495 // VideoStreams are created appropriately for the simulcast case.
6496 EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
6497 // Layer 0: Min bitrate above default max (target/max should be adjusted).
6498 EXPECT_EQ(kMinBpsLayer0, stream->GetVideoStreams()[0].min_bitrate_bps);
6499 EXPECT_EQ(kMinBpsLayer0, stream->GetVideoStreams()[0].target_bitrate_bps);
6500 EXPECT_EQ(kMinBpsLayer0, stream->GetVideoStreams()[0].max_bitrate_bps);
6501 // Layer 1: Max bitrate below default min (min/target should be adjusted).
6502 EXPECT_EQ(kMaxBpsLayer1, stream->GetVideoStreams()[1].min_bitrate_bps);
6503 EXPECT_EQ(kMaxBpsLayer1, stream->GetVideoStreams()[1].target_bitrate_bps);
6504 EXPECT_EQ(kMaxBpsLayer1, stream->GetVideoStreams()[1].max_bitrate_bps);
6505 // Layer 2: min and max bitrate not configured, default expected.
6506 EXPECT_EQ(kDefault[2].min_bitrate_bps,
6507 stream->GetVideoStreams()[2].min_bitrate_bps);
6508 EXPECT_EQ(kDefault[2].target_bitrate_bps,
6509 stream->GetVideoStreams()[2].target_bitrate_bps);
6510 EXPECT_EQ(kDefault[2].max_bitrate_bps,
6511 stream->GetVideoStreams()[2].max_bitrate_bps);
6512
6513 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
6514}
6515
6516TEST_F(WebRtcVideoChannelTest, BandwidthAboveTotalMaxBitrateGivenToMaxLayer) {
6517 const size_t kNumSimulcastStreams = 3;
6518 const std::vector<webrtc::VideoStream> kDefault = GetSimulcastBitrates720p();
6519 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
6520
6521 // Send a full size frame so all simulcast layers are used when reconfiguring.
Niels Möller805a27e2019-01-21 12:21:27 +01006522 webrtc::test::FrameForwarder frame_forwarder;
Åsa Persson55659812018-06-18 17:51:32 +02006523 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01006524 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
Åsa Persson55659812018-06-18 17:51:32 +02006525 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01006526 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Åsa Persson55659812018-06-18 17:51:32 +02006527
6528 // Set max bitrate for all but the highest layer.
6529 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6530 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6531 parameters.encodings[0].max_bitrate_bps = kDefault[0].max_bitrate_bps;
6532 parameters.encodings[1].max_bitrate_bps = kDefault[1].max_bitrate_bps;
6533 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6534
6535 // Set max bandwidth equal to total max bitrate.
6536 send_parameters_.max_bandwidth_bps =
6537 GetTotalMaxBitrateBps(stream->GetVideoStreams());
6538 ExpectSetMaxBitrate(send_parameters_.max_bandwidth_bps);
6539 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
6540
6541 // No bitrate above the total max to give to the highest layer.
6542 EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
6543 EXPECT_EQ(kDefault[2].max_bitrate_bps,
6544 stream->GetVideoStreams()[2].max_bitrate_bps);
6545
6546 // Set max bandwidth above the total max bitrate.
6547 send_parameters_.max_bandwidth_bps =
6548 GetTotalMaxBitrateBps(stream->GetVideoStreams()) + 1;
6549 ExpectSetMaxBitrate(send_parameters_.max_bandwidth_bps);
6550 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
6551
6552 // The highest layer has no max bitrate set -> the bitrate above the total
6553 // max should be given to the highest layer.
6554 EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
6555 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
6556 GetTotalMaxBitrateBps(stream->GetVideoStreams()));
6557 EXPECT_EQ(kDefault[2].max_bitrate_bps + 1,
6558 stream->GetVideoStreams()[2].max_bitrate_bps);
6559
6560 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
6561}
6562
6563TEST_F(WebRtcVideoChannelTest,
6564 BandwidthAboveTotalMaxBitrateNotGivenToMaxLayerIfMaxBitrateSet) {
6565 const size_t kNumSimulcastStreams = 3;
6566 const std::vector<webrtc::VideoStream> kDefault = GetSimulcastBitrates720p();
6567 EXPECT_EQ(kNumSimulcastStreams, kDefault.size());
6568 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
6569
6570 // Send a full size frame so all simulcast layers are used when reconfiguring.
Niels Möller805a27e2019-01-21 12:21:27 +01006571 webrtc::test::FrameForwarder frame_forwarder;
Åsa Persson55659812018-06-18 17:51:32 +02006572 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01006573 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
Åsa Persson55659812018-06-18 17:51:32 +02006574 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01006575 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Åsa Persson55659812018-06-18 17:51:32 +02006576
6577 // Set max bitrate for the highest layer.
6578 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6579 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6580 parameters.encodings[2].max_bitrate_bps = kDefault[2].max_bitrate_bps;
6581 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6582
6583 // Set max bandwidth above the total max bitrate.
6584 send_parameters_.max_bandwidth_bps =
6585 GetTotalMaxBitrateBps(stream->GetVideoStreams()) + 1;
6586 ExpectSetMaxBitrate(send_parameters_.max_bandwidth_bps);
6587 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
6588
6589 // The highest layer has the max bitrate set -> the bitrate above the total
6590 // max should not be given to the highest layer.
6591 EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
6592 EXPECT_EQ(*parameters.encodings[2].max_bitrate_bps,
6593 stream->GetVideoStreams()[2].max_bitrate_bps);
6594
6595 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
6596}
6597
Åsa Perssonbdee46d2018-06-25 11:28:06 +02006598// Test that min and max bitrate values set via RtpParameters are correctly
6599// propagated to the underlying encoder for a single stream.
6600TEST_F(WebRtcVideoChannelTest, MinAndMaxBitratePropagatedToEncoder) {
6601 FakeVideoSendStream* stream = AddSendStream();
6602 EXPECT_TRUE(channel_->SetSend(true));
6603 EXPECT_TRUE(stream->IsSending());
6604
6605 // Set min and max bitrate.
6606 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6607 EXPECT_EQ(1u, parameters.encodings.size());
6608 parameters.encodings[0].min_bitrate_bps = 80000;
6609 parameters.encodings[0].max_bitrate_bps = 150000;
6610 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6611
6612 // Check that WebRtcVideoSendStream updates VideoEncoderConfig correctly.
6613 webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
6614 EXPECT_EQ(1u, encoder_config.number_of_streams);
6615 EXPECT_EQ(1u, encoder_config.simulcast_layers.size());
6616 EXPECT_EQ(80000, encoder_config.simulcast_layers[0].min_bitrate_bps);
6617 EXPECT_EQ(150000, encoder_config.simulcast_layers[0].max_bitrate_bps);
6618
6619 // FakeVideoSendStream calls CreateEncoderStreams, test that the vector of
6620 // VideoStreams are created appropriately.
6621 EXPECT_EQ(1u, stream->GetVideoStreams().size());
6622 EXPECT_EQ(80000, stream->GetVideoStreams()[0].min_bitrate_bps);
6623 EXPECT_EQ(150000, stream->GetVideoStreams()[0].target_bitrate_bps);
6624 EXPECT_EQ(150000, stream->GetVideoStreams()[0].max_bitrate_bps);
6625}
6626
6627// Test the default min and max bitrate value are correctly propagated to the
6628// underlying encoder for a single stream (when the values are not set via
6629// RtpParameters).
6630TEST_F(WebRtcVideoChannelTest, DefaultMinAndMaxBitratePropagatedToEncoder) {
6631 FakeVideoSendStream* stream = AddSendStream();
6632 EXPECT_TRUE(channel_->SetSend(true));
6633 EXPECT_TRUE(stream->IsSending());
6634
6635 // Check that WebRtcVideoSendStream updates VideoEncoderConfig correctly.
6636 webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
6637 EXPECT_EQ(1u, encoder_config.number_of_streams);
6638 EXPECT_EQ(1u, encoder_config.simulcast_layers.size());
6639 EXPECT_EQ(-1, encoder_config.simulcast_layers[0].min_bitrate_bps);
6640 EXPECT_EQ(-1, encoder_config.simulcast_layers[0].max_bitrate_bps);
6641
6642 // FakeVideoSendStream calls CreateEncoderStreams, test that the vector of
6643 // VideoStreams are created appropriately.
6644 EXPECT_EQ(1u, stream->GetVideoStreams().size());
6645 EXPECT_EQ(cricket::kMinVideoBitrateBps,
6646 stream->GetVideoStreams()[0].min_bitrate_bps);
6647 EXPECT_GT(stream->GetVideoStreams()[0].max_bitrate_bps,
6648 stream->GetVideoStreams()[0].min_bitrate_bps);
6649 EXPECT_EQ(stream->GetVideoStreams()[0].max_bitrate_bps,
6650 stream->GetVideoStreams()[0].target_bitrate_bps);
6651}
6652
Taylor Brandstetter14b9d792016-09-07 17:16:54 -07006653// Test that a stream will not be sending if its encoding is made inactive
6654// through SetRtpSendParameters.
Seth Hampson8234ead2018-02-02 15:16:24 -08006655TEST_F(WebRtcVideoChannelTest, SetRtpSendParametersOneEncodingActive) {
deadbeefdbe2b872016-03-22 15:42:00 -07006656 FakeVideoSendStream* stream = AddSendStream();
6657 EXPECT_TRUE(channel_->SetSend(true));
6658 EXPECT_TRUE(stream->IsSending());
6659
6660 // Get current parameters and change "active" to false.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07006661 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
deadbeefdbe2b872016-03-22 15:42:00 -07006662 ASSERT_EQ(1u, parameters.encodings.size());
6663 ASSERT_TRUE(parameters.encodings[0].active);
6664 parameters.encodings[0].active = false;
Zach Steinba37b4b2018-01-23 15:02:36 -08006665 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
deadbeefdbe2b872016-03-22 15:42:00 -07006666 EXPECT_FALSE(stream->IsSending());
6667
6668 // Now change it back to active and verify we resume sending.
6669 parameters.encodings[0].active = true;
Zach Steinba37b4b2018-01-23 15:02:36 -08006670 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
deadbeefdbe2b872016-03-22 15:42:00 -07006671 EXPECT_TRUE(stream->IsSending());
6672}
6673
Seth Hampson8234ead2018-02-02 15:16:24 -08006674// Tests that when active is updated for any simulcast layer then the send
6675// stream's sending state will be updated and it will be reconfigured with the
6676// new appropriate active simulcast streams.
6677TEST_F(WebRtcVideoChannelTest, SetRtpSendParametersMultipleEncodingsActive) {
6678 // Create the stream params with multiple ssrcs for simulcast.
Åsa Persson31cb8f92018-06-27 10:44:56 +02006679 const size_t kNumSimulcastStreams = 3;
Seth Hampson8234ead2018-02-02 15:16:24 -08006680 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
6681 StreamParams stream_params = CreateSimStreamParams("cname", ssrcs);
6682 FakeVideoSendStream* fake_video_send_stream = AddSendStream(stream_params);
6683 uint32_t primary_ssrc = stream_params.first_ssrc();
6684
Niels Möller805a27e2019-01-21 12:21:27 +01006685 // Using the FrameForwarder, we manually send a full size
Tommi85959932018-02-07 19:26:06 +01006686 // frame. This allows us to test that ReconfigureEncoder is called
6687 // appropriately.
Niels Möller805a27e2019-01-21 12:21:27 +01006688 webrtc::test::FrameForwarder frame_forwarder;
Seth Hampson8234ead2018-02-02 15:16:24 -08006689 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01006690 EXPECT_TRUE(channel_->SetVideoSend(primary_ssrc, &options, &frame_forwarder));
Seth Hampson8234ead2018-02-02 15:16:24 -08006691 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01006692 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame(
6693 1920, 1080, webrtc::VideoRotation::kVideoRotation_0,
6694 rtc::kNumMicrosecsPerSec / 30));
Seth Hampson8234ead2018-02-02 15:16:24 -08006695
6696 // Check that all encodings are initially active.
6697 webrtc::RtpParameters parameters =
6698 channel_->GetRtpSendParameters(primary_ssrc);
Åsa Persson31cb8f92018-06-27 10:44:56 +02006699 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
Seth Hampson8234ead2018-02-02 15:16:24 -08006700 EXPECT_TRUE(parameters.encodings[0].active);
6701 EXPECT_TRUE(parameters.encodings[1].active);
6702 EXPECT_TRUE(parameters.encodings[2].active);
6703 EXPECT_TRUE(fake_video_send_stream->IsSending());
6704
6705 // Only turn on only the middle stream.
6706 parameters.encodings[0].active = false;
6707 parameters.encodings[1].active = true;
6708 parameters.encodings[2].active = false;
6709 EXPECT_TRUE(channel_->SetRtpSendParameters(primary_ssrc, parameters).ok());
6710 // Verify that the active fields are set on the VideoChannel.
6711 parameters = channel_->GetRtpSendParameters(primary_ssrc);
Åsa Persson31cb8f92018-06-27 10:44:56 +02006712 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
Seth Hampson8234ead2018-02-02 15:16:24 -08006713 EXPECT_FALSE(parameters.encodings[0].active);
6714 EXPECT_TRUE(parameters.encodings[1].active);
6715 EXPECT_FALSE(parameters.encodings[2].active);
6716 // Check that the VideoSendStream is updated appropriately. This means its
6717 // send state was updated and it was reconfigured.
6718 EXPECT_TRUE(fake_video_send_stream->IsSending());
6719 std::vector<webrtc::VideoStream> simulcast_streams =
6720 fake_video_send_stream->GetVideoStreams();
Åsa Persson31cb8f92018-06-27 10:44:56 +02006721 EXPECT_EQ(kNumSimulcastStreams, simulcast_streams.size());
Seth Hampson8234ead2018-02-02 15:16:24 -08006722 EXPECT_FALSE(simulcast_streams[0].active);
6723 EXPECT_TRUE(simulcast_streams[1].active);
6724 EXPECT_FALSE(simulcast_streams[2].active);
6725
6726 // Turn off all streams.
6727 parameters.encodings[0].active = false;
6728 parameters.encodings[1].active = false;
6729 parameters.encodings[2].active = false;
6730 EXPECT_TRUE(channel_->SetRtpSendParameters(primary_ssrc, parameters).ok());
6731 // Verify that the active fields are set on the VideoChannel.
6732 parameters = channel_->GetRtpSendParameters(primary_ssrc);
Åsa Persson31cb8f92018-06-27 10:44:56 +02006733 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
Seth Hampson8234ead2018-02-02 15:16:24 -08006734 EXPECT_FALSE(parameters.encodings[0].active);
6735 EXPECT_FALSE(parameters.encodings[1].active);
6736 EXPECT_FALSE(parameters.encodings[2].active);
6737 // Check that the VideoSendStream is off.
6738 EXPECT_FALSE(fake_video_send_stream->IsSending());
6739 simulcast_streams = fake_video_send_stream->GetVideoStreams();
Åsa Persson31cb8f92018-06-27 10:44:56 +02006740 EXPECT_EQ(kNumSimulcastStreams, simulcast_streams.size());
Seth Hampson8234ead2018-02-02 15:16:24 -08006741 EXPECT_FALSE(simulcast_streams[0].active);
6742 EXPECT_FALSE(simulcast_streams[1].active);
6743 EXPECT_FALSE(simulcast_streams[2].active);
6744
Niels Möllerff40b142018-04-09 08:49:14 +02006745 EXPECT_TRUE(channel_->SetVideoSend(primary_ssrc, nullptr, nullptr));
Seth Hampson8234ead2018-02-02 15:16:24 -08006746}
6747
Taylor Brandstetter14b9d792016-09-07 17:16:54 -07006748// Test that if a stream is reconfigured (due to a codec change or other
6749// change) while its encoding is still inactive, it doesn't start sending.
eladalonf1841382017-06-12 01:16:46 -07006750TEST_F(WebRtcVideoChannelTest,
Taylor Brandstetter14b9d792016-09-07 17:16:54 -07006751 InactiveStreamDoesntStartSendingWhenReconfigured) {
6752 // Set an initial codec list, which will be modified later.
6753 cricket::VideoSendParameters parameters1;
magjed509e4fe2016-11-18 01:34:11 -08006754 parameters1.codecs.push_back(GetEngineCodec("VP8"));
6755 parameters1.codecs.push_back(GetEngineCodec("VP9"));
Taylor Brandstetter14b9d792016-09-07 17:16:54 -07006756 EXPECT_TRUE(channel_->SetSendParameters(parameters1));
6757
6758 FakeVideoSendStream* stream = AddSendStream();
6759 EXPECT_TRUE(channel_->SetSend(true));
6760 EXPECT_TRUE(stream->IsSending());
6761
6762 // Get current parameters and change "active" to false.
6763 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6764 ASSERT_EQ(1u, parameters.encodings.size());
6765 ASSERT_TRUE(parameters.encodings[0].active);
6766 parameters.encodings[0].active = false;
6767 EXPECT_EQ(1u, GetFakeSendStreams().size());
6768 EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());
Zach Steinba37b4b2018-01-23 15:02:36 -08006769 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
Taylor Brandstetter14b9d792016-09-07 17:16:54 -07006770 EXPECT_FALSE(stream->IsSending());
6771
6772 // Reorder the codec list, causing the stream to be reconfigured.
6773 cricket::VideoSendParameters parameters2;
magjed509e4fe2016-11-18 01:34:11 -08006774 parameters2.codecs.push_back(GetEngineCodec("VP9"));
6775 parameters2.codecs.push_back(GetEngineCodec("VP8"));
Taylor Brandstetter14b9d792016-09-07 17:16:54 -07006776 EXPECT_TRUE(channel_->SetSendParameters(parameters2));
6777 auto new_streams = GetFakeSendStreams();
6778 // Assert that a new underlying stream was created due to the codec change.
6779 // Otherwise, this test isn't testing what it set out to test.
6780 EXPECT_EQ(1u, GetFakeSendStreams().size());
6781 EXPECT_EQ(2, fake_call_->GetNumCreatedSendStreams());
6782
6783 // Verify that we still are not sending anything, due to the inactive
6784 // encoding.
6785 EXPECT_FALSE(new_streams[0]->IsSending());
6786}
6787
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07006788// Test that GetRtpSendParameters returns the currently configured codecs.
eladalonf1841382017-06-12 01:16:46 -07006789TEST_F(WebRtcVideoChannelTest, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07006790 AddSendStream();
6791 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08006792 parameters.codecs.push_back(GetEngineCodec("VP8"));
6793 parameters.codecs.push_back(GetEngineCodec("VP9"));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07006794 EXPECT_TRUE(channel_->SetSendParameters(parameters));
6795
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07006796 webrtc::RtpParameters rtp_parameters =
6797 channel_->GetRtpSendParameters(last_ssrc_);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07006798 ASSERT_EQ(2u, rtp_parameters.codecs.size());
magjed509e4fe2016-11-18 01:34:11 -08006799 EXPECT_EQ(GetEngineCodec("VP8").ToCodecParameters(),
6800 rtp_parameters.codecs[0]);
6801 EXPECT_EQ(GetEngineCodec("VP9").ToCodecParameters(),
6802 rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07006803}
6804
Florent Castellidacec712018-05-24 16:24:21 +02006805// Test that GetRtpSendParameters returns the currently configured RTCP CNAME.
6806TEST_F(WebRtcVideoChannelTest, GetRtpSendParametersRtcpCname) {
6807 StreamParams params = StreamParams::CreateLegacy(kSsrc);
6808 params.cname = "rtcpcname";
6809 AddSendStream(params);
6810
6811 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrc);
6812 EXPECT_STREQ("rtcpcname", rtp_parameters.rtcp.cname.c_str());
6813}
6814
deadbeeffb2aced2017-01-06 23:05:37 -08006815// Test that RtpParameters for send stream has one encoding and it has
6816// the correct SSRC.
eladalonf1841382017-06-12 01:16:46 -07006817TEST_F(WebRtcVideoChannelTest, GetRtpSendParametersSsrc) {
deadbeeffb2aced2017-01-06 23:05:37 -08006818 AddSendStream();
6819
6820 webrtc::RtpParameters rtp_parameters =
6821 channel_->GetRtpSendParameters(last_ssrc_);
6822 ASSERT_EQ(1u, rtp_parameters.encodings.size());
Oskar Sundbom78807582017-11-16 11:09:55 +01006823 EXPECT_EQ(last_ssrc_, rtp_parameters.encodings[0].ssrc);
deadbeeffb2aced2017-01-06 23:05:37 -08006824}
6825
Florent Castelliabe301f2018-06-12 18:33:49 +02006826TEST_F(WebRtcVideoChannelTest, DetectRtpSendParameterHeaderExtensionsChange) {
6827 AddSendStream();
6828
6829 webrtc::RtpParameters rtp_parameters =
6830 channel_->GetRtpSendParameters(last_ssrc_);
6831 rtp_parameters.header_extensions.emplace_back();
6832
6833 EXPECT_NE(0u, rtp_parameters.header_extensions.size());
6834
6835 webrtc::RTCError result =
6836 channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
6837 EXPECT_EQ(webrtc::RTCErrorType::INVALID_MODIFICATION, result.type());
6838}
6839
Florent Castelli87b3c512018-07-18 16:00:28 +02006840TEST_F(WebRtcVideoChannelTest, GetRtpSendParametersDegradationPreference) {
6841 AddSendStream();
6842
Niels Möller805a27e2019-01-21 12:21:27 +01006843 webrtc::test::FrameForwarder frame_forwarder;
6844 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));
Florent Castelli87b3c512018-07-18 16:00:28 +02006845
6846 webrtc::RtpParameters rtp_parameters =
6847 channel_->GetRtpSendParameters(last_ssrc_);
6848 EXPECT_EQ(rtp_parameters.degradation_preference,
6849 webrtc::DegradationPreference::BALANCED);
6850 rtp_parameters.degradation_preference =
6851 webrtc::DegradationPreference::MAINTAIN_FRAMERATE;
6852
6853 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters).ok());
6854
6855 webrtc::RtpParameters updated_rtp_parameters =
6856 channel_->GetRtpSendParameters(last_ssrc_);
6857 EXPECT_EQ(updated_rtp_parameters.degradation_preference,
6858 webrtc::DegradationPreference::MAINTAIN_FRAMERATE);
6859
6860 // Remove the source since it will be destroyed before the channel
6861 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
6862}
6863
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07006864// Test that if we set/get parameters multiple times, we get the same results.
eladalonf1841382017-06-12 01:16:46 -07006865TEST_F(WebRtcVideoChannelTest, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07006866 AddSendStream();
6867 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08006868 parameters.codecs.push_back(GetEngineCodec("VP8"));
6869 parameters.codecs.push_back(GetEngineCodec("VP9"));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07006870 EXPECT_TRUE(channel_->SetSendParameters(parameters));
6871
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07006872 webrtc::RtpParameters initial_params =
6873 channel_->GetRtpSendParameters(last_ssrc_);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07006874
6875 // We should be able to set the params we just got.
Zach Steinba37b4b2018-01-23 15:02:36 -08006876 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, initial_params).ok());
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07006877
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07006878 // ... And this shouldn't change the params returned by GetRtpSendParameters.
6879 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(last_ssrc_));
6880}
6881
6882// Test that GetRtpReceiveParameters returns the currently configured codecs.
eladalonf1841382017-06-12 01:16:46 -07006883TEST_F(WebRtcVideoChannelTest, GetRtpReceiveParametersCodecs) {
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07006884 AddRecvStream();
6885 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08006886 parameters.codecs.push_back(GetEngineCodec("VP8"));
6887 parameters.codecs.push_back(GetEngineCodec("VP9"));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07006888 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
6889
6890 webrtc::RtpParameters rtp_parameters =
6891 channel_->GetRtpReceiveParameters(last_ssrc_);
6892 ASSERT_EQ(2u, rtp_parameters.codecs.size());
magjed509e4fe2016-11-18 01:34:11 -08006893 EXPECT_EQ(GetEngineCodec("VP8").ToCodecParameters(),
6894 rtp_parameters.codecs[0]);
6895 EXPECT_EQ(GetEngineCodec("VP9").ToCodecParameters(),
6896 rtp_parameters.codecs[1]);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07006897}
6898
johan073ece42016-08-26 02:59:47 -07006899#if defined(WEBRTC_USE_H264)
eladalonf1841382017-06-12 01:16:46 -07006900TEST_F(WebRtcVideoChannelTest, GetRtpReceiveFmtpSprop) {
johan073ece42016-08-26 02:59:47 -07006901#else
eladalonf1841382017-06-12 01:16:46 -07006902TEST_F(WebRtcVideoChannelTest, DISABLED_GetRtpReceiveFmtpSprop) {
johan073ece42016-08-26 02:59:47 -07006903#endif
johan3859c892016-08-05 09:19:25 -07006904 cricket::VideoRecvParameters parameters;
perkj26752742016-10-24 01:21:16 -07006905 cricket::VideoCodec kH264sprop1(101, "H264");
magjed5dfac562016-11-25 03:56:37 -08006906 kH264sprop1.SetParam(kH264FmtpSpropParameterSets, "uvw");
johan3859c892016-08-05 09:19:25 -07006907 parameters.codecs.push_back(kH264sprop1);
perkj26752742016-10-24 01:21:16 -07006908 cricket::VideoCodec kH264sprop2(102, "H264");
magjed5dfac562016-11-25 03:56:37 -08006909 kH264sprop2.SetParam(kH264FmtpSpropParameterSets, "xyz");
johan3859c892016-08-05 09:19:25 -07006910 parameters.codecs.push_back(kH264sprop2);
6911 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
6912
6913 FakeVideoReceiveStream* recv_stream = AddRecvStream();
6914 const webrtc::VideoReceiveStream::Config& cfg = recv_stream->GetConfig();
6915 webrtc::RtpParameters rtp_parameters =
6916 channel_->GetRtpReceiveParameters(last_ssrc_);
6917 ASSERT_EQ(2u, rtp_parameters.codecs.size());
6918 EXPECT_EQ(kH264sprop1.ToCodecParameters(), rtp_parameters.codecs[0]);
6919 ASSERT_EQ(2u, cfg.decoders.size());
6920 EXPECT_EQ(101, cfg.decoders[0].payload_type);
Niels Möllercb7e1d22018-09-11 15:56:04 +02006921 EXPECT_EQ("H264", cfg.decoders[0].video_format.name);
magjed5dfac562016-11-25 03:56:37 -08006922 const auto it0 =
Niels Möllercb7e1d22018-09-11 15:56:04 +02006923 cfg.decoders[0].video_format.parameters.find(kH264FmtpSpropParameterSets);
6924 ASSERT_TRUE(it0 != cfg.decoders[0].video_format.parameters.end());
magjed5dfac562016-11-25 03:56:37 -08006925 EXPECT_EQ("uvw", it0->second);
johan3859c892016-08-05 09:19:25 -07006926
6927 EXPECT_EQ(102, cfg.decoders[1].payload_type);
Niels Möllercb7e1d22018-09-11 15:56:04 +02006928 EXPECT_EQ("H264", cfg.decoders[1].video_format.name);
magjed5dfac562016-11-25 03:56:37 -08006929 const auto it1 =
Niels Möllercb7e1d22018-09-11 15:56:04 +02006930 cfg.decoders[1].video_format.parameters.find(kH264FmtpSpropParameterSets);
6931 ASSERT_TRUE(it1 != cfg.decoders[1].video_format.parameters.end());
magjed5dfac562016-11-25 03:56:37 -08006932 EXPECT_EQ("xyz", it1->second);
johan3859c892016-08-05 09:19:25 -07006933}
6934
sakal1fd95952016-06-22 00:46:15 -07006935// Test that RtpParameters for receive stream has one encoding and it has
6936// the correct SSRC.
eladalonf1841382017-06-12 01:16:46 -07006937TEST_F(WebRtcVideoChannelTest, GetRtpReceiveParametersSsrc) {
sakal1fd95952016-06-22 00:46:15 -07006938 AddRecvStream();
6939
6940 webrtc::RtpParameters rtp_parameters =
6941 channel_->GetRtpReceiveParameters(last_ssrc_);
6942 ASSERT_EQ(1u, rtp_parameters.encodings.size());
Oskar Sundbom78807582017-11-16 11:09:55 +01006943 EXPECT_EQ(last_ssrc_, rtp_parameters.encodings[0].ssrc);
sakal1fd95952016-06-22 00:46:15 -07006944}
6945
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07006946// Test that if we set/get parameters multiple times, we get the same results.
eladalonf1841382017-06-12 01:16:46 -07006947TEST_F(WebRtcVideoChannelTest, SetAndGetRtpReceiveParameters) {
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07006948 AddRecvStream();
6949 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08006950 parameters.codecs.push_back(GetEngineCodec("VP8"));
6951 parameters.codecs.push_back(GetEngineCodec("VP9"));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07006952 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
6953
6954 webrtc::RtpParameters initial_params =
6955 channel_->GetRtpReceiveParameters(last_ssrc_);
6956
6957 // We should be able to set the params we just got.
6958 EXPECT_TRUE(channel_->SetRtpReceiveParameters(last_ssrc_, initial_params));
6959
6960 // ... And this shouldn't change the params returned by
6961 // GetRtpReceiveParameters.
6962 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(last_ssrc_));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07006963}
6964
deadbeef3bc15102017-04-20 19:25:07 -07006965// Test that GetRtpReceiveParameters returns parameters correctly when SSRCs
6966// aren't signaled. It should always return an empty "RtpEncodingParameters",
6967// even after a packet is received and the unsignaled SSRC is known.
eladalonf1841382017-06-12 01:16:46 -07006968TEST_F(WebRtcVideoChannelTest, GetRtpReceiveParametersWithUnsignaledSsrc) {
deadbeef3bc15102017-04-20 19:25:07 -07006969 // Call necessary methods to configure receiving a default stream as
6970 // soon as it arrives.
6971 cricket::VideoRecvParameters parameters;
6972 parameters.codecs.push_back(GetEngineCodec("VP8"));
6973 parameters.codecs.push_back(GetEngineCodec("VP9"));
6974 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
6975
6976 // Call GetRtpReceiveParameters before configured to receive an unsignaled
6977 // stream. Should return nothing.
6978 EXPECT_EQ(webrtc::RtpParameters(), channel_->GetRtpReceiveParameters(0));
6979
6980 // Set a sink for an unsignaled stream.
6981 cricket::FakeVideoRenderer renderer;
6982 // Value of "0" means "unsignaled stream".
6983 EXPECT_TRUE(channel_->SetSink(0, &renderer));
6984
6985 // Call GetRtpReceiveParameters before the SSRC is known. Value of "0"
6986 // in this method means "unsignaled stream".
6987 webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(0);
6988 ASSERT_EQ(1u, rtp_parameters.encodings.size());
6989 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
6990
6991 // Receive VP8 packet.
6992 uint8_t data[kMinRtpPacketLen];
6993 cricket::RtpHeader rtpHeader;
6994 rtpHeader.payload_type = GetEngineCodec("VP8").id;
6995 rtpHeader.seq_num = rtpHeader.timestamp = 0;
6996 rtpHeader.ssrc = kIncomingUnsignalledSsrc;
6997 cricket::SetRtpHeader(data, sizeof(data), rtpHeader);
6998 rtc::CopyOnWriteBuffer packet(data, sizeof(data));
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07006999 channel_->OnPacketReceived(packet, /* packet_time_us */ -1);
deadbeef3bc15102017-04-20 19:25:07 -07007000
7001 // The |ssrc| member should still be unset.
7002 rtp_parameters = channel_->GetRtpReceiveParameters(0);
7003 ASSERT_EQ(1u, rtp_parameters.encodings.size());
7004 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
7005}
7006
eladalonf1841382017-06-12 01:16:46 -07007007void WebRtcVideoChannelTest::TestReceiverLocalSsrcConfiguration(
Peter Boström3548dd22015-05-22 18:48:36 +02007008 bool receiver_first) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02007009 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Peter Boström3548dd22015-05-22 18:48:36 +02007010
7011 const uint32_t kSenderSsrc = 0xC0FFEE;
Peter Boströmdfa28152015-10-21 17:21:10 +02007012 const uint32_t kSecondSenderSsrc = 0xBADCAFE;
Peter Boström3548dd22015-05-22 18:48:36 +02007013 const uint32_t kReceiverSsrc = 0x4711;
Peter Boströmdfa28152015-10-21 17:21:10 +02007014 const uint32_t kExpectedDefaultReceiverSsrc = 1;
Peter Boström3548dd22015-05-22 18:48:36 +02007015
7016 if (receiver_first) {
7017 AddRecvStream(StreamParams::CreateLegacy(kReceiverSsrc));
7018 std::vector<FakeVideoReceiveStream*> receive_streams =
7019 fake_call_->GetVideoReceiveStreams();
7020 ASSERT_EQ(1u, receive_streams.size());
Peter Boströmdfa28152015-10-21 17:21:10 +02007021 // Default local SSRC when we have no sender.
7022 EXPECT_EQ(kExpectedDefaultReceiverSsrc,
7023 receive_streams[0]->GetConfig().rtp.local_ssrc);
Peter Boström3548dd22015-05-22 18:48:36 +02007024 }
7025 AddSendStream(StreamParams::CreateLegacy(kSenderSsrc));
7026 if (!receiver_first)
7027 AddRecvStream(StreamParams::CreateLegacy(kReceiverSsrc));
7028 std::vector<FakeVideoReceiveStream*> receive_streams =
7029 fake_call_->GetVideoReceiveStreams();
7030 ASSERT_EQ(1u, receive_streams.size());
7031 EXPECT_EQ(kSenderSsrc, receive_streams[0]->GetConfig().rtp.local_ssrc);
Peter Boströmdfa28152015-10-21 17:21:10 +02007032
7033 // Removing first sender should fall back to another (in this case the second)
7034 // local send stream's SSRC.
7035 AddSendStream(StreamParams::CreateLegacy(kSecondSenderSsrc));
7036 ASSERT_TRUE(channel_->RemoveSendStream(kSenderSsrc));
Yves Gerey665174f2018-06-19 15:03:05 +02007037 receive_streams = fake_call_->GetVideoReceiveStreams();
Peter Boströmdfa28152015-10-21 17:21:10 +02007038 ASSERT_EQ(1u, receive_streams.size());
7039 EXPECT_EQ(kSecondSenderSsrc, receive_streams[0]->GetConfig().rtp.local_ssrc);
7040
7041 // Removing the last sender should fall back to default local SSRC.
7042 ASSERT_TRUE(channel_->RemoveSendStream(kSecondSenderSsrc));
Yves Gerey665174f2018-06-19 15:03:05 +02007043 receive_streams = fake_call_->GetVideoReceiveStreams();
Peter Boströmdfa28152015-10-21 17:21:10 +02007044 ASSERT_EQ(1u, receive_streams.size());
7045 EXPECT_EQ(kExpectedDefaultReceiverSsrc,
7046 receive_streams[0]->GetConfig().rtp.local_ssrc);
Peter Boström3548dd22015-05-22 18:48:36 +02007047}
7048
eladalonf1841382017-06-12 01:16:46 -07007049TEST_F(WebRtcVideoChannelTest, ConfiguresLocalSsrc) {
Peter Boström3548dd22015-05-22 18:48:36 +02007050 TestReceiverLocalSsrcConfiguration(false);
7051}
7052
eladalonf1841382017-06-12 01:16:46 -07007053TEST_F(WebRtcVideoChannelTest, ConfiguresLocalSsrcOnExistingReceivers) {
Peter Boström3548dd22015-05-22 18:48:36 +02007054 TestReceiverLocalSsrcConfiguration(true);
7055}
7056
eladalonf1841382017-06-12 01:16:46 -07007057class WebRtcVideoChannelSimulcastTest : public testing::Test {
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007058 public:
eladalonf1841382017-06-12 01:16:46 -07007059 WebRtcVideoChannelSimulcastTest()
Sebastian Jansson8f83b422018-02-21 13:07:13 +01007060 : fake_call_(),
Magnus Jedvert02e7a192017-09-23 17:21:32 +02007061 encoder_factory_(new cricket::FakeWebRtcVideoEncoderFactory),
7062 decoder_factory_(new cricket::FakeWebRtcVideoDecoderFactory),
Jiawei Ouc2ebe212018-11-08 10:02:56 -08007063 mock_rate_allocator_factory_(
7064 new webrtc::MockVideoBitrateAllocatorFactory),
Anders Carlsson67537952018-05-03 11:28:29 +02007065 engine_(std::unique_ptr<cricket::FakeWebRtcVideoEncoderFactory>(
Magnus Jedvert02e7a192017-09-23 17:21:32 +02007066 encoder_factory_),
Anders Carlsson67537952018-05-03 11:28:29 +02007067 std::unique_ptr<cricket::FakeWebRtcVideoDecoderFactory>(
Jiawei Ouc2ebe212018-11-08 10:02:56 -08007068 decoder_factory_),
7069 std::unique_ptr<webrtc::VideoBitrateAllocatorFactory>(
7070 mock_rate_allocator_factory_)),
magjed2475ae22017-09-12 04:42:15 -07007071 last_ssrc_(0) {}
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007072
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00007073 void SetUp() override {
Anders Carlsson5f2bb622018-05-14 09:48:06 +02007074 encoder_factory_->AddSupportedVideoCodecType("VP8");
Sebastian Jansson84848f22018-11-16 10:40:36 +01007075 channel_.reset(engine_.CreateMediaChannel(&fake_call_, GetMediaConfig(),
7076 VideoOptions(),
7077 webrtc::CryptoOptions()));
Sergey Ulanove2b15012016-11-22 16:08:30 -08007078 channel_->OnReadyToSend(true);
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007079 last_ssrc_ = 123;
7080 }
7081
7082 protected:
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007083 void VerifySimulcastSettings(const VideoCodec& codec,
perkj26752742016-10-24 01:21:16 -07007084 int capture_width,
7085 int capture_height,
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007086 size_t num_configured_streams,
sprang429600d2017-01-26 06:12:26 -08007087 size_t expected_num_streams,
7088 bool screenshare,
7089 bool conference_mode) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02007090 cricket::VideoSendParameters parameters;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02007091 parameters.codecs.push_back(codec);
sprang429600d2017-01-26 06:12:26 -08007092 parameters.conference_mode = conference_mode;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02007093 ASSERT_TRUE(channel_->SetSendParameters(parameters));
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007094
Peter Boström0c4e06b2015-10-07 12:23:21 +02007095 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
henrikg91d6ede2015-09-17 00:24:34 -07007096 RTC_DCHECK(num_configured_streams <= ssrcs.size());
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007097 ssrcs.resize(num_configured_streams);
7098
sprangf24a0642017-02-28 13:23:26 -08007099 AddSendStream(CreateSimStreamParams("cname", ssrcs));
pbos@webrtc.org86196c42015-02-16 21:02:00 +00007100 // Send a full-size frame to trigger a stream reconfiguration to use all
7101 // expected simulcast layers.
Niels Möller805a27e2019-01-21 12:21:27 +01007102 webrtc::test::FrameForwarder frame_forwarder;
7103 cricket::FakeFrameSource frame_source(capture_width, capture_height,
7104 rtc::kNumMicrosecsPerSec / 30);
7105
sprangf24a0642017-02-28 13:23:26 -08007106 VideoOptions options;
7107 if (screenshare)
Oskar Sundbom78807582017-11-16 11:09:55 +01007108 options.is_screencast = screenshare;
Niels Möller805a27e2019-01-21 12:21:27 +01007109 EXPECT_TRUE(
7110 channel_->SetVideoSend(ssrcs.front(), &options, &frame_forwarder));
sprangf24a0642017-02-28 13:23:26 -08007111 // Fetch the latest stream since SetVideoSend() may recreate it if the
7112 // screen content setting is changed.
7113 FakeVideoSendStream* stream = fake_call_.GetVideoSendStreams().front();
pbos@webrtc.org86196c42015-02-16 21:02:00 +00007114 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01007115 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007116
Zach Stein3ca452b2018-01-18 10:01:24 -08007117 auto rtp_parameters = channel_->GetRtpSendParameters(kSsrcs3[0]);
7118 EXPECT_EQ(num_configured_streams, rtp_parameters.encodings.size());
7119
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007120 std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
7121 ASSERT_EQ(expected_num_streams, video_streams.size());
Ilya Nikolaevskiy33d2a912019-04-02 11:05:03 +02007122 EXPECT_LE(expected_num_streams, stream->GetConfig().rtp.ssrcs.size());
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007123
sprang429600d2017-01-26 06:12:26 -08007124 std::vector<webrtc::VideoStream> expected_streams;
7125 if (conference_mode) {
7126 expected_streams = GetSimulcastConfig(
7127 num_configured_streams, capture_width, capture_height, 0,
Seth Hampson24722b32017-12-22 09:36:42 -08007128 webrtc::kDefaultBitratePriority, kDefaultQpMax,
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +02007129 kDefaultVideoMaxFramerate, screenshare, true);
sprang3ebabf12017-02-16 07:35:22 -08007130 if (screenshare) {
7131 for (const webrtc::VideoStream& stream : expected_streams) {
7132 // Never scale screen content.
Danil Chapovalov350531e2018-06-08 11:04:04 +00007133 EXPECT_EQ(stream.width, rtc::checked_cast<size_t>(capture_width));
7134 EXPECT_EQ(stream.height, rtc::checked_cast<size_t>(capture_height));
sprang3ebabf12017-02-16 07:35:22 -08007135 }
7136 }
sprang429600d2017-01-26 06:12:26 -08007137 } else {
7138 webrtc::VideoStream stream;
7139 stream.width = capture_width;
7140 stream.height = capture_height;
7141 stream.max_framerate = kDefaultVideoMaxFramerate;
Åsa Persson45bbc8a2017-11-13 10:16:47 +01007142 stream.min_bitrate_bps = cricket::kMinVideoBitrateBps;
sprang429600d2017-01-26 06:12:26 -08007143 stream.target_bitrate_bps = stream.max_bitrate_bps =
Åsa Perssonbdee46d2018-06-25 11:28:06 +02007144 GetMaxDefaultBitrateBps(capture_width, capture_height);
sprang429600d2017-01-26 06:12:26 -08007145 stream.max_qp = kDefaultQpMax;
7146 expected_streams.push_back(stream);
7147 }
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007148
7149 ASSERT_EQ(expected_streams.size(), video_streams.size());
7150
7151 size_t num_streams = video_streams.size();
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00007152 int total_max_bitrate_bps = 0;
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007153 for (size_t i = 0; i < num_streams; ++i) {
7154 EXPECT_EQ(expected_streams[i].width, video_streams[i].width);
7155 EXPECT_EQ(expected_streams[i].height, video_streams[i].height);
7156
7157 EXPECT_GT(video_streams[i].max_framerate, 0);
7158 EXPECT_EQ(expected_streams[i].max_framerate,
7159 video_streams[i].max_framerate);
7160
7161 EXPECT_GT(video_streams[i].min_bitrate_bps, 0);
7162 EXPECT_EQ(expected_streams[i].min_bitrate_bps,
7163 video_streams[i].min_bitrate_bps);
7164
7165 EXPECT_GT(video_streams[i].target_bitrate_bps, 0);
7166 EXPECT_EQ(expected_streams[i].target_bitrate_bps,
7167 video_streams[i].target_bitrate_bps);
7168
7169 EXPECT_GT(video_streams[i].max_bitrate_bps, 0);
7170 EXPECT_EQ(expected_streams[i].max_bitrate_bps,
7171 video_streams[i].max_bitrate_bps);
7172
7173 EXPECT_GT(video_streams[i].max_qp, 0);
7174 EXPECT_EQ(expected_streams[i].max_qp, video_streams[i].max_qp);
7175
Sergey Silkina796a7e2018-03-01 15:11:29 +01007176 EXPECT_EQ(conference_mode,
7177 expected_streams[i].num_temporal_layers.has_value());
7178
7179 if (conference_mode) {
7180 EXPECT_EQ(expected_streams[i].num_temporal_layers,
7181 video_streams[i].num_temporal_layers);
7182 }
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00007183
7184 if (i == num_streams - 1) {
7185 total_max_bitrate_bps += video_streams[i].max_bitrate_bps;
7186 } else {
7187 total_max_bitrate_bps += video_streams[i].target_bitrate_bps;
7188 }
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007189 }
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00007190
Niels Möllerff40b142018-04-09 08:49:14 +02007191 EXPECT_TRUE(channel_->SetVideoSend(ssrcs.front(), nullptr, nullptr));
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007192 }
7193
7194 FakeVideoSendStream* AddSendStream() {
7195 return AddSendStream(StreamParams::CreateLegacy(last_ssrc_++));
7196 }
7197
7198 FakeVideoSendStream* AddSendStream(const StreamParams& sp) {
Yves Gerey665174f2018-06-19 15:03:05 +02007199 size_t num_streams = fake_call_.GetVideoSendStreams().size();
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007200 EXPECT_TRUE(channel_->AddSendStream(sp));
7201 std::vector<FakeVideoSendStream*> streams =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02007202 fake_call_.GetVideoSendStreams();
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007203 EXPECT_EQ(num_streams + 1, streams.size());
7204 return streams[streams.size() - 1];
7205 }
7206
7207 std::vector<FakeVideoSendStream*> GetFakeSendStreams() {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02007208 return fake_call_.GetVideoSendStreams();
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007209 }
7210
7211 FakeVideoReceiveStream* AddRecvStream() {
7212 return AddRecvStream(StreamParams::CreateLegacy(last_ssrc_++));
7213 }
7214
7215 FakeVideoReceiveStream* AddRecvStream(const StreamParams& sp) {
Yves Gerey665174f2018-06-19 15:03:05 +02007216 size_t num_streams = fake_call_.GetVideoReceiveStreams().size();
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007217 EXPECT_TRUE(channel_->AddRecvStream(sp));
7218 std::vector<FakeVideoReceiveStream*> streams =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02007219 fake_call_.GetVideoReceiveStreams();
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007220 EXPECT_EQ(num_streams + 1, streams.size());
7221 return streams[streams.size() - 1];
7222 }
7223
skvlad11a9cbf2016-10-07 11:53:05 -07007224 webrtc::RtcEventLogNullImpl event_log_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +02007225 FakeCall fake_call_;
Magnus Jedvert02e7a192017-09-23 17:21:32 +02007226 cricket::FakeWebRtcVideoEncoderFactory* encoder_factory_;
7227 cricket::FakeWebRtcVideoDecoderFactory* decoder_factory_;
Jiawei Ouc2ebe212018-11-08 10:02:56 -08007228 webrtc::MockVideoBitrateAllocatorFactory* mock_rate_allocator_factory_;
eladalonf1841382017-06-12 01:16:46 -07007229 WebRtcVideoEngine engine_;
kwiberg686a8ef2016-02-26 03:00:35 -08007230 std::unique_ptr<VideoMediaChannel> channel_;
Peter Boström0c4e06b2015-10-07 12:23:21 +02007231 uint32_t last_ssrc_;
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007232};
7233
eladalonf1841382017-06-12 01:16:46 -07007234TEST_F(WebRtcVideoChannelSimulcastTest, SetSendCodecsWith2SimulcastStreams) {
sprang429600d2017-01-26 06:12:26 -08007235 VerifySimulcastSettings(cricket::VideoCodec("VP8"), 640, 360, 2, 2, false,
7236 true);
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007237}
7238
eladalonf1841382017-06-12 01:16:46 -07007239TEST_F(WebRtcVideoChannelSimulcastTest, SetSendCodecsWith3SimulcastStreams) {
sprang429600d2017-01-26 06:12:26 -08007240 VerifySimulcastSettings(cricket::VideoCodec("VP8"), 1280, 720, 3, 3, false,
7241 true);
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007242}
7243
7244// Test that we normalize send codec format size in simulcast.
eladalonf1841382017-06-12 01:16:46 -07007245TEST_F(WebRtcVideoChannelSimulcastTest, SetSendCodecsWithOddSizeInSimulcast) {
sprang429600d2017-01-26 06:12:26 -08007246 VerifySimulcastSettings(cricket::VideoCodec("VP8"), 541, 271, 2, 2, false,
7247 true);
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007248}
sprang429600d2017-01-26 06:12:26 -08007249
Ilya Nikolaevskiy3df1d5d2018-08-22 09:26:51 +02007250TEST_F(WebRtcVideoChannelSimulcastTest, SetSendCodecsForScreenshare) {
Ilya Nikolaevskiy3df1d5d2018-08-22 09:26:51 +02007251 VerifySimulcastSettings(cricket::VideoCodec("VP8"), 1280, 720, 3, 1, true,
7252 false);
7253}
7254
Ilya Nikolaevskiy3df1d5d2018-08-22 09:26:51 +02007255TEST_F(WebRtcVideoChannelSimulcastTest,
7256 SetSendCodecsForConferenceModeScreenshare) {
Erik Språng72e52ee2018-11-29 11:41:53 +01007257 webrtc::test::ScopedFieldTrials field_trials(
7258 "WebRTC-SimulcastScreenshare/Disabled/");
Ilya Nikolaevskiy3df1d5d2018-08-22 09:26:51 +02007259 VerifySimulcastSettings(cricket::VideoCodec("VP8"), 1280, 720, 3, 1, true,
7260 true);
7261}
7262
eladalonf1841382017-06-12 01:16:46 -07007263TEST_F(WebRtcVideoChannelSimulcastTest, SetSendCodecsForSimulcastScreenshare) {
sprang429600d2017-01-26 06:12:26 -08007264 VerifySimulcastSettings(cricket::VideoCodec("VP8"), 1280, 720, 3, 2, true,
7265 true);
7266}
7267
eladalonf1841382017-06-12 01:16:46 -07007268TEST_F(WebRtcVideoChannelSimulcastTest,
sprangfe627f32017-03-29 08:24:59 -07007269 NoSimulcastScreenshareWithoutConference) {
sprangfe627f32017-03-29 08:24:59 -07007270 VerifySimulcastSettings(cricket::VideoCodec("VP8"), 1280, 720, 3, 1, true,
7271 false);
7272}
7273
Yves Gereyb6a89422018-10-08 10:08:32 +02007274class WebRtcVideoFakeClock {
Jonas Oreland49ac5952018-09-26 16:04:32 +02007275 public:
Yves Gereyb6a89422018-10-08 10:08:32 +02007276 WebRtcVideoFakeClock() {
Jonas Oreland49ac5952018-09-26 16:04:32 +02007277 fake_clock_.AdvanceTime(webrtc::TimeDelta::ms(1)); // avoid time=0
7278 }
7279 rtc::ScopedFakeClock fake_clock_;
7280};
7281
Yves Gereyb6a89422018-10-08 10:08:32 +02007282// The fake clock needs to be initialized before the call, and not
7283// destroyed until after all threads spawned by the test have been stopped.
7284// This mixin ensures that.
7285class WebRtcVideoChannelTestWithClock : public WebRtcVideoFakeClock,
7286 public WebRtcVideoChannelBaseTest {};
7287
Jonas Oreland49ac5952018-09-26 16:04:32 +02007288TEST_F(WebRtcVideoChannelTestWithClock, GetSources) {
7289 uint8_t data1[] = {0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
7290 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
7291
7292 EXPECT_EQ(0u, channel_->GetSources(kSsrc).size());
7293
7294 rtc::CopyOnWriteBuffer packet1(data1, sizeof(data1));
7295 rtc::SetBE32(packet1.data() + 8, kSsrc);
7296 channel_->SetSink(kDefaultReceiveSsrc, NULL);
7297 EXPECT_TRUE(SetDefaultCodec());
7298 EXPECT_TRUE(SetSend(true));
7299 EXPECT_EQ(0, renderer_.num_rendered_frames());
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07007300 channel_->OnPacketReceived(packet1, /*packet_time_us=*/-1);
Jonas Oreland49ac5952018-09-26 16:04:32 +02007301
7302 std::vector<webrtc::RtpSource> sources = channel_->GetSources(kSsrc);
7303 EXPECT_EQ(1u, sources.size());
7304 EXPECT_EQ(webrtc::RtpSourceType::SSRC, sources[0].source_type());
7305 int64_t timestamp1 = sources[0].timestamp_ms();
7306
7307 // a new packet.
7308 int64_t timeDeltaMs = 1;
7309 fake_clock_.AdvanceTime(webrtc::TimeDelta::ms(timeDeltaMs));
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07007310 channel_->OnPacketReceived(packet1, /*packet_time_us=*/-1);
Jonas Oreland49ac5952018-09-26 16:04:32 +02007311 int64_t timestamp2 = channel_->GetSources(kSsrc)[0].timestamp_ms();
7312 EXPECT_EQ(timestamp2, timestamp1 + timeDeltaMs);
7313
7314 // It only keeps 10s of history.
7315 fake_clock_.AdvanceTime(webrtc::TimeDelta::seconds(10));
7316 fake_clock_.AdvanceTime(webrtc::TimeDelta::ms(1));
7317 EXPECT_EQ(0u, channel_->GetSources(kSsrc).size());
7318}
7319
7320TEST_F(WebRtcVideoChannelTestWithClock, GetContributingSources) {
7321 uint8_t data1[] = {0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7322 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
7323
7324 uint32_t kCsrc = 4321u;
7325 EXPECT_EQ(0u, channel_->GetSources(kSsrc).size());
7326 EXPECT_EQ(0u, channel_->GetSources(kCsrc).size());
7327
7328 rtc::CopyOnWriteBuffer packet1(data1, sizeof(data1));
7329 rtc::SetBE32(packet1.data() + 8, kSsrc);
7330 rtc::SetBE32(packet1.data() + 12, kCsrc);
7331 channel_->SetSink(kDefaultReceiveSsrc, NULL);
7332 EXPECT_TRUE(SetDefaultCodec());
7333 EXPECT_TRUE(SetSend(true));
7334 EXPECT_EQ(0, renderer_.num_rendered_frames());
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07007335 channel_->OnPacketReceived(packet1, /*packet_time_us=*/-1);
Jonas Oreland49ac5952018-09-26 16:04:32 +02007336
7337 {
7338 ASSERT_EQ(2u, channel_->GetSources(kSsrc).size());
7339 EXPECT_EQ(0u, channel_->GetSources(kCsrc).size());
7340 std::vector<webrtc::RtpSource> sources = channel_->GetSources(kSsrc);
7341 EXPECT_EQ(sources[0].timestamp_ms(), sources[1].timestamp_ms());
7342 // 1 SSRC and 1 CSRC.
Steve Anton2c9ebef2019-01-28 17:27:58 -08007343 EXPECT_EQ(1, absl::c_count_if(sources, [](const webrtc::RtpSource& source) {
7344 return source.source_type() == webrtc::RtpSourceType::SSRC;
7345 }));
7346 EXPECT_EQ(1, absl::c_count_if(sources, [](const webrtc::RtpSource& source) {
7347 return source.source_type() == webrtc::RtpSourceType::CSRC;
7348 }));
Jonas Oreland49ac5952018-09-26 16:04:32 +02007349 }
7350 int64_t timestamp1 = channel_->GetSources(kSsrc)[0].timestamp_ms();
7351
7352 // a new packet with only ssrc (i.e no csrc).
7353 uint8_t data2[] = {0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
7354 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
7355 rtc::CopyOnWriteBuffer packet2(data2, sizeof(data2));
7356 rtc::SetBE32(packet2.data() + 8, kSsrc);
7357
7358 int64_t timeDeltaMs = 1;
7359 fake_clock_.AdvanceTime(webrtc::TimeDelta::ms(timeDeltaMs));
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07007360 channel_->OnPacketReceived(packet2, /*packet_time_us=*/-1);
Jonas Oreland49ac5952018-09-26 16:04:32 +02007361
7362 {
7363 ASSERT_EQ(2u, channel_->GetSources(kSsrc).size());
7364 EXPECT_EQ(0u, channel_->GetSources(kCsrc).size());
7365 std::vector<webrtc::RtpSource> sources = channel_->GetSources(kSsrc);
7366 EXPECT_NE(sources[0].timestamp_ms(), sources[1].timestamp_ms());
7367 // 1 SSRC and 1 CSRC.
Steve Anton2c9ebef2019-01-28 17:27:58 -08007368 EXPECT_EQ(1, absl::c_count_if(sources, [](const webrtc::RtpSource& source) {
7369 return source.source_type() == webrtc::RtpSourceType::SSRC;
7370 }));
7371 EXPECT_EQ(1, absl::c_count_if(sources, [](const webrtc::RtpSource& source) {
7372 return source.source_type() == webrtc::RtpSourceType::CSRC;
7373 }));
7374 auto ssrcSource =
7375 absl::c_find_if(sources, [](const webrtc::RtpSource& source) {
Jonas Oreland49ac5952018-09-26 16:04:32 +02007376 return source.source_type() == webrtc::RtpSourceType::SSRC;
7377 });
Steve Anton2c9ebef2019-01-28 17:27:58 -08007378 auto csrcSource =
7379 absl::c_find_if(sources, [](const webrtc::RtpSource& source) {
Jonas Oreland49ac5952018-09-26 16:04:32 +02007380 return source.source_type() == webrtc::RtpSourceType::CSRC;
7381 });
7382
7383 EXPECT_EQ(ssrcSource->timestamp_ms(), timestamp1 + timeDeltaMs);
7384 EXPECT_EQ(csrcSource->timestamp_ms(), timestamp1);
7385 }
7386
7387 // It only keeps 10s of history.
7388 fake_clock_.AdvanceTime(webrtc::TimeDelta::seconds(10));
7389
7390 {
7391 ASSERT_EQ(1u, channel_->GetSources(kSsrc).size());
7392 EXPECT_EQ(0u, channel_->GetSources(kCsrc).size());
7393 std::vector<webrtc::RtpSource> sources = channel_->GetSources(kSsrc);
Steve Anton2c9ebef2019-01-28 17:27:58 -08007394 EXPECT_EQ(1, absl::c_count_if(sources, [](const webrtc::RtpSource& source) {
7395 return source.source_type() == webrtc::RtpSourceType::SSRC;
7396 }));
7397 EXPECT_EQ(0, absl::c_count_if(sources, [](const webrtc::RtpSource& source) {
7398 return source.source_type() == webrtc::RtpSourceType::CSRC;
7399 }));
Jonas Oreland49ac5952018-09-26 16:04:32 +02007400 }
7401
7402 fake_clock_.AdvanceTime(webrtc::TimeDelta::ms(1));
7403 EXPECT_EQ(0u, channel_->GetSources(kSsrc).size());
7404 EXPECT_EQ(0u, channel_->GetSources(kCsrc).size());
7405}
7406
Amit Hilbuchb000b712019-02-25 10:22:14 -08007407TEST_F(WebRtcVideoChannelTest, SetsRidsOnSendStream) {
7408 StreamParams sp = CreateSimStreamParams("cname", {123, 456, 789});
7409
7410 std::vector<std::string> rids = {"f", "h", "q"};
7411 std::vector<cricket::RidDescription> rid_descriptions;
7412 for (const auto& rid : rids) {
7413 rid_descriptions.emplace_back(rid, cricket::RidDirection::kSend);
7414 }
7415 sp.set_rids(rid_descriptions);
7416
7417 ASSERT_TRUE(channel_->AddSendStream(sp));
7418 const auto& streams = fake_call_->GetVideoSendStreams();
7419 ASSERT_EQ(1u, streams.size());
7420 auto stream = streams[0];
7421 ASSERT_NE(stream, nullptr);
7422 const auto& config = stream->GetConfig();
7423 EXPECT_THAT(config.rtp.rids, ::testing::ElementsAreArray(rids));
7424}
7425
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00007426} // namespace cricket