blob: 8381b01cca7e76a7026b717aa52857855f241c4a [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"
Anton Sukhanov4f08faa2019-05-21 11:12:57 -070019#include "api/media_transport_config.h"
Steve Anton10542f22019-01-11 09:11:00 -080020#include "api/rtp_parameters.h"
Piotr (Peter) Slatala946b9682019-03-18 10:25:02 -070021#include "api/test/fake_media_transport.h"
Jiawei Ouc2ebe212018-11-08 10:02:56 -080022#include "api/test/mock_video_bitrate_allocator.h"
23#include "api/test/mock_video_bitrate_allocator_factory.h"
Emircan Uysalerdbcac7f2017-10-30 23:10:12 -070024#include "api/test/mock_video_decoder_factory.h"
25#include "api/test/mock_video_encoder_factory.h"
Jonas Oreland49ac5952018-09-26 16:04:32 +020026#include "api/units/time_delta.h"
Jiawei Ouc2ebe212018-11-08 10:02:56 -080027#include "api/video/builtin_video_bitrate_allocator_factory.h"
Niels Möller805a27e2019-01-21 12:21:27 +010028#include "api/video/i420_buffer.h"
Åsa Persson23eba222018-10-02 14:47:06 +020029#include "api/video/video_bitrate_allocation.h"
Anders Carlsson5f2bb622018-05-14 09:48:06 +020030#include "api/video_codecs/builtin_video_decoder_factory.h"
31#include "api/video_codecs/builtin_video_encoder_factory.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020032#include "api/video_codecs/sdp_video_format.h"
33#include "api/video_codecs/video_decoder_factory.h"
34#include "api/video_codecs/video_encoder.h"
35#include "api/video_codecs/video_encoder_factory.h"
36#include "call/flexfec_receive_stream.h"
37#include "common_video/h264/profile_level_id.h"
38#include "logging/rtc_event_log/rtc_event_log.h"
Niels Möller805a27e2019-01-21 12:21:27 +010039#include "media/base/fake_frame_source.h"
Steve Anton10542f22019-01-11 09:11:00 -080040#include "media/base/fake_network_interface.h"
Steve Anton10542f22019-01-11 09:11:00 -080041#include "media/base/fake_video_renderer.h"
42#include "media/base/media_constants.h"
43#include "media/base/rtp_utils.h"
44#include "media/base/test_utils.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020045#include "media/engine/constants.h"
Steve Anton10542f22019-01-11 09:11:00 -080046#include "media/engine/fake_webrtc_call.h"
47#include "media/engine/fake_webrtc_video_engine.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020048#include "media/engine/simulcast.h"
Steve Anton10542f22019-01-11 09:11:00 -080049#include "media/engine/webrtc_video_engine.h"
50#include "media/engine/webrtc_voice_engine.h"
Åsa Persson23cd45a2018-07-03 10:40:40 +020051#include "modules/rtp_rtcp/include/rtp_header_parser.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020052#include "rtc_base/arraysize.h"
Steve Anton10542f22019-01-11 09:11:00 -080053#include "rtc_base/fake_clock.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020054#include "rtc_base/gunit.h"
Yves Gerey665174f2018-06-19 15:03:05 +020055#include "rtc_base/numerics/safe_conversions.h"
Steve Antonf3802842019-01-24 19:07:40 -080056#include "rtc_base/time_utils.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020057#include "test/field_trial.h"
Niels Möllerd0f0f682019-01-14 09:09:53 +010058#include "test/frame_generator.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020059#include "test/gmock.h"
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000060
Mirko Bonadei6a489f22019-04-09 15:11:12 +020061using ::testing::Field;
Sebastian Jansson8f83b422018-02-21 13:07:13 +010062using webrtc::BitrateConstraints;
isheriff6f8d6862016-05-26 11:24:55 -070063using webrtc::RtpExtension;
64
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000065namespace {
buildbot@webrtc.orga8530772014-12-10 09:01:18 +000066static const int kDefaultQpMax = 56;
buildbot@webrtc.orga8530772014-12-10 09:01:18 +000067
noahricd10a68e2015-07-10 11:27:55 -070068static const uint8_t kRedRtxPayloadType = 125;
69
Niels Möller6557d0c2018-04-11 15:18:34 +020070static const uint32_t kTimeout = 5000U;
71static const uint32_t kDefaultReceiveSsrc = 0;
72static const uint32_t kSsrc = 1234u;
73static const uint32_t kSsrcs4[] = {1, 2, 3, 4};
74static const int kVideoWidth = 640;
75static const int kVideoHeight = 360;
76static const int kFramerate = 30;
77
Peter Boström0c4e06b2015-10-07 12:23:21 +020078static const uint32_t kSsrcs1[] = {1};
79static const uint32_t kSsrcs3[] = {1, 2, 3};
80static const uint32_t kRtxSsrcs1[] = {4};
brandtr468da7c2016-11-22 02:16:47 -080081static const uint32_t kFlexfecSsrc = 5;
Peter Boström0c4e06b2015-10-07 12:23:21 +020082static const uint32_t kIncomingUnsignalledSsrc = 0xC0FFEE;
mzanaty8a855d62017-02-17 15:46:43 -080083static const uint32_t kDefaultRecvSsrc = 0;
84
pbos@webrtc.org3c107582014-07-20 15:27:35 +000085static const char kUnsupportedExtensionName[] =
86 "urn:ietf:params:rtp-hdrext:unsupported";
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +000087
magjed509e4fe2016-11-18 01:34:11 -080088cricket::VideoCodec RemoveFeedbackParams(cricket::VideoCodec&& codec) {
89 codec.feedback_params = cricket::FeedbackParams();
Mirko Bonadei29a8d102018-04-25 23:58:26 +020090 return std::move(codec);
magjed509e4fe2016-11-18 01:34:11 -080091}
92
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +000093void VerifyCodecHasDefaultFeedbackParams(const cricket::VideoCodec& codec) {
94 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
95 cricket::kRtcpFbParamNack, cricket::kParamValueEmpty)));
96 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
97 cricket::kRtcpFbParamNack, cricket::kRtcpFbNackParamPli)));
98 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
99 cricket::kRtcpFbParamRemb, cricket::kParamValueEmpty)));
100 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
stefan43edf0f2015-11-20 18:05:48 -0800101 cricket::kRtcpFbParamTransportCc, cricket::kParamValueEmpty)));
102 EXPECT_TRUE(codec.HasFeedbackParam(cricket::FeedbackParam(
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +0000103 cricket::kRtcpFbParamCcm, cricket::kRtcpFbCcmParamFir)));
104}
105
magjed725e4842016-11-16 00:48:13 -0800106// Return true if any codec in |codecs| is an RTX codec with associated payload
107// type |payload_type|.
108bool HasRtxCodec(const std::vector<cricket::VideoCodec>& codecs,
109 int payload_type) {
110 for (const cricket::VideoCodec& codec : codecs) {
111 int associated_payload_type;
Niels Möller039743e2018-10-23 10:07:25 +0200112 if (absl::EqualsIgnoreCase(codec.name.c_str(), "rtx") &&
magjed725e4842016-11-16 00:48:13 -0800113 codec.GetParam(cricket::kCodecParamAssociatedPayloadType,
114 &associated_payload_type) &&
115 associated_payload_type == payload_type) {
116 return true;
117 }
118 }
119 return false;
120}
121
nisseca5706d2017-09-11 02:32:16 -0700122// TODO(nisse): Duplicated in call.cc.
123const int* FindKeyByValue(const std::map<int, int>& m, int v) {
124 for (const auto& kv : m) {
125 if (kv.second == v)
126 return &kv.first;
127 }
128 return nullptr;
129}
130
Yves Gerey665174f2018-06-19 15:03:05 +0200131bool HasRtxReceiveAssociation(const webrtc::VideoReceiveStream::Config& config,
132 int payload_type) {
nisseca5706d2017-09-11 02:32:16 -0700133 return FindKeyByValue(config.rtp.rtx_associated_payload_types,
134 payload_type) != nullptr;
135}
136
137// Check that there's an Rtx payload type for each decoder.
138bool VerifyRtxReceiveAssociations(
139 const webrtc::VideoReceiveStream::Config& config) {
140 for (const auto& decoder : config.decoders) {
141 if (!HasRtxReceiveAssociation(config, decoder.payload_type))
142 return false;
143 }
144 return true;
145}
146
brandtrffc61182016-11-28 06:02:22 -0800147rtc::scoped_refptr<webrtc::VideoFrameBuffer> CreateBlackFrameBuffer(
nisse64ec8f82016-09-27 00:17:25 -0700148 int width,
149 int height) {
150 rtc::scoped_refptr<webrtc::I420Buffer> buffer =
151 webrtc::I420Buffer::Create(width, height);
nisseaf916892017-01-10 07:44:26 -0800152 webrtc::I420Buffer::SetBlack(buffer);
nisse64ec8f82016-09-27 00:17:25 -0700153 return buffer;
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +0000154}
155
Shao Changbine62202f2015-04-21 20:24:50 +0800156void VerifySendStreamHasRtxTypes(const webrtc::VideoSendStream::Config& config,
157 const std::map<int, int>& rtx_types) {
158 std::map<int, int>::const_iterator it;
Niels Möller259a4972018-04-05 15:36:51 +0200159 it = rtx_types.find(config.rtp.payload_type);
Shao Changbine62202f2015-04-21 20:24:50 +0800160 EXPECT_TRUE(it != rtx_types.end() &&
161 it->second == config.rtp.rtx.payload_type);
162
brandtrb5f2c3f2016-10-04 23:28:39 -0700163 if (config.rtp.ulpfec.red_rtx_payload_type != -1) {
164 it = rtx_types.find(config.rtp.ulpfec.red_payload_type);
Shao Changbine62202f2015-04-21 20:24:50 +0800165 EXPECT_TRUE(it != rtx_types.end() &&
brandtrb5f2c3f2016-10-04 23:28:39 -0700166 it->second == config.rtp.ulpfec.red_rtx_payload_type);
Shao Changbine62202f2015-04-21 20:24:50 +0800167 }
168}
kthelgason2bc68642017-02-07 07:02:22 -0800169
170cricket::MediaConfig GetMediaConfig() {
171 cricket::MediaConfig media_config;
Niels Möller1d7ecd22018-01-18 15:25:12 +0100172 media_config.video.enable_cpu_adaptation = false;
kthelgason2bc68642017-02-07 07:02:22 -0800173 return media_config;
174}
nisse26e3abb2017-08-25 04:44:25 -0700175
Åsa Perssonbdee46d2018-06-25 11:28:06 +0200176// Values from GetMaxDefaultVideoBitrateKbps in webrtcvideoengine.cc.
177int GetMaxDefaultBitrateBps(size_t width, size_t height) {
178 if (width * height <= 320 * 240) {
179 return 600000;
180 } else if (width * height <= 640 * 480) {
181 return 1700000;
182 } else if (width * height <= 960 * 540) {
183 return 2000000;
184 } else {
185 return 2500000;
186 }
187}
188
Niels Möller731a2c22018-07-30 15:08:07 +0200189class MockVideoSource : public rtc::VideoSourceInterface<webrtc::VideoFrame> {
190 public:
191 MOCK_METHOD2(AddOrUpdateSink,
192 void(rtc::VideoSinkInterface<webrtc::VideoFrame>* sink,
193 const rtc::VideoSinkWants& wants));
194 MOCK_METHOD1(RemoveSink,
195 void(rtc::VideoSinkInterface<webrtc::VideoFrame>* sink));
196};
197
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000198} // namespace
199
Yves Gerey665174f2018-06-19 15:03:05 +0200200#define EXPECT_FRAME_WAIT(c, w, h, t) \
Niels Möller6557d0c2018-04-11 15:18:34 +0200201 EXPECT_EQ_WAIT((c), renderer_.num_rendered_frames(), (t)); \
Yves Gerey665174f2018-06-19 15:03:05 +0200202 EXPECT_EQ((w), renderer_.width()); \
203 EXPECT_EQ((h), renderer_.height()); \
Niels Möller6557d0c2018-04-11 15:18:34 +0200204 EXPECT_EQ(0, renderer_.errors());
205
Yves Gerey665174f2018-06-19 15:03:05 +0200206#define EXPECT_FRAME_ON_RENDERER_WAIT(r, c, w, h, t) \
Niels Möller6557d0c2018-04-11 15:18:34 +0200207 EXPECT_EQ_WAIT((c), (r).num_rendered_frames(), (t)); \
Yves Gerey665174f2018-06-19 15:03:05 +0200208 EXPECT_EQ((w), (r).width()); \
209 EXPECT_EQ((h), (r).height()); \
Niels Möller6557d0c2018-04-11 15:18:34 +0200210 EXPECT_EQ(0, (r).errors());
211
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000212namespace cricket {
eladalonf1841382017-06-12 01:16:46 -0700213class WebRtcVideoEngineTest : public ::testing::Test {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000214 public:
eladalonf1841382017-06-12 01:16:46 -0700215 WebRtcVideoEngineTest() : WebRtcVideoEngineTest("") {}
216 explicit WebRtcVideoEngineTest(const char* field_trials)
stefanc1aeaf02015-10-15 07:26:07 -0700217 : override_field_trials_(field_trials),
skvlad11a9cbf2016-10-07 11:53:05 -0700218 call_(webrtc::Call::Create(webrtc::Call::Config(&event_log_))),
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200219 encoder_factory_(new cricket::FakeWebRtcVideoEncoderFactory),
220 decoder_factory_(new cricket::FakeWebRtcVideoDecoderFactory),
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +0200221 video_bitrate_allocator_factory_(
222 webrtc::CreateBuiltinVideoBitrateAllocatorFactory()),
Anders Carlsson67537952018-05-03 11:28:29 +0200223 engine_(std::unique_ptr<cricket::FakeWebRtcVideoEncoderFactory>(
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200224 encoder_factory_),
Anders Carlsson67537952018-05-03 11:28:29 +0200225 std::unique_ptr<cricket::FakeWebRtcVideoDecoderFactory>(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +0200226 decoder_factory_)) {
Ilya Nikolaevskiy9c38c472018-09-03 16:11:42 +0200227 // Ensure fake clock doesn't return 0, which will cause some initializations
228 // fail inside RTP senders.
Sebastian Jansson40889f32019-04-17 12:11:20 +0200229 fake_clock_.AdvanceTime(webrtc::TimeDelta::us(1));
Ilya Nikolaevskiy9c38c472018-09-03 16:11:42 +0200230 }
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000231
232 protected:
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200233 void AssignDefaultAptRtxTypes();
234 void AssignDefaultCodec();
235
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +0100236 // Find the index of the codec in the engine with the given name. The codec
237 // must be present.
Oleh Prypina40f8242017-12-21 13:32:23 +0100238 size_t GetEngineCodecIndex(const std::string& name) const;
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +0100239
magjed509e4fe2016-11-18 01:34:11 -0800240 // Find the codec in the engine with the given name. The codec must be
241 // present.
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +0100242 cricket::VideoCodec GetEngineCodec(const std::string& name) const;
magjed509e4fe2016-11-18 01:34:11 -0800243
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200244 VideoMediaChannel* SetSendParamsWithAllSupportedCodecs();
pbos@webrtc.orgfa553ef2014-10-20 11:07:07 +0000245
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200246 VideoMediaChannel* SetRecvParamsWithSupportedCodecs(
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000247 const std::vector<VideoCodec>& codecs);
248
Elad Alon157540a2019-02-08 23:37:52 +0100249 void ExpectRtpCapabilitySupport(const char* uri, bool supported) const;
Peter Boströme4499152016-02-05 11:13:28 +0100250
Ilya Nikolaevskiy9c38c472018-09-03 16:11:42 +0200251 // Has to be the first one, so it is initialized before the call or there is a
252 // race condition in the clock access.
253 rtc::ScopedFakeClock fake_clock_;
stefanc1aeaf02015-10-15 07:26:07 -0700254 webrtc::test::ScopedFieldTrials override_field_trials_;
skvlad11a9cbf2016-10-07 11:53:05 -0700255 webrtc::RtcEventLogNullImpl event_log_;
eladalonf1841382017-06-12 01:16:46 -0700256 // Used in WebRtcVideoEngineVoiceTest, but defined here so it's properly
pbos@webrtc.orgf1f0d9a2015-03-02 13:30:15 +0000257 // initialized when the constructor is called.
kwiberg686a8ef2016-02-26 03:00:35 -0800258 std::unique_ptr<webrtc::Call> call_;
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200259 cricket::FakeWebRtcVideoEncoderFactory* encoder_factory_;
260 cricket::FakeWebRtcVideoDecoderFactory* decoder_factory_;
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +0200261 std::unique_ptr<webrtc::VideoBitrateAllocatorFactory>
262 video_bitrate_allocator_factory_;
eladalonf1841382017-06-12 01:16:46 -0700263 WebRtcVideoEngine engine_;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000264 VideoCodec default_codec_;
Shao Changbine62202f2015-04-21 20:24:50 +0800265 std::map<int, int> default_apt_rtx_types_;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000266};
267
eladalonf1841382017-06-12 01:16:46 -0700268TEST_F(WebRtcVideoEngineTest, DefaultRtxCodecHasAssociatedPayloadTypeSet) {
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200269 encoder_factory_->AddSupportedVideoCodecType("VP8");
270 AssignDefaultCodec();
271
pbos@webrtc.orge322a172014-06-13 11:47:28 +0000272 std::vector<VideoCodec> engine_codecs = engine_.codecs();
273 for (size_t i = 0; i < engine_codecs.size(); ++i) {
274 if (engine_codecs[i].name != kRtxCodecName)
275 continue;
276 int associated_payload_type;
277 EXPECT_TRUE(engine_codecs[i].GetParam(kCodecParamAssociatedPayloadType,
pbos@webrtc.org42684be2014-10-03 11:25:45 +0000278 &associated_payload_type));
pbos@webrtc.orge322a172014-06-13 11:47:28 +0000279 EXPECT_EQ(default_codec_.id, associated_payload_type);
280 return;
281 }
282 FAIL() << "No RTX codec found among default codecs.";
283}
284
eladalonf1841382017-06-12 01:16:46 -0700285TEST_F(WebRtcVideoEngineTest, SupportsTimestampOffsetHeaderExtension) {
Elad Alon157540a2019-02-08 23:37:52 +0100286 ExpectRtpCapabilitySupport(RtpExtension::kTimestampOffsetUri, true);
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000287}
288
eladalonf1841382017-06-12 01:16:46 -0700289TEST_F(WebRtcVideoEngineTest, SupportsAbsoluteSenderTimeHeaderExtension) {
Elad Alon157540a2019-02-08 23:37:52 +0100290 ExpectRtpCapabilitySupport(RtpExtension::kAbsSendTimeUri, true);
pbos@webrtc.org587ef602014-06-16 17:32:02 +0000291}
292
eladalonf1841382017-06-12 01:16:46 -0700293TEST_F(WebRtcVideoEngineTest, SupportsTransportSequenceNumberHeaderExtension) {
Elad Alon157540a2019-02-08 23:37:52 +0100294 ExpectRtpCapabilitySupport(RtpExtension::kTransportSequenceNumberUri, true);
stefanc1aeaf02015-10-15 07:26:07 -0700295}
296
eladalonf1841382017-06-12 01:16:46 -0700297TEST_F(WebRtcVideoEngineTest, SupportsVideoRotationHeaderExtension) {
Elad Alon157540a2019-02-08 23:37:52 +0100298 ExpectRtpCapabilitySupport(RtpExtension::kVideoRotationUri, true);
299}
300
301TEST_F(WebRtcVideoEngineTest, SupportsPlayoutDelayHeaderExtension) {
302 ExpectRtpCapabilitySupport(RtpExtension::kPlayoutDelayUri, true);
303}
304
305TEST_F(WebRtcVideoEngineTest, SupportsVideoContentTypeHeaderExtension) {
306 ExpectRtpCapabilitySupport(RtpExtension::kVideoContentTypeUri, true);
307}
308
309TEST_F(WebRtcVideoEngineTest, SupportsVideoTimingHeaderExtension) {
310 ExpectRtpCapabilitySupport(RtpExtension::kVideoTimingUri, true);
311}
312
313TEST_F(WebRtcVideoEngineTest, SupportsFrameMarkingHeaderExtension) {
314 ExpectRtpCapabilitySupport(RtpExtension::kFrameMarkingUri, true);
Johannes Krond0b69a82018-12-03 14:18:53 +0100315}
316
317TEST_F(WebRtcVideoEngineTest, SupportsColorSpaceHeaderExtension) {
Elad Alon157540a2019-02-08 23:37:52 +0100318 ExpectRtpCapabilitySupport(RtpExtension::kColorSpaceUri, true);
319}
320
Elad Alonccb9b752019-02-19 13:01:31 +0100321TEST_F(WebRtcVideoEngineTest, AdvertiseGenericDescriptor00) {
322 ExpectRtpCapabilitySupport(RtpExtension::kGenericFrameDescriptorUri00, false);
323}
324
325TEST_F(WebRtcVideoEngineTest, AdvertiseGenericDescriptor01) {
326 ExpectRtpCapabilitySupport(RtpExtension::kGenericFrameDescriptorUri01, false);
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700327}
328
philipel1e054862018-10-08 16:13:53 +0200329class WebRtcVideoEngineTestWithGenericDescriptor
330 : public WebRtcVideoEngineTest {
331 public:
332 WebRtcVideoEngineTestWithGenericDescriptor()
333 : WebRtcVideoEngineTest("WebRTC-GenericDescriptorAdvertised/Enabled/") {}
334};
335
Elad Alonccb9b752019-02-19 13:01:31 +0100336TEST_F(WebRtcVideoEngineTestWithGenericDescriptor,
337 AdvertiseGenericDescriptor00) {
338 ExpectRtpCapabilitySupport(RtpExtension::kGenericFrameDescriptorUri00, true);
339}
340
341TEST_F(WebRtcVideoEngineTestWithGenericDescriptor,
342 AdvertiseGenericDescriptor01) {
343 ExpectRtpCapabilitySupport(RtpExtension::kGenericFrameDescriptorUri01, true);
philipel1e054862018-10-08 16:13:53 +0200344}
345
eladalonf1841382017-06-12 01:16:46 -0700346TEST_F(WebRtcVideoEngineTest, CVOSetHeaderExtensionBeforeCapturer) {
Niels Möller731a2c22018-07-30 15:08:07 +0200347 // Allocate the source first to prevent early destruction before channel's
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700348 // dtor is called.
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200349 ::testing::NiceMock<MockVideoSource> video_source;
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700350
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200351 encoder_factory_->AddSupportedVideoCodecType("VP8");
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700352
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200353 std::unique_ptr<VideoMediaChannel> channel(
354 SetSendParamsWithAllSupportedCodecs());
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700355 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(kSsrc)));
356
357 // Add CVO extension.
358 const int id = 1;
magjed509e4fe2016-11-18 01:34:11 -0800359 cricket::VideoSendParameters parameters;
360 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200361 parameters.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -0700362 RtpExtension(RtpExtension::kVideoRotationUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200363 EXPECT_TRUE(channel->SetSendParameters(parameters));
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700364
Niels Möller731a2c22018-07-30 15:08:07 +0200365 EXPECT_CALL(
366 video_source,
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200367 AddOrUpdateSink(::testing::_,
Niels Möller731a2c22018-07-30 15:08:07 +0200368 Field(&rtc::VideoSinkWants::rotation_applied, false)));
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700369 // Set capturer.
Niels Möller731a2c22018-07-30 15:08:07 +0200370 EXPECT_TRUE(channel->SetVideoSend(kSsrc, nullptr, &video_source));
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700371
372 // Verify capturer has turned off applying rotation.
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200373 ::testing::Mock::VerifyAndClear(&video_source);
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700374
375 // Verify removing header extension turns on applying rotation.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200376 parameters.extensions.clear();
Niels Möller731a2c22018-07-30 15:08:07 +0200377 EXPECT_CALL(
378 video_source,
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200379 AddOrUpdateSink(::testing::_,
Niels Möller731a2c22018-07-30 15:08:07 +0200380 Field(&rtc::VideoSinkWants::rotation_applied, true)));
381
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200382 EXPECT_TRUE(channel->SetSendParameters(parameters));
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700383}
384
eladalonf1841382017-06-12 01:16:46 -0700385TEST_F(WebRtcVideoEngineTest, CVOSetHeaderExtensionBeforeAddSendStream) {
Niels Möller731a2c22018-07-30 15:08:07 +0200386 // Allocate the source first to prevent early destruction before channel's
perkj91e1c152016-03-02 05:34:00 -0800387 // dtor is called.
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200388 ::testing::NiceMock<MockVideoSource> video_source;
perkj91e1c152016-03-02 05:34:00 -0800389
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200390 encoder_factory_->AddSupportedVideoCodecType("VP8");
perkj91e1c152016-03-02 05:34:00 -0800391
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200392 std::unique_ptr<VideoMediaChannel> channel(
393 SetSendParamsWithAllSupportedCodecs());
perkj91e1c152016-03-02 05:34:00 -0800394 // Add CVO extension.
395 const int id = 1;
magjed509e4fe2016-11-18 01:34:11 -0800396 cricket::VideoSendParameters parameters;
397 parameters.codecs.push_back(GetEngineCodec("VP8"));
perkj91e1c152016-03-02 05:34:00 -0800398 parameters.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -0700399 RtpExtension(RtpExtension::kVideoRotationUri, id));
perkj91e1c152016-03-02 05:34:00 -0800400 EXPECT_TRUE(channel->SetSendParameters(parameters));
401 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(kSsrc)));
402
Niels Möller731a2c22018-07-30 15:08:07 +0200403 // Set source.
404 EXPECT_CALL(
405 video_source,
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200406 AddOrUpdateSink(::testing::_,
Niels Möller731a2c22018-07-30 15:08:07 +0200407 Field(&rtc::VideoSinkWants::rotation_applied, false)));
408 EXPECT_TRUE(channel->SetVideoSend(kSsrc, nullptr, &video_source));
perkj91e1c152016-03-02 05:34:00 -0800409}
410
eladalonf1841382017-06-12 01:16:46 -0700411TEST_F(WebRtcVideoEngineTest, CVOSetHeaderExtensionAfterCapturer) {
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200412 ::testing::NiceMock<MockVideoSource> video_source;
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700413
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200414 encoder_factory_->AddSupportedVideoCodecType("VP8");
415 encoder_factory_->AddSupportedVideoCodecType("VP9");
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700416
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200417 std::unique_ptr<VideoMediaChannel> channel(
418 SetSendParamsWithAllSupportedCodecs());
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700419 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(kSsrc)));
420
421 // Set capturer.
Niels Möller731a2c22018-07-30 15:08:07 +0200422 EXPECT_CALL(
423 video_source,
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200424 AddOrUpdateSink(::testing::_,
Niels Möller731a2c22018-07-30 15:08:07 +0200425 Field(&rtc::VideoSinkWants::rotation_applied, true)));
426 EXPECT_TRUE(channel->SetVideoSend(kSsrc, nullptr, &video_source));
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700427
perkjcaafdba2016-03-20 07:34:29 -0700428 // Verify capturer has turned on applying rotation.
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200429 ::testing::Mock::VerifyAndClear(&video_source);
perkjcaafdba2016-03-20 07:34:29 -0700430
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700431 // Add CVO extension.
432 const int id = 1;
magjed509e4fe2016-11-18 01:34:11 -0800433 cricket::VideoSendParameters parameters;
434 parameters.codecs.push_back(GetEngineCodec("VP8"));
435 parameters.codecs.push_back(GetEngineCodec("VP9"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200436 parameters.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -0700437 RtpExtension(RtpExtension::kVideoRotationUri, id));
perkjcaafdba2016-03-20 07:34:29 -0700438 // Also remove the first codec to trigger a codec change as well.
439 parameters.codecs.erase(parameters.codecs.begin());
Niels Möller731a2c22018-07-30 15:08:07 +0200440 EXPECT_CALL(
441 video_source,
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200442 AddOrUpdateSink(::testing::_,
Niels Möller731a2c22018-07-30 15:08:07 +0200443 Field(&rtc::VideoSinkWants::rotation_applied, false)));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200444 EXPECT_TRUE(channel->SetSendParameters(parameters));
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700445
446 // Verify capturer has turned off applying rotation.
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200447 ::testing::Mock::VerifyAndClear(&video_source);
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700448
449 // Verify removing header extension turns on applying rotation.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200450 parameters.extensions.clear();
Niels Möller731a2c22018-07-30 15:08:07 +0200451 EXPECT_CALL(
452 video_source,
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200453 AddOrUpdateSink(::testing::_,
Niels Möller731a2c22018-07-30 15:08:07 +0200454 Field(&rtc::VideoSinkWants::rotation_applied, true)));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200455 EXPECT_TRUE(channel->SetSendParameters(parameters));
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -0700456}
457
eladalonf1841382017-06-12 01:16:46 -0700458TEST_F(WebRtcVideoEngineTest, SetSendFailsBeforeSettingCodecs) {
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200459 encoder_factory_->AddSupportedVideoCodecType("VP8");
460
Sebastian Jansson84848f22018-11-16 10:40:36 +0100461 std::unique_ptr<VideoMediaChannel> channel(engine_.CreateMediaChannel(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +0200462 call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
463 video_bitrate_allocator_factory_.get()));
pbos@webrtc.org5301b0f2014-07-17 08:51:46 +0000464
465 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(123)));
466
467 EXPECT_FALSE(channel->SetSend(true))
468 << "Channel should not start without codecs.";
469 EXPECT_TRUE(channel->SetSend(false))
470 << "Channel should be stoppable even without set codecs.";
471}
472
eladalonf1841382017-06-12 01:16:46 -0700473TEST_F(WebRtcVideoEngineTest, GetStatsWithoutSendCodecsSetDoesNotCrash) {
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200474 encoder_factory_->AddSupportedVideoCodecType("VP8");
475
Sebastian Jansson84848f22018-11-16 10:40:36 +0100476 std::unique_ptr<VideoMediaChannel> channel(engine_.CreateMediaChannel(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +0200477 call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
478 video_bitrate_allocator_factory_.get()));
pbos@webrtc.orgc3d2bd22014-08-12 20:55:10 +0000479 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(123)));
480 VideoMediaInfo info;
481 channel->GetStats(&info);
482}
483
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200484TEST_F(WebRtcVideoEngineTest, UseFactoryForVp8WhenSupported) {
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200485 encoder_factory_->AddSupportedVideoCodecType("VP8");
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000486
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200487 std::unique_ptr<VideoMediaChannel> channel(
488 SetSendParamsWithAllSupportedCodecs());
Sergey Ulanove2b15012016-11-22 16:08:30 -0800489 channel->OnReadyToSend(true);
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000490
491 EXPECT_TRUE(
492 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200493 EXPECT_EQ(0, encoder_factory_->GetNumCreatedEncoders());
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000494 EXPECT_TRUE(channel->SetSend(true));
Niels Möllerd0f0f682019-01-14 09:09:53 +0100495 webrtc::test::FrameForwarder frame_forwarder;
496 cricket::FakeFrameSource frame_source(1280, 720,
497 rtc::kNumMicrosecsPerSec / 30);
498 EXPECT_TRUE(channel->SetVideoSend(kSsrc, nullptr, &frame_forwarder));
499 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
Per21d45d22016-10-30 21:37:57 +0100500 // Sending one frame will have allocate the encoder.
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200501 ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(1));
502 EXPECT_TRUE_WAIT(encoder_factory_->encoders()[0]->GetNumEncodedFrames() > 0,
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000503 kTimeout);
504
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200505 int num_created_encoders = encoder_factory_->GetNumCreatedEncoders();
Per21d45d22016-10-30 21:37:57 +0100506 EXPECT_EQ(num_created_encoders, 1);
pbos@webrtc.org86196c42015-02-16 21:02:00 +0000507
508 // Setting codecs of the same type should not reallocate any encoders
509 // (expecting a no-op).
magjed509e4fe2016-11-18 01:34:11 -0800510 cricket::VideoSendParameters parameters;
511 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200512 EXPECT_TRUE(channel->SetSendParameters(parameters));
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200513 EXPECT_EQ(num_created_encoders, encoder_factory_->GetNumCreatedEncoders());
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000514
515 // Remove stream previously added to free the external encoder instance.
516 EXPECT_TRUE(channel->RemoveSendStream(kSsrc));
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200517 EXPECT_EQ(0u, encoder_factory_->encoders().size());
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000518}
519
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200520// Test that when an encoder factory supports H264, we add an RTX
521// codec for it.
522// TODO(deadbeef): This test should be updated if/when we start
523// adding RTX codecs for unrecognized codec names.
524TEST_F(WebRtcVideoEngineTest, RtxCodecAddedForH264Codec) {
magjed725e4842016-11-16 00:48:13 -0800525 using webrtc::H264::ProfileLevelIdToString;
526 using webrtc::H264::ProfileLevelId;
527 using webrtc::H264::kLevel1;
Anders Carlsson67537952018-05-03 11:28:29 +0200528 webrtc::SdpVideoFormat h264_constrained_baseline("H264");
529 h264_constrained_baseline.parameters[kH264FmtpProfileLevelId] =
magjed725e4842016-11-16 00:48:13 -0800530 *ProfileLevelIdToString(
531 ProfileLevelId(webrtc::H264::kProfileConstrainedBaseline, kLevel1));
Anders Carlsson67537952018-05-03 11:28:29 +0200532 webrtc::SdpVideoFormat h264_constrained_high("H264");
533 h264_constrained_high.parameters[kH264FmtpProfileLevelId] =
magjed725e4842016-11-16 00:48:13 -0800534 *ProfileLevelIdToString(
535 ProfileLevelId(webrtc::H264::kProfileConstrainedHigh, kLevel1));
Anders Carlsson67537952018-05-03 11:28:29 +0200536 webrtc::SdpVideoFormat h264_high("H264");
537 h264_high.parameters[kH264FmtpProfileLevelId] = *ProfileLevelIdToString(
magjed725e4842016-11-16 00:48:13 -0800538 ProfileLevelId(webrtc::H264::kProfileHigh, kLevel1));
539
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200540 encoder_factory_->AddSupportedVideoCodec(h264_constrained_baseline);
541 encoder_factory_->AddSupportedVideoCodec(h264_constrained_high);
542 encoder_factory_->AddSupportedVideoCodec(h264_high);
Taylor Brandstetter6c3e7882016-06-29 11:14:19 -0700543
magjed725e4842016-11-16 00:48:13 -0800544 // First figure out what payload types the test codecs got assigned.
545 const std::vector<cricket::VideoCodec> codecs = engine_.codecs();
magjed509e4fe2016-11-18 01:34:11 -0800546 // Now search for RTX codecs for them. Expect that they all have associated
547 // RTX codecs.
magjed725e4842016-11-16 00:48:13 -0800548 EXPECT_TRUE(HasRtxCodec(
Anders Carlsson67537952018-05-03 11:28:29 +0200549 codecs,
550 FindMatchingCodec(codecs, cricket::VideoCodec(h264_constrained_baseline))
551 ->id));
magjed725e4842016-11-16 00:48:13 -0800552 EXPECT_TRUE(HasRtxCodec(
Anders Carlsson67537952018-05-03 11:28:29 +0200553 codecs,
554 FindMatchingCodec(codecs, cricket::VideoCodec(h264_constrained_high))
555 ->id));
magjed509e4fe2016-11-18 01:34:11 -0800556 EXPECT_TRUE(HasRtxCodec(
Anders Carlsson67537952018-05-03 11:28:29 +0200557 codecs, FindMatchingCodec(codecs, cricket::VideoCodec(h264_high))->id));
Taylor Brandstetter6c3e7882016-06-29 11:14:19 -0700558}
559
Mirko Bonadei8ef57932018-11-16 14:38:03 +0100560#if defined(RTC_ENABLE_VP9)
eladalonf1841382017-06-12 01:16:46 -0700561TEST_F(WebRtcVideoEngineTest, CanConstructDecoderForVp9EncoderFactory) {
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200562 encoder_factory_->AddSupportedVideoCodecType("VP9");
Peter Boström53eda3d2015-03-27 15:53:18 +0100563
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200564 std::unique_ptr<VideoMediaChannel> channel(
565 SetSendParamsWithAllSupportedCodecs());
Peter Boström53eda3d2015-03-27 15:53:18 +0100566
567 EXPECT_TRUE(
568 channel->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
569}
Mirko Bonadei8ef57932018-11-16 14:38:03 +0100570#endif // defined(RTC_ENABLE_VP9)
Peter Boström53eda3d2015-03-27 15:53:18 +0100571
eladalonf1841382017-06-12 01:16:46 -0700572TEST_F(WebRtcVideoEngineTest, PropagatesInputFrameTimestamp) {
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200573 encoder_factory_->AddSupportedVideoCodecType("VP8");
Sebastian Jansson8f83b422018-02-21 13:07:13 +0100574 FakeCall* fake_call = new FakeCall();
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200575 call_.reset(fake_call);
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200576 std::unique_ptr<VideoMediaChannel> channel(
577 SetSendParamsWithAllSupportedCodecs());
qiangchenc27d89f2015-07-16 10:27:16 -0700578
579 EXPECT_TRUE(
580 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
581
Niels Möllerd0f0f682019-01-14 09:09:53 +0100582 webrtc::test::FrameForwarder frame_forwarder;
583 cricket::FakeFrameSource frame_source(1280, 720,
584 rtc::kNumMicrosecsPerSec / 60);
585 EXPECT_TRUE(channel->SetVideoSend(kSsrc, nullptr, &frame_forwarder));
qiangchenc27d89f2015-07-16 10:27:16 -0700586 channel->SetSend(true);
587
Fredrik Solenberg709ed672015-09-15 12:26:33 +0200588 FakeVideoSendStream* stream = fake_call->GetVideoSendStreams()[0];
qiangchenc27d89f2015-07-16 10:27:16 -0700589
Niels Möllerd0f0f682019-01-14 09:09:53 +0100590 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
pbos1cb121d2015-09-14 11:38:38 -0700591 int64_t last_timestamp = stream->GetLastTimestamp();
qiangchenc27d89f2015-07-16 10:27:16 -0700592 for (int i = 0; i < 10; i++) {
Niels Möllerd0f0f682019-01-14 09:09:53 +0100593 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
pbos1cb121d2015-09-14 11:38:38 -0700594 int64_t timestamp = stream->GetLastTimestamp();
qiangchenc27d89f2015-07-16 10:27:16 -0700595 int64_t interval = timestamp - last_timestamp;
596
597 // Precision changes from nanosecond to millisecond.
598 // Allow error to be no more than 1.
599 EXPECT_NEAR(cricket::VideoFormat::FpsToInterval(60) / 1E6, interval, 1);
600
601 last_timestamp = timestamp;
602 }
603
Niels Möllerd0f0f682019-01-14 09:09:53 +0100604 frame_forwarder.IncomingCapturedFrame(
605 frame_source.GetFrame(1280, 720, webrtc::VideoRotation::kVideoRotation_0,
606 rtc::kNumMicrosecsPerSec / 30));
qiangchenc27d89f2015-07-16 10:27:16 -0700607 last_timestamp = stream->GetLastTimestamp();
608 for (int i = 0; i < 10; i++) {
Niels Möllerd0f0f682019-01-14 09:09:53 +0100609 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame(
610 1280, 720, webrtc::VideoRotation::kVideoRotation_0,
611 rtc::kNumMicrosecsPerSec / 30));
pbos1cb121d2015-09-14 11:38:38 -0700612 int64_t timestamp = stream->GetLastTimestamp();
qiangchenc27d89f2015-07-16 10:27:16 -0700613 int64_t interval = timestamp - last_timestamp;
614
615 // Precision changes from nanosecond to millisecond.
616 // Allow error to be no more than 1.
617 EXPECT_NEAR(cricket::VideoFormat::FpsToInterval(30) / 1E6, interval, 1);
618
619 last_timestamp = timestamp;
620 }
621
622 // Remove stream previously added to free the external encoder instance.
623 EXPECT_TRUE(channel->RemoveSendStream(kSsrc));
624}
625
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200626void WebRtcVideoEngineTest::AssignDefaultAptRtxTypes() {
627 std::vector<VideoCodec> engine_codecs = engine_.codecs();
628 RTC_DCHECK(!engine_codecs.empty());
629 for (const cricket::VideoCodec& codec : engine_codecs) {
630 if (codec.name == "rtx") {
631 int associated_payload_type;
632 if (codec.GetParam(kCodecParamAssociatedPayloadType,
633 &associated_payload_type)) {
634 default_apt_rtx_types_[associated_payload_type] = codec.id;
635 }
636 }
637 }
638}
639
640void WebRtcVideoEngineTest::AssignDefaultCodec() {
641 std::vector<VideoCodec> engine_codecs = engine_.codecs();
642 RTC_DCHECK(!engine_codecs.empty());
643 bool codec_set = false;
644 for (const cricket::VideoCodec& codec : engine_codecs) {
645 if (!codec_set && codec.name != "rtx" && codec.name != "red" &&
646 codec.name != "ulpfec") {
647 default_codec_ = codec;
648 codec_set = true;
649 }
650 }
651
652 RTC_DCHECK(codec_set);
653}
654
Oleh Prypina40f8242017-12-21 13:32:23 +0100655size_t WebRtcVideoEngineTest::GetEngineCodecIndex(
656 const std::string& name) const {
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +0100657 const std::vector<cricket::VideoCodec> codecs = engine_.codecs();
658 for (size_t i = 0; i < codecs.size(); ++i) {
659 const cricket::VideoCodec engine_codec = codecs[i];
Niels Möller039743e2018-10-23 10:07:25 +0200660 if (!absl::EqualsIgnoreCase(name, engine_codec.name))
Magnus Jedvert8deb8182017-10-05 13:13:32 +0200661 continue;
662 // The tests only use H264 Constrained Baseline. Make sure we don't return
663 // an internal H264 codec from the engine with a different H264 profile.
Niels Möller039743e2018-10-23 10:07:25 +0200664 if (absl::EqualsIgnoreCase(name.c_str(), kH264CodecName)) {
Danil Chapovalov00c71832018-06-15 15:58:38 +0200665 const absl::optional<webrtc::H264::ProfileLevelId> profile_level_id =
Magnus Jedvert8deb8182017-10-05 13:13:32 +0200666 webrtc::H264::ParseSdpProfileLevelId(engine_codec.params);
667 if (profile_level_id->profile !=
668 webrtc::H264::kProfileConstrainedBaseline) {
669 continue;
670 }
671 }
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +0100672 return i;
magjed509e4fe2016-11-18 01:34:11 -0800673 }
674 // This point should never be reached.
675 ADD_FAILURE() << "Unrecognized codec name: " << name;
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +0100676 return -1;
677}
678
679cricket::VideoCodec WebRtcVideoEngineTest::GetEngineCodec(
680 const std::string& name) const {
681 return engine_.codecs()[GetEngineCodecIndex(name)];
magjed509e4fe2016-11-18 01:34:11 -0800682}
683
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200684VideoMediaChannel*
685WebRtcVideoEngineTest::SetSendParamsWithAllSupportedCodecs() {
Sebastian Jansson84848f22018-11-16 10:40:36 +0100686 VideoMediaChannel* channel = engine_.CreateMediaChannel(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +0200687 call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
688 video_bitrate_allocator_factory_.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200689 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -0800690 // We need to look up the codec in the engine to get the correct payload type.
Anders Carlsson67537952018-05-03 11:28:29 +0200691 for (const webrtc::SdpVideoFormat& format :
692 encoder_factory_->GetSupportedFormats()) {
693 cricket::VideoCodec engine_codec = GetEngineCodec(format.name);
Steve Anton2c9ebef2019-01-28 17:27:58 -0800694 if (!absl::c_linear_search(parameters.codecs, engine_codec)) {
Anders Carlsson67537952018-05-03 11:28:29 +0200695 parameters.codecs.push_back(engine_codec);
696 }
697 }
magjed509e4fe2016-11-18 01:34:11 -0800698
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200699 EXPECT_TRUE(channel->SetSendParameters(parameters));
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000700
701 return channel;
702}
703
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200704VideoMediaChannel* WebRtcVideoEngineTest::SetRecvParamsWithSupportedCodecs(
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000705 const std::vector<VideoCodec>& codecs) {
Sebastian Jansson84848f22018-11-16 10:40:36 +0100706 VideoMediaChannel* channel = engine_.CreateMediaChannel(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +0200707 call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
708 video_bitrate_allocator_factory_.get());
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200709 cricket::VideoRecvParameters parameters;
710 parameters.codecs = codecs;
711 EXPECT_TRUE(channel->SetRecvParameters(parameters));
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000712
713 return channel;
714}
715
Elad Alon157540a2019-02-08 23:37:52 +0100716void WebRtcVideoEngineTest::ExpectRtpCapabilitySupport(const char* uri,
717 bool supported) const {
718 const RtpCapabilities capabilities = engine_.GetCapabilities();
719 if (supported) {
720 EXPECT_THAT(capabilities.header_extensions,
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200721 ::testing::Contains(::testing::Field(&RtpExtension::uri, uri)));
Elad Alon157540a2019-02-08 23:37:52 +0100722 } else {
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200723 EXPECT_THAT(capabilities.header_extensions,
724 ::testing::Each(::testing::Field(&RtpExtension::uri,
725 ::testing::StrNe(uri))));
Elad Alon157540a2019-02-08 23:37:52 +0100726 }
727}
728
eladalonf1841382017-06-12 01:16:46 -0700729TEST_F(WebRtcVideoEngineTest, UsesSimulcastAdapterForVp8Factories) {
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200730 encoder_factory_->AddSupportedVideoCodecType("VP8");
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000731
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200732 std::unique_ptr<VideoMediaChannel> channel(
733 SetSendParamsWithAllSupportedCodecs());
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000734
Peter Boström0c4e06b2015-10-07 12:23:21 +0200735 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000736
Yves Gerey665174f2018-06-19 15:03:05 +0200737 EXPECT_TRUE(channel->AddSendStream(CreateSimStreamParams("cname", ssrcs)));
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000738 EXPECT_TRUE(channel->SetSend(true));
739
Niels Möller805a27e2019-01-21 12:21:27 +0100740 webrtc::test::FrameForwarder frame_forwarder;
741 cricket::FakeFrameSource frame_source(1280, 720,
742 rtc::kNumMicrosecsPerSec / 60);
743 EXPECT_TRUE(channel->SetVideoSend(ssrcs.front(), nullptr, &frame_forwarder));
744 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
pbos@webrtc.org86196c42015-02-16 21:02:00 +0000745
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200746 ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(2));
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000747
748 // Verify that encoders are configured for simulcast through adapter
749 // (increasing resolution and only configured to send one stream each).
750 int prev_width = -1;
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200751 for (size_t i = 0; i < encoder_factory_->encoders().size(); ++i) {
752 ASSERT_TRUE(encoder_factory_->encoders()[i]->WaitForInitEncode());
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000753 webrtc::VideoCodec codec_settings =
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200754 encoder_factory_->encoders()[i]->GetCodecSettings();
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000755 EXPECT_EQ(0, codec_settings.numberOfSimulcastStreams);
756 EXPECT_GT(codec_settings.width, prev_width);
757 prev_width = codec_settings.width;
758 }
pbos@webrtc.org86196c42015-02-16 21:02:00 +0000759
Niels Möllerff40b142018-04-09 08:49:14 +0200760 EXPECT_TRUE(channel->SetVideoSend(ssrcs.front(), nullptr, nullptr));
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000761
762 channel.reset();
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200763 ASSERT_EQ(0u, encoder_factory_->encoders().size());
pbos@webrtc.orgf18fba22015-01-14 16:26:23 +0000764}
765
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200766TEST_F(WebRtcVideoEngineTest, ChannelWithH264CanChangeToVp8) {
767 encoder_factory_->AddSupportedVideoCodecType("VP8");
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200768 encoder_factory_->AddSupportedVideoCodecType("H264");
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000769
Niels Möllerd0f0f682019-01-14 09:09:53 +0100770 // Frame source.
771 webrtc::test::FrameForwarder frame_forwarder;
772 cricket::FakeFrameSource frame_source(1280, 720,
773 rtc::kNumMicrosecsPerSec / 30);
Niels Möller4db138e2018-04-19 09:04:13 +0200774
Sebastian Jansson84848f22018-11-16 10:40:36 +0100775 std::unique_ptr<VideoMediaChannel> channel(engine_.CreateMediaChannel(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +0200776 call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
777 video_bitrate_allocator_factory_.get()));
Anders Carlsson67537952018-05-03 11:28:29 +0200778 cricket::VideoSendParameters parameters;
779 parameters.codecs.push_back(GetEngineCodec("H264"));
780 EXPECT_TRUE(channel->SetSendParameters(parameters));
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000781
782 EXPECT_TRUE(
783 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
Niels Möllerd0f0f682019-01-14 09:09:53 +0100784 EXPECT_TRUE(channel->SetVideoSend(kSsrc, nullptr, &frame_forwarder));
Niels Möller4db138e2018-04-19 09:04:13 +0200785 // Sending one frame will have allocate the 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
788 ASSERT_EQ_WAIT(1u, encoder_factory_->encoders().size(), kTimeout);
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000789
Anders Carlsson67537952018-05-03 11:28:29 +0200790 cricket::VideoSendParameters new_parameters;
791 new_parameters.codecs.push_back(GetEngineCodec("VP8"));
792 EXPECT_TRUE(channel->SetSendParameters(new_parameters));
Niels Möller4db138e2018-04-19 09:04:13 +0200793
794 // Sending one frame will switch encoder.
Niels Möllerd0f0f682019-01-14 09:09:53 +0100795 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
Niels Möller4db138e2018-04-19 09:04:13 +0200796
Anders Carlsson8a150d92018-05-14 12:40:04 +0200797 EXPECT_EQ_WAIT(1u, encoder_factory_->encoders().size(), kTimeout);
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000798}
799
eladalonf1841382017-06-12 01:16:46 -0700800TEST_F(WebRtcVideoEngineTest,
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000801 UsesSimulcastAdapterForVp8WithCombinedVP8AndH264Factory) {
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200802 encoder_factory_->AddSupportedVideoCodecType("VP8");
803 encoder_factory_->AddSupportedVideoCodecType("H264");
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000804
Sebastian Jansson84848f22018-11-16 10:40:36 +0100805 std::unique_ptr<VideoMediaChannel> channel(engine_.CreateMediaChannel(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +0200806 call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
807 video_bitrate_allocator_factory_.get()));
magjed509e4fe2016-11-18 01:34:11 -0800808 cricket::VideoSendParameters parameters;
809 parameters.codecs.push_back(GetEngineCodec("VP8"));
810 EXPECT_TRUE(channel->SetSendParameters(parameters));
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000811
Peter Boström0c4e06b2015-10-07 12:23:21 +0200812 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000813
Yves Gerey665174f2018-06-19 15:03:05 +0200814 EXPECT_TRUE(channel->AddSendStream(CreateSimStreamParams("cname", ssrcs)));
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000815 EXPECT_TRUE(channel->SetSend(true));
816
817 // Send a fake frame, or else the media engine will configure the simulcast
818 // encoder adapter at a low-enough size that it'll only create a single
819 // encoder layer.
Niels Möller805a27e2019-01-21 12:21:27 +0100820 webrtc::test::FrameForwarder frame_forwarder;
821 cricket::FakeFrameSource frame_source(1280, 720,
822 rtc::kNumMicrosecsPerSec / 30);
823 EXPECT_TRUE(channel->SetVideoSend(ssrcs.front(), nullptr, &frame_forwarder));
824 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000825
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200826 ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(2));
827 ASSERT_TRUE(encoder_factory_->encoders()[0]->WaitForInitEncode());
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000828 EXPECT_EQ(webrtc::kVideoCodecVP8,
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200829 encoder_factory_->encoders()[0]->GetCodecSettings().codecType);
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000830
831 channel.reset();
832 // Make sure DestroyVideoEncoder was called on the factory.
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200833 EXPECT_EQ(0u, encoder_factory_->encoders().size());
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000834}
835
eladalonf1841382017-06-12 01:16:46 -0700836TEST_F(WebRtcVideoEngineTest,
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000837 DestroysNonSimulcastEncoderFromCombinedVP8AndH264Factory) {
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200838 encoder_factory_->AddSupportedVideoCodecType("VP8");
839 encoder_factory_->AddSupportedVideoCodecType("H264");
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000840
Sebastian Jansson84848f22018-11-16 10:40:36 +0100841 std::unique_ptr<VideoMediaChannel> channel(engine_.CreateMediaChannel(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +0200842 call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
843 video_bitrate_allocator_factory_.get()));
magjed509e4fe2016-11-18 01:34:11 -0800844 cricket::VideoSendParameters parameters;
845 parameters.codecs.push_back(GetEngineCodec("H264"));
846 EXPECT_TRUE(channel->SetSendParameters(parameters));
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000847
848 EXPECT_TRUE(
849 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
Per21d45d22016-10-30 21:37:57 +0100850
851 // Send a frame of 720p. This should trigger a "real" encoder initialization.
Niels Möller805a27e2019-01-21 12:21:27 +0100852 webrtc::test::FrameForwarder frame_forwarder;
853 cricket::FakeFrameSource frame_source(1280, 720,
854 rtc::kNumMicrosecsPerSec / 30);
855 EXPECT_TRUE(channel->SetVideoSend(kSsrc, nullptr, &frame_forwarder));
856 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
Niels Möller4db138e2018-04-19 09:04:13 +0200857 ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(1));
858 ASSERT_EQ(1u, encoder_factory_->encoders().size());
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200859 ASSERT_TRUE(encoder_factory_->encoders()[0]->WaitForInitEncode());
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000860 EXPECT_EQ(webrtc::kVideoCodecH264,
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200861 encoder_factory_->encoders()[0]->GetCodecSettings().codecType);
pthatcher@webrtc.org818c4982015-03-06 02:20:58 +0000862
863 channel.reset();
864 // Make sure DestroyVideoEncoder was called on the factory.
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200865 ASSERT_EQ(0u, encoder_factory_->encoders().size());
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000866}
867
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200868TEST_F(WebRtcVideoEngineTest, SimulcastEnabledForH264BehindFieldTrial) {
869 webrtc::test::ScopedFieldTrials override_field_trials_(
870 "WebRTC-H264Simulcast/Enabled/");
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200871 encoder_factory_->AddSupportedVideoCodecType("H264");
noahricfdac5162015-08-27 01:59:29 -0700872
Sebastian Jansson84848f22018-11-16 10:40:36 +0100873 std::unique_ptr<VideoMediaChannel> channel(engine_.CreateMediaChannel(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +0200874 call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
875 video_bitrate_allocator_factory_.get()));
Anders Carlsson67537952018-05-03 11:28:29 +0200876 cricket::VideoSendParameters parameters;
877 parameters.codecs.push_back(GetEngineCodec("H264"));
878 EXPECT_TRUE(channel->SetSendParameters(parameters));
noahricfdac5162015-08-27 01:59:29 -0700879
Peter Boström0c4e06b2015-10-07 12:23:21 +0200880 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
noahricfdac5162015-08-27 01:59:29 -0700881 EXPECT_TRUE(
882 channel->AddSendStream(cricket::CreateSimStreamParams("cname", ssrcs)));
Peter Boströmce23bee2016-02-02 14:14:30 +0100883
884 // Send a frame of 720p. This should trigger a "real" encoder initialization.
Niels Möller805a27e2019-01-21 12:21:27 +0100885 webrtc::test::FrameForwarder frame_forwarder;
886 cricket::FakeFrameSource frame_source(1280, 720,
887 rtc::kNumMicrosecsPerSec / 30);
888 EXPECT_TRUE(channel->SetVideoSend(ssrcs[0], nullptr, &frame_forwarder));
889 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
Peter Boströmce23bee2016-02-02 14:14:30 +0100890
Niels Möller4db138e2018-04-19 09:04:13 +0200891 ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(1));
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200892 ASSERT_EQ(1u, encoder_factory_->encoders().size());
893 FakeWebRtcVideoEncoder* encoder = encoder_factory_->encoders()[0];
894 ASSERT_TRUE(encoder_factory_->encoders()[0]->WaitForInitEncode());
noahricfdac5162015-08-27 01:59:29 -0700895 EXPECT_EQ(webrtc::kVideoCodecH264, encoder->GetCodecSettings().codecType);
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +0200896 EXPECT_LT(1u, encoder->GetCodecSettings().numberOfSimulcastStreams);
Niels Möllerff40b142018-04-09 08:49:14 +0200897 EXPECT_TRUE(channel->SetVideoSend(ssrcs[0], nullptr, nullptr));
noahricfdac5162015-08-27 01:59:29 -0700898}
899
brandtrffc61182016-11-28 06:02:22 -0800900// Test that the FlexFEC field trial properly alters the output of
eladalonf1841382017-06-12 01:16:46 -0700901// WebRtcVideoEngine::codecs(), for an existing |engine_| object.
brandtrffc61182016-11-28 06:02:22 -0800902//
903// TODO(brandtr): Remove this test, when the FlexFEC field trial is gone.
eladalonf1841382017-06-12 01:16:46 -0700904TEST_F(WebRtcVideoEngineTest,
brandtrffc61182016-11-28 06:02:22 -0800905 Flexfec03SupportedAsInternalCodecBehindFieldTrial) {
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200906 encoder_factory_->AddSupportedVideoCodecType("VP8");
907
Steve Anton2c9ebef2019-01-28 17:27:58 -0800908 auto flexfec = Field("name", &VideoCodec::name, "flexfec-03");
brandtrffc61182016-11-28 06:02:22 -0800909
910 // FlexFEC is not active without field trial.
Steve Anton2c9ebef2019-01-28 17:27:58 -0800911 EXPECT_THAT(engine_.codecs(), Not(Contains(flexfec)));
brandtrffc61182016-11-28 06:02:22 -0800912
913 // FlexFEC is active with field trial.
914 webrtc::test::ScopedFieldTrials override_field_trials_(
brandtr340e3fd2017-02-28 15:43:10 -0800915 "WebRTC-FlexFEC-03-Advertised/Enabled/");
Steve Anton2c9ebef2019-01-28 17:27:58 -0800916 EXPECT_THAT(engine_.codecs(), Contains(flexfec));
brandtrffc61182016-11-28 06:02:22 -0800917}
918
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200919// Test that codecs are added in the order they are reported from the factory.
920TEST_F(WebRtcVideoEngineTest, ReportSupportedCodecs) {
921 encoder_factory_->AddSupportedVideoCodecType("VP8");
922 const char* kFakeCodecName = "FakeCodec";
923 encoder_factory_->AddSupportedVideoCodecType(kFakeCodecName);
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000924
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200925 // The last reported codec should appear after the first codec in the vector.
Oleh Prypina40f8242017-12-21 13:32:23 +0100926 const size_t vp8_index = GetEngineCodecIndex("VP8");
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200927 const size_t fake_codec_index = GetEngineCodecIndex(kFakeCodecName);
928 EXPECT_LT(vp8_index, fake_codec_index);
pbos@webrtc.org7fe1e032014-10-14 04:25:33 +0000929}
930
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200931// Test that a codec that was added after the engine was initialized
brandtrffc61182016-11-28 06:02:22 -0800932// does show up in the codec list after it was added.
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200933TEST_F(WebRtcVideoEngineTest, ReportSupportedAddedCodec) {
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +0100934 const char* kFakeExternalCodecName1 = "FakeExternalCodec1";
935 const char* kFakeExternalCodecName2 = "FakeExternalCodec2";
Magnus Jedvert154ee1f2017-11-15 19:27:11 +0100936
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +0100937 // Set up external encoder factory with first codec, and initialize engine.
938 encoder_factory_->AddSupportedVideoCodecType(kFakeExternalCodecName1);
939
brandtrffc61182016-11-28 06:02:22 -0800940 std::vector<cricket::VideoCodec> codecs_before(engine_.codecs());
brandtrffc61182016-11-28 06:02:22 -0800941
942 // Add second codec.
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +0100943 encoder_factory_->AddSupportedVideoCodecType(kFakeExternalCodecName2);
brandtrffc61182016-11-28 06:02:22 -0800944 std::vector<cricket::VideoCodec> codecs_after(engine_.codecs());
Sami Kalliomäkie9a18b22018-07-13 10:28:21 +0200945 // The codec itself and RTX should have been added.
946 EXPECT_EQ(codecs_before.size() + 2, codecs_after.size());
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +0100947
948 // Check that both fake codecs are present and that the second fake codec
949 // appears after the first fake codec.
Oleh Prypina40f8242017-12-21 13:32:23 +0100950 const size_t fake_codec_index1 = GetEngineCodecIndex(kFakeExternalCodecName1);
951 const size_t fake_codec_index2 = GetEngineCodecIndex(kFakeExternalCodecName2);
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +0100952 EXPECT_LT(fake_codec_index1, fake_codec_index2);
brandtrffc61182016-11-28 06:02:22 -0800953}
954
Sami Kalliomäkie9a18b22018-07-13 10:28:21 +0200955TEST_F(WebRtcVideoEngineTest, ReportRtxForExternalCodec) {
956 const char* kFakeCodecName = "FakeCodec";
957 encoder_factory_->AddSupportedVideoCodecType(kFakeCodecName);
958
959 const size_t fake_codec_index = GetEngineCodecIndex(kFakeCodecName);
960 EXPECT_EQ("rtx", engine_.codecs().at(fake_codec_index + 1).name);
961}
962
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200963TEST_F(WebRtcVideoEngineTest, RegisterDecodersIfSupported) {
964 encoder_factory_->AddSupportedVideoCodecType("VP8");
Anders Carlsson67537952018-05-03 11:28:29 +0200965 decoder_factory_->AddSupportedVideoCodecType(webrtc::SdpVideoFormat("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200966 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -0800967 parameters.codecs.push_back(GetEngineCodec("VP8"));
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000968
kwiberg686a8ef2016-02-26 03:00:35 -0800969 std::unique_ptr<VideoMediaChannel> channel(
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200970 SetRecvParamsWithSupportedCodecs(parameters.codecs));
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000971
972 EXPECT_TRUE(
973 channel->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200974 ASSERT_EQ(1u, decoder_factory_->decoders().size());
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000975
976 // Setting codecs of the same type should not reallocate the decoder.
Fredrik Solenbergb071a192015-09-17 16:42:56 +0200977 EXPECT_TRUE(channel->SetRecvParameters(parameters));
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200978 EXPECT_EQ(1, decoder_factory_->GetNumCreatedDecoders());
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000979
980 // Remove stream previously added to free the external decoder instance.
981 EXPECT_TRUE(channel->RemoveRecvStream(kSsrc));
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200982 EXPECT_EQ(0u, decoder_factory_->decoders().size());
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000983}
984
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200985// Verifies that we can set up decoders.
986TEST_F(WebRtcVideoEngineTest, RegisterH264DecoderIfSupported) {
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000987 // TODO(pbos): Do not assume that encoder/decoder support is symmetric. We
988 // can't even query the WebRtcVideoDecoderFactory for supported codecs.
989 // For now we add a FakeWebRtcVideoEncoderFactory to add H264 to supported
990 // codecs.
Magnus Jedvert02e7a192017-09-23 17:21:32 +0200991 encoder_factory_->AddSupportedVideoCodecType("H264");
Anders Carlsson67537952018-05-03 11:28:29 +0200992 decoder_factory_->AddSupportedVideoCodecType(webrtc::SdpVideoFormat("H264"));
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000993 std::vector<cricket::VideoCodec> codecs;
magjed509e4fe2016-11-18 01:34:11 -0800994 codecs.push_back(GetEngineCodec("H264"));
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000995
kwiberg686a8ef2016-02-26 03:00:35 -0800996 std::unique_ptr<VideoMediaChannel> channel(
Anders Carlsson5f2bb622018-05-14 09:48:06 +0200997 SetRecvParamsWithSupportedCodecs(codecs));
pbos@webrtc.org96a93252014-11-03 14:46:44 +0000998
999 EXPECT_TRUE(
1000 channel->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001001 ASSERT_EQ(1u, decoder_factory_->decoders().size());
pbos@webrtc.org96a93252014-11-03 14:46:44 +00001002}
1003
Jonas Oreland49ac5952018-09-26 16:04:32 +02001004// Tests when GetSources is called with non-existing ssrc, it will return an
1005// empty list of RtpSource without crashing.
1006TEST_F(WebRtcVideoEngineTest, GetSourcesWithNonExistingSsrc) {
1007 // Setup an recv stream with |kSsrc|.
1008 encoder_factory_->AddSupportedVideoCodecType("VP8");
1009 decoder_factory_->AddSupportedVideoCodecType(webrtc::SdpVideoFormat("VP8"));
1010 cricket::VideoRecvParameters parameters;
1011 parameters.codecs.push_back(GetEngineCodec("VP8"));
1012 std::unique_ptr<VideoMediaChannel> channel(
1013 SetRecvParamsWithSupportedCodecs(parameters.codecs));
1014
1015 EXPECT_TRUE(
1016 channel->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
1017
1018 // Call GetSources with |kSsrc + 1| which doesn't exist.
1019 std::vector<webrtc::RtpSource> sources = channel->GetSources(kSsrc + 1);
1020 EXPECT_EQ(0u, sources.size());
1021}
1022
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001023TEST(WebRtcVideoEngineNewVideoCodecFactoryTest, NullFactories) {
1024 std::unique_ptr<webrtc::VideoEncoderFactory> encoder_factory;
1025 std::unique_ptr<webrtc::VideoDecoderFactory> decoder_factory;
1026 WebRtcVideoEngine engine(std::move(encoder_factory),
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02001027 std::move(decoder_factory));
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001028 EXPECT_EQ(0u, engine.codecs().size());
1029}
1030
1031TEST(WebRtcVideoEngineNewVideoCodecFactoryTest, EmptyFactories) {
1032 // |engine| take ownership of the factories.
Emircan Uysalerdbcac7f2017-10-30 23:10:12 -07001033 webrtc::MockVideoEncoderFactory* encoder_factory =
1034 new webrtc::MockVideoEncoderFactory();
1035 webrtc::MockVideoDecoderFactory* decoder_factory =
1036 new webrtc::MockVideoDecoderFactory();
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001037 WebRtcVideoEngine engine(
1038 (std::unique_ptr<webrtc::VideoEncoderFactory>(encoder_factory)),
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02001039 (std::unique_ptr<webrtc::VideoDecoderFactory>(decoder_factory)));
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001040 EXPECT_CALL(*encoder_factory, GetSupportedFormats());
1041 EXPECT_EQ(0u, engine.codecs().size());
1042 EXPECT_CALL(*encoder_factory, Die());
1043 EXPECT_CALL(*decoder_factory, Die());
1044}
1045
1046// Test full behavior in the video engine when video codec factories of the new
1047// type are injected supporting the single codec Vp8. Check the returned codecs
1048// from the engine and that we will create a Vp8 encoder and decoder using the
1049// new factories.
1050TEST(WebRtcVideoEngineNewVideoCodecFactoryTest, Vp8) {
1051 // |engine| take ownership of the factories.
Emircan Uysalerdbcac7f2017-10-30 23:10:12 -07001052 webrtc::MockVideoEncoderFactory* encoder_factory =
1053 new webrtc::MockVideoEncoderFactory();
1054 webrtc::MockVideoDecoderFactory* decoder_factory =
1055 new webrtc::MockVideoDecoderFactory();
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02001056 std::unique_ptr<webrtc::MockVideoBitrateAllocatorFactory>
1057 rate_allocator_factory =
1058 absl::make_unique<webrtc::MockVideoBitrateAllocatorFactory>();
Jiawei Ouc2ebe212018-11-08 10:02:56 -08001059 EXPECT_CALL(*rate_allocator_factory,
1060 CreateVideoBitrateAllocatorProxy(Field(
1061 &webrtc::VideoCodec::codecType, webrtc::kVideoCodecVP8)))
Mirko Bonadei6a489f22019-04-09 15:11:12 +02001062 .WillOnce(::testing::Return(new webrtc::MockVideoBitrateAllocator()));
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001063 WebRtcVideoEngine engine(
1064 (std::unique_ptr<webrtc::VideoEncoderFactory>(encoder_factory)),
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02001065 (std::unique_ptr<webrtc::VideoDecoderFactory>(decoder_factory)));
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001066 const webrtc::SdpVideoFormat vp8_format("VP8");
1067 const std::vector<webrtc::SdpVideoFormat> supported_formats = {vp8_format};
1068 EXPECT_CALL(*encoder_factory, GetSupportedFormats())
Mirko Bonadei6a489f22019-04-09 15:11:12 +02001069 .WillRepeatedly(::testing::Return(supported_formats));
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001070
1071 // Verify the codecs from the engine.
1072 const std::vector<VideoCodec> engine_codecs = engine.codecs();
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +01001073 // Verify default codecs has been added correctly.
1074 EXPECT_EQ(5u, engine_codecs.size());
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001075 EXPECT_EQ("VP8", engine_codecs.at(0).name);
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +01001076
1077 // RTX codec for VP8.
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001078 EXPECT_EQ("rtx", engine_codecs.at(1).name);
Magnus Jedvert9b16e2d2017-11-18 12:08:55 +01001079 int vp8_associated_payload;
1080 EXPECT_TRUE(engine_codecs.at(1).GetParam(kCodecParamAssociatedPayloadType,
1081 &vp8_associated_payload));
1082 EXPECT_EQ(vp8_associated_payload, engine_codecs.at(0).id);
1083
1084 EXPECT_EQ(kRedCodecName, engine_codecs.at(2).name);
1085
1086 // RTX codec for RED.
1087 EXPECT_EQ("rtx", engine_codecs.at(3).name);
1088 int red_associated_payload;
1089 EXPECT_TRUE(engine_codecs.at(3).GetParam(kCodecParamAssociatedPayloadType,
1090 &red_associated_payload));
1091 EXPECT_EQ(red_associated_payload, engine_codecs.at(2).id);
1092
1093 EXPECT_EQ(kUlpfecCodecName, engine_codecs.at(4).name);
1094
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001095 int associated_payload_type;
1096 EXPECT_TRUE(engine_codecs.at(1).GetParam(
1097 cricket::kCodecParamAssociatedPayloadType, &associated_payload_type));
1098 EXPECT_EQ(engine_codecs.at(0).id, associated_payload_type);
1099 // Verify default parameters has been added to the VP8 codec.
1100 VerifyCodecHasDefaultFeedbackParams(engine_codecs.at(0));
1101
1102 // Mock encoder creation. |engine| take ownership of the encoder.
Mirta Dvornicic1ec2a162018-12-10 09:47:34 +00001103 webrtc::VideoEncoderFactory::CodecInfo codec_info;
1104 codec_info.is_hardware_accelerated = false;
1105 codec_info.has_internal_source = false;
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001106 const webrtc::SdpVideoFormat format("VP8");
Mirta Dvornicic1ec2a162018-12-10 09:47:34 +00001107 EXPECT_CALL(*encoder_factory, QueryVideoEncoder(format))
Mirko Bonadei6a489f22019-04-09 15:11:12 +02001108 .WillRepeatedly(::testing::Return(codec_info));
Anders Carlsson67537952018-05-03 11:28:29 +02001109 FakeWebRtcVideoEncoder* const encoder = new FakeWebRtcVideoEncoder(nullptr);
Niels Möllerc572ff32018-11-07 08:43:50 +01001110 rtc::Event encoder_created;
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001111 EXPECT_CALL(*encoder_factory, CreateVideoEncoderProxy(format))
Niels Möller4db138e2018-04-19 09:04:13 +02001112 .WillOnce(
1113 ::testing::DoAll(::testing::InvokeWithoutArgs(
1114 [&encoder_created]() { encoder_created.Set(); }),
1115 ::testing::Return(encoder)));
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001116
1117 // Mock decoder creation. |engine| take ownership of the decoder.
Anders Carlsson67537952018-05-03 11:28:29 +02001118 FakeWebRtcVideoDecoder* const decoder = new FakeWebRtcVideoDecoder(nullptr);
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001119 EXPECT_CALL(*decoder_factory, CreateVideoDecoderProxy(format))
Mirko Bonadei6a489f22019-04-09 15:11:12 +02001120 .WillOnce(::testing::Return(decoder));
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001121
1122 // Create a call.
1123 webrtc::RtcEventLogNullImpl event_log;
1124 std::unique_ptr<webrtc::Call> call(
1125 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
1126
1127 // Create send channel.
1128 const int send_ssrc = 123;
Sebastian Jansson84848f22018-11-16 10:40:36 +01001129 std::unique_ptr<VideoMediaChannel> send_channel(engine.CreateMediaChannel(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02001130 call.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
1131 rate_allocator_factory.get()));
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001132 cricket::VideoSendParameters send_parameters;
1133 send_parameters.codecs.push_back(engine_codecs.at(0));
1134 EXPECT_TRUE(send_channel->SetSendParameters(send_parameters));
1135 send_channel->OnReadyToSend(true);
1136 EXPECT_TRUE(
1137 send_channel->AddSendStream(StreamParams::CreateLegacy(send_ssrc)));
1138 EXPECT_TRUE(send_channel->SetSend(true));
1139
Niels Möller4db138e2018-04-19 09:04:13 +02001140 // Set capturer.
Niels Möller805a27e2019-01-21 12:21:27 +01001141 webrtc::test::FrameForwarder frame_forwarder;
1142 cricket::FakeFrameSource frame_source(1280, 720,
1143 rtc::kNumMicrosecsPerSec / 30);
1144 EXPECT_TRUE(send_channel->SetVideoSend(send_ssrc, nullptr, &frame_forwarder));
Niels Möller4db138e2018-04-19 09:04:13 +02001145 // Sending one frame will allocate the encoder.
Niels Möller805a27e2019-01-21 12:21:27 +01001146 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
Niels Möller4db138e2018-04-19 09:04:13 +02001147 encoder_created.Wait(kTimeout);
1148
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001149 // Create recv channel.
1150 const int recv_ssrc = 321;
Sebastian Jansson84848f22018-11-16 10:40:36 +01001151 std::unique_ptr<VideoMediaChannel> recv_channel(engine.CreateMediaChannel(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02001152 call.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
1153 rate_allocator_factory.get()));
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001154 cricket::VideoRecvParameters recv_parameters;
1155 recv_parameters.codecs.push_back(engine_codecs.at(0));
1156 EXPECT_TRUE(recv_channel->SetRecvParameters(recv_parameters));
1157 EXPECT_TRUE(recv_channel->AddRecvStream(
1158 cricket::StreamParams::CreateLegacy(recv_ssrc)));
1159
1160 // Remove streams previously added to free the encoder and decoder instance.
1161 EXPECT_CALL(*encoder_factory, Die());
1162 EXPECT_CALL(*decoder_factory, Die());
Jiawei Ouc2ebe212018-11-08 10:02:56 -08001163 EXPECT_CALL(*rate_allocator_factory, Die());
Magnus Jedvertd4b0c052017-09-14 10:24:54 +02001164 EXPECT_TRUE(send_channel->RemoveSendStream(send_ssrc));
1165 EXPECT_TRUE(recv_channel->RemoveRecvStream(recv_ssrc));
1166}
1167
Magnus Jedvert7501b1c2017-11-09 13:43:42 +01001168// Test behavior when decoder factory fails to create a decoder (returns null).
1169TEST(WebRtcVideoEngineNewVideoCodecFactoryTest, NullDecoder) {
1170 // |engine| take ownership of the factories.
1171 webrtc::MockVideoEncoderFactory* encoder_factory =
Jiawei Ouc2ebe212018-11-08 10:02:56 -08001172 new webrtc::MockVideoEncoderFactory();
Magnus Jedvert7501b1c2017-11-09 13:43:42 +01001173 webrtc::MockVideoDecoderFactory* decoder_factory =
Jiawei Ouc2ebe212018-11-08 10:02:56 -08001174 new webrtc::MockVideoDecoderFactory();
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02001175 std::unique_ptr<webrtc::MockVideoBitrateAllocatorFactory>
1176 rate_allocator_factory =
1177 absl::make_unique<webrtc::MockVideoBitrateAllocatorFactory>();
Magnus Jedvert7501b1c2017-11-09 13:43:42 +01001178 WebRtcVideoEngine engine(
1179 (std::unique_ptr<webrtc::VideoEncoderFactory>(encoder_factory)),
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02001180 (std::unique_ptr<webrtc::VideoDecoderFactory>(decoder_factory)));
Magnus Jedvert7501b1c2017-11-09 13:43:42 +01001181 const webrtc::SdpVideoFormat vp8_format("VP8");
1182 const std::vector<webrtc::SdpVideoFormat> supported_formats = {vp8_format};
1183 EXPECT_CALL(*encoder_factory, GetSupportedFormats())
Mirko Bonadei6a489f22019-04-09 15:11:12 +02001184 .WillRepeatedly(::testing::Return(supported_formats));
Magnus Jedvert7501b1c2017-11-09 13:43:42 +01001185
1186 // Decoder creation fails.
Mirko Bonadei6a489f22019-04-09 15:11:12 +02001187 EXPECT_CALL(*decoder_factory, CreateVideoDecoderProxy(::testing::_))
1188 .WillOnce(::testing::Return(nullptr));
Magnus Jedvert7501b1c2017-11-09 13:43:42 +01001189
1190 // Create a call.
1191 webrtc::RtcEventLogNullImpl event_log;
1192 std::unique_ptr<webrtc::Call> call(
1193 webrtc::Call::Create(webrtc::Call::Config(&event_log)));
1194
1195 // Create recv channel.
1196 const int recv_ssrc = 321;
Sebastian Jansson84848f22018-11-16 10:40:36 +01001197 std::unique_ptr<VideoMediaChannel> recv_channel(engine.CreateMediaChannel(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02001198 call.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
1199 rate_allocator_factory.get()));
Magnus Jedvert7501b1c2017-11-09 13:43:42 +01001200 cricket::VideoRecvParameters recv_parameters;
1201 recv_parameters.codecs.push_back(engine.codecs().front());
1202 EXPECT_TRUE(recv_channel->SetRecvParameters(recv_parameters));
1203 EXPECT_TRUE(recv_channel->AddRecvStream(
1204 cricket::StreamParams::CreateLegacy(recv_ssrc)));
1205
1206 // Remove streams previously added to free the encoder and decoder instance.
1207 EXPECT_TRUE(recv_channel->RemoveRecvStream(recv_ssrc));
1208}
1209
eladalonf1841382017-06-12 01:16:46 -07001210TEST_F(WebRtcVideoEngineTest, DISABLED_RecreatesEncoderOnContentTypeChange) {
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001211 encoder_factory_->AddSupportedVideoCodecType("VP8");
Sebastian Jansson8f83b422018-02-21 13:07:13 +01001212 std::unique_ptr<FakeCall> fake_call(new FakeCall());
Anders Carlsson5f2bb622018-05-14 09:48:06 +02001213 std::unique_ptr<VideoMediaChannel> channel(
1214 SetSendParamsWithAllSupportedCodecs());
sprangf24a0642017-02-28 13:23:26 -08001215 ASSERT_TRUE(
1216 channel->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
1217 cricket::VideoCodec codec = GetEngineCodec("VP8");
1218 cricket::VideoSendParameters parameters;
1219 parameters.codecs.push_back(codec);
1220 channel->OnReadyToSend(true);
1221 channel->SetSend(true);
1222 ASSERT_TRUE(channel->SetSendParameters(parameters));
1223
Niels Möller805a27e2019-01-21 12:21:27 +01001224 webrtc::test::FrameForwarder frame_forwarder;
1225 cricket::FakeFrameSource frame_source(1280, 720,
1226 rtc::kNumMicrosecsPerSec / 30);
sprangf24a0642017-02-28 13:23:26 -08001227 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01001228 EXPECT_TRUE(channel->SetVideoSend(kSsrc, &options, &frame_forwarder));
sprangf24a0642017-02-28 13:23:26 -08001229
Niels Möller805a27e2019-01-21 12:21:27 +01001230 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001231 ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(1));
Niels Möllere3cf3d02018-06-13 11:52:16 +02001232 EXPECT_EQ(webrtc::VideoCodecMode::kRealtimeVideo,
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001233 encoder_factory_->encoders().back()->GetCodecSettings().mode);
sprangf24a0642017-02-28 13:23:26 -08001234
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 // No change in content type, keep current encoder.
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001238 EXPECT_EQ(1, encoder_factory_->GetNumCreatedEncoders());
sprangf24a0642017-02-28 13:23:26 -08001239
1240 options.is_screencast.emplace(true);
Niels Möller805a27e2019-01-21 12:21:27 +01001241 EXPECT_TRUE(channel->SetVideoSend(kSsrc, &options, &frame_forwarder));
1242 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
sprangf24a0642017-02-28 13:23:26 -08001243 // Change to screen content, recreate encoder. For the simulcast encoder
1244 // adapter case, this will result in two calls since InitEncode triggers a
1245 // a new instance.
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001246 ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(2));
Niels Möllere3cf3d02018-06-13 11:52:16 +02001247 EXPECT_EQ(webrtc::VideoCodecMode::kScreensharing,
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001248 encoder_factory_->encoders().back()->GetCodecSettings().mode);
sprangf24a0642017-02-28 13:23:26 -08001249
Niels Möller805a27e2019-01-21 12:21:27 +01001250 EXPECT_TRUE(channel->SetVideoSend(kSsrc, &options, &frame_forwarder));
1251 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
sprangf24a0642017-02-28 13:23:26 -08001252 // Still screen content, no need to update encoder.
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001253 EXPECT_EQ(2, encoder_factory_->GetNumCreatedEncoders());
sprangf24a0642017-02-28 13:23:26 -08001254
1255 options.is_screencast.emplace(false);
1256 options.video_noise_reduction.emplace(false);
Niels Möller805a27e2019-01-21 12:21:27 +01001257 EXPECT_TRUE(channel->SetVideoSend(kSsrc, &options, &frame_forwarder));
sprangf24a0642017-02-28 13:23:26 -08001258 // Change back to regular video content, update encoder. Also change
1259 // a non |is_screencast| option just to verify it doesn't affect recreation.
Niels Möller805a27e2019-01-21 12:21:27 +01001260 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001261 ASSERT_TRUE(encoder_factory_->WaitForCreatedVideoEncoders(3));
Niels Möllere3cf3d02018-06-13 11:52:16 +02001262 EXPECT_EQ(webrtc::VideoCodecMode::kRealtimeVideo,
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001263 encoder_factory_->encoders().back()->GetCodecSettings().mode);
sprangf24a0642017-02-28 13:23:26 -08001264
1265 // Remove stream previously added to free the external encoder instance.
1266 EXPECT_TRUE(channel->RemoveSendStream(kSsrc));
Magnus Jedvert02e7a192017-09-23 17:21:32 +02001267 EXPECT_EQ(0u, encoder_factory_->encoders().size());
sprangf24a0642017-02-28 13:23:26 -08001268}
1269
Mirko Bonadei6a489f22019-04-09 15:11:12 +02001270class WebRtcVideoChannelBaseTest : public ::testing::Test {
Niels Möller6557d0c2018-04-11 15:18:34 +02001271 protected:
1272 WebRtcVideoChannelBaseTest()
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02001273 : video_bitrate_allocator_factory_(
1274 webrtc::CreateBuiltinVideoBitrateAllocatorFactory()),
1275 engine_(webrtc::CreateBuiltinVideoEncoderFactory(),
1276 webrtc::CreateBuiltinVideoDecoderFactory()) {}
Niels Möller6557d0c2018-04-11 15:18:34 +02001277
1278 virtual void SetUp() {
Jonas Oreland49ac5952018-09-26 16:04:32 +02001279 // One testcase calls SetUp in a loop, only create call_ once.
1280 if (!call_) {
1281 call_.reset(webrtc::Call::Create(webrtc::Call::Config(&event_log_)));
1282 }
Niels Möller6557d0c2018-04-11 15:18:34 +02001283 cricket::MediaConfig media_config;
1284 // Disabling cpu overuse detection actually disables quality scaling too; it
1285 // implies DegradationPreference kMaintainResolution. Automatic scaling
1286 // needs to be disabled, otherwise, tests which check the size of received
1287 // frames become flaky.
1288 media_config.video.enable_cpu_adaptation = false;
Sebastian Jansson84848f22018-11-16 10:40:36 +01001289 channel_.reset(
1290 static_cast<cricket::WebRtcVideoChannel*>(engine_.CreateMediaChannel(
1291 call_.get(), media_config, cricket::VideoOptions(),
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02001292 webrtc::CryptoOptions(), video_bitrate_allocator_factory_.get())));
Niels Möller6557d0c2018-04-11 15:18:34 +02001293 channel_->OnReadyToSend(true);
1294 EXPECT_TRUE(channel_.get() != NULL);
1295 network_interface_.SetDestination(channel_.get());
Anton Sukhanov4f08faa2019-05-21 11:12:57 -07001296 channel_->SetInterface(&network_interface_, webrtc::MediaTransportConfig());
Niels Möller6557d0c2018-04-11 15:18:34 +02001297 cricket::VideoRecvParameters parameters;
1298 parameters.codecs = engine_.codecs();
1299 channel_->SetRecvParameters(parameters);
1300 EXPECT_TRUE(channel_->AddSendStream(DefaultSendStreamParams()));
Niels Möller805a27e2019-01-21 12:21:27 +01001301 frame_forwarder_ = absl::make_unique<webrtc::test::FrameForwarder>();
1302 frame_source_ = absl::make_unique<cricket::FakeFrameSource>(
1303 640, 480, rtc::kNumMicrosecsPerSec / kFramerate);
1304 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, nullptr, frame_forwarder_.get()));
Niels Möller6557d0c2018-04-11 15:18:34 +02001305 }
1306
1307 // Utility method to setup an additional stream to send and receive video.
1308 // Used to test send and recv between two streams.
1309 void SetUpSecondStream() {
1310 SetUpSecondStreamWithNoRecv();
1311 // Setup recv for second stream.
1312 EXPECT_TRUE(channel_->AddRecvStream(
1313 cricket::StreamParams::CreateLegacy(kSsrc + 2)));
1314 // Make the second renderer available for use by a new stream.
1315 EXPECT_TRUE(channel_->SetSink(kSsrc + 2, &renderer2_));
1316 }
1317 // Setup an additional stream just to send video. Defer add recv stream.
1318 // This is required if you want to test unsignalled recv of video rtp packets.
1319 void SetUpSecondStreamWithNoRecv() {
1320 // SetUp() already added kSsrc make sure duplicate SSRCs cant be added.
Yves Gerey665174f2018-06-19 15:03:05 +02001321 EXPECT_TRUE(
1322 channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
Niels Möller6557d0c2018-04-11 15:18:34 +02001323 EXPECT_TRUE(channel_->SetSink(kSsrc, &renderer_));
Yves Gerey665174f2018-06-19 15:03:05 +02001324 EXPECT_FALSE(
1325 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
Niels Möller6557d0c2018-04-11 15:18:34 +02001326 EXPECT_TRUE(channel_->AddSendStream(
1327 cricket::StreamParams::CreateLegacy(kSsrc + 2)));
1328 // We dont add recv for the second stream.
1329
1330 // Setup the receive and renderer for second stream after send.
Niels Möller805a27e2019-01-21 12:21:27 +01001331 frame_forwarder_2_ = absl::make_unique<webrtc::test::FrameForwarder>();
Yves Gerey665174f2018-06-19 15:03:05 +02001332 EXPECT_TRUE(
Niels Möller805a27e2019-01-21 12:21:27 +01001333 channel_->SetVideoSend(kSsrc + 2, nullptr, frame_forwarder_2_.get()));
Niels Möller6557d0c2018-04-11 15:18:34 +02001334 }
Yves Gerey665174f2018-06-19 15:03:05 +02001335 virtual void TearDown() { channel_.reset(); }
1336 bool SetDefaultCodec() { return SetOneCodec(DefaultCodec()); }
Niels Möller6557d0c2018-04-11 15:18:34 +02001337
1338 bool SetOneCodec(const cricket::VideoCodec& codec) {
Niels Möller805a27e2019-01-21 12:21:27 +01001339 frame_source_ = absl::make_unique<cricket::FakeFrameSource>(
1340 kVideoWidth, kVideoHeight, rtc::kNumMicrosecsPerSec / kFramerate);
Niels Möller6557d0c2018-04-11 15:18:34 +02001341
1342 bool sending = channel_->sending();
1343 bool success = SetSend(false);
1344 if (success) {
1345 cricket::VideoSendParameters parameters;
1346 parameters.codecs.push_back(codec);
1347 success = channel_->SetSendParameters(parameters);
1348 }
1349 if (success) {
1350 success = SetSend(sending);
1351 }
1352 return success;
1353 }
Yves Gerey665174f2018-06-19 15:03:05 +02001354 bool SetSend(bool send) { return channel_->SetSend(send); }
Niels Möller805a27e2019-01-21 12:21:27 +01001355 void SendFrame() {
1356 if (frame_forwarder_2_) {
1357 frame_forwarder_2_->IncomingCapturedFrame(frame_source_->GetFrame());
Niels Möller6557d0c2018-04-11 15:18:34 +02001358 }
Niels Möller805a27e2019-01-21 12:21:27 +01001359 frame_forwarder_->IncomingCapturedFrame(frame_source_->GetFrame());
Niels Möller6557d0c2018-04-11 15:18:34 +02001360 }
1361 bool WaitAndSendFrame(int wait_ms) {
1362 bool ret = rtc::Thread::Current()->ProcessMessages(wait_ms);
Niels Möller805a27e2019-01-21 12:21:27 +01001363 SendFrame();
Niels Möller6557d0c2018-04-11 15:18:34 +02001364 return ret;
1365 }
Yves Gerey665174f2018-06-19 15:03:05 +02001366 int NumRtpBytes() { return network_interface_.NumRtpBytes(); }
Niels Möller6557d0c2018-04-11 15:18:34 +02001367 int NumRtpBytes(uint32_t ssrc) {
1368 return network_interface_.NumRtpBytes(ssrc);
1369 }
Yves Gerey665174f2018-06-19 15:03:05 +02001370 int NumRtpPackets() { return network_interface_.NumRtpPackets(); }
Niels Möller6557d0c2018-04-11 15:18:34 +02001371 int NumRtpPackets(uint32_t ssrc) {
1372 return network_interface_.NumRtpPackets(ssrc);
1373 }
Yves Gerey665174f2018-06-19 15:03:05 +02001374 int NumSentSsrcs() { return network_interface_.NumSentSsrcs(); }
Niels Möller6557d0c2018-04-11 15:18:34 +02001375 const rtc::CopyOnWriteBuffer* GetRtpPacket(int index) {
1376 return network_interface_.GetRtpPacket(index);
1377 }
1378 static int GetPayloadType(const rtc::CopyOnWriteBuffer* p) {
Åsa Persson23cd45a2018-07-03 10:40:40 +02001379 webrtc::RTPHeader header;
1380 EXPECT_TRUE(ParseRtpPacket(p, &header));
1381 return header.payloadType;
Niels Möller6557d0c2018-04-11 15:18:34 +02001382 }
Åsa Persson23cd45a2018-07-03 10:40:40 +02001383
Niels Möller6557d0c2018-04-11 15:18:34 +02001384 static bool ParseRtpPacket(const rtc::CopyOnWriteBuffer* p,
Åsa Persson23cd45a2018-07-03 10:40:40 +02001385 webrtc::RTPHeader* header) {
1386 std::unique_ptr<webrtc::RtpHeaderParser> parser(
1387 webrtc::RtpHeaderParser::Create());
1388 return parser->Parse(p->cdata(), p->size(), header);
Niels Möller6557d0c2018-04-11 15:18:34 +02001389 }
1390
1391 // Tests that we can send and receive frames.
1392 void SendAndReceive(const cricket::VideoCodec& codec) {
1393 EXPECT_TRUE(SetOneCodec(codec));
1394 EXPECT_TRUE(SetSend(true));
1395 EXPECT_TRUE(channel_->SetSink(kDefaultReceiveSsrc, &renderer_));
1396 EXPECT_EQ(0, renderer_.num_rendered_frames());
Niels Möller805a27e2019-01-21 12:21:27 +01001397 SendFrame();
Niels Möller6557d0c2018-04-11 15:18:34 +02001398 EXPECT_FRAME_WAIT(1, kVideoWidth, kVideoHeight, kTimeout);
1399 std::unique_ptr<const rtc::CopyOnWriteBuffer> p(GetRtpPacket(0));
1400 EXPECT_EQ(codec.id, GetPayloadType(p.get()));
1401 }
1402
1403 void SendReceiveManyAndGetStats(const cricket::VideoCodec& codec,
Yves Gerey665174f2018-06-19 15:03:05 +02001404 int duration_sec,
1405 int fps) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001406 EXPECT_TRUE(SetOneCodec(codec));
1407 EXPECT_TRUE(SetSend(true));
1408 EXPECT_TRUE(channel_->SetSink(kDefaultReceiveSsrc, &renderer_));
1409 EXPECT_EQ(0, renderer_.num_rendered_frames());
1410 for (int i = 0; i < duration_sec; ++i) {
1411 for (int frame = 1; frame <= fps; ++frame) {
1412 EXPECT_TRUE(WaitAndSendFrame(1000 / fps));
1413 EXPECT_FRAME_WAIT(frame + i * fps, kVideoWidth, kVideoHeight, kTimeout);
1414 }
1415 }
1416 std::unique_ptr<const rtc::CopyOnWriteBuffer> p(GetRtpPacket(0));
1417 EXPECT_EQ(codec.id, GetPayloadType(p.get()));
1418 }
1419
Niels Möller6557d0c2018-04-11 15:18:34 +02001420 cricket::VideoSenderInfo GetSenderStats(size_t i) {
1421 cricket::VideoMediaInfo info;
1422 EXPECT_TRUE(channel_->GetStats(&info));
1423 return info.senders[i];
1424 }
1425
1426 cricket::VideoReceiverInfo GetReceiverStats(size_t i) {
1427 cricket::VideoMediaInfo info;
1428 EXPECT_TRUE(channel_->GetStats(&info));
1429 return info.receivers[i];
1430 }
1431
1432 // Two streams one channel tests.
1433
1434 // Tests that we can send and receive frames.
1435 void TwoStreamsSendAndReceive(const cricket::VideoCodec& codec) {
1436 SetUpSecondStream();
1437 // Test sending and receiving on first stream.
1438 SendAndReceive(codec);
1439 // Test sending and receiving on second stream.
1440 EXPECT_EQ_WAIT(1, renderer2_.num_rendered_frames(), kTimeout);
1441 EXPECT_GT(NumRtpPackets(), 0);
1442 EXPECT_EQ(1, renderer2_.num_rendered_frames());
1443 }
1444
1445 cricket::VideoCodec GetEngineCodec(const std::string& name) {
1446 for (const cricket::VideoCodec& engine_codec : engine_.codecs()) {
Niels Möller039743e2018-10-23 10:07:25 +02001447 if (absl::EqualsIgnoreCase(name, engine_codec.name))
Niels Möller6557d0c2018-04-11 15:18:34 +02001448 return engine_codec;
1449 }
1450 // This point should never be reached.
1451 ADD_FAILURE() << "Unrecognized codec name: " << name;
1452 return cricket::VideoCodec();
1453 }
1454
1455 cricket::VideoCodec DefaultCodec() { return GetEngineCodec("VP8"); }
1456
1457 cricket::StreamParams DefaultSendStreamParams() {
1458 return cricket::StreamParams::CreateLegacy(kSsrc);
1459 }
1460
1461 webrtc::RtcEventLogNullImpl event_log_;
Jonas Oreland49ac5952018-09-26 16:04:32 +02001462 std::unique_ptr<webrtc::Call> call_;
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02001463 std::unique_ptr<webrtc::VideoBitrateAllocatorFactory>
1464 video_bitrate_allocator_factory_;
Niels Möller6557d0c2018-04-11 15:18:34 +02001465 WebRtcVideoEngine engine_;
Niels Möller805a27e2019-01-21 12:21:27 +01001466
1467 std::unique_ptr<cricket::FakeFrameSource> frame_source_;
1468 std::unique_ptr<webrtc::test::FrameForwarder> frame_forwarder_;
1469 std::unique_ptr<webrtc::test::FrameForwarder> frame_forwarder_2_;
1470
Niels Möller6557d0c2018-04-11 15:18:34 +02001471 std::unique_ptr<WebRtcVideoChannel> channel_;
1472 cricket::FakeNetworkInterface network_interface_;
1473 cricket::FakeVideoRenderer renderer_;
1474
1475 // Used by test cases where 2 streams are run on the same channel.
1476 cricket::FakeVideoRenderer renderer2_;
1477};
1478
1479// Test that SetSend works.
srtee0c2eea2017-12-15 17:44:33 +01001480TEST_F(WebRtcVideoChannelBaseTest, SetSend) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001481 EXPECT_FALSE(channel_->sending());
Niels Möller805a27e2019-01-21 12:21:27 +01001482 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, nullptr, frame_forwarder_.get()));
Niels Möller6557d0c2018-04-11 15:18:34 +02001483 EXPECT_TRUE(SetOneCodec(DefaultCodec()));
1484 EXPECT_FALSE(channel_->sending());
1485 EXPECT_TRUE(SetSend(true));
1486 EXPECT_TRUE(channel_->sending());
Niels Möller805a27e2019-01-21 12:21:27 +01001487 SendFrame();
Niels Möller6557d0c2018-04-11 15:18:34 +02001488 EXPECT_TRUE_WAIT(NumRtpPackets() > 0, kTimeout);
1489 EXPECT_TRUE(SetSend(false));
1490 EXPECT_FALSE(channel_->sending());
srtee0c2eea2017-12-15 17:44:33 +01001491}
Niels Möller6557d0c2018-04-11 15:18:34 +02001492
1493// Test that SetSend fails without codecs being set.
srtee0c2eea2017-12-15 17:44:33 +01001494TEST_F(WebRtcVideoChannelBaseTest, SetSendWithoutCodecs) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001495 EXPECT_FALSE(channel_->sending());
1496 EXPECT_FALSE(SetSend(true));
1497 EXPECT_FALSE(channel_->sending());
srtee0c2eea2017-12-15 17:44:33 +01001498}
Niels Möller6557d0c2018-04-11 15:18:34 +02001499
1500// Test that we properly set the send and recv buffer sizes by the time
1501// SetSend is called.
srtee0c2eea2017-12-15 17:44:33 +01001502TEST_F(WebRtcVideoChannelBaseTest, SetSendSetsTransportBufferSizes) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001503 EXPECT_TRUE(SetOneCodec(DefaultCodec()));
1504 EXPECT_TRUE(SetSend(true));
1505 EXPECT_EQ(64 * 1024, network_interface_.sendbuf_size());
Johannes Krond38a2b82018-10-23 11:31:19 +02001506 EXPECT_EQ(256 * 1024, network_interface_.recvbuf_size());
Erik Språng820ebd02018-08-20 17:14:25 +02001507}
1508
Johannes Kron5a0665b2019-04-08 10:35:50 +02001509// Test that we properly set the send and recv buffer sizes when overriding
1510// via field trials.
1511TEST_F(WebRtcVideoChannelBaseTest, OverridesRecvBufferSize) {
1512 // Set field trial to override the default recv buffer size, and then re-run
1513 // setup where the interface is created and configured.
1514 const int kCustomRecvBufferSize = 123456;
1515 webrtc::test::ScopedFieldTrials field_trial(
1516 "WebRTC-IncreasedReceivebuffers/123456/");
1517 SetUp();
1518
1519 EXPECT_TRUE(SetOneCodec(DefaultCodec()));
1520 EXPECT_TRUE(SetSend(true));
1521 EXPECT_EQ(64 * 1024, network_interface_.sendbuf_size());
1522 EXPECT_EQ(kCustomRecvBufferSize, network_interface_.recvbuf_size());
1523}
1524
1525// Test that we properly set the send and recv buffer sizes when overriding
1526// via field trials with suffix.
1527TEST_F(WebRtcVideoChannelBaseTest, OverridesRecvBufferSizeWithSuffix) {
1528 // Set field trial to override the default recv buffer size, and then re-run
1529 // setup where the interface is created and configured.
1530 const int kCustomRecvBufferSize = 123456;
1531 webrtc::test::ScopedFieldTrials field_trial(
1532 "WebRTC-IncreasedReceivebuffers/123456_Dogfood/");
1533 SetUp();
1534
1535 EXPECT_TRUE(SetOneCodec(DefaultCodec()));
1536 EXPECT_TRUE(SetSend(true));
1537 EXPECT_EQ(64 * 1024, network_interface_.sendbuf_size());
1538 EXPECT_EQ(kCustomRecvBufferSize, network_interface_.recvbuf_size());
1539}
1540
1541// Test that we properly set the send and recv buffer sizes when overriding
1542// via field trials that don't make any sense.
1543TEST_F(WebRtcVideoChannelBaseTest, InvalidRecvBufferSize) {
1544 // Set bogus field trial values to override the default recv buffer size, and
1545 // then re-run setup where the interface is created and configured. The
1546 // default value should still be used.
1547
1548 for (std::string group : {" ", "NotANumber", "-1", "0"}) {
1549 std::string field_trial_string = "WebRTC-IncreasedReceivebuffers/";
1550 field_trial_string += group;
1551 field_trial_string += "/";
1552 webrtc::test::ScopedFieldTrials field_trial(field_trial_string);
1553 SetUp();
1554
1555 EXPECT_TRUE(SetOneCodec(DefaultCodec()));
1556 EXPECT_TRUE(SetSend(true));
1557 EXPECT_EQ(64 * 1024, network_interface_.sendbuf_size());
1558 EXPECT_EQ(256 * 1024, network_interface_.recvbuf_size());
1559 }
1560}
1561
Niels Möller6557d0c2018-04-11 15:18:34 +02001562// Test that stats work properly for a 1-1 call.
srtee0c2eea2017-12-15 17:44:33 +01001563TEST_F(WebRtcVideoChannelBaseTest, GetStats) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001564 const int kDurationSec = 3;
1565 const int kFps = 10;
1566 SendReceiveManyAndGetStats(DefaultCodec(), kDurationSec, kFps);
1567
1568 cricket::VideoMediaInfo info;
1569 EXPECT_TRUE(channel_->GetStats(&info));
1570
1571 ASSERT_EQ(1U, info.senders.size());
1572 // TODO(whyuan): bytes_sent and bytes_rcvd are different. Are both payload?
1573 // For webrtc, bytes_sent does not include the RTP header length.
1574 EXPECT_GT(info.senders[0].bytes_sent, 0);
1575 EXPECT_EQ(NumRtpPackets(), info.senders[0].packets_sent);
1576 EXPECT_EQ(0.0, info.senders[0].fraction_lost);
1577 ASSERT_TRUE(info.senders[0].codec_payload_type);
1578 EXPECT_EQ(DefaultCodec().id, *info.senders[0].codec_payload_type);
1579 EXPECT_EQ(0, info.senders[0].firs_rcvd);
1580 EXPECT_EQ(0, info.senders[0].plis_rcvd);
1581 EXPECT_EQ(0, info.senders[0].nacks_rcvd);
1582 EXPECT_EQ(kVideoWidth, info.senders[0].send_frame_width);
1583 EXPECT_EQ(kVideoHeight, info.senders[0].send_frame_height);
1584 EXPECT_GT(info.senders[0].framerate_input, 0);
1585 EXPECT_GT(info.senders[0].framerate_sent, 0);
1586
1587 EXPECT_EQ(1U, info.send_codecs.count(DefaultCodec().id));
1588 EXPECT_EQ(DefaultCodec().ToCodecParameters(),
1589 info.send_codecs[DefaultCodec().id]);
1590
1591 ASSERT_EQ(1U, info.receivers.size());
1592 EXPECT_EQ(1U, info.senders[0].ssrcs().size());
1593 EXPECT_EQ(1U, info.receivers[0].ssrcs().size());
1594 EXPECT_EQ(info.senders[0].ssrcs()[0], info.receivers[0].ssrcs()[0]);
1595 ASSERT_TRUE(info.receivers[0].codec_payload_type);
1596 EXPECT_EQ(DefaultCodec().id, *info.receivers[0].codec_payload_type);
1597 EXPECT_EQ(NumRtpBytes(), info.receivers[0].bytes_rcvd);
1598 EXPECT_EQ(NumRtpPackets(), info.receivers[0].packets_rcvd);
1599 EXPECT_EQ(0.0, info.receivers[0].fraction_lost);
1600 EXPECT_EQ(0, info.receivers[0].packets_lost);
1601 // TODO(asapersson): Not set for webrtc. Handle missing stats.
1602 // EXPECT_EQ(0, info.receivers[0].packets_concealed);
1603 EXPECT_EQ(0, info.receivers[0].firs_sent);
1604 EXPECT_EQ(0, info.receivers[0].plis_sent);
1605 EXPECT_EQ(0, info.receivers[0].nacks_sent);
1606 EXPECT_EQ(kVideoWidth, info.receivers[0].frame_width);
1607 EXPECT_EQ(kVideoHeight, info.receivers[0].frame_height);
1608 EXPECT_GT(info.receivers[0].framerate_rcvd, 0);
1609 EXPECT_GT(info.receivers[0].framerate_decoded, 0);
1610 EXPECT_GT(info.receivers[0].framerate_output, 0);
1611
1612 EXPECT_EQ(1U, info.receive_codecs.count(DefaultCodec().id));
1613 EXPECT_EQ(DefaultCodec().ToCodecParameters(),
1614 info.receive_codecs[DefaultCodec().id]);
srtee0c2eea2017-12-15 17:44:33 +01001615}
Niels Möller6557d0c2018-04-11 15:18:34 +02001616
1617// Test that stats work properly for a conf call with multiple recv streams.
srtee0c2eea2017-12-15 17:44:33 +01001618TEST_F(WebRtcVideoChannelBaseTest, GetStatsMultipleRecvStreams) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001619 cricket::FakeVideoRenderer renderer1, renderer2;
1620 EXPECT_TRUE(SetOneCodec(DefaultCodec()));
1621 cricket::VideoSendParameters parameters;
1622 parameters.codecs.push_back(DefaultCodec());
1623 parameters.conference_mode = true;
1624 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1625 EXPECT_TRUE(SetSend(true));
Yves Gerey665174f2018-06-19 15:03:05 +02001626 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
1627 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
Niels Möller6557d0c2018-04-11 15:18:34 +02001628 EXPECT_TRUE(channel_->SetSink(1, &renderer1));
1629 EXPECT_TRUE(channel_->SetSink(2, &renderer2));
1630 EXPECT_EQ(0, renderer1.num_rendered_frames());
1631 EXPECT_EQ(0, renderer2.num_rendered_frames());
1632 std::vector<uint32_t> ssrcs;
1633 ssrcs.push_back(1);
1634 ssrcs.push_back(2);
1635 network_interface_.SetConferenceMode(true, ssrcs);
Niels Möller805a27e2019-01-21 12:21:27 +01001636 SendFrame();
Niels Möller6557d0c2018-04-11 15:18:34 +02001637 EXPECT_FRAME_ON_RENDERER_WAIT(renderer1, 1, kVideoWidth, kVideoHeight,
1638 kTimeout);
1639 EXPECT_FRAME_ON_RENDERER_WAIT(renderer2, 1, kVideoWidth, kVideoHeight,
1640 kTimeout);
1641
1642 EXPECT_TRUE(channel_->SetSend(false));
1643
1644 cricket::VideoMediaInfo info;
1645 EXPECT_TRUE(channel_->GetStats(&info));
1646 ASSERT_EQ(1U, info.senders.size());
1647 // TODO(whyuan): bytes_sent and bytes_rcvd are different. Are both payload?
1648 // For webrtc, bytes_sent does not include the RTP header length.
1649 EXPECT_GT(GetSenderStats(0).bytes_sent, 0);
1650 EXPECT_EQ_WAIT(NumRtpPackets(), GetSenderStats(0).packets_sent, kTimeout);
1651 EXPECT_EQ(kVideoWidth, GetSenderStats(0).send_frame_width);
1652 EXPECT_EQ(kVideoHeight, GetSenderStats(0).send_frame_height);
1653
1654 ASSERT_EQ(2U, info.receivers.size());
1655 for (size_t i = 0; i < info.receivers.size(); ++i) {
1656 EXPECT_EQ(1U, GetReceiverStats(i).ssrcs().size());
1657 EXPECT_EQ(i + 1, GetReceiverStats(i).ssrcs()[0]);
1658 EXPECT_EQ_WAIT(NumRtpBytes(), GetReceiverStats(i).bytes_rcvd, kTimeout);
Yves Gerey665174f2018-06-19 15:03:05 +02001659 EXPECT_EQ_WAIT(NumRtpPackets(), GetReceiverStats(i).packets_rcvd, kTimeout);
Niels Möller6557d0c2018-04-11 15:18:34 +02001660 EXPECT_EQ_WAIT(kVideoWidth, GetReceiverStats(i).frame_width, kTimeout);
1661 EXPECT_EQ_WAIT(kVideoHeight, GetReceiverStats(i).frame_height, kTimeout);
1662 }
srtee0c2eea2017-12-15 17:44:33 +01001663}
Niels Möller6557d0c2018-04-11 15:18:34 +02001664
1665// Test that stats work properly for a conf call with multiple send streams.
srtee0c2eea2017-12-15 17:44:33 +01001666TEST_F(WebRtcVideoChannelBaseTest, GetStatsMultipleSendStreams) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001667 // Normal setup; note that we set the SSRC explicitly to ensure that
1668 // it will come first in the senders map.
1669 EXPECT_TRUE(SetOneCodec(DefaultCodec()));
1670 cricket::VideoSendParameters parameters;
1671 parameters.codecs.push_back(DefaultCodec());
1672 parameters.conference_mode = true;
1673 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Yves Gerey665174f2018-06-19 15:03:05 +02001674 EXPECT_TRUE(
1675 channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
Niels Möller6557d0c2018-04-11 15:18:34 +02001676 EXPECT_TRUE(channel_->SetSink(kSsrc, &renderer_));
1677 EXPECT_TRUE(SetSend(true));
Niels Möller805a27e2019-01-21 12:21:27 +01001678 SendFrame();
Niels Möller6557d0c2018-04-11 15:18:34 +02001679 EXPECT_TRUE_WAIT(NumRtpPackets() > 0, kTimeout);
1680 EXPECT_FRAME_WAIT(1, kVideoWidth, kVideoHeight, kTimeout);
1681
1682 // Add an additional capturer, and hook up a renderer to receive it.
1683 cricket::FakeVideoRenderer renderer2;
Niels Möller805a27e2019-01-21 12:21:27 +01001684 webrtc::test::FrameForwarder frame_forwarder;
Niels Möller6557d0c2018-04-11 15:18:34 +02001685 const int kTestWidth = 160;
1686 const int kTestHeight = 120;
Niels Möller805a27e2019-01-21 12:21:27 +01001687 cricket::FakeFrameSource frame_source(kTestWidth, kTestHeight,
1688 rtc::kNumMicrosecsPerSec / 5);
Yves Gerey665174f2018-06-19 15:03:05 +02001689 EXPECT_TRUE(
1690 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(5678)));
Niels Möller805a27e2019-01-21 12:21:27 +01001691 EXPECT_TRUE(channel_->SetVideoSend(5678, nullptr, &frame_forwarder));
Yves Gerey665174f2018-06-19 15:03:05 +02001692 EXPECT_TRUE(
1693 channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(5678)));
Niels Möller6557d0c2018-04-11 15:18:34 +02001694 EXPECT_TRUE(channel_->SetSink(5678, &renderer2));
Niels Möller805a27e2019-01-21 12:21:27 +01001695 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
Yves Gerey665174f2018-06-19 15:03:05 +02001696 EXPECT_FRAME_ON_RENDERER_WAIT(renderer2, 1, kTestWidth, kTestHeight,
1697 kTimeout);
Niels Möller6557d0c2018-04-11 15:18:34 +02001698
1699 // Get stats, and make sure they are correct for two senders. We wait until
1700 // the number of expected packets have been sent to avoid races where we
1701 // check stats before it has been updated.
1702 cricket::VideoMediaInfo info;
1703 for (uint32_t i = 0; i < kTimeout; ++i) {
1704 rtc::Thread::Current()->ProcessMessages(1);
1705 EXPECT_TRUE(channel_->GetStats(&info));
1706 ASSERT_EQ(2U, info.senders.size());
1707 if (info.senders[0].packets_sent + info.senders[1].packets_sent ==
1708 NumRtpPackets()) {
1709 // Stats have been updated for both sent frames, expectations can be
1710 // checked now.
1711 break;
1712 }
1713 }
1714 EXPECT_EQ(NumRtpPackets(),
1715 info.senders[0].packets_sent + info.senders[1].packets_sent)
1716 << "Timed out while waiting for packet counts for all sent packets.";
1717 EXPECT_EQ(1U, info.senders[0].ssrcs().size());
1718 EXPECT_EQ(1234U, info.senders[0].ssrcs()[0]);
1719 EXPECT_EQ(kVideoWidth, info.senders[0].send_frame_width);
1720 EXPECT_EQ(kVideoHeight, info.senders[0].send_frame_height);
1721 EXPECT_EQ(1U, info.senders[1].ssrcs().size());
1722 EXPECT_EQ(5678U, info.senders[1].ssrcs()[0]);
1723 EXPECT_EQ(kTestWidth, info.senders[1].send_frame_width);
1724 EXPECT_EQ(kTestHeight, info.senders[1].send_frame_height);
1725 // The capturer must be unregistered here as it runs out of it's scope next.
1726 channel_->SetVideoSend(5678, nullptr, nullptr);
srtee0c2eea2017-12-15 17:44:33 +01001727}
pbos@webrtc.org8fdeee62014-07-20 14:40:23 +00001728
Niels Möller6557d0c2018-04-11 15:18:34 +02001729// Test that we can set the bandwidth.
srtee0c2eea2017-12-15 17:44:33 +01001730TEST_F(WebRtcVideoChannelBaseTest, SetSendBandwidth) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001731 cricket::VideoSendParameters parameters;
1732 parameters.codecs.push_back(DefaultCodec());
1733 parameters.max_bandwidth_bps = -1; // <= 0 means unlimited.
1734 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1735 parameters.max_bandwidth_bps = 128 * 1024;
1736 EXPECT_TRUE(channel_->SetSendParameters(parameters));
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// Test that we can set the SSRC for the default send source.
srtee0c2eea2017-12-15 17:44:33 +01001740TEST_F(WebRtcVideoChannelBaseTest, SetSendSsrc) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001741 EXPECT_TRUE(SetDefaultCodec());
1742 EXPECT_TRUE(SetSend(true));
Niels Möller805a27e2019-01-21 12:21:27 +01001743 SendFrame();
Niels Möller6557d0c2018-04-11 15:18:34 +02001744 EXPECT_TRUE_WAIT(NumRtpPackets() > 0, kTimeout);
Åsa Persson23cd45a2018-07-03 10:40:40 +02001745 webrtc::RTPHeader header;
Niels Möller6557d0c2018-04-11 15:18:34 +02001746 std::unique_ptr<const rtc::CopyOnWriteBuffer> p(GetRtpPacket(0));
Åsa Persson23cd45a2018-07-03 10:40:40 +02001747 EXPECT_TRUE(ParseRtpPacket(p.get(), &header));
1748 EXPECT_EQ(kSsrc, header.ssrc);
1749
Niels Möller6557d0c2018-04-11 15:18:34 +02001750 // Packets are being paced out, so these can mismatch between the first and
1751 // second call to NumRtpPackets until pending packets are paced out.
Åsa Persson23cd45a2018-07-03 10:40:40 +02001752 EXPECT_EQ_WAIT(NumRtpPackets(), NumRtpPackets(header.ssrc), kTimeout);
1753 EXPECT_EQ_WAIT(NumRtpBytes(), NumRtpBytes(header.ssrc), kTimeout);
Niels Möller6557d0c2018-04-11 15:18:34 +02001754 EXPECT_EQ(1, NumSentSsrcs());
1755 EXPECT_EQ(0, NumRtpPackets(kSsrc - 1));
1756 EXPECT_EQ(0, NumRtpBytes(kSsrc - 1));
srtee0c2eea2017-12-15 17:44:33 +01001757}
Niels Möller6557d0c2018-04-11 15:18:34 +02001758
1759// Test that we can set the SSRC even after codecs are set.
srtee0c2eea2017-12-15 17:44:33 +01001760TEST_F(WebRtcVideoChannelBaseTest, SetSendSsrcAfterSetCodecs) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001761 // Remove stream added in Setup.
1762 EXPECT_TRUE(channel_->RemoveSendStream(kSsrc));
1763 EXPECT_TRUE(SetDefaultCodec());
Niels Möller6557d0c2018-04-11 15:18:34 +02001764 EXPECT_TRUE(
Yves Gerey665174f2018-06-19 15:03:05 +02001765 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(999)));
Niels Möller805a27e2019-01-21 12:21:27 +01001766 EXPECT_TRUE(channel_->SetVideoSend(999u, nullptr, frame_forwarder_.get()));
Niels Möller6557d0c2018-04-11 15:18:34 +02001767 EXPECT_TRUE(SetSend(true));
1768 EXPECT_TRUE(WaitAndSendFrame(0));
1769 EXPECT_TRUE_WAIT(NumRtpPackets() > 0, kTimeout);
Åsa Persson23cd45a2018-07-03 10:40:40 +02001770 webrtc::RTPHeader header;
Niels Möller6557d0c2018-04-11 15:18:34 +02001771 std::unique_ptr<const rtc::CopyOnWriteBuffer> p(GetRtpPacket(0));
Åsa Persson23cd45a2018-07-03 10:40:40 +02001772 EXPECT_TRUE(ParseRtpPacket(p.get(), &header));
1773 EXPECT_EQ(999u, header.ssrc);
Niels Möller6557d0c2018-04-11 15:18:34 +02001774 // Packets are being paced out, so these can mismatch between the first and
1775 // second call to NumRtpPackets until pending packets are paced out.
Åsa Persson23cd45a2018-07-03 10:40:40 +02001776 EXPECT_EQ_WAIT(NumRtpPackets(), NumRtpPackets(header.ssrc), kTimeout);
1777 EXPECT_EQ_WAIT(NumRtpBytes(), NumRtpBytes(header.ssrc), kTimeout);
Niels Möller6557d0c2018-04-11 15:18:34 +02001778 EXPECT_EQ(1, NumSentSsrcs());
1779 EXPECT_EQ(0, NumRtpPackets(kSsrc));
1780 EXPECT_EQ(0, NumRtpBytes(kSsrc));
srtee0c2eea2017-12-15 17:44:33 +01001781}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001782
Niels Möller6557d0c2018-04-11 15:18:34 +02001783// Test that we can set the default video renderer before and after
1784// media is received.
srtee0c2eea2017-12-15 17:44:33 +01001785TEST_F(WebRtcVideoChannelBaseTest, SetSink) {
Yves Gerey665174f2018-06-19 15:03:05 +02001786 uint8_t data1[] = {0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
1787 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
Niels Möller6557d0c2018-04-11 15:18:34 +02001788
1789 rtc::CopyOnWriteBuffer packet1(data1, sizeof(data1));
1790 rtc::SetBE32(packet1.data() + 8, kSsrc);
1791 channel_->SetSink(kDefaultReceiveSsrc, NULL);
1792 EXPECT_TRUE(SetDefaultCodec());
1793 EXPECT_TRUE(SetSend(true));
1794 EXPECT_EQ(0, renderer_.num_rendered_frames());
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07001795 channel_->OnPacketReceived(packet1, /* packet_time_us */ -1);
Niels Möller6557d0c2018-04-11 15:18:34 +02001796 EXPECT_TRUE(channel_->SetSink(kDefaultReceiveSsrc, &renderer_));
Niels Möller805a27e2019-01-21 12:21:27 +01001797 SendFrame();
Niels Möller6557d0c2018-04-11 15:18:34 +02001798 EXPECT_FRAME_WAIT(1, kVideoWidth, kVideoHeight, kTimeout);
srtee0c2eea2017-12-15 17:44:33 +01001799}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001800
Niels Möller6557d0c2018-04-11 15:18:34 +02001801// Tests setting up and configuring a send stream.
srtee0c2eea2017-12-15 17:44:33 +01001802TEST_F(WebRtcVideoChannelBaseTest, AddRemoveSendStreams) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001803 EXPECT_TRUE(SetOneCodec(DefaultCodec()));
1804 EXPECT_TRUE(SetSend(true));
1805 EXPECT_TRUE(channel_->SetSink(kDefaultReceiveSsrc, &renderer_));
Niels Möller805a27e2019-01-21 12:21:27 +01001806 SendFrame();
Niels Möller6557d0c2018-04-11 15:18:34 +02001807 EXPECT_FRAME_WAIT(1, kVideoWidth, kVideoHeight, kTimeout);
1808 EXPECT_GT(NumRtpPackets(), 0);
Åsa Persson23cd45a2018-07-03 10:40:40 +02001809 webrtc::RTPHeader header;
Niels Möller6557d0c2018-04-11 15:18:34 +02001810 size_t last_packet = NumRtpPackets() - 1;
Yves Gerey665174f2018-06-19 15:03:05 +02001811 std::unique_ptr<const rtc::CopyOnWriteBuffer> p(
1812 GetRtpPacket(static_cast<int>(last_packet)));
Åsa Persson23cd45a2018-07-03 10:40:40 +02001813 EXPECT_TRUE(ParseRtpPacket(p.get(), &header));
1814 EXPECT_EQ(kSsrc, header.ssrc);
Niels Möller6557d0c2018-04-11 15:18:34 +02001815
1816 // Remove the send stream that was added during Setup.
1817 EXPECT_TRUE(channel_->RemoveSendStream(kSsrc));
1818 int rtp_packets = NumRtpPackets();
1819
Niels Möller6557d0c2018-04-11 15:18:34 +02001820 EXPECT_TRUE(
Yves Gerey665174f2018-06-19 15:03:05 +02001821 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(789u)));
Niels Möller805a27e2019-01-21 12:21:27 +01001822 EXPECT_TRUE(channel_->SetVideoSend(789u, nullptr, frame_forwarder_.get()));
Niels Möller6557d0c2018-04-11 15:18:34 +02001823 EXPECT_EQ(rtp_packets, NumRtpPackets());
1824 // Wait 30ms to guarantee the engine does not drop the frame.
1825 EXPECT_TRUE(WaitAndSendFrame(30));
1826 EXPECT_TRUE_WAIT(NumRtpPackets() > rtp_packets, kTimeout);
1827
1828 last_packet = NumRtpPackets() - 1;
1829 p.reset(GetRtpPacket(static_cast<int>(last_packet)));
Åsa Persson23cd45a2018-07-03 10:40:40 +02001830 EXPECT_TRUE(ParseRtpPacket(p.get(), &header));
1831 EXPECT_EQ(789u, header.ssrc);
srtee0c2eea2017-12-15 17:44:33 +01001832}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001833
Niels Möller6557d0c2018-04-11 15:18:34 +02001834// Tests the behavior of incoming streams in a conference scenario.
srtee0c2eea2017-12-15 17:44:33 +01001835TEST_F(WebRtcVideoChannelBaseTest, SimulateConference) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001836 cricket::FakeVideoRenderer renderer1, renderer2;
1837 EXPECT_TRUE(SetDefaultCodec());
1838 cricket::VideoSendParameters parameters;
1839 parameters.codecs.push_back(DefaultCodec());
1840 parameters.conference_mode = true;
1841 EXPECT_TRUE(channel_->SetSendParameters(parameters));
1842 EXPECT_TRUE(SetSend(true));
Yves Gerey665174f2018-06-19 15:03:05 +02001843 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
1844 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
Niels Möller6557d0c2018-04-11 15:18:34 +02001845 EXPECT_TRUE(channel_->SetSink(1, &renderer1));
1846 EXPECT_TRUE(channel_->SetSink(2, &renderer2));
1847 EXPECT_EQ(0, renderer1.num_rendered_frames());
1848 EXPECT_EQ(0, renderer2.num_rendered_frames());
1849 std::vector<uint32_t> ssrcs;
1850 ssrcs.push_back(1);
1851 ssrcs.push_back(2);
1852 network_interface_.SetConferenceMode(true, ssrcs);
Niels Möller805a27e2019-01-21 12:21:27 +01001853 SendFrame();
Niels Möller6557d0c2018-04-11 15:18:34 +02001854 EXPECT_FRAME_ON_RENDERER_WAIT(renderer1, 1, kVideoWidth, kVideoHeight,
1855 kTimeout);
1856 EXPECT_FRAME_ON_RENDERER_WAIT(renderer2, 1, kVideoWidth, kVideoHeight,
1857 kTimeout);
1858
1859 std::unique_ptr<const rtc::CopyOnWriteBuffer> p(GetRtpPacket(0));
1860 EXPECT_EQ(DefaultCodec().id, GetPayloadType(p.get()));
1861 EXPECT_EQ(kVideoWidth, renderer1.width());
1862 EXPECT_EQ(kVideoHeight, renderer1.height());
1863 EXPECT_EQ(kVideoWidth, renderer2.width());
1864 EXPECT_EQ(kVideoHeight, renderer2.height());
1865 EXPECT_TRUE(channel_->RemoveRecvStream(2));
1866 EXPECT_TRUE(channel_->RemoveRecvStream(1));
srtee0c2eea2017-12-15 17:44:33 +01001867}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001868
Niels Möller6557d0c2018-04-11 15:18:34 +02001869// Tests that we can add and remove capturers and frames are sent out properly
srtee0c2eea2017-12-15 17:44:33 +01001870TEST_F(WebRtcVideoChannelBaseTest, DISABLED_AddRemoveCapturer) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001871 using cricket::VideoCodec;
1872 using cricket::VideoOptions;
1873 using cricket::VideoFormat;
1874 using cricket::FOURCC_I420;
1875
1876 VideoCodec codec = DefaultCodec();
1877 const int time_between_send_ms = VideoFormat::FpsToInterval(kFramerate);
1878 EXPECT_TRUE(SetOneCodec(codec));
1879 EXPECT_TRUE(SetSend(true));
1880 EXPECT_TRUE(channel_->SetSink(kDefaultReceiveSsrc, &renderer_));
1881 EXPECT_EQ(0, renderer_.num_rendered_frames());
Niels Möller805a27e2019-01-21 12:21:27 +01001882 SendFrame();
Niels Möller6557d0c2018-04-11 15:18:34 +02001883 EXPECT_FRAME_WAIT(1, kVideoWidth, kVideoHeight, kTimeout);
Niels Möller805a27e2019-01-21 12:21:27 +01001884
1885 webrtc::test::FrameForwarder frame_forwarder;
1886 cricket::FakeFrameSource frame_source(480, 360, rtc::kNumMicrosecsPerSec / 30,
1887 rtc::kNumMicrosecsPerSec / 30);
Niels Möller6557d0c2018-04-11 15:18:34 +02001888
1889 // TODO(nisse): This testcase fails if we don't configure
1890 // screencast. It's unclear why, I see nothing obvious in this
1891 // test which is related to screencast logic.
1892 VideoOptions video_options;
1893 video_options.is_screencast = true;
1894 channel_->SetVideoSend(kSsrc, &video_options, nullptr);
1895
Niels Möller6557d0c2018-04-11 15:18:34 +02001896 int captured_frames = 1;
1897 for (int iterations = 0; iterations < 2; ++iterations) {
Niels Möller805a27e2019-01-21 12:21:27 +01001898 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, nullptr, &frame_forwarder));
Niels Möller6557d0c2018-04-11 15:18:34 +02001899 rtc::Thread::Current()->ProcessMessages(time_between_send_ms);
Niels Möller805a27e2019-01-21 12:21:27 +01001900 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
1901
Niels Möller6557d0c2018-04-11 15:18:34 +02001902 ++captured_frames;
1903 // Wait until frame of right size is captured.
1904 EXPECT_TRUE_WAIT(renderer_.num_rendered_frames() >= captured_frames &&
Niels Möller805a27e2019-01-21 12:21:27 +01001905 480 == renderer_.width() &&
1906 360 == renderer_.height() && !renderer_.black_frame(),
Yves Gerey665174f2018-06-19 15:03:05 +02001907 kTimeout);
Niels Möller6557d0c2018-04-11 15:18:34 +02001908 EXPECT_GE(renderer_.num_rendered_frames(), captured_frames);
Niels Möller805a27e2019-01-21 12:21:27 +01001909 EXPECT_EQ(480, renderer_.width());
1910 EXPECT_EQ(360, renderer_.height());
Niels Möller6557d0c2018-04-11 15:18:34 +02001911 captured_frames = renderer_.num_rendered_frames() + 1;
1912 EXPECT_FALSE(renderer_.black_frame());
1913 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, nullptr, nullptr));
1914 // Make sure a black frame is generated within the specified timeout.
1915 // The black frame should be the resolution of the previous frame to
1916 // prevent expensive encoder reconfigurations.
1917 EXPECT_TRUE_WAIT(renderer_.num_rendered_frames() >= captured_frames &&
Niels Möller805a27e2019-01-21 12:21:27 +01001918 480 == renderer_.width() &&
1919 360 == renderer_.height() && renderer_.black_frame(),
Yves Gerey665174f2018-06-19 15:03:05 +02001920 kTimeout);
Niels Möller6557d0c2018-04-11 15:18:34 +02001921 EXPECT_GE(renderer_.num_rendered_frames(), captured_frames);
Niels Möller805a27e2019-01-21 12:21:27 +01001922 EXPECT_EQ(480, renderer_.width());
1923 EXPECT_EQ(360, renderer_.height());
Niels Möller6557d0c2018-04-11 15:18:34 +02001924 EXPECT_TRUE(renderer_.black_frame());
1925
1926 // The black frame has the same timestamp as the next frame since it's
1927 // timestamp is set to the last frame's timestamp + interval. WebRTC will
1928 // not render a frame with the same timestamp so capture another frame
1929 // with the frame capturer to increment the next frame's timestamp.
Niels Möller805a27e2019-01-21 12:21:27 +01001930 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
Niels Möller6557d0c2018-04-11 15:18:34 +02001931 }
srtee0c2eea2017-12-15 17:44:33 +01001932}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001933
Niels Möller6557d0c2018-04-11 15:18:34 +02001934// Tests that if SetVideoSend is called with a NULL capturer after the
1935// capturer was already removed, the application doesn't crash (and no black
1936// frame is sent).
srtee0c2eea2017-12-15 17:44:33 +01001937TEST_F(WebRtcVideoChannelBaseTest, RemoveCapturerWithoutAdd) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001938 EXPECT_TRUE(SetOneCodec(DefaultCodec()));
1939 EXPECT_TRUE(SetSend(true));
1940 EXPECT_TRUE(channel_->SetSink(kDefaultReceiveSsrc, &renderer_));
1941 EXPECT_EQ(0, renderer_.num_rendered_frames());
Niels Möller805a27e2019-01-21 12:21:27 +01001942 SendFrame();
Niels Möller6557d0c2018-04-11 15:18:34 +02001943 EXPECT_FRAME_WAIT(1, kVideoWidth, kVideoHeight, kTimeout);
1944 // Wait for one frame so they don't get dropped because we send frames too
1945 // tightly.
1946 rtc::Thread::Current()->ProcessMessages(30);
1947 // Remove the capturer.
1948 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, nullptr, nullptr));
1949
1950 // No capturer was added, so this SetVideoSend shouldn't do anything.
1951 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, nullptr, nullptr));
1952 rtc::Thread::Current()->ProcessMessages(300);
1953 // Verify no more frames were sent.
1954 EXPECT_EQ(1, renderer_.num_rendered_frames());
srtee0c2eea2017-12-15 17:44:33 +01001955}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00001956
Niels Möller6557d0c2018-04-11 15:18:34 +02001957// Tests that we can add and remove capturer as unique sources.
srtee0c2eea2017-12-15 17:44:33 +01001958TEST_F(WebRtcVideoChannelBaseTest, AddRemoveCapturerMultipleSources) {
Niels Möller6557d0c2018-04-11 15:18:34 +02001959 // WebRTC implementation will drop frames if pushed to quickly. Wait the
1960 // interval time to avoid that.
1961 // WebRTC implementation will drop frames if pushed to quickly. Wait the
1962 // interval time to avoid that.
1963 // Set up the stream associated with the engine.
Yves Gerey665174f2018-06-19 15:03:05 +02001964 EXPECT_TRUE(
1965 channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrc)));
Niels Möller6557d0c2018-04-11 15:18:34 +02001966 EXPECT_TRUE(channel_->SetSink(kSsrc, &renderer_));
1967 cricket::VideoFormat capture_format(
1968 kVideoWidth, kVideoHeight,
1969 cricket::VideoFormat::FpsToInterval(kFramerate), cricket::FOURCC_I420);
1970 // Set up additional stream 1.
1971 cricket::FakeVideoRenderer renderer1;
1972 EXPECT_FALSE(channel_->SetSink(1, &renderer1));
Yves Gerey665174f2018-06-19 15:03:05 +02001973 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
Niels Möller6557d0c2018-04-11 15:18:34 +02001974 EXPECT_TRUE(channel_->SetSink(1, &renderer1));
Yves Gerey665174f2018-06-19 15:03:05 +02001975 EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(1)));
Niels Möller805a27e2019-01-21 12:21:27 +01001976
1977 webrtc::test::FrameForwarder frame_forwarder1;
1978 cricket::FakeFrameSource frame_source(kVideoWidth, kVideoHeight,
1979 rtc::kNumMicrosecsPerSec / kFramerate);
1980
Niels Möller6557d0c2018-04-11 15:18:34 +02001981 // Set up additional stream 2.
1982 cricket::FakeVideoRenderer renderer2;
1983 EXPECT_FALSE(channel_->SetSink(2, &renderer2));
Yves Gerey665174f2018-06-19 15:03:05 +02001984 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(2)));
Niels Möller6557d0c2018-04-11 15:18:34 +02001985 EXPECT_TRUE(channel_->SetSink(2, &renderer2));
Yves Gerey665174f2018-06-19 15:03:05 +02001986 EXPECT_TRUE(channel_->AddSendStream(cricket::StreamParams::CreateLegacy(2)));
Niels Möller805a27e2019-01-21 12:21:27 +01001987 webrtc::test::FrameForwarder frame_forwarder2;
1988
Niels Möller6557d0c2018-04-11 15:18:34 +02001989 // State for all the streams.
1990 EXPECT_TRUE(SetOneCodec(DefaultCodec()));
1991 // A limitation in the lmi implementation requires that SetVideoSend() is
1992 // called after SetOneCodec().
1993 // TODO(hellner): this seems like an unnecessary constraint, fix it.
Niels Möller805a27e2019-01-21 12:21:27 +01001994 EXPECT_TRUE(channel_->SetVideoSend(1, nullptr, &frame_forwarder1));
1995 EXPECT_TRUE(channel_->SetVideoSend(2, nullptr, &frame_forwarder2));
Niels Möller6557d0c2018-04-11 15:18:34 +02001996 EXPECT_TRUE(SetSend(true));
1997 // Test capturer associated with engine.
1998 const int kTestWidth = 160;
1999 const int kTestHeight = 120;
Niels Möller805a27e2019-01-21 12:21:27 +01002000 frame_forwarder1.IncomingCapturedFrame(frame_source.GetFrame(
2001 kTestWidth, kTestHeight, webrtc::VideoRotation::kVideoRotation_0,
2002 rtc::kNumMicrosecsPerSec / kFramerate));
Yves Gerey665174f2018-06-19 15:03:05 +02002003 EXPECT_FRAME_ON_RENDERER_WAIT(renderer1, 1, kTestWidth, kTestHeight,
2004 kTimeout);
Niels Möller6557d0c2018-04-11 15:18:34 +02002005 // Capture a frame with additional capturer2, frames should be received
Niels Möller805a27e2019-01-21 12:21:27 +01002006 frame_forwarder2.IncomingCapturedFrame(frame_source.GetFrame(
2007 kTestWidth, kTestHeight, webrtc::VideoRotation::kVideoRotation_0,
2008 rtc::kNumMicrosecsPerSec / kFramerate));
Yves Gerey665174f2018-06-19 15:03:05 +02002009 EXPECT_FRAME_ON_RENDERER_WAIT(renderer2, 1, kTestWidth, kTestHeight,
2010 kTimeout);
Niels Möller6557d0c2018-04-11 15:18:34 +02002011 // Successfully remove the capturer.
2012 EXPECT_TRUE(channel_->SetVideoSend(kSsrc, nullptr, nullptr));
2013 // The capturers must be unregistered here as it runs out of it's scope
2014 // next.
2015 EXPECT_TRUE(channel_->SetVideoSend(1, nullptr, nullptr));
2016 EXPECT_TRUE(channel_->SetVideoSend(2, nullptr, nullptr));
srtee0c2eea2017-12-15 17:44:33 +01002017}
Niels Möller6557d0c2018-04-11 15:18:34 +02002018
2019// Tests empty StreamParams is rejected.
srtee0c2eea2017-12-15 17:44:33 +01002020TEST_F(WebRtcVideoChannelBaseTest, RejectEmptyStreamParams) {
Niels Möller6557d0c2018-04-11 15:18:34 +02002021 // Remove the send stream that was added during Setup.
2022 EXPECT_TRUE(channel_->RemoveSendStream(kSsrc));
2023
2024 cricket::StreamParams empty;
2025 EXPECT_FALSE(channel_->AddSendStream(empty));
Yves Gerey665174f2018-06-19 15:03:05 +02002026 EXPECT_TRUE(
2027 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(789u)));
srtee0c2eea2017-12-15 17:44:33 +01002028}
Niels Möller6557d0c2018-04-11 15:18:34 +02002029
2030// Test that multiple send streams can be created and deleted properly.
srtee0c2eea2017-12-15 17:44:33 +01002031TEST_F(WebRtcVideoChannelBaseTest, MultipleSendStreams) {
Niels Möller6557d0c2018-04-11 15:18:34 +02002032 // Remove stream added in Setup. I.e. remove stream corresponding to default
2033 // channel.
2034 EXPECT_TRUE(channel_->RemoveSendStream(kSsrc));
Yves Gerey665174f2018-06-19 15:03:05 +02002035 const unsigned int kSsrcsSize = sizeof(kSsrcs4) / sizeof(kSsrcs4[0]);
Niels Möller6557d0c2018-04-11 15:18:34 +02002036 for (unsigned int i = 0; i < kSsrcsSize; ++i) {
2037 EXPECT_TRUE(channel_->AddSendStream(
2038 cricket::StreamParams::CreateLegacy(kSsrcs4[i])));
2039 }
2040 // Delete one of the non default channel streams, let the destructor delete
2041 // the remaining ones.
2042 EXPECT_TRUE(channel_->RemoveSendStream(kSsrcs4[kSsrcsSize - 1]));
2043 // Stream should already be deleted.
2044 EXPECT_FALSE(channel_->RemoveSendStream(kSsrcs4[kSsrcsSize - 1]));
srtee0c2eea2017-12-15 17:44:33 +01002045}
pbos@webrtc.orgc4175b92014-09-03 15:25:49 +00002046
eladalonf1841382017-06-12 01:16:46 -07002047TEST_F(WebRtcVideoChannelBaseTest, SendAndReceiveVp8Vga) {
magjed509e4fe2016-11-18 01:34:11 -08002048 SendAndReceive(GetEngineCodec("VP8"));
pbos@webrtc.org9359cb32014-07-23 15:44:48 +00002049}
2050
eladalonf1841382017-06-12 01:16:46 -07002051TEST_F(WebRtcVideoChannelBaseTest, SendAndReceiveVp8Qvga) {
magjed509e4fe2016-11-18 01:34:11 -08002052 SendAndReceive(GetEngineCodec("VP8"));
pbos@webrtc.org9359cb32014-07-23 15:44:48 +00002053}
2054
eladalonf1841382017-06-12 01:16:46 -07002055TEST_F(WebRtcVideoChannelBaseTest, SendAndReceiveVp8SvcQqvga) {
magjed509e4fe2016-11-18 01:34:11 -08002056 SendAndReceive(GetEngineCodec("VP8"));
pbos@webrtc.org9359cb32014-07-23 15:44:48 +00002057}
2058
eladalonf1841382017-06-12 01:16:46 -07002059TEST_F(WebRtcVideoChannelBaseTest, TwoStreamsSendAndReceive) {
Peter Boströmd1f584b2016-04-20 16:31:53 +02002060 // Set a high bitrate to not be downscaled by VP8 due to low initial start
2061 // bitrates. This currently happens at <250k, and two streams sharing 300k
2062 // initially will use QVGA instead of VGA.
2063 // TODO(pbos): Set up the quality scaler so that both senders reliably start
2064 // at QVGA, then verify that instead.
magjed509e4fe2016-11-18 01:34:11 -08002065 cricket::VideoCodec codec = GetEngineCodec("VP8");
Peter Boströmd1f584b2016-04-20 16:31:53 +02002066 codec.params[kCodecParamStartBitrate] = "1000000";
Niels Möller6557d0c2018-04-11 15:18:34 +02002067 TwoStreamsSendAndReceive(codec);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002068}
2069
eladalonf1841382017-06-12 01:16:46 -07002070class WebRtcVideoChannelTest : public WebRtcVideoEngineTest {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002071 public:
eladalonf1841382017-06-12 01:16:46 -07002072 WebRtcVideoChannelTest() : WebRtcVideoChannelTest("") {}
2073 explicit WebRtcVideoChannelTest(const char* field_trials)
Niels Möller805a27e2019-01-21 12:21:27 +01002074 : WebRtcVideoEngineTest(field_trials),
2075 frame_source_(1280, 720, rtc::kNumMicrosecsPerSec / 30),
2076 last_ssrc_(0) {}
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00002077 void SetUp() override {
Anders Carlsson5f2bb622018-05-14 09:48:06 +02002078 encoder_factory_->AddSupportedVideoCodecType("VP8");
2079 encoder_factory_->AddSupportedVideoCodecType("VP9");
2080#if defined(WEBRTC_USE_H264)
2081 encoder_factory_->AddSupportedVideoCodecType("H264");
2082#endif
2083
Sebastian Jansson8f83b422018-02-21 13:07:13 +01002084 fake_call_.reset(new FakeCall());
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02002085 channel_.reset(engine_.CreateMediaChannel(
2086 fake_call_.get(), GetMediaConfig(), VideoOptions(),
2087 webrtc::CryptoOptions(), video_bitrate_allocator_factory_.get()));
Sergey Ulanove2b15012016-11-22 16:08:30 -08002088 channel_->OnReadyToSend(true);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002089 last_ssrc_ = 123;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002090 send_parameters_.codecs = engine_.codecs();
2091 recv_parameters_.codecs = engine_.codecs();
2092 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002093 }
2094
2095 protected:
2096 FakeVideoSendStream* AddSendStream() {
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002097 return AddSendStream(StreamParams::CreateLegacy(++last_ssrc_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002098 }
2099
2100 FakeVideoSendStream* AddSendStream(const StreamParams& sp) {
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002101 size_t num_streams = fake_call_->GetVideoSendStreams().size();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002102 EXPECT_TRUE(channel_->AddSendStream(sp));
2103 std::vector<FakeVideoSendStream*> streams =
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002104 fake_call_->GetVideoSendStreams();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002105 EXPECT_EQ(num_streams + 1, streams.size());
2106 return streams[streams.size() - 1];
2107 }
2108
2109 std::vector<FakeVideoSendStream*> GetFakeSendStreams() {
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002110 return fake_call_->GetVideoSendStreams();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002111 }
2112
2113 FakeVideoReceiveStream* AddRecvStream() {
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002114 return AddRecvStream(StreamParams::CreateLegacy(++last_ssrc_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002115 }
2116
2117 FakeVideoReceiveStream* AddRecvStream(const StreamParams& sp) {
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002118 size_t num_streams = fake_call_->GetVideoReceiveStreams().size();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002119 EXPECT_TRUE(channel_->AddRecvStream(sp));
2120 std::vector<FakeVideoReceiveStream*> streams =
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002121 fake_call_->GetVideoReceiveStreams();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002122 EXPECT_EQ(num_streams + 1, streams.size());
2123 return streams[streams.size() - 1];
2124 }
2125
pbos@webrtc.org00873182014-11-25 14:03:34 +00002126 void SetSendCodecsShouldWorkForBitrates(const char* min_bitrate_kbps,
2127 int expected_min_bitrate_bps,
2128 const char* start_bitrate_kbps,
2129 int expected_start_bitrate_bps,
2130 const char* max_bitrate_kbps,
2131 int expected_max_bitrate_bps) {
Sebastian Jansson8f83b422018-02-21 13:07:13 +01002132 ExpectSetBitrateParameters(expected_min_bitrate_bps,
2133 expected_start_bitrate_bps,
2134 expected_max_bitrate_bps);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002135 auto& codecs = send_parameters_.codecs;
2136 codecs.clear();
magjed509e4fe2016-11-18 01:34:11 -08002137 codecs.push_back(GetEngineCodec("VP8"));
pbos@webrtc.org00873182014-11-25 14:03:34 +00002138 codecs[0].params[kCodecParamMinBitrate] = min_bitrate_kbps;
2139 codecs[0].params[kCodecParamStartBitrate] = start_bitrate_kbps;
2140 codecs[0].params[kCodecParamMaxBitrate] = max_bitrate_kbps;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002141 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Sebastian Jansson8f83b422018-02-21 13:07:13 +01002142 }
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002143
Sebastian Jansson8f83b422018-02-21 13:07:13 +01002144 void ExpectSetBitrateParameters(int min_bitrate_bps,
2145 int start_bitrate_bps,
2146 int max_bitrate_bps) {
2147 EXPECT_CALL(
2148 *fake_call_->GetMockTransportControllerSend(),
2149 SetSdpBitrateParameters(AllOf(
2150 Field(&BitrateConstraints::min_bitrate_bps, min_bitrate_bps),
2151 Field(&BitrateConstraints::start_bitrate_bps, start_bitrate_bps),
2152 Field(&BitrateConstraints::max_bitrate_bps, max_bitrate_bps))));
2153 }
2154
2155 void ExpectSetMaxBitrate(int max_bitrate_bps) {
2156 EXPECT_CALL(*fake_call_->GetMockTransportControllerSend(),
2157 SetSdpBitrateParameters(Field(
2158 &BitrateConstraints::max_bitrate_bps, max_bitrate_bps)));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002159 }
2160
Johannes Kron9190b822018-10-29 11:22:05 +01002161 void TestExtmapAllowMixedCaller(bool extmap_allow_mixed) {
2162 // For a caller, the answer will be applied in set remote description
2163 // where SetSendParameters() is called.
2164 EXPECT_TRUE(
2165 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
2166 send_parameters_.extmap_allow_mixed = extmap_allow_mixed;
2167 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
2168 const webrtc::VideoSendStream::Config& config =
2169 fake_call_->GetVideoSendStreams()[0]->GetConfig();
2170 EXPECT_EQ(extmap_allow_mixed, config.rtp.extmap_allow_mixed);
2171 }
2172
2173 void TestExtmapAllowMixedCallee(bool extmap_allow_mixed) {
2174 // For a callee, the answer will be applied in set local description
2175 // where SetExtmapAllowMixed() and AddSendStream() are called.
2176 channel_->SetExtmapAllowMixed(extmap_allow_mixed);
2177 EXPECT_TRUE(
2178 channel_->AddSendStream(cricket::StreamParams::CreateLegacy(kSsrc)));
2179 const webrtc::VideoSendStream::Config& config =
2180 fake_call_->GetVideoSendStreams()[0]->GetConfig();
2181 EXPECT_EQ(extmap_allow_mixed, config.rtp.extmap_allow_mixed);
2182 }
2183
isheriff6f8d6862016-05-26 11:24:55 -07002184 void TestSetSendRtpHeaderExtensions(const std::string& ext_uri) {
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002185 // Enable extension.
2186 const int id = 1;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002187 cricket::VideoSendParameters parameters = send_parameters_;
isheriff6f8d6862016-05-26 11:24:55 -07002188 parameters.extensions.push_back(RtpExtension(ext_uri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002189 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002190 FakeVideoSendStream* send_stream =
2191 AddSendStream(cricket::StreamParams::CreateLegacy(123));
2192
2193 // Verify the send extension id.
2194 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
2195 EXPECT_EQ(id, send_stream->GetConfig().rtp.extensions[0].id);
isheriff6f8d6862016-05-26 11:24:55 -07002196 EXPECT_EQ(ext_uri, send_stream->GetConfig().rtp.extensions[0].uri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002197 // Verify call with same set of extensions returns true.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002198 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002199 // Verify that SetSendRtpHeaderExtensions doesn't implicitly add them for
2200 // receivers.
2201 EXPECT_TRUE(AddRecvStream(cricket::StreamParams::CreateLegacy(123))
2202 ->GetConfig()
2203 .rtp.extensions.empty());
2204
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00002205 // Verify that existing RTP header extensions can be removed.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002206 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Fredrik Solenberg709ed672015-09-15 12:26:33 +02002207 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
2208 send_stream = fake_call_->GetVideoSendStreams()[0];
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00002209 EXPECT_TRUE(send_stream->GetConfig().rtp.extensions.empty());
2210
2211 // Verify that adding receive RTP header extensions adds them for existing
2212 // streams.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002213 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Fredrik Solenberg709ed672015-09-15 12:26:33 +02002214 send_stream = fake_call_->GetVideoSendStreams()[0];
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00002215 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
2216 EXPECT_EQ(id, send_stream->GetConfig().rtp.extensions[0].id);
isheriff6f8d6862016-05-26 11:24:55 -07002217 EXPECT_EQ(ext_uri, send_stream->GetConfig().rtp.extensions[0].uri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002218 }
2219
isheriff6f8d6862016-05-26 11:24:55 -07002220 void TestSetRecvRtpHeaderExtensions(const std::string& ext_uri) {
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002221 // Enable extension.
2222 const int id = 1;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002223 cricket::VideoRecvParameters parameters = recv_parameters_;
isheriff6f8d6862016-05-26 11:24:55 -07002224 parameters.extensions.push_back(RtpExtension(ext_uri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002225 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002226
2227 FakeVideoReceiveStream* recv_stream =
2228 AddRecvStream(cricket::StreamParams::CreateLegacy(123));
2229
2230 // Verify the recv extension id.
2231 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.extensions.size());
2232 EXPECT_EQ(id, recv_stream->GetConfig().rtp.extensions[0].id);
isheriff6f8d6862016-05-26 11:24:55 -07002233 EXPECT_EQ(ext_uri, recv_stream->GetConfig().rtp.extensions[0].uri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002234 // Verify call with same set of extensions returns true.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002235 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00002236
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002237 // Verify that SetRecvRtpHeaderExtensions doesn't implicitly add them for
2238 // senders.
2239 EXPECT_TRUE(AddSendStream(cricket::StreamParams::CreateLegacy(123))
2240 ->GetConfig()
2241 .rtp.extensions.empty());
2242
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00002243 // Verify that existing RTP header extensions can be removed.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002244 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
Fredrik Solenberg709ed672015-09-15 12:26:33 +02002245 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
2246 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00002247 EXPECT_TRUE(recv_stream->GetConfig().rtp.extensions.empty());
2248
2249 // Verify that adding receive RTP header extensions adds them for existing
2250 // streams.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002251 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
Fredrik Solenberg709ed672015-09-15 12:26:33 +02002252 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00002253 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.extensions.size());
2254 EXPECT_EQ(id, recv_stream->GetConfig().rtp.extensions[0].id);
isheriff6f8d6862016-05-26 11:24:55 -07002255 EXPECT_EQ(ext_uri, recv_stream->GetConfig().rtp.extensions[0].uri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002256 }
2257
Stefan Holmerbbaf3632015-10-29 18:53:23 +01002258 void TestExtensionFilter(const std::vector<std::string>& extensions,
2259 const std::string& expected_extension) {
2260 cricket::VideoSendParameters parameters = send_parameters_;
2261 int expected_id = -1;
2262 int id = 1;
2263 for (const std::string& extension : extensions) {
2264 if (extension == expected_extension)
2265 expected_id = id;
isheriff6f8d6862016-05-26 11:24:55 -07002266 parameters.extensions.push_back(RtpExtension(extension, id++));
Stefan Holmerbbaf3632015-10-29 18:53:23 +01002267 }
2268 EXPECT_TRUE(channel_->SetSendParameters(parameters));
2269 FakeVideoSendStream* send_stream =
2270 AddSendStream(cricket::StreamParams::CreateLegacy(123));
2271
2272 // Verify that only one of them has been set, and that it is the one with
2273 // highest priority (transport sequence number).
2274 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
2275 EXPECT_EQ(expected_id, send_stream->GetConfig().rtp.extensions[0].id);
2276 EXPECT_EQ(expected_extension,
isheriff6f8d6862016-05-26 11:24:55 -07002277 send_stream->GetConfig().rtp.extensions[0].uri);
Stefan Holmerbbaf3632015-10-29 18:53:23 +01002278 }
2279
asapersson3c81a1a2017-06-14 05:52:21 -07002280 void TestDegradationPreference(bool resolution_scaling_enabled,
2281 bool fps_scaling_enabled);
2282
Erik Språngefbde372015-04-29 16:21:28 +02002283 void TestCpuAdaptation(bool enable_overuse, bool is_screenshare);
Peter Boström3548dd22015-05-22 18:48:36 +02002284 void TestReceiverLocalSsrcConfiguration(bool receiver_first);
magjed509e4fe2016-11-18 01:34:11 -08002285 void TestReceiveUnsignaledSsrcPacket(uint8_t payload_type,
2286 bool expect_created_receive_stream);
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002287
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002288 FakeVideoSendStream* SetDenoisingOption(
nisse05103312016-03-16 02:22:50 -07002289 uint32_t ssrc,
Niels Möller805a27e2019-01-21 12:21:27 +01002290 webrtc::test::FrameForwarder* frame_forwarder,
nisse0db023a2016-03-01 04:29:59 -08002291 bool enabled) {
nisse05103312016-03-16 02:22:50 -07002292 cricket::VideoOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002293 options.video_noise_reduction = enabled;
Niels Möller805a27e2019-01-21 12:21:27 +01002294 EXPECT_TRUE(channel_->SetVideoSend(ssrc, &options, frame_forwarder));
nisse0db023a2016-03-01 04:29:59 -08002295 // Options only take effect on the next frame.
Niels Möller805a27e2019-01-21 12:21:27 +01002296 frame_forwarder->IncomingCapturedFrame(frame_source_.GetFrame());
nisse0db023a2016-03-01 04:29:59 -08002297
Erik Språng143cec12015-04-28 10:01:41 +02002298 return fake_call_->GetVideoSendStreams().back();
2299 }
2300
Peter Boström2feafdb2015-09-09 14:32:14 +02002301 FakeVideoSendStream* SetUpSimulcast(bool enabled, bool with_rtx) {
2302 const int kRtxSsrcOffset = 0xDEADBEEF;
Erik Språng143cec12015-04-28 10:01:41 +02002303 last_ssrc_ += 3;
Peter Boström2feafdb2015-09-09 14:32:14 +02002304 std::vector<uint32_t> ssrcs;
2305 std::vector<uint32_t> rtx_ssrcs;
2306 uint32_t num_streams = enabled ? 3 : 1;
2307 for (uint32_t i = 0; i < num_streams; ++i) {
2308 uint32_t ssrc = last_ssrc_ + i;
2309 ssrcs.push_back(ssrc);
2310 if (with_rtx) {
2311 rtx_ssrcs.push_back(ssrc + kRtxSsrcOffset);
2312 }
Erik Språng143cec12015-04-28 10:01:41 +02002313 }
Peter Boström2feafdb2015-09-09 14:32:14 +02002314 if (with_rtx) {
2315 return AddSendStream(
2316 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
2317 }
2318 return AddSendStream(CreateSimStreamParams("cname", ssrcs));
Erik Språng143cec12015-04-28 10:01:41 +02002319 }
2320
perkjfa10b552016-10-02 23:45:26 -07002321 int GetMaxEncoderBitrate() {
skvladdc1c62c2016-03-16 19:07:43 -07002322 std::vector<FakeVideoSendStream*> streams =
2323 fake_call_->GetVideoSendStreams();
perkjfa10b552016-10-02 23:45:26 -07002324 EXPECT_EQ(1u, streams.size());
skvladdc1c62c2016-03-16 19:07:43 -07002325 FakeVideoSendStream* stream = streams[streams.size() - 1];
Mirko Bonadeif859e552018-05-30 15:31:29 +02002326 EXPECT_EQ(1u, stream->GetEncoderConfig().number_of_streams);
perkjfa10b552016-10-02 23:45:26 -07002327 return stream->GetVideoStreams()[0].max_bitrate_bps;
skvladdc1c62c2016-03-16 19:07:43 -07002328 }
2329
perkjfa10b552016-10-02 23:45:26 -07002330 void SetAndExpectMaxBitrate(int global_max,
skvladdc1c62c2016-03-16 19:07:43 -07002331 int stream_max,
2332 int expected_encoder_bitrate) {
2333 VideoSendParameters limited_send_params = send_parameters_;
2334 limited_send_params.max_bandwidth_bps = global_max;
2335 EXPECT_TRUE(channel_->SetSendParameters(limited_send_params));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07002336 webrtc::RtpParameters parameters =
2337 channel_->GetRtpSendParameters(last_ssrc_);
skvladdc1c62c2016-03-16 19:07:43 -07002338 EXPECT_EQ(1UL, parameters.encodings.size());
Oskar Sundbom78807582017-11-16 11:09:55 +01002339 parameters.encodings[0].max_bitrate_bps = stream_max;
Zach Steinba37b4b2018-01-23 15:02:36 -08002340 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
skvladdc1c62c2016-03-16 19:07:43 -07002341 // Read back the parameteres and verify they have the correct value
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07002342 parameters = channel_->GetRtpSendParameters(last_ssrc_);
skvladdc1c62c2016-03-16 19:07:43 -07002343 EXPECT_EQ(1UL, parameters.encodings.size());
Oskar Sundbom78807582017-11-16 11:09:55 +01002344 EXPECT_EQ(stream_max, parameters.encodings[0].max_bitrate_bps);
skvladdc1c62c2016-03-16 19:07:43 -07002345 // Verify that the new value propagated down to the encoder
perkjfa10b552016-10-02 23:45:26 -07002346 EXPECT_EQ(expected_encoder_bitrate, GetMaxEncoderBitrate());
skvladdc1c62c2016-03-16 19:07:43 -07002347 }
2348
Åsa Persson55659812018-06-18 17:51:32 +02002349 // Values from kSimulcastConfigs in simulcast.cc.
2350 const std::vector<webrtc::VideoStream> GetSimulcastBitrates720p() const {
2351 std::vector<webrtc::VideoStream> layers(3);
2352 layers[0].min_bitrate_bps = 30000;
2353 layers[0].target_bitrate_bps = 150000;
2354 layers[0].max_bitrate_bps = 200000;
2355 layers[1].min_bitrate_bps = 150000;
2356 layers[1].target_bitrate_bps = 500000;
2357 layers[1].max_bitrate_bps = 700000;
2358 layers[2].min_bitrate_bps = 600000;
2359 layers[2].target_bitrate_bps = 2500000;
2360 layers[2].max_bitrate_bps = 2500000;
2361 return layers;
2362 }
2363
Niels Möller805a27e2019-01-21 12:21:27 +01002364 cricket::FakeFrameSource frame_source_;
kwiberg686a8ef2016-02-26 03:00:35 -08002365 std::unique_ptr<FakeCall> fake_call_;
2366 std::unique_ptr<VideoMediaChannel> channel_;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002367 cricket::VideoSendParameters send_parameters_;
2368 cricket::VideoRecvParameters recv_parameters_;
Peter Boström0c4e06b2015-10-07 12:23:21 +02002369 uint32_t last_ssrc_;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002370};
2371
eladalonf1841382017-06-12 01:16:46 -07002372TEST_F(WebRtcVideoChannelTest, SetsSyncGroupFromSyncLabel) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02002373 const uint32_t kVideoSsrc = 123;
pbos8fc7fa72015-07-15 08:02:58 -07002374 const std::string kSyncLabel = "AvSyncLabel";
2375
2376 cricket::StreamParams sp = cricket::StreamParams::CreateLegacy(kVideoSsrc);
Seth Hampson845e8782018-03-02 11:34:10 -08002377 sp.set_stream_ids({kSyncLabel});
pbos8fc7fa72015-07-15 08:02:58 -07002378 EXPECT_TRUE(channel_->AddRecvStream(sp));
2379
Mirko Bonadeif859e552018-05-30 15:31:29 +02002380 EXPECT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
pbos8fc7fa72015-07-15 08:02:58 -07002381 EXPECT_EQ(kSyncLabel,
2382 fake_call_->GetVideoReceiveStreams()[0]->GetConfig().sync_group)
2383 << "SyncGroup should be set based on sync_label";
2384}
2385
eladalonf1841382017-06-12 01:16:46 -07002386TEST_F(WebRtcVideoChannelTest, RecvStreamWithSimAndRtx) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002387 cricket::VideoSendParameters parameters;
2388 parameters.codecs = engine_.codecs();
2389 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002390 EXPECT_TRUE(channel_->SetSend(true));
nisse4b4dc862016-02-17 05:25:36 -08002391 parameters.conference_mode = true;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002392 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002393
2394 // Send side.
Peter Boström0c4e06b2015-10-07 12:23:21 +02002395 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
2396 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002397 FakeVideoSendStream* send_stream = AddSendStream(
2398 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
2399
2400 ASSERT_EQ(rtx_ssrcs.size(), send_stream->GetConfig().rtp.rtx.ssrcs.size());
2401 for (size_t i = 0; i < rtx_ssrcs.size(); ++i)
2402 EXPECT_EQ(rtx_ssrcs[i], send_stream->GetConfig().rtp.rtx.ssrcs[i]);
2403
2404 // Receiver side.
2405 FakeVideoReceiveStream* recv_stream = AddRecvStream(
2406 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
nisse26e3abb2017-08-25 04:44:25 -07002407 EXPECT_FALSE(
2408 recv_stream->GetConfig().rtp.rtx_associated_payload_types.empty());
nisseca5706d2017-09-11 02:32:16 -07002409 EXPECT_TRUE(VerifyRtxReceiveAssociations(recv_stream->GetConfig()))
Peter Boströmd8b01092016-05-12 16:44:36 +02002410 << "RTX should be mapped for all decoders/payload types.";
nisseca5706d2017-09-11 02:32:16 -07002411 EXPECT_TRUE(HasRtxReceiveAssociation(recv_stream->GetConfig(),
Yves Gerey665174f2018-06-19 15:03:05 +02002412 GetEngineCodec("red").id))
nisseca5706d2017-09-11 02:32:16 -07002413 << "RTX should be mapped for the RED payload type";
2414
brandtr14742122017-01-27 04:53:07 -08002415 EXPECT_EQ(rtx_ssrcs[0], recv_stream->GetConfig().rtp.rtx_ssrc);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002416}
2417
eladalonf1841382017-06-12 01:16:46 -07002418TEST_F(WebRtcVideoChannelTest, RecvStreamWithRtx) {
pbos@webrtc.orge322a172014-06-13 11:47:28 +00002419 // Setup one channel with an associated RTX stream.
2420 cricket::StreamParams params =
2421 cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
2422 params.AddFidSsrc(kSsrcs1[0], kRtxSsrcs1[0]);
2423 FakeVideoReceiveStream* recv_stream = AddRecvStream(params);
brandtr14742122017-01-27 04:53:07 -08002424 EXPECT_EQ(kRtxSsrcs1[0], recv_stream->GetConfig().rtp.rtx_ssrc);
nisseca5706d2017-09-11 02:32:16 -07002425
2426 EXPECT_TRUE(VerifyRtxReceiveAssociations(recv_stream->GetConfig()))
2427 << "RTX should be mapped for all decoders/payload types.";
2428 EXPECT_TRUE(HasRtxReceiveAssociation(recv_stream->GetConfig(),
Yves Gerey665174f2018-06-19 15:03:05 +02002429 GetEngineCodec("red").id))
nisseca5706d2017-09-11 02:32:16 -07002430 << "RTX should be mapped for the RED payload type";
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002431}
2432
eladalonf1841382017-06-12 01:16:46 -07002433TEST_F(WebRtcVideoChannelTest, RecvStreamNoRtx) {
pbos@webrtc.orge322a172014-06-13 11:47:28 +00002434 // Setup one channel without an associated RTX stream.
2435 cricket::StreamParams params =
2436 cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
2437 FakeVideoReceiveStream* recv_stream = AddRecvStream(params);
brandtr14742122017-01-27 04:53:07 -08002438 ASSERT_EQ(0U, recv_stream->GetConfig().rtp.rtx_ssrc);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002439}
2440
Johannes Kron9190b822018-10-29 11:22:05 +01002441// Test propagation of extmap allow mixed setting.
2442TEST_F(WebRtcVideoChannelTest, SetExtmapAllowMixedAsCaller) {
2443 TestExtmapAllowMixedCaller(/*extmap_allow_mixed=*/true);
2444}
2445TEST_F(WebRtcVideoChannelTest, SetExtmapAllowMixedDisabledAsCaller) {
2446 TestExtmapAllowMixedCaller(/*extmap_allow_mixed=*/false);
2447}
2448TEST_F(WebRtcVideoChannelTest, SetExtmapAllowMixedAsCallee) {
2449 TestExtmapAllowMixedCallee(/*extmap_allow_mixed=*/true);
2450}
2451TEST_F(WebRtcVideoChannelTest, SetExtmapAllowMixedDisabledAsCallee) {
2452 TestExtmapAllowMixedCallee(/*extmap_allow_mixed=*/false);
2453}
2454
eladalonf1841382017-06-12 01:16:46 -07002455TEST_F(WebRtcVideoChannelTest, NoHeaderExtesionsByDefault) {
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002456 FakeVideoSendStream* send_stream =
2457 AddSendStream(cricket::StreamParams::CreateLegacy(kSsrcs1[0]));
2458 ASSERT_TRUE(send_stream->GetConfig().rtp.extensions.empty());
2459
2460 FakeVideoReceiveStream* recv_stream =
2461 AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrcs1[0]));
2462 ASSERT_TRUE(recv_stream->GetConfig().rtp.extensions.empty());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002463}
2464
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002465// Test support for RTP timestamp offset header extension.
eladalonf1841382017-06-12 01:16:46 -07002466TEST_F(WebRtcVideoChannelTest, SendRtpTimestampOffsetHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002467 TestSetSendRtpHeaderExtensions(RtpExtension::kTimestampOffsetUri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002468}
isheriff6f8d6862016-05-26 11:24:55 -07002469
eladalonf1841382017-06-12 01:16:46 -07002470TEST_F(WebRtcVideoChannelTest, RecvRtpTimestampOffsetHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002471 TestSetRecvRtpHeaderExtensions(RtpExtension::kTimestampOffsetUri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002472}
2473
2474// Test support for absolute send time header extension.
eladalonf1841382017-06-12 01:16:46 -07002475TEST_F(WebRtcVideoChannelTest, SendAbsoluteSendTimeHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002476 TestSetSendRtpHeaderExtensions(RtpExtension::kAbsSendTimeUri);
pbos@webrtc.org587ef602014-06-16 17:32:02 +00002477}
isheriff6f8d6862016-05-26 11:24:55 -07002478
eladalonf1841382017-06-12 01:16:46 -07002479TEST_F(WebRtcVideoChannelTest, RecvAbsoluteSendTimeHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002480 TestSetRecvRtpHeaderExtensions(RtpExtension::kAbsSendTimeUri);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002481}
2482
eladalonf1841382017-06-12 01:16:46 -07002483TEST_F(WebRtcVideoChannelTest, FiltersExtensionsPicksTransportSeqNum) {
Stefan Holmerbbaf3632015-10-29 18:53:23 +01002484 // Enable three redundant extensions.
2485 std::vector<std::string> extensions;
isheriff6f8d6862016-05-26 11:24:55 -07002486 extensions.push_back(RtpExtension::kAbsSendTimeUri);
2487 extensions.push_back(RtpExtension::kTimestampOffsetUri);
2488 extensions.push_back(RtpExtension::kTransportSequenceNumberUri);
2489 TestExtensionFilter(extensions, RtpExtension::kTransportSequenceNumberUri);
Stefan Holmerbbaf3632015-10-29 18:53:23 +01002490}
2491
eladalonf1841382017-06-12 01:16:46 -07002492TEST_F(WebRtcVideoChannelTest, FiltersExtensionsPicksAbsSendTime) {
Stefan Holmerbbaf3632015-10-29 18:53:23 +01002493 // Enable two redundant extensions.
2494 std::vector<std::string> extensions;
isheriff6f8d6862016-05-26 11:24:55 -07002495 extensions.push_back(RtpExtension::kAbsSendTimeUri);
2496 extensions.push_back(RtpExtension::kTimestampOffsetUri);
2497 TestExtensionFilter(extensions, RtpExtension::kAbsSendTimeUri);
Stefan Holmerbbaf3632015-10-29 18:53:23 +01002498}
2499
stefanc1aeaf02015-10-15 07:26:07 -07002500// Test support for transport sequence number header extension.
eladalonf1841382017-06-12 01:16:46 -07002501TEST_F(WebRtcVideoChannelTest, SendTransportSequenceNumberHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002502 TestSetSendRtpHeaderExtensions(RtpExtension::kTransportSequenceNumberUri);
stefanc1aeaf02015-10-15 07:26:07 -07002503}
eladalonf1841382017-06-12 01:16:46 -07002504TEST_F(WebRtcVideoChannelTest, RecvTransportSequenceNumberHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002505 TestSetRecvRtpHeaderExtensions(RtpExtension::kTransportSequenceNumberUri);
stefanc1aeaf02015-10-15 07:26:07 -07002506}
2507
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -07002508// Test support for video rotation header extension.
eladalonf1841382017-06-12 01:16:46 -07002509TEST_F(WebRtcVideoChannelTest, SendVideoRotationHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002510 TestSetSendRtpHeaderExtensions(RtpExtension::kVideoRotationUri);
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -07002511}
eladalonf1841382017-06-12 01:16:46 -07002512TEST_F(WebRtcVideoChannelTest, RecvVideoRotationHeaderExtensions) {
isheriff6f8d6862016-05-26 11:24:55 -07002513 TestSetRecvRtpHeaderExtensions(RtpExtension::kVideoRotationUri);
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -07002514}
2515
eladalonf1841382017-06-12 01:16:46 -07002516TEST_F(WebRtcVideoChannelTest, IdenticalSendExtensionsDoesntRecreateStream) {
Stefan Holmerbbaf3632015-10-29 18:53:23 +01002517 const int kAbsSendTimeId = 1;
2518 const int kVideoRotationId = 2;
isheriff6f8d6862016-05-26 11:24:55 -07002519 send_parameters_.extensions.push_back(
2520 RtpExtension(RtpExtension::kAbsSendTimeUri, kAbsSendTimeId));
2521 send_parameters_.extensions.push_back(
2522 RtpExtension(RtpExtension::kVideoRotationUri, kVideoRotationId));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00002523
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002524 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00002525 FakeVideoSendStream* send_stream =
2526 AddSendStream(cricket::StreamParams::CreateLegacy(123));
2527
2528 EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());
Stefan Holmerbbaf3632015-10-29 18:53:23 +01002529 ASSERT_EQ(2u, send_stream->GetConfig().rtp.extensions.size());
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00002530
2531 // Setting the same extensions (even if in different order) shouldn't
2532 // reallocate the stream.
Steve Anton2c9ebef2019-01-28 17:27:58 -08002533 absl::c_reverse(send_parameters_.extensions);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002534 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00002535
2536 EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());
2537
2538 // Setting different extensions should recreate the stream.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002539 send_parameters_.extensions.resize(1);
2540 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00002541
2542 EXPECT_EQ(2, fake_call_->GetNumCreatedSendStreams());
2543}
2544
eladalonf1841382017-06-12 01:16:46 -07002545TEST_F(WebRtcVideoChannelTest, IdenticalRecvExtensionsDoesntRecreateStream) {
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00002546 const int kTOffsetId = 1;
2547 const int kAbsSendTimeId = 2;
Guo-wei Shieh64c1e8c2015-04-01 15:33:06 -07002548 const int kVideoRotationId = 3;
isheriff6f8d6862016-05-26 11:24:55 -07002549 recv_parameters_.extensions.push_back(
2550 RtpExtension(RtpExtension::kAbsSendTimeUri, kAbsSendTimeId));
2551 recv_parameters_.extensions.push_back(
2552 RtpExtension(RtpExtension::kTimestampOffsetUri, kTOffsetId));
2553 recv_parameters_.extensions.push_back(
2554 RtpExtension(RtpExtension::kVideoRotationUri, kVideoRotationId));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00002555
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002556 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
Peter Boström54be3e02015-05-25 15:04:24 +02002557 FakeVideoReceiveStream* recv_stream =
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00002558 AddRecvStream(cricket::StreamParams::CreateLegacy(123));
2559
2560 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
Peter Boström54be3e02015-05-25 15:04:24 +02002561 ASSERT_EQ(3u, recv_stream->GetConfig().rtp.extensions.size());
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00002562
2563 // Setting the same extensions (even if in different order) shouldn't
2564 // reallocate the stream.
Steve Anton2c9ebef2019-01-28 17:27:58 -08002565 absl::c_reverse(recv_parameters_.extensions);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002566 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00002567
2568 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
2569
2570 // Setting different extensions should recreate the stream.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002571 recv_parameters_.extensions.resize(1);
2572 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
pbos@webrtc.orgc37e72e2015-01-05 18:51:13 +00002573
2574 EXPECT_EQ(2, fake_call_->GetNumCreatedReceiveStreams());
2575}
2576
eladalonf1841382017-06-12 01:16:46 -07002577TEST_F(WebRtcVideoChannelTest,
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002578 SetSendRtpHeaderExtensionsExcludeUnsupportedExtensions) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002579 const int kUnsupportedId = 1;
2580 const int kTOffsetId = 2;
2581
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002582 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002583 RtpExtension(kUnsupportedExtensionName, kUnsupportedId));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002584 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002585 RtpExtension(RtpExtension::kTimestampOffsetUri, kTOffsetId));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002586 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002587 FakeVideoSendStream* send_stream =
2588 AddSendStream(cricket::StreamParams::CreateLegacy(123));
2589
2590 // Only timestamp offset extension is set to send stream,
2591 // unsupported rtp extension is ignored.
2592 ASSERT_EQ(1u, send_stream->GetConfig().rtp.extensions.size());
isheriff6f8d6862016-05-26 11:24:55 -07002593 EXPECT_STREQ(RtpExtension::kTimestampOffsetUri,
2594 send_stream->GetConfig().rtp.extensions[0].uri.c_str());
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002595}
2596
eladalonf1841382017-06-12 01:16:46 -07002597TEST_F(WebRtcVideoChannelTest,
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002598 SetRecvRtpHeaderExtensionsExcludeUnsupportedExtensions) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002599 const int kUnsupportedId = 1;
2600 const int kTOffsetId = 2;
2601
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002602 recv_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002603 RtpExtension(kUnsupportedExtensionName, kUnsupportedId));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002604 recv_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002605 RtpExtension(RtpExtension::kTimestampOffsetUri, kTOffsetId));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002606 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002607 FakeVideoReceiveStream* recv_stream =
2608 AddRecvStream(cricket::StreamParams::CreateLegacy(123));
2609
2610 // Only timestamp offset extension is set to receive stream,
2611 // unsupported rtp extension is ignored.
2612 ASSERT_EQ(1u, recv_stream->GetConfig().rtp.extensions.size());
isheriff6f8d6862016-05-26 11:24:55 -07002613 EXPECT_STREQ(RtpExtension::kTimestampOffsetUri,
2614 recv_stream->GetConfig().rtp.extensions[0].uri.c_str());
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002615}
2616
eladalonf1841382017-06-12 01:16:46 -07002617TEST_F(WebRtcVideoChannelTest, SetSendRtpHeaderExtensionsRejectsIncorrectIds) {
Peter Boström23914fe2015-03-31 15:08:04 +02002618 const int kIncorrectIds[] = {-2, -1, 0, 15, 16};
pkasting@chromium.orge7a4a122015-01-28 21:36:55 +00002619 for (size_t i = 0; i < arraysize(kIncorrectIds); ++i) {
isheriff6f8d6862016-05-26 11:24:55 -07002620 send_parameters_.extensions.push_back(
2621 RtpExtension(RtpExtension::kTimestampOffsetUri, kIncorrectIds[i]));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002622 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_))
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002623 << "Bad extension id '" << kIncorrectIds[i] << "' accepted.";
2624 }
2625}
2626
eladalonf1841382017-06-12 01:16:46 -07002627TEST_F(WebRtcVideoChannelTest, SetRecvRtpHeaderExtensionsRejectsIncorrectIds) {
Peter Boström23914fe2015-03-31 15:08:04 +02002628 const int kIncorrectIds[] = {-2, -1, 0, 15, 16};
pkasting@chromium.orge7a4a122015-01-28 21:36:55 +00002629 for (size_t i = 0; i < arraysize(kIncorrectIds); ++i) {
isheriff6f8d6862016-05-26 11:24:55 -07002630 recv_parameters_.extensions.push_back(
2631 RtpExtension(RtpExtension::kTimestampOffsetUri, kIncorrectIds[i]));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002632 EXPECT_FALSE(channel_->SetRecvParameters(recv_parameters_))
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002633 << "Bad extension id '" << kIncorrectIds[i] << "' accepted.";
2634 }
2635}
2636
eladalonf1841382017-06-12 01:16:46 -07002637TEST_F(WebRtcVideoChannelTest, SetSendRtpHeaderExtensionsRejectsDuplicateIds) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002638 const int id = 1;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002639 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002640 RtpExtension(RtpExtension::kTimestampOffsetUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002641 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002642 RtpExtension(RtpExtension::kAbsSendTimeUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002643 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002644
2645 // Duplicate entries are also not supported.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002646 send_parameters_.extensions.clear();
2647 send_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002648 RtpExtension(RtpExtension::kTimestampOffsetUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002649 send_parameters_.extensions.push_back(send_parameters_.extensions.back());
2650 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002651}
2652
eladalonf1841382017-06-12 01:16:46 -07002653TEST_F(WebRtcVideoChannelTest, SetRecvRtpHeaderExtensionsRejectsDuplicateIds) {
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002654 const int id = 1;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002655 recv_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002656 RtpExtension(RtpExtension::kTimestampOffsetUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002657 recv_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002658 RtpExtension(RtpExtension::kAbsSendTimeUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002659 EXPECT_FALSE(channel_->SetRecvParameters(recv_parameters_));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002660
2661 // Duplicate entries are also not supported.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002662 recv_parameters_.extensions.clear();
2663 recv_parameters_.extensions.push_back(
isheriff6f8d6862016-05-26 11:24:55 -07002664 RtpExtension(RtpExtension::kTimestampOffsetUri, id));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002665 recv_parameters_.extensions.push_back(recv_parameters_.extensions.back());
2666 EXPECT_FALSE(channel_->SetRecvParameters(recv_parameters_));
pbos@webrtc.org3c107582014-07-20 15:27:35 +00002667}
2668
eladalonf1841382017-06-12 01:16:46 -07002669TEST_F(WebRtcVideoChannelTest, AddRecvStreamOnlyUsesOneReceiveStream) {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002670 EXPECT_TRUE(channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(1)));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002671 EXPECT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002672}
2673
eladalonf1841382017-06-12 01:16:46 -07002674TEST_F(WebRtcVideoChannelTest, RtcpIsCompoundByDefault) {
Peter Boströmd7da1202015-06-05 14:09:38 +02002675 FakeVideoReceiveStream* stream = AddRecvStream();
pbosda903ea2015-10-02 02:36:56 -07002676 EXPECT_EQ(webrtc::RtcpMode::kCompound, stream->GetConfig().rtp.rtcp_mode);
Peter Boströmd7da1202015-06-05 14:09:38 +02002677}
2678
eladalonf1841382017-06-12 01:16:46 -07002679TEST_F(WebRtcVideoChannelTest, RembIsEnabledByDefault) {
pbos@webrtc.org257e1302014-07-25 19:01:32 +00002680 FakeVideoReceiveStream* stream = AddRecvStream();
2681 EXPECT_TRUE(stream->GetConfig().rtp.remb);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002682}
2683
eladalonf1841382017-06-12 01:16:46 -07002684TEST_F(WebRtcVideoChannelTest, TransportCcIsEnabledByDefault) {
stefan43edf0f2015-11-20 18:05:48 -08002685 FakeVideoReceiveStream* stream = AddRecvStream();
2686 EXPECT_TRUE(stream->GetConfig().rtp.transport_cc);
2687}
2688
eladalonf1841382017-06-12 01:16:46 -07002689TEST_F(WebRtcVideoChannelTest, RembCanBeEnabledAndDisabled) {
pbos@webrtc.org257e1302014-07-25 19:01:32 +00002690 FakeVideoReceiveStream* stream = AddRecvStream();
2691 EXPECT_TRUE(stream->GetConfig().rtp.remb);
2692
Peter Boström126c03e2015-05-11 12:48:12 +02002693 // Verify that REMB is turned off when send(!) codecs without REMB are set.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002694 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002695 parameters.codecs.push_back(RemoveFeedbackParams(GetEngineCodec("VP8")));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002696 EXPECT_TRUE(parameters.codecs[0].feedback_params.params().empty());
2697 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002698 stream = fake_call_->GetVideoReceiveStreams()[0];
pbos@webrtc.org257e1302014-07-25 19:01:32 +00002699 EXPECT_FALSE(stream->GetConfig().rtp.remb);
2700
2701 // Verify that REMB is turned on when setting default codecs since the
2702 // default codecs have REMB enabled.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002703 parameters.codecs = engine_.codecs();
2704 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00002705 stream = fake_call_->GetVideoReceiveStreams()[0];
pbos@webrtc.org257e1302014-07-25 19:01:32 +00002706 EXPECT_TRUE(stream->GetConfig().rtp.remb);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002707}
2708
eladalonf1841382017-06-12 01:16:46 -07002709TEST_F(WebRtcVideoChannelTest, TransportCcCanBeEnabledAndDisabled) {
stefan43edf0f2015-11-20 18:05:48 -08002710 FakeVideoReceiveStream* stream = AddRecvStream();
2711 EXPECT_TRUE(stream->GetConfig().rtp.transport_cc);
2712
2713 // Verify that transport cc feedback is turned off when send(!) codecs without
2714 // transport cc feedback are set.
2715 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002716 parameters.codecs.push_back(RemoveFeedbackParams(GetEngineCodec("VP8")));
stefan43edf0f2015-11-20 18:05:48 -08002717 EXPECT_TRUE(parameters.codecs[0].feedback_params.params().empty());
2718 EXPECT_TRUE(channel_->SetSendParameters(parameters));
2719 stream = fake_call_->GetVideoReceiveStreams()[0];
2720 EXPECT_FALSE(stream->GetConfig().rtp.transport_cc);
2721
2722 // Verify that transport cc feedback is turned on when setting default codecs
2723 // since the default codecs have transport cc feedback enabled.
2724 parameters.codecs = engine_.codecs();
2725 EXPECT_TRUE(channel_->SetSendParameters(parameters));
2726 stream = fake_call_->GetVideoReceiveStreams()[0];
2727 EXPECT_TRUE(stream->GetConfig().rtp.transport_cc);
2728}
2729
eladalonf1841382017-06-12 01:16:46 -07002730TEST_F(WebRtcVideoChannelTest, NackIsEnabledByDefault) {
Anders Carlsson5f2bb622018-05-14 09:48:06 +02002731 AssignDefaultCodec();
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +00002732 VerifyCodecHasDefaultFeedbackParams(default_codec_);
2733
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002734 cricket::VideoSendParameters parameters;
2735 parameters.codecs = engine_.codecs();
2736 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org19864742014-05-30 07:35:47 +00002737 EXPECT_TRUE(channel_->SetSend(true));
2738
2739 // Send side.
2740 FakeVideoSendStream* send_stream =
2741 AddSendStream(cricket::StreamParams::CreateLegacy(1));
2742 EXPECT_GT(send_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
2743
2744 // Receiver side.
2745 FakeVideoReceiveStream* recv_stream =
2746 AddRecvStream(cricket::StreamParams::CreateLegacy(1));
2747 EXPECT_GT(recv_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
2748
2749 // Nack history size should match between sender and receiver.
2750 EXPECT_EQ(send_stream->GetConfig().rtp.nack.rtp_history_ms,
2751 recv_stream->GetConfig().rtp.nack.rtp_history_ms);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002752}
2753
eladalonf1841382017-06-12 01:16:46 -07002754TEST_F(WebRtcVideoChannelTest, NackCanBeEnabledAndDisabled) {
Peter Boström67c9df72015-05-11 14:34:58 +02002755 FakeVideoSendStream* send_stream = AddSendStream();
Peter Boström3548dd22015-05-22 18:48:36 +02002756 FakeVideoReceiveStream* recv_stream = AddRecvStream();
Peter Boström67c9df72015-05-11 14:34:58 +02002757
2758 EXPECT_GT(recv_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
2759 EXPECT_GT(send_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
2760
2761 // Verify that NACK is turned off when send(!) codecs without NACK are set.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002762 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002763 parameters.codecs.push_back(RemoveFeedbackParams(GetEngineCodec("VP8")));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002764 EXPECT_TRUE(parameters.codecs[0].feedback_params.params().empty());
2765 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Peter Boström67c9df72015-05-11 14:34:58 +02002766 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
2767 EXPECT_EQ(0, recv_stream->GetConfig().rtp.nack.rtp_history_ms);
2768 send_stream = fake_call_->GetVideoSendStreams()[0];
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +00002769 EXPECT_EQ(0, send_stream->GetConfig().rtp.nack.rtp_history_ms);
2770
Peter Boström67c9df72015-05-11 14:34:58 +02002771 // Verify that NACK is turned on when setting default codecs since the
2772 // default codecs have NACK enabled.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002773 parameters.codecs = engine_.codecs();
2774 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Peter Boström67c9df72015-05-11 14:34:58 +02002775 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
2776 EXPECT_GT(recv_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
2777 send_stream = fake_call_->GetVideoSendStreams()[0];
2778 EXPECT_GT(send_stream->GetConfig().rtp.nack.rtp_history_ms, 0);
pbos@webrtc.orgf99c2f22014-06-13 12:27:38 +00002779}
2780
Peter Boströme7ba0862016-03-12 00:02:28 +01002781// This test verifies that new frame sizes reconfigures encoders even though not
2782// (yet) sending. The purpose of this is to permit encoding as quickly as
2783// possible once we start sending. Likely the frames being input are from the
2784// same source that will be sent later, which just means that we're ready
2785// earlier.
eladalonf1841382017-06-12 01:16:46 -07002786TEST_F(WebRtcVideoChannelTest, ReconfiguresEncodersWhenNotSending) {
Peter Boströme7ba0862016-03-12 00:02:28 +01002787 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002788 parameters.codecs.push_back(GetEngineCodec("VP8"));
Peter Boströme7ba0862016-03-12 00:02:28 +01002789 ASSERT_TRUE(channel_->SetSendParameters(parameters));
2790 channel_->SetSend(false);
2791
2792 FakeVideoSendStream* stream = AddSendStream();
2793
perkjfa10b552016-10-02 23:45:26 -07002794 // No frames entered.
Peter Boströme7ba0862016-03-12 00:02:28 +01002795 std::vector<webrtc::VideoStream> streams = stream->GetVideoStreams();
Danil Chapovalov350531e2018-06-08 11:04:04 +00002796 EXPECT_EQ(0u, streams[0].width);
2797 EXPECT_EQ(0u, streams[0].height);
Peter Boströme7ba0862016-03-12 00:02:28 +01002798
Niels Möller805a27e2019-01-21 12:21:27 +01002799 webrtc::test::FrameForwarder frame_forwarder;
2800 cricket::FakeFrameSource frame_source(1280, 720,
2801 rtc::kNumMicrosecsPerSec / 30);
2802
2803 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));
2804 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
Peter Boströme7ba0862016-03-12 00:02:28 +01002805
2806 // Frame entered, should be reconfigured to new dimensions.
2807 streams = stream->GetVideoStreams();
Niels Möller805a27e2019-01-21 12:21:27 +01002808 EXPECT_EQ(rtc::checked_cast<size_t>(1280), streams[0].width);
2809 EXPECT_EQ(rtc::checked_cast<size_t>(720), streams[0].height);
Peter Boströme7ba0862016-03-12 00:02:28 +01002810
Niels Möllerff40b142018-04-09 08:49:14 +02002811 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
Peter Boströme7ba0862016-03-12 00:02:28 +01002812}
2813
eladalonf1841382017-06-12 01:16:46 -07002814TEST_F(WebRtcVideoChannelTest, UsesCorrectSettingsForScreencast) {
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00002815 static const int kScreenshareMinBitrateKbps = 800;
magjed509e4fe2016-11-18 01:34:11 -08002816 cricket::VideoCodec codec = GetEngineCodec("VP8");
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002817 cricket::VideoSendParameters parameters;
2818 parameters.codecs.push_back(codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002819 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00002820 AddSendStream();
2821
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);
nisse05103312016-03-16 02:22:50 -07002825 VideoOptions min_bitrate_options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002826 min_bitrate_options.screencast_min_bitrate_kbps = kScreenshareMinBitrateKbps;
Niels Möller805a27e2019-01-21 12:21:27 +01002827 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &min_bitrate_options,
2828 &frame_forwarder));
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00002829
2830 EXPECT_TRUE(channel_->SetSend(true));
2831
Niels Möller805a27e2019-01-21 12:21:27 +01002832 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00002833 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
2834 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
2835
2836 EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());
2837
2838 // Verify non-screencast settings.
perkj26091b12016-09-01 01:17:40 -07002839 webrtc::VideoEncoderConfig encoder_config =
2840 send_stream->GetEncoderConfig().Copy();
Erik Språng143cec12015-04-28 10:01:41 +02002841 EXPECT_EQ(webrtc::VideoEncoderConfig::ContentType::kRealtimeVideo,
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00002842 encoder_config.content_type);
perkjfa10b552016-10-02 23:45:26 -07002843 std::vector<webrtc::VideoStream> streams = send_stream->GetVideoStreams();
Niels Möller805a27e2019-01-21 12:21:27 +01002844 EXPECT_EQ(rtc::checked_cast<size_t>(1280), streams.front().width);
2845 EXPECT_EQ(rtc::checked_cast<size_t>(720), streams.front().height);
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00002846 EXPECT_EQ(0, encoder_config.min_transmit_bitrate_bps)
2847 << "Non-screenshare shouldn't use min-transmit bitrate.";
2848
Niels Möllerff40b142018-04-09 08:49:14 +02002849 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
perkjd533aec2017-01-13 05:57:25 -08002850 EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());
nisse05103312016-03-16 02:22:50 -07002851 VideoOptions screencast_options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002852 screencast_options.is_screencast = true;
Niels Möller805a27e2019-01-21 12:21:27 +01002853 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &screencast_options,
2854 &frame_forwarder));
2855 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
sprangf24a0642017-02-28 13:23:26 -08002856 // Send stream recreated after option change.
2857 ASSERT_EQ(2, fake_call_->GetNumCreatedSendStreams());
2858 send_stream = fake_call_->GetVideoSendStreams().front();
2859 EXPECT_EQ(1, send_stream->GetNumberOfSwappedFrames());
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00002860
2861 // Verify screencast settings.
perkj26091b12016-09-01 01:17:40 -07002862 encoder_config = send_stream->GetEncoderConfig().Copy();
Erik Språng143cec12015-04-28 10:01:41 +02002863 EXPECT_EQ(webrtc::VideoEncoderConfig::ContentType::kScreen,
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00002864 encoder_config.content_type);
2865 EXPECT_EQ(kScreenshareMinBitrateKbps * 1000,
2866 encoder_config.min_transmit_bitrate_bps);
2867
perkjfa10b552016-10-02 23:45:26 -07002868 streams = send_stream->GetVideoStreams();
Niels Möller805a27e2019-01-21 12:21:27 +01002869 EXPECT_EQ(rtc::checked_cast<size_t>(1280), streams.front().width);
2870 EXPECT_EQ(rtc::checked_cast<size_t>(720), streams.front().height);
Sergey Silkina796a7e2018-03-01 15:11:29 +01002871 EXPECT_FALSE(streams[0].num_temporal_layers.has_value());
Niels Möllerff40b142018-04-09 08:49:14 +02002872 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002873}
2874
eladalonf1841382017-06-12 01:16:46 -07002875TEST_F(WebRtcVideoChannelTest,
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002876 ConferenceModeScreencastConfiguresTemporalLayer) {
Rasmus Brandt195d1d72018-05-09 11:28:01 +02002877 static const int kConferenceScreencastTemporalBitrateBps = 200 * 1000;
nisse4b4dc862016-02-17 05:25:36 -08002878 send_parameters_.conference_mode = true;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002879 channel_->SetSendParameters(send_parameters_);
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002880
2881 AddSendStream();
nisse05103312016-03-16 02:22:50 -07002882 VideoOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002883 options.is_screencast = true;
Niels Möller805a27e2019-01-21 12:21:27 +01002884 webrtc::test::FrameForwarder frame_forwarder;
2885 cricket::FakeFrameSource frame_source(1280, 720,
2886 rtc::kNumMicrosecsPerSec / 30);
2887 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002888 EXPECT_TRUE(channel_->SetSend(true));
2889
Niels Möller805a27e2019-01-21 12:21:27 +01002890 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002891 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
2892 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
2893
perkj26091b12016-09-01 01:17:40 -07002894 webrtc::VideoEncoderConfig encoder_config =
2895 send_stream->GetEncoderConfig().Copy();
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002896
2897 // Verify screencast settings.
perkj26091b12016-09-01 01:17:40 -07002898 encoder_config = send_stream->GetEncoderConfig().Copy();
Erik Språng143cec12015-04-28 10:01:41 +02002899 EXPECT_EQ(webrtc::VideoEncoderConfig::ContentType::kScreen,
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002900 encoder_config.content_type);
perkjfa10b552016-10-02 23:45:26 -07002901
2902 std::vector<webrtc::VideoStream> streams = send_stream->GetVideoStreams();
2903 ASSERT_EQ(1u, streams.size());
Sergey Silkina796a7e2018-03-01 15:11:29 +01002904 ASSERT_EQ(2u, streams[0].num_temporal_layers);
pbos@webrtc.orgb7ed7792014-10-31 13:08:10 +00002905 EXPECT_EQ(kConferenceScreencastTemporalBitrateBps,
Sergey Silkina796a7e2018-03-01 15:11:29 +01002906 streams[0].target_bitrate_bps);
pbos@webrtc.orgefc82c22014-10-27 13:58:00 +00002907
Niels Möllerff40b142018-04-09 08:49:14 +02002908 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00002909}
2910
eladalonf1841382017-06-12 01:16:46 -07002911TEST_F(WebRtcVideoChannelTest, SuspendBelowMinBitrateDisabledByDefault) {
pbos@webrtc.org5ff71ab2014-07-23 07:28:56 +00002912 FakeVideoSendStream* stream = AddSendStream();
2913 EXPECT_FALSE(stream->GetConfig().suspend_below_min_bitrate);
2914}
2915
eladalonf1841382017-06-12 01:16:46 -07002916TEST_F(WebRtcVideoChannelTest, SetMediaConfigSuspendBelowMinBitrate) {
kthelgason2bc68642017-02-07 07:02:22 -08002917 MediaConfig media_config = GetMediaConfig();
nisse0db023a2016-03-01 04:29:59 -08002918 media_config.video.suspend_below_min_bitrate = true;
2919
Sebastian Jansson84848f22018-11-16 10:40:36 +01002920 channel_.reset(engine_.CreateMediaChannel(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02002921 fake_call_.get(), media_config, VideoOptions(), webrtc::CryptoOptions(),
2922 video_bitrate_allocator_factory_.get()));
Sergey Ulanove2b15012016-11-22 16:08:30 -08002923 channel_->OnReadyToSend(true);
nisse0db023a2016-03-01 04:29:59 -08002924
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002925 channel_->SetSendParameters(send_parameters_);
pbos@webrtc.org5ff71ab2014-07-23 07:28:56 +00002926
2927 FakeVideoSendStream* stream = AddSendStream();
2928 EXPECT_TRUE(stream->GetConfig().suspend_below_min_bitrate);
2929
nisse0db023a2016-03-01 04:29:59 -08002930 media_config.video.suspend_below_min_bitrate = false;
Sebastian Jansson84848f22018-11-16 10:40:36 +01002931 channel_.reset(engine_.CreateMediaChannel(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02002932 fake_call_.get(), media_config, VideoOptions(), webrtc::CryptoOptions(),
2933 video_bitrate_allocator_factory_.get()));
Sergey Ulanove2b15012016-11-22 16:08:30 -08002934 channel_->OnReadyToSend(true);
nisse0db023a2016-03-01 04:29:59 -08002935
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002936 channel_->SetSendParameters(send_parameters_);
pbos@webrtc.org5ff71ab2014-07-23 07:28:56 +00002937
nisse0db023a2016-03-01 04:29:59 -08002938 stream = AddSendStream();
pbos@webrtc.org5ff71ab2014-07-23 07:28:56 +00002939 EXPECT_FALSE(stream->GetConfig().suspend_below_min_bitrate);
2940}
2941
eladalonf1841382017-06-12 01:16:46 -07002942TEST_F(WebRtcVideoChannelTest, Vp8DenoisingEnabledByDefault) {
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00002943 FakeVideoSendStream* stream = AddSendStream();
2944 webrtc::VideoCodecVP8 vp8_settings;
2945 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
2946 EXPECT_TRUE(vp8_settings.denoisingOn);
2947}
2948
eladalonf1841382017-06-12 01:16:46 -07002949TEST_F(WebRtcVideoChannelTest, VerifyVp8SpecificSettings) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002950 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08002951 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02002952 ASSERT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00002953
Peter Boström2feafdb2015-09-09 14:32:14 +02002954 // Single-stream settings should apply with RTX as well (verifies that we
2955 // check number of regular SSRCs and not StreamParams::ssrcs which contains
2956 // both RTX and regular SSRCs).
2957 FakeVideoSendStream* stream = SetUpSimulcast(false, true);
Erik Språng143cec12015-04-28 10:01:41 +02002958
Niels Möller805a27e2019-01-21 12:21:27 +01002959 webrtc::test::FrameForwarder frame_forwarder;
2960 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));
Erik Språng143cec12015-04-28 10:01:41 +02002961 channel_->SetSend(true);
2962
Niels Möller805a27e2019-01-21 12:21:27 +01002963 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Erik Språng143cec12015-04-28 10:01:41 +02002964
pbos4cba4eb2015-10-26 11:18:18 -07002965 webrtc::VideoCodecVP8 vp8_settings;
2966 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
2967 EXPECT_TRUE(vp8_settings.denoisingOn)
2968 << "VP8 denoising should be on by default.";
2969
Niels Möller805a27e2019-01-21 12:21:27 +01002970 stream = SetDenoisingOption(last_ssrc_, &frame_forwarder, false);
Erik Språng143cec12015-04-28 10:01:41 +02002971
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00002972 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
2973 EXPECT_FALSE(vp8_settings.denoisingOn);
Erik Språng143cec12015-04-28 10:01:41 +02002974 EXPECT_TRUE(vp8_settings.automaticResizeOn);
2975 EXPECT_TRUE(vp8_settings.frameDroppingOn);
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00002976
Niels Möller805a27e2019-01-21 12:21:27 +01002977 stream = SetDenoisingOption(last_ssrc_, &frame_forwarder, true);
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00002978
pbos@webrtc.org6f48f1b2014-07-22 16:29:54 +00002979 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
2980 EXPECT_TRUE(vp8_settings.denoisingOn);
Erik Språng143cec12015-04-28 10:01:41 +02002981 EXPECT_TRUE(vp8_settings.automaticResizeOn);
2982 EXPECT_TRUE(vp8_settings.frameDroppingOn);
2983
Niels Möllerff40b142018-04-09 08:49:14 +02002984 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
Peter Boström2feafdb2015-09-09 14:32:14 +02002985 stream = SetUpSimulcast(true, false);
Niels Möller805a27e2019-01-21 12:21:27 +01002986 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));
Erik Språng143cec12015-04-28 10:01:41 +02002987 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01002988 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Erik Språng143cec12015-04-28 10:01:41 +02002989
Mirko Bonadeif859e552018-05-30 15:31:29 +02002990 EXPECT_EQ(3u, stream->GetVideoStreams().size());
Erik Språng143cec12015-04-28 10:01:41 +02002991 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
2992 // Autmatic resize off when using simulcast.
2993 EXPECT_FALSE(vp8_settings.automaticResizeOn);
2994 EXPECT_TRUE(vp8_settings.frameDroppingOn);
2995
2996 // In screen-share mode, denoising is forced off and simulcast disabled.
nisse05103312016-03-16 02:22:50 -07002997 VideoOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01002998 options.is_screencast = true;
Niels Möller805a27e2019-01-21 12:21:27 +01002999 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
Niels Möller60653ba2016-03-02 11:41:36 +01003000
Niels Möller805a27e2019-01-21 12:21:27 +01003001 stream = SetDenoisingOption(last_ssrc_, &frame_forwarder, false);
Erik Språng143cec12015-04-28 10:01:41 +02003002
Mirko Bonadeif859e552018-05-30 15:31:29 +02003003 EXPECT_EQ(1u, stream->GetVideoStreams().size());
Erik Språng143cec12015-04-28 10:01:41 +02003004 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
3005 EXPECT_FALSE(vp8_settings.denoisingOn);
3006 // Resizing and frame dropping always off for screen sharing.
3007 EXPECT_FALSE(vp8_settings.automaticResizeOn);
3008 EXPECT_FALSE(vp8_settings.frameDroppingOn);
3009
Niels Möller805a27e2019-01-21 12:21:27 +01003010 stream = SetDenoisingOption(last_ssrc_, &frame_forwarder, true);
Erik Språng143cec12015-04-28 10:01:41 +02003011
3012 ASSERT_TRUE(stream->GetVp8Settings(&vp8_settings)) << "No VP8 config set.";
3013 EXPECT_FALSE(vp8_settings.denoisingOn);
3014 EXPECT_FALSE(vp8_settings.automaticResizeOn);
3015 EXPECT_FALSE(vp8_settings.frameDroppingOn);
3016
Niels Möllerff40b142018-04-09 08:49:14 +02003017 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
Erik Språng143cec12015-04-28 10:01:41 +02003018}
3019
deadbeef119760a2016-04-04 11:43:27 -07003020// Test that setting the same options doesn't result in the encoder being
3021// reconfigured.
eladalonf1841382017-06-12 01:16:46 -07003022TEST_F(WebRtcVideoChannelTest, SetIdenticalOptionsDoesntReconfigureEncoder) {
deadbeef119760a2016-04-04 11:43:27 -07003023 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01003024 webrtc::test::FrameForwarder frame_forwarder;
deadbeef119760a2016-04-04 11:43:27 -07003025
perkjfa10b552016-10-02 23:45:26 -07003026 AddSendStream();
perkjfa10b552016-10-02 23:45:26 -07003027 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08003028 parameters.codecs.push_back(GetEngineCodec("VP8"));
perkjfa10b552016-10-02 23:45:26 -07003029 ASSERT_TRUE(channel_->SetSendParameters(parameters));
3030 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
3031
Niels Möller805a27e2019-01-21 12:21:27 +01003032 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
3033 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
3034 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
perkjfa10b552016-10-02 23:45:26 -07003035 // Expect 1 reconfigurations at this point from the initial configuration.
3036 EXPECT_EQ(1, send_stream->num_encoder_reconfigurations());
deadbeef119760a2016-04-04 11:43:27 -07003037
3038 // Set the options one more time and expect no additional reconfigurations.
Niels Möller805a27e2019-01-21 12:21:27 +01003039 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
perkjfa10b552016-10-02 23:45:26 -07003040 EXPECT_EQ(1, send_stream->num_encoder_reconfigurations());
3041
3042 // Change |options| and expect 2 reconfigurations.
Oskar Sundbom78807582017-11-16 11:09:55 +01003043 options.video_noise_reduction = true;
Niels Möller805a27e2019-01-21 12:21:27 +01003044 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
deadbeef119760a2016-04-04 11:43:27 -07003045 EXPECT_EQ(2, send_stream->num_encoder_reconfigurations());
3046
Niels Möllerff40b142018-04-09 08:49:14 +02003047 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
deadbeef119760a2016-04-04 11:43:27 -07003048}
3049
eladalonf1841382017-06-12 01:16:46 -07003050class Vp9SettingsTest : public WebRtcVideoChannelTest {
Erik Språng143cec12015-04-28 10:01:41 +02003051 public:
asaperssonc5dabdd2016-03-21 04:15:50 -07003052 Vp9SettingsTest() : Vp9SettingsTest("") {}
3053 explicit Vp9SettingsTest(const char* field_trials)
eladalonf1841382017-06-12 01:16:46 -07003054 : WebRtcVideoChannelTest(field_trials) {
Magnus Jedvert02e7a192017-09-23 17:21:32 +02003055 encoder_factory_->AddSupportedVideoCodecType("VP9");
Erik Språng143cec12015-04-28 10:01:41 +02003056 }
3057 virtual ~Vp9SettingsTest() {}
3058
3059 protected:
Erik Språng143cec12015-04-28 10:01:41 +02003060 void TearDown() override {
3061 // Remove references to encoder_factory_ since this will be destroyed
3062 // before channel_ and engine_.
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003063 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
Erik Språng143cec12015-04-28 10:01:41 +02003064 }
Erik Språng143cec12015-04-28 10:01:41 +02003065};
3066
3067TEST_F(Vp9SettingsTest, VerifyVp9SpecificSettings) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003068 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08003069 parameters.codecs.push_back(GetEngineCodec("VP9"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003070 ASSERT_TRUE(channel_->SetSendParameters(parameters));
Erik Språng143cec12015-04-28 10:01:41 +02003071
Peter Boström2feafdb2015-09-09 14:32:14 +02003072 FakeVideoSendStream* stream = SetUpSimulcast(false, false);
Erik Språng143cec12015-04-28 10:01:41 +02003073
Niels Möller805a27e2019-01-21 12:21:27 +01003074 webrtc::test::FrameForwarder frame_forwarder;
3075 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));
Erik Språng143cec12015-04-28 10:01:41 +02003076 channel_->SetSend(true);
3077
Niels Möller805a27e2019-01-21 12:21:27 +01003078 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Erik Språng143cec12015-04-28 10:01:41 +02003079
pbos4cba4eb2015-10-26 11:18:18 -07003080 webrtc::VideoCodecVP9 vp9_settings;
3081 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
jianja5e8aa62017-03-27 10:09:00 -07003082 EXPECT_TRUE(vp9_settings.denoisingOn)
3083 << "VP9 denoising should be on by default.";
pbos4cba4eb2015-10-26 11:18:18 -07003084
Niels Möller805a27e2019-01-21 12:21:27 +01003085 stream = SetDenoisingOption(last_ssrc_, &frame_forwarder, false);
Erik Språng143cec12015-04-28 10:01:41 +02003086
Erik Språng143cec12015-04-28 10:01:41 +02003087 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
3088 EXPECT_FALSE(vp9_settings.denoisingOn);
3089 // Frame dropping always on for real time video.
3090 EXPECT_TRUE(vp9_settings.frameDroppingOn);
3091
Niels Möller805a27e2019-01-21 12:21:27 +01003092 stream = SetDenoisingOption(last_ssrc_, &frame_forwarder, true);
Erik Språng143cec12015-04-28 10:01:41 +02003093
3094 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
3095 EXPECT_TRUE(vp9_settings.denoisingOn);
3096 EXPECT_TRUE(vp9_settings.frameDroppingOn);
3097
3098 // In screen-share mode, denoising is forced off.
nisse05103312016-03-16 02:22:50 -07003099 VideoOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01003100 options.is_screencast = true;
Niels Möller805a27e2019-01-21 12:21:27 +01003101 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
perkj2d5f0912016-02-29 00:04:41 -08003102
Niels Möller805a27e2019-01-21 12:21:27 +01003103 stream = SetDenoisingOption(last_ssrc_, &frame_forwarder, false);
Erik Språng143cec12015-04-28 10:01:41 +02003104
3105 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
3106 EXPECT_FALSE(vp9_settings.denoisingOn);
Sergey Silkinbe71a1e2018-05-17 16:46:43 +02003107 // Frame dropping always on for screen sharing.
3108 EXPECT_TRUE(vp9_settings.frameDroppingOn);
Erik Språng143cec12015-04-28 10:01:41 +02003109
Niels Möller805a27e2019-01-21 12:21:27 +01003110 stream = SetDenoisingOption(last_ssrc_, &frame_forwarder, false);
Erik Språng143cec12015-04-28 10:01:41 +02003111
3112 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
3113 EXPECT_FALSE(vp9_settings.denoisingOn);
Sergey Silkinbe71a1e2018-05-17 16:46:43 +02003114 EXPECT_TRUE(vp9_settings.frameDroppingOn);
Erik Språng143cec12015-04-28 10:01:41 +02003115
Niels Möllerff40b142018-04-09 08:49:14 +02003116 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003117}
3118
Sergey Silkinf18072e2018-03-14 10:35:35 +01003119TEST_F(Vp9SettingsTest, MultipleSsrcsEnablesSvc) {
3120 cricket::VideoSendParameters parameters;
3121 parameters.codecs.push_back(GetEngineCodec("VP9"));
3122 ASSERT_TRUE(channel_->SetSendParameters(parameters));
3123
3124 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
3125
3126 FakeVideoSendStream* stream =
3127 AddSendStream(CreateSimStreamParams("cname", ssrcs));
3128
3129 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
Sergey Silkinf18072e2018-03-14 10:35:35 +01003130
Niels Möller805a27e2019-01-21 12:21:27 +01003131 webrtc::test::FrameForwarder frame_forwarder;
3132 EXPECT_TRUE(channel_->SetVideoSend(ssrcs[0], nullptr, &frame_forwarder));
Sergey Silkinf18072e2018-03-14 10:35:35 +01003133 channel_->SetSend(true);
3134
Niels Möller805a27e2019-01-21 12:21:27 +01003135 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Sergey Silkinf18072e2018-03-14 10:35:35 +01003136
3137 webrtc::VideoCodecVP9 vp9_settings;
3138 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
3139
3140 const size_t kNumSpatialLayers = ssrcs.size();
3141 const size_t kNumTemporalLayers = 3;
3142 EXPECT_EQ(vp9_settings.numberOfSpatialLayers, kNumSpatialLayers);
3143 EXPECT_EQ(vp9_settings.numberOfTemporalLayers, kNumTemporalLayers);
3144
Niels Möllerff40b142018-04-09 08:49:14 +02003145 EXPECT_TRUE(channel_->SetVideoSend(ssrcs[0], nullptr, nullptr));
Sergey Silkinf18072e2018-03-14 10:35:35 +01003146}
3147
Ilya Nikolaevskiy33d2a912019-04-02 11:05:03 +02003148TEST_F(Vp9SettingsTest, SvcModeCreatesSingleRtpStream) {
3149 cricket::VideoSendParameters parameters;
3150 parameters.codecs.push_back(GetEngineCodec("VP9"));
3151 ASSERT_TRUE(channel_->SetSendParameters(parameters));
3152
3153 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
3154
3155 FakeVideoSendStream* stream =
3156 AddSendStream(CreateSimStreamParams("cname", ssrcs));
3157
3158 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
3159
3160 // Despite 3 ssrcs provided, single layer is used.
3161 EXPECT_EQ(1u, config.rtp.ssrcs.size());
3162
3163 webrtc::test::FrameForwarder frame_forwarder;
3164 EXPECT_TRUE(channel_->SetVideoSend(ssrcs[0], nullptr, &frame_forwarder));
3165 channel_->SetSend(true);
3166
3167 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
3168
3169 webrtc::VideoCodecVP9 vp9_settings;
3170 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
3171
3172 const size_t kNumSpatialLayers = ssrcs.size();
3173 EXPECT_EQ(vp9_settings.numberOfSpatialLayers, kNumSpatialLayers);
3174
3175 EXPECT_TRUE(channel_->SetVideoSend(ssrcs[0], nullptr, nullptr));
3176}
3177
Sergey Silkin8b9b5f92018-12-10 09:28:53 +01003178TEST_F(Vp9SettingsTest, AllEncodingParametersCopied) {
3179 cricket::VideoSendParameters send_parameters;
3180 send_parameters.codecs.push_back(GetEngineCodec("VP9"));
3181 ASSERT_TRUE(channel_->SetSendParameters(send_parameters));
3182
3183 const size_t kNumSpatialLayers = 3;
3184 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
3185
3186 FakeVideoSendStream* stream =
3187 AddSendStream(CreateSimStreamParams("cname", ssrcs));
3188
3189 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(ssrcs[0]);
3190 ASSERT_EQ(kNumSpatialLayers, parameters.encodings.size());
3191 ASSERT_TRUE(parameters.encodings[0].active);
3192 ASSERT_TRUE(parameters.encodings[1].active);
3193 ASSERT_TRUE(parameters.encodings[2].active);
3194 // Invert value to verify copying.
3195 parameters.encodings[1].active = false;
3196 EXPECT_TRUE(channel_->SetRtpSendParameters(ssrcs[0], parameters).ok());
3197
3198 webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
3199
3200 // number_of_streams should be 1 since all spatial layers are sent on the
3201 // same SSRC. But encoding parameters of all layers is supposed to be copied
3202 // and stored in simulcast_layers[].
3203 EXPECT_EQ(1u, encoder_config.number_of_streams);
3204 EXPECT_EQ(encoder_config.simulcast_layers.size(), kNumSpatialLayers);
3205 EXPECT_TRUE(encoder_config.simulcast_layers[0].active);
3206 EXPECT_FALSE(encoder_config.simulcast_layers[1].active);
3207 EXPECT_TRUE(encoder_config.simulcast_layers[2].active);
3208}
3209
Sergey Silkincf267052019-04-09 11:40:09 +02003210class Vp9SettingsTestWithFieldTrial
3211 : public Vp9SettingsTest,
3212 public ::testing::WithParamInterface<
3213 ::testing::tuple<const char*, int, int, webrtc::InterLayerPredMode>> {
asaperssonc5dabdd2016-03-21 04:15:50 -07003214 protected:
Sergey Silkincf267052019-04-09 11:40:09 +02003215 Vp9SettingsTestWithFieldTrial()
3216 : Vp9SettingsTest(::testing::get<0>(GetParam())),
3217 num_spatial_layers_(::testing::get<1>(GetParam())),
3218 num_temporal_layers_(::testing::get<2>(GetParam())),
Sergey Silkin19da5ce2019-05-20 17:57:17 +02003219 inter_layer_pred_mode_(::testing::get<3>(GetParam())) {}
Sergey Silkincf267052019-04-09 11:40:09 +02003220
3221 void VerifySettings(int num_spatial_layers,
3222 int num_temporal_layers,
3223 webrtc::InterLayerPredMode interLayerPred) {
asaperssonc5dabdd2016-03-21 04:15:50 -07003224 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08003225 parameters.codecs.push_back(GetEngineCodec("VP9"));
asaperssonc5dabdd2016-03-21 04:15:50 -07003226 ASSERT_TRUE(channel_->SetSendParameters(parameters));
3227
3228 FakeVideoSendStream* stream = SetUpSimulcast(false, false);
3229
Niels Möller805a27e2019-01-21 12:21:27 +01003230 webrtc::test::FrameForwarder frame_forwarder;
3231 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));
asaperssonc5dabdd2016-03-21 04:15:50 -07003232 channel_->SetSend(true);
3233
Niels Möller805a27e2019-01-21 12:21:27 +01003234 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
asaperssonc5dabdd2016-03-21 04:15:50 -07003235
3236 webrtc::VideoCodecVP9 vp9_settings;
3237 ASSERT_TRUE(stream->GetVp9Settings(&vp9_settings)) << "No VP9 config set.";
3238 EXPECT_EQ(num_spatial_layers, vp9_settings.numberOfSpatialLayers);
3239 EXPECT_EQ(num_temporal_layers, vp9_settings.numberOfTemporalLayers);
Sergey Silkin19da5ce2019-05-20 17:57:17 +02003240 EXPECT_EQ(inter_layer_pred_mode_, vp9_settings.interLayerPred);
asaperssonc5dabdd2016-03-21 04:15:50 -07003241
Niels Möllerff40b142018-04-09 08:49:14 +02003242 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
asaperssonc5dabdd2016-03-21 04:15:50 -07003243 }
Sergey Silkincf267052019-04-09 11:40:09 +02003244
3245 const uint8_t num_spatial_layers_;
3246 const uint8_t num_temporal_layers_;
Sergey Silkin19da5ce2019-05-20 17:57:17 +02003247 const webrtc::InterLayerPredMode inter_layer_pred_mode_;
asaperssonc5dabdd2016-03-21 04:15:50 -07003248};
3249
Sergey Silkincf267052019-04-09 11:40:09 +02003250TEST_P(Vp9SettingsTestWithFieldTrial, VerifyCodecSettings) {
Sergey Silkin19da5ce2019-05-20 17:57:17 +02003251 VerifySettings(num_spatial_layers_, num_temporal_layers_,
3252 inter_layer_pred_mode_);
asaperssonc5dabdd2016-03-21 04:15:50 -07003253}
3254
Sergey Silkincf267052019-04-09 11:40:09 +02003255INSTANTIATE_TEST_SUITE_P(
3256 ,
3257 Vp9SettingsTestWithFieldTrial,
3258 ::testing::Values(
3259 std::make_tuple("", 1, 1, webrtc::InterLayerPredMode::kOnKeyPic),
3260 std::make_tuple("WebRTC-SupportVP9SVC/Default/",
3261 1,
3262 1,
3263 webrtc::InterLayerPredMode::kOnKeyPic),
3264 std::make_tuple("WebRTC-SupportVP9SVC/EnabledByFlag_2SL3TL/",
3265 2,
3266 3,
3267 webrtc::InterLayerPredMode::kOnKeyPic),
Sergey Silkin19da5ce2019-05-20 17:57:17 +02003268 std::make_tuple("WebRTC-Vp9InterLayerPred/Default/",
Sergey Silkincf267052019-04-09 11:40:09 +02003269 1,
3270 1,
Sergey Silkin19da5ce2019-05-20 17:57:17 +02003271 webrtc::InterLayerPredMode::kOnKeyPic),
3272 std::make_tuple("WebRTC-Vp9InterLayerPred/Disabled/",
Sergey Silkincf267052019-04-09 11:40:09 +02003273 1,
3274 1,
Sergey Silkin19da5ce2019-05-20 17:57:17 +02003275 webrtc::InterLayerPredMode::kOnKeyPic),
3276 std::make_tuple(
3277 "WebRTC-Vp9InterLayerPred/Enabled,inter_layer_pred_mode:off/",
3278 1,
3279 1,
3280 webrtc::InterLayerPredMode::kOff),
3281 std::make_tuple(
3282 "WebRTC-Vp9InterLayerPred/Enabled,inter_layer_pred_mode:on/",
3283 1,
3284 1,
3285 webrtc::InterLayerPredMode::kOn),
3286 std::make_tuple(
3287 "WebRTC-Vp9InterLayerPred/Enabled,inter_layer_pred_mode:onkeypic/",
3288 1,
3289 1,
3290 webrtc::InterLayerPredMode::kOnKeyPic)));
asaperssonc5dabdd2016-03-21 04:15:50 -07003291
Åsa Persson45bbc8a2017-11-13 10:16:47 +01003292TEST_F(WebRtcVideoChannelTest, VerifyMinBitrate) {
3293 std::vector<webrtc::VideoStream> streams = AddSendStream()->GetVideoStreams();
3294 ASSERT_EQ(1u, streams.size());
3295 EXPECT_EQ(cricket::kMinVideoBitrateBps, streams[0].min_bitrate_bps);
3296}
3297
3298TEST_F(WebRtcVideoChannelTest, VerifyMinBitrateWithForcedFallbackFieldTrial) {
3299 webrtc::test::ScopedFieldTrials override_field_trials_(
3300 "WebRTC-VP8-Forced-Fallback-Encoder-v2/Enabled-1,2,34567/");
3301 std::vector<webrtc::VideoStream> streams = AddSendStream()->GetVideoStreams();
3302 ASSERT_EQ(1u, streams.size());
3303 EXPECT_EQ(34567, streams[0].min_bitrate_bps);
3304}
3305
asapersson3c81a1a2017-06-14 05:52:21 -07003306TEST_F(WebRtcVideoChannelTest,
3307 BalancedDegradationPreferenceNotSupportedWithoutFieldtrial) {
3308 webrtc::test::ScopedFieldTrials override_field_trials_(
3309 "WebRTC-Video-BalancedDegradation/Disabled/");
3310 const bool kResolutionScalingEnabled = true;
3311 const bool kFpsScalingEnabled = false;
3312 TestDegradationPreference(kResolutionScalingEnabled, kFpsScalingEnabled);
3313}
3314
3315TEST_F(WebRtcVideoChannelTest,
3316 BalancedDegradationPreferenceSupportedBehindFieldtrial) {
3317 webrtc::test::ScopedFieldTrials override_field_trials_(
3318 "WebRTC-Video-BalancedDegradation/Enabled/");
3319 const bool kResolutionScalingEnabled = true;
3320 const bool kFpsScalingEnabled = true;
3321 TestDegradationPreference(kResolutionScalingEnabled, kFpsScalingEnabled);
3322}
3323
eladalonf1841382017-06-12 01:16:46 -07003324TEST_F(WebRtcVideoChannelTest, AdaptsOnOveruse) {
Erik Språngefbde372015-04-29 16:21:28 +02003325 TestCpuAdaptation(true, false);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003326}
3327
eladalonf1841382017-06-12 01:16:46 -07003328TEST_F(WebRtcVideoChannelTest, DoesNotAdaptOnOveruseWhenDisabled) {
Erik Språngefbde372015-04-29 16:21:28 +02003329 TestCpuAdaptation(false, false);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003330}
3331
Niels Möller3de32e62019-01-18 08:42:18 +01003332TEST_F(WebRtcVideoChannelTest, DoesNotAdaptWhenScreeensharing) {
3333 TestCpuAdaptation(false, true);
3334}
3335
eladalonf1841382017-06-12 01:16:46 -07003336TEST_F(WebRtcVideoChannelTest, DoesNotAdaptOnOveruseWhenScreensharing) {
Erik Språngefbde372015-04-29 16:21:28 +02003337 TestCpuAdaptation(true, true);
3338}
3339
eladalonf1841382017-06-12 01:16:46 -07003340TEST_F(WebRtcVideoChannelTest, PreviousAdaptationDoesNotApplyToScreenshare) {
magjed509e4fe2016-11-18 01:34:11 -08003341 cricket::VideoCodec codec = GetEngineCodec("VP8");
Per766ad3b2016-04-05 15:23:49 +02003342 cricket::VideoSendParameters parameters;
3343 parameters.codecs.push_back(codec);
3344
kthelgason2bc68642017-02-07 07:02:22 -08003345 MediaConfig media_config = GetMediaConfig();
Niels Möller1d7ecd22018-01-18 15:25:12 +01003346 media_config.video.enable_cpu_adaptation = true;
Sebastian Jansson84848f22018-11-16 10:40:36 +01003347 channel_.reset(engine_.CreateMediaChannel(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02003348 fake_call_.get(), media_config, VideoOptions(), webrtc::CryptoOptions(),
3349 video_bitrate_allocator_factory_.get()));
Sergey Ulanove2b15012016-11-22 16:08:30 -08003350 channel_->OnReadyToSend(true);
Per766ad3b2016-04-05 15:23:49 +02003351 ASSERT_TRUE(channel_->SetSendParameters(parameters));
3352
3353 AddSendStream();
Niels Möller805a27e2019-01-21 12:21:27 +01003354 webrtc::test::FrameForwarder frame_forwarder;
Per766ad3b2016-04-05 15:23:49 +02003355
Per766ad3b2016-04-05 15:23:49 +02003356 ASSERT_TRUE(channel_->SetSend(true));
3357 cricket::VideoOptions camera_options;
Oskar Sundbom78807582017-11-16 11:09:55 +01003358 camera_options.is_screencast = false;
Niels Möller805a27e2019-01-21 12:21:27 +01003359 channel_->SetVideoSend(last_ssrc_, &camera_options, &frame_forwarder);
Per766ad3b2016-04-05 15:23:49 +02003360
3361 ASSERT_EQ(1u, fake_call_->GetVideoSendStreams().size());
3362 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
Per766ad3b2016-04-05 15:23:49 +02003363
Niels Möllerdcc70292019-01-15 16:32:38 +01003364 EXPECT_TRUE(send_stream->resolution_scaling_enabled());
3365 // Dont' expect anything on framerate_scaling_enabled, since the default is
3366 // transitioning from MAINTAIN_FRAMERATE to BALANCED.
Per766ad3b2016-04-05 15:23:49 +02003367
Niels Möllerdcc70292019-01-15 16:32:38 +01003368 // Switch to screen share. Expect no resolution scaling.
Per766ad3b2016-04-05 15:23:49 +02003369 cricket::VideoOptions screenshare_options;
Oskar Sundbom78807582017-11-16 11:09:55 +01003370 screenshare_options.is_screencast = true;
Niels Möller805a27e2019-01-21 12:21:27 +01003371 channel_->SetVideoSend(last_ssrc_, &screenshare_options, &frame_forwarder);
sprangf24a0642017-02-28 13:23:26 -08003372 ASSERT_EQ(2, fake_call_->GetNumCreatedSendStreams());
3373 send_stream = fake_call_->GetVideoSendStreams().front();
Niels Möllerdcc70292019-01-15 16:32:38 +01003374 EXPECT_FALSE(send_stream->resolution_scaling_enabled());
Per766ad3b2016-04-05 15:23:49 +02003375
Niels Möllerdcc70292019-01-15 16:32:38 +01003376 // Switch back to the normal capturer. Expect resolution scaling to be
3377 // reenabled.
Niels Möller805a27e2019-01-21 12:21:27 +01003378 channel_->SetVideoSend(last_ssrc_, &camera_options, &frame_forwarder);
3379 send_stream = fake_call_->GetVideoSendStreams().front();
sprangf24a0642017-02-28 13:23:26 -08003380 ASSERT_EQ(3, fake_call_->GetNumCreatedSendStreams());
3381 send_stream = fake_call_->GetVideoSendStreams().front();
Niels Möllerdcc70292019-01-15 16:32:38 +01003382 EXPECT_TRUE(send_stream->resolution_scaling_enabled());
Per766ad3b2016-04-05 15:23:49 +02003383
Niels Möllerff40b142018-04-09 08:49:14 +02003384 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
Per766ad3b2016-04-05 15:23:49 +02003385}
3386
asapersson3c81a1a2017-06-14 05:52:21 -07003387// TODO(asapersson): Remove this test when the balanced field trial is removed.
3388void WebRtcVideoChannelTest::TestDegradationPreference(
3389 bool resolution_scaling_enabled,
3390 bool fps_scaling_enabled) {
3391 cricket::VideoCodec codec = GetEngineCodec("VP8");
3392 cricket::VideoSendParameters parameters;
3393 parameters.codecs.push_back(codec);
3394
3395 MediaConfig media_config = GetMediaConfig();
Niels Möller1d7ecd22018-01-18 15:25:12 +01003396 media_config.video.enable_cpu_adaptation = true;
Sebastian Jansson84848f22018-11-16 10:40:36 +01003397 channel_.reset(engine_.CreateMediaChannel(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02003398 fake_call_.get(), media_config, VideoOptions(), webrtc::CryptoOptions(),
3399 video_bitrate_allocator_factory_.get()));
asapersson3c81a1a2017-06-14 05:52:21 -07003400 channel_->OnReadyToSend(true);
3401
3402 EXPECT_TRUE(channel_->SetSendParameters(parameters));
3403
3404 AddSendStream();
3405
Niels Möller805a27e2019-01-21 12:21:27 +01003406 webrtc::test::FrameForwarder frame_forwarder;
asapersson3c81a1a2017-06-14 05:52:21 -07003407 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01003408 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
asapersson3c81a1a2017-06-14 05:52:21 -07003409
3410 EXPECT_TRUE(channel_->SetSend(true));
3411
3412 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
3413 EXPECT_EQ(resolution_scaling_enabled,
3414 send_stream->resolution_scaling_enabled());
3415 EXPECT_EQ(fps_scaling_enabled, send_stream->framerate_scaling_enabled());
3416
Niels Möllerff40b142018-04-09 08:49:14 +02003417 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
asapersson3c81a1a2017-06-14 05:52:21 -07003418}
3419
eladalonf1841382017-06-12 01:16:46 -07003420void WebRtcVideoChannelTest::TestCpuAdaptation(bool enable_overuse,
3421 bool is_screenshare) {
magjed509e4fe2016-11-18 01:34:11 -08003422 cricket::VideoCodec codec = GetEngineCodec("VP8");
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003423 cricket::VideoSendParameters parameters;
3424 parameters.codecs.push_back(codec);
nisse51542be2016-02-12 02:27:06 -08003425
kthelgason2bc68642017-02-07 07:02:22 -08003426 MediaConfig media_config = GetMediaConfig();
3427 if (enable_overuse) {
Niels Möller1d7ecd22018-01-18 15:25:12 +01003428 media_config.video.enable_cpu_adaptation = true;
pbos@webrtc.org42684be2014-10-03 11:25:45 +00003429 }
Sebastian Jansson84848f22018-11-16 10:40:36 +01003430 channel_.reset(engine_.CreateMediaChannel(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02003431 fake_call_.get(), media_config, VideoOptions(), webrtc::CryptoOptions(),
3432 video_bitrate_allocator_factory_.get()));
Sergey Ulanove2b15012016-11-22 16:08:30 -08003433 channel_->OnReadyToSend(true);
nisse51542be2016-02-12 02:27:06 -08003434
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003435 EXPECT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00003436
3437 AddSendStream();
3438
Niels Möller805a27e2019-01-21 12:21:27 +01003439 webrtc::test::FrameForwarder frame_forwarder;
nisse05103312016-03-16 02:22:50 -07003440 VideoOptions options;
Oskar Sundbom78807582017-11-16 11:09:55 +01003441 options.is_screencast = is_screenshare;
Niels Möller805a27e2019-01-21 12:21:27 +01003442 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00003443
3444 EXPECT_TRUE(channel_->SetSend(true));
3445
solenberge5269742015-09-08 05:13:22 -07003446 FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
perkj2d5f0912016-02-29 00:04:41 -08003447
sprangc5d62e22017-04-02 23:53:04 -07003448 if (!enable_overuse) {
perkj803d97f2016-11-01 11:45:46 -07003449 EXPECT_FALSE(send_stream->resolution_scaling_enabled());
sprangc5d62e22017-04-02 23:53:04 -07003450 EXPECT_FALSE(send_stream->framerate_scaling_enabled());
Niels Möller805a27e2019-01-21 12:21:27 +01003451 } else if (is_screenshare) {
sprangc5d62e22017-04-02 23:53:04 -07003452 EXPECT_FALSE(send_stream->resolution_scaling_enabled());
3453 EXPECT_TRUE(send_stream->framerate_scaling_enabled());
3454 } else {
3455 EXPECT_TRUE(send_stream->resolution_scaling_enabled());
3456 EXPECT_FALSE(send_stream->framerate_scaling_enabled());
3457 }
Niels Möllerff40b142018-04-09 08:49:14 +02003458 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003459}
3460
eladalonf1841382017-06-12 01:16:46 -07003461TEST_F(WebRtcVideoChannelTest, EstimatesNtpStartTimeCorrectly) {
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00003462 // Start at last timestamp to verify that wraparounds are estimated correctly.
3463 static const uint32_t kInitialTimestamp = 0xFFFFFFFFu;
3464 static const int64_t kInitialNtpTimeMs = 1247891230;
3465 static const int kFrameOffsetMs = 20;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003466 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003467
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00003468 FakeVideoReceiveStream* stream = AddRecvStream();
3469 cricket::FakeVideoRenderer renderer;
nisse08582ff2016-02-04 01:24:52 -08003470 EXPECT_TRUE(channel_->SetSink(last_ssrc_, &renderer));
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00003471
Artem Titov1ebfb6a2019-01-03 23:49:37 +01003472 webrtc::VideoFrame video_frame =
3473 webrtc::VideoFrame::Builder()
3474 .set_video_frame_buffer(CreateBlackFrameBuffer(4, 4))
3475 .set_timestamp_rtp(kInitialTimestamp)
3476 .set_timestamp_us(0)
3477 .set_rotation(webrtc::kVideoRotation_0)
3478 .build();
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00003479 // Initial NTP time is not available on the first frame, but should still be
3480 // able to be estimated.
nisseeb83a1a2016-03-21 01:27:56 -07003481 stream->InjectFrame(video_frame);
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00003482
3483 EXPECT_EQ(1, renderer.num_rendered_frames());
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00003484
3485 // This timestamp is kInitialTimestamp (-1) + kFrameOffsetMs * 90, which
3486 // triggers a constant-overflow warning, hence we're calculating it explicitly
3487 // here.
Sebastian Jansson40889f32019-04-17 12:11:20 +02003488 fake_clock_.AdvanceTime(webrtc::TimeDelta::ms(kFrameOffsetMs));
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00003489 video_frame.set_timestamp(kFrameOffsetMs * 90 - 1);
3490 video_frame.set_ntp_time_ms(kInitialNtpTimeMs + kFrameOffsetMs);
nisseeb83a1a2016-03-21 01:27:56 -07003491 stream->InjectFrame(video_frame);
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00003492
3493 EXPECT_EQ(2, renderer.num_rendered_frames());
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00003494
3495 // Verify that NTP time has been correctly deduced.
3496 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00003497 ASSERT_TRUE(channel_->GetStats(&info));
magjed@webrtc.orgfc5ad952015-01-27 09:57:01 +00003498 ASSERT_EQ(1u, info.receivers.size());
3499 EXPECT_EQ(kInitialNtpTimeMs, info.receivers[0].capture_start_ntp_time_ms);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003500}
3501
eladalonf1841382017-06-12 01:16:46 -07003502TEST_F(WebRtcVideoChannelTest, SetDefaultSendCodecs) {
Anders Carlsson5f2bb622018-05-14 09:48:06 +02003503 AssignDefaultAptRtxTypes();
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003504 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003505
3506 VideoCodec codec;
3507 EXPECT_TRUE(channel_->GetSendCodec(&codec));
pbos@webrtc.org9fbb7172014-06-13 09:34:13 +00003508 EXPECT_TRUE(codec.Matches(engine_.codecs()[0]));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003509
3510 // Using a RTX setup to verify that the default RTX payload type is good.
Peter Boström0c4e06b2015-10-07 12:23:21 +02003511 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
3512 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003513 FakeVideoSendStream* stream = AddSendStream(
3514 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs));
perkj26091b12016-09-01 01:17:40 -07003515 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003516
3517 // Make sure NACK and FEC are enabled on the correct payload types.
3518 EXPECT_EQ(1000, config.rtp.nack.rtp_history_ms);
magjed509e4fe2016-11-18 01:34:11 -08003519 EXPECT_EQ(GetEngineCodec("ulpfec").id, config.rtp.ulpfec.ulpfec_payload_type);
3520 EXPECT_EQ(GetEngineCodec("red").id, config.rtp.ulpfec.red_payload_type);
pbos@webrtc.org269605c2014-06-26 08:49:03 +00003521
3522 EXPECT_EQ(1u, config.rtp.rtx.ssrcs.size());
3523 EXPECT_EQ(kRtxSsrcs1[0], config.rtp.rtx.ssrcs[0]);
Shao Changbine62202f2015-04-21 20:24:50 +08003524 VerifySendStreamHasRtxTypes(config, default_apt_rtx_types_);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003525 // TODO(juberti): Check RTCP, PLI, TMMBR.
3526}
3527
brandtr31bd2242017-05-19 05:47:46 -07003528// The following four tests ensures that FlexFEC is not activated by default
3529// when the field trials are not enabled.
3530// TODO(brandtr): Remove or update these tests when FlexFEC _is_ enabled by
3531// default.
Yves Gerey665174f2018-06-19 15:03:05 +02003532TEST_F(WebRtcVideoChannelTest, FlexfecSendCodecWithoutSsrcNotExposedByDefault) {
brandtr468da7c2016-11-22 02:16:47 -08003533 FakeVideoSendStream* stream = AddSendStream();
3534 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
3535
brandtr3d200bd2017-01-16 06:59:19 -08003536 EXPECT_EQ(-1, config.rtp.flexfec.payload_type);
brandtr31bd2242017-05-19 05:47:46 -07003537 EXPECT_EQ(0U, config.rtp.flexfec.ssrc);
3538 EXPECT_TRUE(config.rtp.flexfec.protected_media_ssrcs.empty());
brandtr468da7c2016-11-22 02:16:47 -08003539}
3540
eladalonf1841382017-06-12 01:16:46 -07003541TEST_F(WebRtcVideoChannelTest, FlexfecSendCodecWithSsrcNotExposedByDefault) {
brandtr468da7c2016-11-22 02:16:47 -08003542 FakeVideoSendStream* stream = AddSendStream(
3543 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
3544 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
3545
brandtr3d200bd2017-01-16 06:59:19 -08003546 EXPECT_EQ(-1, config.rtp.flexfec.payload_type);
brandtr31bd2242017-05-19 05:47:46 -07003547 EXPECT_EQ(0U, config.rtp.flexfec.ssrc);
3548 EXPECT_TRUE(config.rtp.flexfec.protected_media_ssrcs.empty());
3549}
3550
Yves Gerey665174f2018-06-19 15:03:05 +02003551TEST_F(WebRtcVideoChannelTest, FlexfecRecvCodecWithoutSsrcNotExposedByDefault) {
brandtr31bd2242017-05-19 05:47:46 -07003552 AddRecvStream();
3553
3554 const std::vector<FakeFlexfecReceiveStream*>& streams =
3555 fake_call_->GetFlexfecReceiveStreams();
3556 EXPECT_TRUE(streams.empty());
3557}
3558
eladalonf1841382017-06-12 01:16:46 -07003559TEST_F(WebRtcVideoChannelTest, FlexfecRecvCodecWithSsrcNotExposedByDefault) {
brandtr31bd2242017-05-19 05:47:46 -07003560 AddRecvStream(
3561 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
3562
3563 const std::vector<FakeFlexfecReceiveStream*>& streams =
3564 fake_call_->GetFlexfecReceiveStreams();
3565 EXPECT_TRUE(streams.empty());
brandtr468da7c2016-11-22 02:16:47 -08003566}
3567
3568// TODO(brandtr): When FlexFEC is no longer behind a field trial, merge all
3569// tests that use this test fixture into the corresponding "non-field trial"
3570// tests.
eladalonf1841382017-06-12 01:16:46 -07003571class WebRtcVideoChannelFlexfecRecvTest : public WebRtcVideoChannelTest {
brandtr468da7c2016-11-22 02:16:47 -08003572 public:
eladalonf1841382017-06-12 01:16:46 -07003573 WebRtcVideoChannelFlexfecRecvTest()
3574 : WebRtcVideoChannelTest("WebRTC-FlexFEC-03-Advertised/Enabled/") {}
brandtr468da7c2016-11-22 02:16:47 -08003575};
3576
eladalonf1841382017-06-12 01:16:46 -07003577TEST_F(WebRtcVideoChannelFlexfecRecvTest,
brandtr36e7d702017-01-13 07:15:54 -08003578 DefaultFlexfecCodecHasTransportCcAndRembFeedbackParam) {
3579 EXPECT_TRUE(cricket::HasTransportCc(GetEngineCodec("flexfec-03")));
3580 EXPECT_TRUE(cricket::HasRemb(GetEngineCodec("flexfec-03")));
3581}
3582
eladalonf1841382017-06-12 01:16:46 -07003583TEST_F(WebRtcVideoChannelFlexfecRecvTest, SetDefaultRecvCodecsWithoutSsrc) {
brandtr31bd2242017-05-19 05:47:46 -07003584 AddRecvStream();
3585
3586 const std::vector<FakeFlexfecReceiveStream*>& streams =
3587 fake_call_->GetFlexfecReceiveStreams();
3588 EXPECT_TRUE(streams.empty());
Rasmus Brandt60bb6fe2018-02-05 09:51:47 +01003589
3590 const std::vector<FakeVideoReceiveStream*>& video_streams =
3591 fake_call_->GetVideoReceiveStreams();
3592 ASSERT_EQ(1U, video_streams.size());
3593 const FakeVideoReceiveStream& video_stream = *video_streams.front();
3594 EXPECT_EQ(0, video_stream.GetNumAddedSecondarySinks());
3595 EXPECT_EQ(0, video_stream.GetNumRemovedSecondarySinks());
brandtr31bd2242017-05-19 05:47:46 -07003596}
3597
eladalonf1841382017-06-12 01:16:46 -07003598TEST_F(WebRtcVideoChannelFlexfecRecvTest, SetDefaultRecvCodecsWithSsrc) {
brandtr31bd2242017-05-19 05:47:46 -07003599 AddRecvStream(
3600 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
3601
3602 const std::vector<FakeFlexfecReceiveStream*>& streams =
3603 fake_call_->GetFlexfecReceiveStreams();
3604 ASSERT_EQ(1U, streams.size());
3605 const FakeFlexfecReceiveStream* stream = streams.front();
3606 const webrtc::FlexfecReceiveStream::Config& config = stream->GetConfig();
3607 EXPECT_EQ(GetEngineCodec("flexfec-03").id, config.payload_type);
3608 EXPECT_EQ(kFlexfecSsrc, config.remote_ssrc);
3609 ASSERT_EQ(1U, config.protected_media_ssrcs.size());
3610 EXPECT_EQ(kSsrcs1[0], config.protected_media_ssrcs[0]);
brandtr7cd28b92017-09-22 00:26:25 -07003611
3612 const std::vector<FakeVideoReceiveStream*>& video_streams =
3613 fake_call_->GetVideoReceiveStreams();
3614 ASSERT_EQ(1U, video_streams.size());
Rasmus Brandt60bb6fe2018-02-05 09:51:47 +01003615 const FakeVideoReceiveStream& video_stream = *video_streams.front();
3616 EXPECT_EQ(1, video_stream.GetNumAddedSecondarySinks());
brandtr7cd28b92017-09-22 00:26:25 -07003617 const webrtc::VideoReceiveStream::Config& video_config =
Rasmus Brandt60bb6fe2018-02-05 09:51:47 +01003618 video_stream.GetConfig();
brandtr7cd28b92017-09-22 00:26:25 -07003619 EXPECT_TRUE(video_config.rtp.protected_by_flexfec);
brandtr31bd2242017-05-19 05:47:46 -07003620}
3621
eladalonf1841382017-06-12 01:16:46 -07003622TEST_F(WebRtcVideoChannelFlexfecRecvTest,
brandtr11fb4722017-05-30 01:31:37 -07003623 EnablingFlexfecDoesNotRecreateVideoReceiveStream) {
3624 cricket::VideoRecvParameters recv_parameters;
3625 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
3626 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
3627
3628 AddRecvStream(
3629 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
3630 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
Rasmus Brandt60bb6fe2018-02-05 09:51:47 +01003631 const std::vector<FakeVideoReceiveStream*>& video_streams =
3632 fake_call_->GetVideoReceiveStreams();
3633 ASSERT_EQ(1U, video_streams.size());
3634 const FakeVideoReceiveStream& video_stream = *video_streams.front();
3635 EXPECT_EQ(0, video_stream.GetNumAddedSecondarySinks());
3636 EXPECT_EQ(0, video_stream.GetNumRemovedSecondarySinks());
brandtr11fb4722017-05-30 01:31:37 -07003637
3638 // Enable FlexFEC.
3639 recv_parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
3640 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
3641 EXPECT_EQ(2, fake_call_->GetNumCreatedReceiveStreams())
3642 << "Enabling FlexFEC should create FlexfecReceiveStream.";
3643 EXPECT_EQ(1U, fake_call_->GetVideoReceiveStreams().size())
3644 << "Enabling FlexFEC should not create VideoReceiveStream.";
3645 EXPECT_EQ(1U, fake_call_->GetFlexfecReceiveStreams().size())
3646 << "Enabling FlexFEC should create a single FlexfecReceiveStream.";
Rasmus Brandt60bb6fe2018-02-05 09:51:47 +01003647 EXPECT_EQ(1, video_stream.GetNumAddedSecondarySinks());
3648 EXPECT_EQ(0, video_stream.GetNumRemovedSecondarySinks());
brandtr11fb4722017-05-30 01:31:37 -07003649}
3650
eladalonf1841382017-06-12 01:16:46 -07003651TEST_F(WebRtcVideoChannelFlexfecRecvTest,
brandtr11fb4722017-05-30 01:31:37 -07003652 DisablingFlexfecDoesNotRecreateVideoReceiveStream) {
3653 cricket::VideoRecvParameters recv_parameters;
3654 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
3655 recv_parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
3656 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
3657
3658 AddRecvStream(
3659 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
3660 EXPECT_EQ(2, fake_call_->GetNumCreatedReceiveStreams());
brandtr11fb4722017-05-30 01:31:37 -07003661 EXPECT_EQ(1U, fake_call_->GetFlexfecReceiveStreams().size());
Rasmus Brandt60bb6fe2018-02-05 09:51:47 +01003662 const std::vector<FakeVideoReceiveStream*>& video_streams =
3663 fake_call_->GetVideoReceiveStreams();
3664 ASSERT_EQ(1U, video_streams.size());
3665 const FakeVideoReceiveStream& video_stream = *video_streams.front();
3666 EXPECT_EQ(1, video_stream.GetNumAddedSecondarySinks());
3667 EXPECT_EQ(0, video_stream.GetNumRemovedSecondarySinks());
brandtr11fb4722017-05-30 01:31:37 -07003668
3669 // Disable FlexFEC.
3670 recv_parameters.codecs.clear();
3671 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
3672 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
3673 EXPECT_EQ(2, fake_call_->GetNumCreatedReceiveStreams())
3674 << "Disabling FlexFEC should not recreate VideoReceiveStream.";
3675 EXPECT_EQ(1U, fake_call_->GetVideoReceiveStreams().size())
3676 << "Disabling FlexFEC should not destroy VideoReceiveStream.";
3677 EXPECT_TRUE(fake_call_->GetFlexfecReceiveStreams().empty())
3678 << "Disabling FlexFEC should destroy FlexfecReceiveStream.";
Rasmus Brandt60bb6fe2018-02-05 09:51:47 +01003679 EXPECT_EQ(1, video_stream.GetNumAddedSecondarySinks());
3680 EXPECT_EQ(1, video_stream.GetNumRemovedSecondarySinks());
brandtr11fb4722017-05-30 01:31:37 -07003681}
3682
brandtr31bd2242017-05-19 05:47:46 -07003683// TODO(brandtr): When FlexFEC is no longer behind a field trial, merge all
3684// tests that use this test fixture into the corresponding "non-field trial"
3685// tests.
eladalonf1841382017-06-12 01:16:46 -07003686class WebRtcVideoChannelFlexfecSendRecvTest : public WebRtcVideoChannelTest {
brandtr31bd2242017-05-19 05:47:46 -07003687 public:
eladalonf1841382017-06-12 01:16:46 -07003688 WebRtcVideoChannelFlexfecSendRecvTest()
3689 : WebRtcVideoChannelTest(
brandtr31bd2242017-05-19 05:47:46 -07003690 "WebRTC-FlexFEC-03-Advertised/Enabled/WebRTC-FlexFEC-03/Enabled/") {
3691 }
3692};
3693
Yves Gerey665174f2018-06-19 15:03:05 +02003694TEST_F(WebRtcVideoChannelFlexfecSendRecvTest, SetDefaultSendCodecsWithoutSsrc) {
brandtr468da7c2016-11-22 02:16:47 -08003695 FakeVideoSendStream* stream = AddSendStream();
3696 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
3697
brandtr3d200bd2017-01-16 06:59:19 -08003698 EXPECT_EQ(GetEngineCodec("flexfec-03").id, config.rtp.flexfec.payload_type);
3699 EXPECT_EQ(0U, config.rtp.flexfec.ssrc);
3700 EXPECT_TRUE(config.rtp.flexfec.protected_media_ssrcs.empty());
brandtr468da7c2016-11-22 02:16:47 -08003701}
3702
eladalonf1841382017-06-12 01:16:46 -07003703TEST_F(WebRtcVideoChannelFlexfecSendRecvTest, SetDefaultSendCodecsWithSsrc) {
brandtr468da7c2016-11-22 02:16:47 -08003704 FakeVideoSendStream* stream = AddSendStream(
3705 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
3706 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
3707
brandtr3d200bd2017-01-16 06:59:19 -08003708 EXPECT_EQ(GetEngineCodec("flexfec-03").id, config.rtp.flexfec.payload_type);
3709 EXPECT_EQ(kFlexfecSsrc, config.rtp.flexfec.ssrc);
3710 ASSERT_EQ(1U, config.rtp.flexfec.protected_media_ssrcs.size());
3711 EXPECT_EQ(kSsrcs1[0], config.rtp.flexfec.protected_media_ssrcs[0]);
brandtr468da7c2016-11-22 02:16:47 -08003712}
3713
eladalonf1841382017-06-12 01:16:46 -07003714TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithoutFec) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003715 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08003716 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003717 ASSERT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003718
3719 FakeVideoSendStream* stream = AddSendStream();
perkj26091b12016-09-01 01:17:40 -07003720 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003721
brandtrb5f2c3f2016-10-04 23:28:39 -07003722 EXPECT_EQ(-1, config.rtp.ulpfec.ulpfec_payload_type);
3723 EXPECT_EQ(-1, config.rtp.ulpfec.red_payload_type);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003724}
3725
eladalonf1841382017-06-12 01:16:46 -07003726TEST_F(WebRtcVideoChannelFlexfecSendRecvTest, SetSendCodecsWithoutFec) {
brandtr468da7c2016-11-22 02:16:47 -08003727 cricket::VideoSendParameters parameters;
3728 parameters.codecs.push_back(GetEngineCodec("VP8"));
3729 ASSERT_TRUE(channel_->SetSendParameters(parameters));
3730
3731 FakeVideoSendStream* stream = AddSendStream();
3732 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
3733
brandtr3d200bd2017-01-16 06:59:19 -08003734 EXPECT_EQ(-1, config.rtp.flexfec.payload_type);
brandtr468da7c2016-11-22 02:16:47 -08003735}
3736
eladalonf1841382017-06-12 01:16:46 -07003737TEST_F(WebRtcVideoChannelFlexfecRecvTest, SetRecvCodecsWithFec) {
brandtr9c3d4c42017-01-23 06:59:13 -08003738 AddRecvStream(
3739 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
brandtr9c3d4c42017-01-23 06:59:13 -08003740
3741 cricket::VideoRecvParameters recv_parameters;
3742 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
3743 recv_parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
3744 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
brandtr9d58d942017-02-03 04:43:41 -08003745
3746 const std::vector<FakeFlexfecReceiveStream*>& flexfec_streams =
3747 fake_call_->GetFlexfecReceiveStreams();
3748 ASSERT_EQ(1U, flexfec_streams.size());
3749 const FakeFlexfecReceiveStream* flexfec_stream = flexfec_streams.front();
3750 const webrtc::FlexfecReceiveStream::Config& flexfec_stream_config =
3751 flexfec_stream->GetConfig();
brandtr9c3d4c42017-01-23 06:59:13 -08003752 EXPECT_EQ(GetEngineCodec("flexfec-03").id,
brandtr9d58d942017-02-03 04:43:41 -08003753 flexfec_stream_config.payload_type);
3754 EXPECT_EQ(kFlexfecSsrc, flexfec_stream_config.remote_ssrc);
3755 ASSERT_EQ(1U, flexfec_stream_config.protected_media_ssrcs.size());
3756 EXPECT_EQ(kSsrcs1[0], flexfec_stream_config.protected_media_ssrcs[0]);
3757 const std::vector<FakeVideoReceiveStream*>& video_streams =
3758 fake_call_->GetVideoReceiveStreams();
3759 const FakeVideoReceiveStream* video_stream = video_streams.front();
3760 const webrtc::VideoReceiveStream::Config& video_stream_config =
3761 video_stream->GetConfig();
3762 EXPECT_EQ(video_stream_config.rtp.local_ssrc,
3763 flexfec_stream_config.local_ssrc);
3764 EXPECT_EQ(video_stream_config.rtp.rtcp_mode, flexfec_stream_config.rtcp_mode);
3765 EXPECT_EQ(video_stream_config.rtcp_send_transport,
3766 flexfec_stream_config.rtcp_send_transport);
3767 // TODO(brandtr): Update this EXPECT when we set |transport_cc| in a
3768 // spec-compliant way.
3769 EXPECT_EQ(video_stream_config.rtp.transport_cc,
3770 flexfec_stream_config.transport_cc);
3771 EXPECT_EQ(video_stream_config.rtp.rtcp_mode, flexfec_stream_config.rtcp_mode);
3772 EXPECT_EQ(video_stream_config.rtp.extensions,
3773 flexfec_stream_config.rtp_header_extensions);
brandtr9c3d4c42017-01-23 06:59:13 -08003774}
3775
brandtr31bd2242017-05-19 05:47:46 -07003776// We should not send FlexFEC, even if we advertise it, unless the right
3777// field trial is set.
3778// TODO(brandtr): Remove when FlexFEC is enabled by default.
eladalonf1841382017-06-12 01:16:46 -07003779TEST_F(WebRtcVideoChannelFlexfecRecvTest,
brandtr31bd2242017-05-19 05:47:46 -07003780 SetSendCodecsWithoutSsrcWithFecDoesNotEnableFec) {
3781 cricket::VideoSendParameters parameters;
3782 parameters.codecs.push_back(GetEngineCodec("VP8"));
3783 parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
3784 ASSERT_TRUE(channel_->SetSendParameters(parameters));
3785
3786 FakeVideoSendStream* stream = AddSendStream();
3787 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
3788
3789 EXPECT_EQ(-1, config.rtp.flexfec.payload_type);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003790 EXPECT_EQ(0u, config.rtp.flexfec.ssrc);
brandtr31bd2242017-05-19 05:47:46 -07003791 EXPECT_TRUE(config.rtp.flexfec.protected_media_ssrcs.empty());
3792}
3793
eladalonf1841382017-06-12 01:16:46 -07003794TEST_F(WebRtcVideoChannelFlexfecRecvTest,
brandtr31bd2242017-05-19 05:47:46 -07003795 SetSendCodecsWithSsrcWithFecDoesNotEnableFec) {
3796 cricket::VideoSendParameters parameters;
3797 parameters.codecs.push_back(GetEngineCodec("VP8"));
3798 parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
3799 ASSERT_TRUE(channel_->SetSendParameters(parameters));
3800
3801 FakeVideoSendStream* stream = AddSendStream(
3802 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
3803 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
3804
3805 EXPECT_EQ(-1, config.rtp.flexfec.payload_type);
Mirko Bonadeif859e552018-05-30 15:31:29 +02003806 EXPECT_EQ(0u, config.rtp.flexfec.ssrc);
brandtr31bd2242017-05-19 05:47:46 -07003807 EXPECT_TRUE(config.rtp.flexfec.protected_media_ssrcs.empty());
3808}
3809
eladalonf1841382017-06-12 01:16:46 -07003810TEST_F(WebRtcVideoChannelTest,
pbos@webrtc.org269605c2014-06-26 08:49:03 +00003811 SetSendCodecRejectsRtxWithoutAssociatedPayloadType) {
magjed509e4fe2016-11-18 01:34:11 -08003812 const int kUnusedPayloadType = 127;
3813 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType));
3814
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003815 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08003816 cricket::VideoCodec rtx_codec(kUnusedPayloadType, "rtx");
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003817 parameters.codecs.push_back(rtx_codec);
3818 EXPECT_FALSE(channel_->SetSendParameters(parameters))
pbos@webrtc.org269605c2014-06-26 08:49:03 +00003819 << "RTX codec without associated payload type should be rejected.";
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003820}
3821
eladalonf1841382017-06-12 01:16:46 -07003822TEST_F(WebRtcVideoChannelTest,
pbos@webrtc.org269605c2014-06-26 08:49:03 +00003823 SetSendCodecRejectsRtxWithoutMatchingVideoCodec) {
magjed509e4fe2016-11-18 01:34:11 -08003824 const int kUnusedPayloadType1 = 126;
3825 const int kUnusedPayloadType2 = 127;
3826 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType1));
3827 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType2));
3828 {
3829 cricket::VideoCodec rtx_codec = cricket::VideoCodec::CreateRtxCodec(
3830 kUnusedPayloadType1, GetEngineCodec("VP8").id);
3831 cricket::VideoSendParameters parameters;
3832 parameters.codecs.push_back(GetEngineCodec("VP8"));
3833 parameters.codecs.push_back(rtx_codec);
3834 ASSERT_TRUE(channel_->SetSendParameters(parameters));
3835 }
3836 {
3837 cricket::VideoCodec rtx_codec = cricket::VideoCodec::CreateRtxCodec(
3838 kUnusedPayloadType1, kUnusedPayloadType2);
3839 cricket::VideoSendParameters parameters;
3840 parameters.codecs.push_back(GetEngineCodec("VP8"));
3841 parameters.codecs.push_back(rtx_codec);
3842 EXPECT_FALSE(channel_->SetSendParameters(parameters))
3843 << "RTX without matching video codec should be rejected.";
3844 }
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003845}
3846
eladalonf1841382017-06-12 01:16:46 -07003847TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithChangedRtxPayloadType) {
brandtr14742122017-01-27 04:53:07 -08003848 const int kUnusedPayloadType1 = 126;
3849 const int kUnusedPayloadType2 = 127;
3850 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType1));
3851 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType2));
3852
3853 // SSRCs for RTX.
3854 cricket::StreamParams params =
3855 cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
3856 params.AddFidSsrc(kSsrcs1[0], kRtxSsrcs1[0]);
3857 AddSendStream(params);
3858
3859 // Original payload type for RTX.
3860 cricket::VideoSendParameters parameters;
3861 parameters.codecs.push_back(GetEngineCodec("VP8"));
3862 cricket::VideoCodec rtx_codec(kUnusedPayloadType1, "rtx");
3863 rtx_codec.SetParam("apt", GetEngineCodec("VP8").id);
3864 parameters.codecs.push_back(rtx_codec);
3865 EXPECT_TRUE(channel_->SetSendParameters(parameters));
3866 ASSERT_EQ(1U, fake_call_->GetVideoSendStreams().size());
3867 const webrtc::VideoSendStream::Config& config_before =
3868 fake_call_->GetVideoSendStreams()[0]->GetConfig();
3869 EXPECT_EQ(kUnusedPayloadType1, config_before.rtp.rtx.payload_type);
3870 ASSERT_EQ(1U, config_before.rtp.rtx.ssrcs.size());
3871 EXPECT_EQ(kRtxSsrcs1[0], config_before.rtp.rtx.ssrcs[0]);
3872
3873 // Change payload type for RTX.
3874 parameters.codecs[1].id = kUnusedPayloadType2;
3875 EXPECT_TRUE(channel_->SetSendParameters(parameters));
3876 ASSERT_EQ(1U, fake_call_->GetVideoSendStreams().size());
3877 const webrtc::VideoSendStream::Config& config_after =
3878 fake_call_->GetVideoSendStreams()[0]->GetConfig();
3879 EXPECT_EQ(kUnusedPayloadType2, config_after.rtp.rtx.payload_type);
3880 ASSERT_EQ(1U, config_after.rtp.rtx.ssrcs.size());
3881 EXPECT_EQ(kRtxSsrcs1[0], config_after.rtp.rtx.ssrcs[0]);
3882}
3883
eladalonf1841382017-06-12 01:16:46 -07003884TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithoutFecDisablesFec) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003885 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08003886 parameters.codecs.push_back(GetEngineCodec("VP8"));
3887 parameters.codecs.push_back(GetEngineCodec("ulpfec"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003888 ASSERT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org269605c2014-06-26 08:49:03 +00003889
3890 FakeVideoSendStream* stream = AddSendStream();
perkj26091b12016-09-01 01:17:40 -07003891 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
pbos@webrtc.org269605c2014-06-26 08:49:03 +00003892
magjed509e4fe2016-11-18 01:34:11 -08003893 EXPECT_EQ(GetEngineCodec("ulpfec").id, config.rtp.ulpfec.ulpfec_payload_type);
pbos@webrtc.org269605c2014-06-26 08:49:03 +00003894
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003895 parameters.codecs.pop_back();
3896 ASSERT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00003897 stream = fake_call_->GetVideoSendStreams()[0];
brandtr468da7c2016-11-22 02:16:47 -08003898 ASSERT_TRUE(stream != nullptr);
perkj26091b12016-09-01 01:17:40 -07003899 config = stream->GetConfig().Copy();
brandtrb5f2c3f2016-10-04 23:28:39 -07003900 EXPECT_EQ(-1, config.rtp.ulpfec.ulpfec_payload_type)
brandtr468da7c2016-11-22 02:16:47 -08003901 << "SetSendCodec without ULPFEC should disable current ULPFEC.";
3902}
3903
eladalonf1841382017-06-12 01:16:46 -07003904TEST_F(WebRtcVideoChannelFlexfecSendRecvTest,
brandtr31bd2242017-05-19 05:47:46 -07003905 SetSendCodecsWithoutFecDisablesFec) {
brandtr468da7c2016-11-22 02:16:47 -08003906 cricket::VideoSendParameters parameters;
3907 parameters.codecs.push_back(GetEngineCodec("VP8"));
3908 parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
3909 ASSERT_TRUE(channel_->SetSendParameters(parameters));
3910
3911 FakeVideoSendStream* stream = AddSendStream(
3912 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
3913 webrtc::VideoSendStream::Config config = stream->GetConfig().Copy();
3914
brandtr3d200bd2017-01-16 06:59:19 -08003915 EXPECT_EQ(GetEngineCodec("flexfec-03").id, config.rtp.flexfec.payload_type);
3916 EXPECT_EQ(kFlexfecSsrc, config.rtp.flexfec.ssrc);
brandtr468da7c2016-11-22 02:16:47 -08003917 ASSERT_EQ(1U, config.rtp.flexfec.protected_media_ssrcs.size());
3918 EXPECT_EQ(kSsrcs1[0], config.rtp.flexfec.protected_media_ssrcs[0]);
3919
3920 parameters.codecs.pop_back();
3921 ASSERT_TRUE(channel_->SetSendParameters(parameters));
3922 stream = fake_call_->GetVideoSendStreams()[0];
3923 ASSERT_TRUE(stream != nullptr);
3924 config = stream->GetConfig().Copy();
brandtr3d200bd2017-01-16 06:59:19 -08003925 EXPECT_EQ(-1, config.rtp.flexfec.payload_type)
brandtr468da7c2016-11-22 02:16:47 -08003926 << "SetSendCodec without FlexFEC should disable current FlexFEC.";
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003927}
3928
eladalonf1841382017-06-12 01:16:46 -07003929TEST_F(WebRtcVideoChannelTest, SetSendCodecsChangesExistingStreams) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003930 cricket::VideoSendParameters parameters;
perkj26752742016-10-24 01:21:16 -07003931 cricket::VideoCodec codec(100, "VP8");
3932 codec.SetParam(kCodecParamMaxQuantization, kDefaultQpMax);
3933 parameters.codecs.push_back(codec);
perkjfa10b552016-10-02 23:45:26 -07003934
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003935 ASSERT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org86196c42015-02-16 21:02:00 +00003936 channel_->SetSend(true);
pbos@webrtc.org38ce7d02014-07-16 08:01:38 +00003937
pbos@webrtc.org86196c42015-02-16 21:02:00 +00003938 FakeVideoSendStream* stream = AddSendStream();
Niels Möller805a27e2019-01-21 12:21:27 +01003939 webrtc::test::FrameForwarder frame_forwarder;
3940 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));
pbos@webrtc.org86196c42015-02-16 21:02:00 +00003941
3942 std::vector<webrtc::VideoStream> streams = stream->GetVideoStreams();
perkjfa10b552016-10-02 23:45:26 -07003943 EXPECT_EQ(kDefaultQpMax, streams[0].max_qp);
pbos@webrtc.org38ce7d02014-07-16 08:01:38 +00003944
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003945 parameters.codecs.clear();
perkj26752742016-10-24 01:21:16 -07003946 codec.SetParam(kCodecParamMaxQuantization, kDefaultQpMax + 1);
3947 parameters.codecs.push_back(codec);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003948 ASSERT_TRUE(channel_->SetSendParameters(parameters));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00003949 streams = fake_call_->GetVideoSendStreams()[0]->GetVideoStreams();
perkjfa10b552016-10-02 23:45:26 -07003950 EXPECT_EQ(kDefaultQpMax + 1, streams[0].max_qp);
Niels Möllerff40b142018-04-09 08:49:14 +02003951 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003952}
3953
eladalonf1841382017-06-12 01:16:46 -07003954TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithBitrates) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00003955 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
3956 200000);
3957}
3958
eladalonf1841382017-06-12 01:16:46 -07003959TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithHighMaxBitrate) {
pbos@webrtc.orga5f6fb52015-03-23 22:29:39 +00003960 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "10000", 10000000);
3961 std::vector<webrtc::VideoStream> streams = AddSendStream()->GetVideoStreams();
3962 ASSERT_EQ(1u, streams.size());
3963 EXPECT_EQ(10000000, streams[0].max_bitrate_bps);
3964}
3965
eladalonf1841382017-06-12 01:16:46 -07003966TEST_F(WebRtcVideoChannelTest,
pbos@webrtc.org00873182014-11-25 14:03:34 +00003967 SetSendCodecsWithoutBitratesUsesCorrectDefaults) {
Sebastian Jansson8f83b422018-02-21 13:07:13 +01003968 SetSendCodecsShouldWorkForBitrates("", 0, "", -1, "", -1);
pbos@webrtc.org00873182014-11-25 14:03:34 +00003969}
3970
eladalonf1841382017-06-12 01:16:46 -07003971TEST_F(WebRtcVideoChannelTest, SetSendCodecsCapsMinAndStartBitrate) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00003972 SetSendCodecsShouldWorkForBitrates("-1", 0, "-100", -1, "", -1);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003973}
3974
eladalonf1841382017-06-12 01:16:46 -07003975TEST_F(WebRtcVideoChannelTest, SetSendCodecsRejectsMaxLessThanMinBitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02003976 send_parameters_.codecs[0].params[kCodecParamMinBitrate] = "300";
3977 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "200";
3978 EXPECT_FALSE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00003979}
3980
Taylor Brandstetter58f2bd92016-04-26 17:15:23 -07003981// Test that when both the codec-specific bitrate params and max_bandwidth_bps
3982// are present in the same send parameters, the settings are combined correctly.
eladalonf1841382017-06-12 01:16:46 -07003983TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithBitratesAndMaxSendBandwidth) {
Taylor Brandstetter58f2bd92016-04-26 17:15:23 -07003984 send_parameters_.codecs[0].params[kCodecParamMinBitrate] = "100";
3985 send_parameters_.codecs[0].params[kCodecParamStartBitrate] = "200";
3986 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "300";
3987 send_parameters_.max_bandwidth_bps = 400000;
Taylor Brandstetter58f2bd92016-04-26 17:15:23 -07003988 // We expect max_bandwidth_bps to take priority, if set.
Sebastian Jansson8f83b422018-02-21 13:07:13 +01003989 ExpectSetBitrateParameters(100000, 200000, 400000);
3990 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
3991 // Since the codec isn't changing, start_bitrate_bps should be -1.
3992 ExpectSetBitrateParameters(100000, -1, 350000);
Taylor Brandstetter58f2bd92016-04-26 17:15:23 -07003993
3994 // Decrease max_bandwidth_bps.
3995 send_parameters_.max_bandwidth_bps = 350000;
3996 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Taylor Brandstetter58f2bd92016-04-26 17:15:23 -07003997
3998 // Now try again with the values flipped around.
3999 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "400";
4000 send_parameters_.max_bandwidth_bps = 300000;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01004001 ExpectSetBitrateParameters(100000, 200000, 300000);
Taylor Brandstetter58f2bd92016-04-26 17:15:23 -07004002 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Taylor Brandstetter58f2bd92016-04-26 17:15:23 -07004003
4004 // If we change the codec max, max_bandwidth_bps should still apply.
4005 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "350";
Sebastian Jansson8f83b422018-02-21 13:07:13 +01004006 ExpectSetBitrateParameters(100000, 200000, 300000);
Taylor Brandstetter58f2bd92016-04-26 17:15:23 -07004007 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Taylor Brandstetter58f2bd92016-04-26 17:15:23 -07004008}
4009
Piotr (Peter) Slatala946b9682019-03-18 10:25:02 -07004010// Test that when both the codec-specific bitrate params and max_bandwidth_bps
4011// are present in the same send parameters, the settings are combined correctly.
4012TEST_F(WebRtcVideoChannelTest,
4013 SetSendCodecsWithBitratesAndMaxSendBandwidthForMediaTransport) {
4014 // Same as SetSendCodecsWithBitratesAndMaxSendBandwidth but with Media
4015 // Transport.
4016 webrtc::MediaTransportSettings settings;
4017 settings.is_caller = true;
4018 webrtc::FakeMediaTransport fake_media_transport(settings);
4019 std::unique_ptr<cricket::FakeNetworkInterface> network_interface(
4020 new cricket::FakeNetworkInterface);
Anton Sukhanov4f08faa2019-05-21 11:12:57 -07004021 channel_->SetInterface(network_interface.get(),
4022 webrtc::MediaTransportConfig(&fake_media_transport));
Piotr (Peter) Slatala946b9682019-03-18 10:25:02 -07004023
4024 send_parameters_.codecs[0].params[kCodecParamMinBitrate] = "100";
4025 send_parameters_.codecs[0].params[kCodecParamStartBitrate] = "200";
4026 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "300";
4027 send_parameters_.max_bandwidth_bps = 400000;
4028 {
4029 // We expect max_bandwidth_bps to take priority, if set.
4030 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
4031 ASSERT_EQ(1u,
4032 fake_media_transport.target_rate_constraints_in_order().size());
4033 const webrtc::MediaTransportTargetRateConstraints& constraint =
4034 fake_media_transport.target_rate_constraints_in_order()[0];
4035 ASSERT_EQ(webrtc::DataRate::bps(100000), constraint.min_bitrate);
4036 ASSERT_EQ(webrtc::DataRate::bps(200000), constraint.starting_bitrate);
4037 ASSERT_EQ(webrtc::DataRate::bps(400000), constraint.max_bitrate);
4038 }
4039
4040 {
4041 // Decrease max_bandwidth_bps.
4042 send_parameters_.max_bandwidth_bps = 350000;
4043 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
4044 ASSERT_EQ(2u,
4045 fake_media_transport.target_rate_constraints_in_order().size());
4046 const webrtc::MediaTransportTargetRateConstraints& constraint =
4047 fake_media_transport.target_rate_constraints_in_order()[1];
4048
4049 // Since the codec isn't changing, start_bitrate_bps should be 0.
4050 ASSERT_EQ(webrtc::DataRate::bps(100000), constraint.min_bitrate);
4051 ASSERT_EQ(absl::nullopt, constraint.starting_bitrate);
4052 ASSERT_EQ(webrtc::DataRate::bps(350000), constraint.max_bitrate);
4053 }
4054
4055 {
4056 // Now try again with the values flipped around.
4057 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "400";
4058 send_parameters_.max_bandwidth_bps = 300000;
4059 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
4060 ASSERT_EQ(3u,
4061 fake_media_transport.target_rate_constraints_in_order().size());
4062 const webrtc::MediaTransportTargetRateConstraints& constraint =
4063 fake_media_transport.target_rate_constraints_in_order()[2];
4064
4065 ASSERT_EQ(webrtc::DataRate::bps(100000), constraint.min_bitrate);
4066 ASSERT_EQ(webrtc::DataRate::bps(200000), constraint.starting_bitrate);
4067 ASSERT_EQ(webrtc::DataRate::bps(300000), constraint.max_bitrate);
4068 }
4069
4070 {
4071 // Now try again with the values flipped around.
4072 // If we change the codec max, max_bandwidth_bps should still apply.
4073 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "350";
4074 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
4075 ASSERT_EQ(4u,
4076 fake_media_transport.target_rate_constraints_in_order().size());
4077 const webrtc::MediaTransportTargetRateConstraints& constraint =
4078 fake_media_transport.target_rate_constraints_in_order()[3];
4079
4080 ASSERT_EQ(webrtc::DataRate::bps(100000), constraint.min_bitrate);
4081 ASSERT_EQ(webrtc::DataRate::bps(200000), constraint.starting_bitrate);
4082 ASSERT_EQ(webrtc::DataRate::bps(300000), constraint.max_bitrate);
4083 }
4084}
4085
Yves Gerey665174f2018-06-19 15:03:05 +02004086TEST_F(WebRtcVideoChannelTest, SetMaxSendBandwidthShouldPreserveOtherBitrates) {
pbos@webrtc.org00873182014-11-25 14:03:34 +00004087 SetSendCodecsShouldWorkForBitrates("100", 100000, "150", 150000, "200",
4088 200000);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004089 send_parameters_.max_bandwidth_bps = 300000;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01004090 // Setting max bitrate should keep previous min bitrate.
4091 // Setting max bitrate should not reset start bitrate.
4092 ExpectSetBitrateParameters(100000, -1, 300000);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004093 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.org00873182014-11-25 14:03:34 +00004094}
4095
eladalonf1841382017-06-12 01:16:46 -07004096TEST_F(WebRtcVideoChannelTest, SetMaxSendBandwidthShouldBeRemovable) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004097 send_parameters_.max_bandwidth_bps = 300000;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01004098 ExpectSetMaxBitrate(300000);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004099 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos5c7760a2017-03-10 11:23:12 -08004100 // -1 means to disable max bitrate (set infinite).
4101 send_parameters_.max_bandwidth_bps = -1;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01004102 ExpectSetMaxBitrate(-1);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004103 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004104}
4105
eladalonf1841382017-06-12 01:16:46 -07004106TEST_F(WebRtcVideoChannelTest, SetMaxSendBandwidthAndAddSendStream) {
perkjfa10b552016-10-02 23:45:26 -07004107 send_parameters_.max_bandwidth_bps = 99999;
4108 FakeVideoSendStream* stream = AddSendStream();
Sebastian Jansson8f83b422018-02-21 13:07:13 +01004109 ExpectSetMaxBitrate(send_parameters_.max_bandwidth_bps);
perkjfa10b552016-10-02 23:45:26 -07004110 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
perkjfa10b552016-10-02 23:45:26 -07004111 ASSERT_EQ(1u, stream->GetVideoStreams().size());
4112 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
4113 stream->GetVideoStreams()[0].max_bitrate_bps);
4114
4115 send_parameters_.max_bandwidth_bps = 77777;
Sebastian Jansson8f83b422018-02-21 13:07:13 +01004116 ExpectSetMaxBitrate(send_parameters_.max_bandwidth_bps);
perkjfa10b552016-10-02 23:45:26 -07004117 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
4118 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
perkjfa10b552016-10-02 23:45:26 -07004119 stream->GetVideoStreams()[0].max_bitrate_bps);
4120}
4121
Seth Hampsonfeec91e2018-07-13 10:41:10 -07004122// Tests that when the codec specific max bitrate and VideoSendParameters
4123// max_bandwidth_bps are used, that it sets the VideoStream's max bitrate
4124// appropriately.
4125TEST_F(WebRtcVideoChannelTest,
4126 MaxBitratePrioritizesVideoSendParametersOverCodecMaxBitrate) {
4127 send_parameters_.codecs[0].params[kCodecParamMinBitrate] = "100";
4128 send_parameters_.codecs[0].params[kCodecParamStartBitrate] = "200";
4129 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "300";
4130 send_parameters_.max_bandwidth_bps = -1;
4131 AddSendStream();
4132 ExpectSetMaxBitrate(300000);
4133 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
4134
4135 std::vector<FakeVideoSendStream*> video_send_streams = GetFakeSendStreams();
4136 ASSERT_EQ(1u, video_send_streams.size());
4137 FakeVideoSendStream* video_send_stream = video_send_streams[0];
4138 ASSERT_EQ(1u, video_send_streams[0]->GetVideoStreams().size());
4139 // First the max bitrate is set based upon the codec param.
4140 EXPECT_EQ(300000,
4141 video_send_streams[0]->GetVideoStreams()[0].max_bitrate_bps);
4142
4143 // The VideoSendParameters max bitrate overrides the codec's.
4144 send_parameters_.max_bandwidth_bps = 500000;
4145 ExpectSetMaxBitrate(send_parameters_.max_bandwidth_bps);
4146 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
4147 ASSERT_EQ(1u, video_send_stream->GetVideoStreams().size());
4148 EXPECT_EQ(500000, video_send_stream->GetVideoStreams()[0].max_bitrate_bps);
4149}
4150
4151// Tests that when the codec specific max bitrate and RtpParameters
4152// max_bitrate_bps are used, that it sets the VideoStream's max bitrate
4153// appropriately.
4154TEST_F(WebRtcVideoChannelTest,
4155 MaxBitratePrioritizesRtpParametersOverCodecMaxBitrate) {
4156 send_parameters_.codecs[0].params[kCodecParamMinBitrate] = "100";
4157 send_parameters_.codecs[0].params[kCodecParamStartBitrate] = "200";
4158 send_parameters_.codecs[0].params[kCodecParamMaxBitrate] = "300";
4159 send_parameters_.max_bandwidth_bps = -1;
4160 AddSendStream();
4161 ExpectSetMaxBitrate(300000);
4162 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
4163
4164 std::vector<FakeVideoSendStream*> video_send_streams = GetFakeSendStreams();
4165 ASSERT_EQ(1u, video_send_streams.size());
4166 FakeVideoSendStream* video_send_stream = video_send_streams[0];
4167 ASSERT_EQ(1u, video_send_stream->GetVideoStreams().size());
4168 // First the max bitrate is set based upon the codec param.
4169 EXPECT_EQ(300000, video_send_stream->GetVideoStreams()[0].max_bitrate_bps);
4170
4171 // The RtpParameter max bitrate overrides the codec's.
4172 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
4173 ASSERT_EQ(1u, parameters.encodings.size());
4174 parameters.encodings[0].max_bitrate_bps = 500000;
4175 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
4176 ASSERT_EQ(1u, video_send_stream->GetVideoStreams().size());
4177 EXPECT_EQ(parameters.encodings[0].max_bitrate_bps,
4178 video_send_stream->GetVideoStreams()[0].max_bitrate_bps);
4179}
4180
Åsa Persson55659812018-06-18 17:51:32 +02004181TEST_F(WebRtcVideoChannelTest,
4182 MaxBitrateIsMinimumOfMaxSendBandwidthAndMaxEncodingBitrate) {
4183 send_parameters_.max_bandwidth_bps = 99999;
4184 FakeVideoSendStream* stream = AddSendStream();
4185 ExpectSetMaxBitrate(send_parameters_.max_bandwidth_bps);
4186 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
4187 ASSERT_EQ(1u, stream->GetVideoStreams().size());
4188 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
4189 stream->GetVideoStreams()[0].max_bitrate_bps);
4190
4191 // Get and set the rtp encoding parameters.
4192 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
4193 EXPECT_EQ(1u, parameters.encodings.size());
4194
4195 parameters.encodings[0].max_bitrate_bps = 99999 - 1;
4196 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
4197 EXPECT_EQ(parameters.encodings[0].max_bitrate_bps,
4198 stream->GetVideoStreams()[0].max_bitrate_bps);
4199
4200 parameters.encodings[0].max_bitrate_bps = 99999 + 1;
4201 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
4202 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
4203 stream->GetVideoStreams()[0].max_bitrate_bps);
4204}
4205
eladalonf1841382017-06-12 01:16:46 -07004206TEST_F(WebRtcVideoChannelTest, SetMaxSendBitrateCanIncreaseSenderBitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004207 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004208 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004209 ASSERT_TRUE(channel_->SetSendParameters(parameters));
Peter Boströmdfd53fe2015-03-27 15:58:11 +01004210 channel_->SetSend(true);
4211
4212 FakeVideoSendStream* stream = AddSendStream();
4213
Niels Möller805a27e2019-01-21 12:21:27 +01004214 webrtc::test::FrameForwarder frame_forwarder;
4215 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));
Peter Boström3afc8c42016-01-27 16:45:21 +01004216
Peter Boströmdfd53fe2015-03-27 15:58:11 +01004217 std::vector<webrtc::VideoStream> streams = stream->GetVideoStreams();
4218 int initial_max_bitrate_bps = streams[0].max_bitrate_bps;
4219 EXPECT_GT(initial_max_bitrate_bps, 0);
4220
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004221 parameters.max_bandwidth_bps = initial_max_bitrate_bps * 2;
4222 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Peter Boström3afc8c42016-01-27 16:45:21 +01004223 // Insert a frame to update the encoder config.
Niels Möller805a27e2019-01-21 12:21:27 +01004224 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Peter Boströmdfd53fe2015-03-27 15:58:11 +01004225 streams = stream->GetVideoStreams();
4226 EXPECT_EQ(initial_max_bitrate_bps * 2, streams[0].max_bitrate_bps);
Niels Möllerff40b142018-04-09 08:49:14 +02004227 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
Peter Boströmdfd53fe2015-03-27 15:58:11 +01004228}
4229
eladalonf1841382017-06-12 01:16:46 -07004230TEST_F(WebRtcVideoChannelTest,
Peter Boströmdfd53fe2015-03-27 15:58:11 +01004231 SetMaxSendBitrateCanIncreaseSimulcastSenderBitrate) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004232 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004233 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004234 ASSERT_TRUE(channel_->SetSendParameters(parameters));
Peter Boströmdfd53fe2015-03-27 15:58:11 +01004235 channel_->SetSend(true);
4236
4237 FakeVideoSendStream* stream = AddSendStream(
4238 cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kSsrcs3)));
4239
4240 // Send a frame to make sure this scales up to >1 stream (simulcast).
Niels Möller805a27e2019-01-21 12:21:27 +01004241 webrtc::test::FrameForwarder frame_forwarder;
4242 EXPECT_TRUE(channel_->SetVideoSend(kSsrcs3[0], nullptr, &frame_forwarder));
4243 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Peter Boströmdfd53fe2015-03-27 15:58:11 +01004244
4245 std::vector<webrtc::VideoStream> streams = stream->GetVideoStreams();
4246 ASSERT_GT(streams.size(), 1u)
4247 << "Without simulcast this test doesn't make sense.";
pbosbe16f792015-10-16 12:49:39 -07004248 int initial_max_bitrate_bps = GetTotalMaxBitrateBps(streams);
Peter Boströmdfd53fe2015-03-27 15:58:11 +01004249 EXPECT_GT(initial_max_bitrate_bps, 0);
4250
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004251 parameters.max_bandwidth_bps = initial_max_bitrate_bps * 2;
4252 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Peter Boström3afc8c42016-01-27 16:45:21 +01004253 // Insert a frame to update the encoder config.
Niels Möller805a27e2019-01-21 12:21:27 +01004254 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Peter Boströmdfd53fe2015-03-27 15:58:11 +01004255 streams = stream->GetVideoStreams();
pbosbe16f792015-10-16 12:49:39 -07004256 int increased_max_bitrate_bps = GetTotalMaxBitrateBps(streams);
Peter Boströmdfd53fe2015-03-27 15:58:11 +01004257 EXPECT_EQ(initial_max_bitrate_bps * 2, increased_max_bitrate_bps);
4258
Niels Möllerff40b142018-04-09 08:49:14 +02004259 EXPECT_TRUE(channel_->SetVideoSend(kSsrcs3[0], nullptr, nullptr));
Peter Boströmdfd53fe2015-03-27 15:58:11 +01004260}
4261
eladalonf1841382017-06-12 01:16:46 -07004262TEST_F(WebRtcVideoChannelTest, SetSendCodecsWithMaxQuantization) {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004263 static const char* kMaxQuantization = "21";
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004264 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004265 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004266 parameters.codecs[0].params[kCodecParamMaxQuantization] = kMaxQuantization;
4267 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Mirko Bonadeif859e552018-05-30 15:31:29 +02004268 EXPECT_EQ(atoi(kMaxQuantization),
pbos@webrtc.org6ae48c62014-06-06 10:49:19 +00004269 AddSendStream()->GetVideoStreams().back().max_qp);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004270
4271 VideoCodec codec;
4272 EXPECT_TRUE(channel_->GetSendCodec(&codec));
4273 EXPECT_EQ(kMaxQuantization, codec.params[kCodecParamMaxQuantization]);
4274}
4275
eladalonf1841382017-06-12 01:16:46 -07004276TEST_F(WebRtcVideoChannelTest, SetSendCodecsRejectBadPayloadTypes) {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004277 // TODO(pbos): Should we only allow the dynamic range?
pkasting@chromium.orge7a4a122015-01-28 21:36:55 +00004278 static const int kIncorrectPayloads[] = {-2, -1, 128, 129};
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004279 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004280 parameters.codecs.push_back(GetEngineCodec("VP8"));
pkasting@chromium.orge7a4a122015-01-28 21:36:55 +00004281 for (size_t i = 0; i < arraysize(kIncorrectPayloads); ++i) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004282 parameters.codecs[0].id = kIncorrectPayloads[i];
4283 EXPECT_FALSE(channel_->SetSendParameters(parameters))
pkasting@chromium.orgd3245462015-02-23 21:28:22 +00004284 << "Bad payload type '" << kIncorrectPayloads[i] << "' accepted.";
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004285 }
4286}
4287
eladalonf1841382017-06-12 01:16:46 -07004288TEST_F(WebRtcVideoChannelTest, SetSendCodecsAcceptAllValidPayloadTypes) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004289 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004290 parameters.codecs.push_back(GetEngineCodec("VP8"));
magjedf823ede2016-11-12 09:53:04 -08004291 for (int payload_type = 96; payload_type <= 127; ++payload_type) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004292 parameters.codecs[0].id = payload_type;
4293 EXPECT_TRUE(channel_->SetSendParameters(parameters))
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004294 << "Payload type '" << payload_type << "' rejected.";
4295 }
4296}
4297
deadbeef67cf2c12016-04-13 10:07:16 -07004298// Test that setting the a different set of codecs but with an identical front
4299// codec doesn't result in the stream being recreated.
4300// This may happen when a subsequent negotiation includes fewer codecs, as a
4301// result of one of the codecs being rejected.
eladalonf1841382017-06-12 01:16:46 -07004302TEST_F(WebRtcVideoChannelTest,
deadbeef67cf2c12016-04-13 10:07:16 -07004303 SetSendCodecsIdenticalFirstCodecDoesntRecreateStream) {
4304 cricket::VideoSendParameters parameters1;
magjed509e4fe2016-11-18 01:34:11 -08004305 parameters1.codecs.push_back(GetEngineCodec("VP8"));
4306 parameters1.codecs.push_back(GetEngineCodec("VP9"));
deadbeef67cf2c12016-04-13 10:07:16 -07004307 EXPECT_TRUE(channel_->SetSendParameters(parameters1));
4308
4309 AddSendStream();
4310 EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());
4311
4312 cricket::VideoSendParameters parameters2;
magjed509e4fe2016-11-18 01:34:11 -08004313 parameters2.codecs.push_back(GetEngineCodec("VP8"));
deadbeef67cf2c12016-04-13 10:07:16 -07004314 EXPECT_TRUE(channel_->SetSendParameters(parameters2));
4315 EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());
4316}
4317
eladalonf1841382017-06-12 01:16:46 -07004318TEST_F(WebRtcVideoChannelTest, SetRecvCodecsWithOnlyVp8) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004319 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004320 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004321 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004322}
4323
pbos@webrtc.orge322a172014-06-13 11:47:28 +00004324// Test that we set our inbound RTX codecs properly.
eladalonf1841382017-06-12 01:16:46 -07004325TEST_F(WebRtcVideoChannelTest, SetRecvCodecsWithRtx) {
magjed509e4fe2016-11-18 01:34:11 -08004326 const int kUnusedPayloadType1 = 126;
4327 const int kUnusedPayloadType2 = 127;
4328 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType1));
4329 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType2));
4330
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004331 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004332 parameters.codecs.push_back(GetEngineCodec("VP8"));
4333 cricket::VideoCodec rtx_codec(kUnusedPayloadType1, "rtx");
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004334 parameters.codecs.push_back(rtx_codec);
4335 EXPECT_FALSE(channel_->SetRecvParameters(parameters))
pbos@webrtc.orge322a172014-06-13 11:47:28 +00004336 << "RTX codec without associated payload should be rejected.";
4337
magjed509e4fe2016-11-18 01:34:11 -08004338 parameters.codecs[1].SetParam("apt", kUnusedPayloadType2);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004339 EXPECT_FALSE(channel_->SetRecvParameters(parameters))
pbos@webrtc.orge322a172014-06-13 11:47:28 +00004340 << "RTX codec with invalid associated payload type should be rejected.";
4341
magjed509e4fe2016-11-18 01:34:11 -08004342 parameters.codecs[1].SetParam("apt", GetEngineCodec("VP8").id);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004343 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orge322a172014-06-13 11:47:28 +00004344
magjed509e4fe2016-11-18 01:34:11 -08004345 cricket::VideoCodec rtx_codec2(kUnusedPayloadType2, "rtx");
pbos@webrtc.orge322a172014-06-13 11:47:28 +00004346 rtx_codec2.SetParam("apt", rtx_codec.id);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004347 parameters.codecs.push_back(rtx_codec2);
pbos@webrtc.orge322a172014-06-13 11:47:28 +00004348
Yves Gerey665174f2018-06-19 15:03:05 +02004349 EXPECT_FALSE(channel_->SetRecvParameters(parameters))
4350 << "RTX codec with another RTX as associated payload type should be "
4351 "rejected.";
pbos@webrtc.orge322a172014-06-13 11:47:28 +00004352}
4353
eladalonf1841382017-06-12 01:16:46 -07004354TEST_F(WebRtcVideoChannelTest, SetRecvCodecsWithChangedRtxPayloadType) {
brandtr14742122017-01-27 04:53:07 -08004355 const int kUnusedPayloadType1 = 126;
4356 const int kUnusedPayloadType2 = 127;
4357 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType1));
4358 EXPECT_FALSE(FindCodecById(engine_.codecs(), kUnusedPayloadType2));
4359
4360 // SSRCs for RTX.
4361 cricket::StreamParams params =
4362 cricket::StreamParams::CreateLegacy(kSsrcs1[0]);
4363 params.AddFidSsrc(kSsrcs1[0], kRtxSsrcs1[0]);
4364 AddRecvStream(params);
4365
4366 // Original payload type for RTX.
4367 cricket::VideoRecvParameters parameters;
4368 parameters.codecs.push_back(GetEngineCodec("VP8"));
4369 cricket::VideoCodec rtx_codec(kUnusedPayloadType1, "rtx");
4370 rtx_codec.SetParam("apt", GetEngineCodec("VP8").id);
4371 parameters.codecs.push_back(rtx_codec);
4372 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
4373 ASSERT_EQ(1U, fake_call_->GetVideoReceiveStreams().size());
4374 const webrtc::VideoReceiveStream::Config& config_before =
4375 fake_call_->GetVideoReceiveStreams()[0]->GetConfig();
nisse26e3abb2017-08-25 04:44:25 -07004376 EXPECT_EQ(1U, config_before.rtp.rtx_associated_payload_types.size());
4377 const int* payload_type_before = FindKeyByValue(
4378 config_before.rtp.rtx_associated_payload_types, GetEngineCodec("VP8").id);
4379 ASSERT_NE(payload_type_before, nullptr);
4380 EXPECT_EQ(kUnusedPayloadType1, *payload_type_before);
brandtr14742122017-01-27 04:53:07 -08004381 EXPECT_EQ(kRtxSsrcs1[0], config_before.rtp.rtx_ssrc);
4382
4383 // Change payload type for RTX.
4384 parameters.codecs[1].id = kUnusedPayloadType2;
4385 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
4386 ASSERT_EQ(1U, fake_call_->GetVideoReceiveStreams().size());
4387 const webrtc::VideoReceiveStream::Config& config_after =
4388 fake_call_->GetVideoReceiveStreams()[0]->GetConfig();
nisse26e3abb2017-08-25 04:44:25 -07004389 EXPECT_EQ(1U, config_after.rtp.rtx_associated_payload_types.size());
4390 const int* payload_type_after = FindKeyByValue(
4391 config_after.rtp.rtx_associated_payload_types, GetEngineCodec("VP8").id);
4392 ASSERT_NE(payload_type_after, nullptr);
4393 EXPECT_EQ(kUnusedPayloadType2, *payload_type_after);
brandtr14742122017-01-27 04:53:07 -08004394 EXPECT_EQ(kRtxSsrcs1[0], config_after.rtp.rtx_ssrc);
4395}
4396
eladalonf1841382017-06-12 01:16:46 -07004397TEST_F(WebRtcVideoChannelTest, SetRecvCodecsDifferentPayloadType) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004398 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004399 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004400 parameters.codecs[0].id = 99;
4401 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004402}
4403
eladalonf1841382017-06-12 01:16:46 -07004404TEST_F(WebRtcVideoChannelTest, SetRecvCodecsAcceptDefaultCodecs) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004405 cricket::VideoRecvParameters parameters;
4406 parameters.codecs = engine_.codecs();
4407 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgccbed3b2014-07-11 13:02:54 +00004408
4409 FakeVideoReceiveStream* stream = AddRecvStream();
Tommi733b5472016-06-10 17:58:01 +02004410 const webrtc::VideoReceiveStream::Config& config = stream->GetConfig();
Niels Möllercb7e1d22018-09-11 15:56:04 +02004411 EXPECT_EQ(engine_.codecs()[0].name, config.decoders[0].video_format.name);
pbos@webrtc.org776e6f22014-10-29 15:28:39 +00004412 EXPECT_EQ(engine_.codecs()[0].id, config.decoders[0].payload_type);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004413}
4414
eladalonf1841382017-06-12 01:16:46 -07004415TEST_F(WebRtcVideoChannelTest, SetRecvCodecsRejectUnsupportedCodec) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004416 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004417 parameters.codecs.push_back(GetEngineCodec("VP8"));
perkj26752742016-10-24 01:21:16 -07004418 parameters.codecs.push_back(VideoCodec(101, "WTF3"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004419 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004420}
4421
eladalonf1841382017-06-12 01:16:46 -07004422TEST_F(WebRtcVideoChannelTest, SetRecvCodecsAcceptsMultipleVideoCodecs) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004423 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004424 parameters.codecs.push_back(GetEngineCodec("VP8"));
4425 parameters.codecs.push_back(GetEngineCodec("VP9"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004426 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004427}
4428
eladalonf1841382017-06-12 01:16:46 -07004429TEST_F(WebRtcVideoChannelTest, SetRecvCodecsWithoutFecDisablesFec) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004430 cricket::VideoSendParameters send_parameters;
magjed509e4fe2016-11-18 01:34:11 -08004431 send_parameters.codecs.push_back(GetEngineCodec("VP8"));
4432 send_parameters.codecs.push_back(GetEngineCodec("red"));
4433 send_parameters.codecs.push_back(GetEngineCodec("ulpfec"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004434 ASSERT_TRUE(channel_->SetSendParameters(send_parameters));
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00004435
4436 FakeVideoReceiveStream* stream = AddRecvStream();
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00004437
magjed509e4fe2016-11-18 01:34:11 -08004438 EXPECT_EQ(GetEngineCodec("ulpfec").id,
nisse3b3622f2017-09-26 02:49:21 -07004439 stream->GetConfig().rtp.ulpfec_payload_type);
pbos@webrtc.orgd1ea06b2014-07-18 09:35:58 +00004440
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004441 cricket::VideoRecvParameters recv_parameters;
magjed509e4fe2016-11-18 01:34:11 -08004442 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004443 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
pbos@webrtc.org42684be2014-10-03 11:25:45 +00004444 stream = fake_call_->GetVideoReceiveStreams()[0];
brandtr468da7c2016-11-22 02:16:47 -08004445 ASSERT_TRUE(stream != nullptr);
nisse3b3622f2017-09-26 02:49:21 -07004446 EXPECT_EQ(-1, stream->GetConfig().rtp.ulpfec_payload_type)
brandtr468da7c2016-11-22 02:16:47 -08004447 << "SetSendCodec without ULPFEC should disable current ULPFEC.";
4448}
4449
eladalonf1841382017-06-12 01:16:46 -07004450TEST_F(WebRtcVideoChannelFlexfecRecvTest, SetRecvParamsWithoutFecDisablesFec) {
brandtr468da7c2016-11-22 02:16:47 -08004451 AddRecvStream(
4452 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
brandtr9c3d4c42017-01-23 06:59:13 -08004453 const std::vector<FakeFlexfecReceiveStream*>& streams =
brandtr468da7c2016-11-22 02:16:47 -08004454 fake_call_->GetFlexfecReceiveStreams();
4455
4456 ASSERT_EQ(1U, streams.size());
brandtr9c3d4c42017-01-23 06:59:13 -08004457 const FakeFlexfecReceiveStream* stream = streams.front();
4458 EXPECT_EQ(GetEngineCodec("flexfec-03").id, stream->GetConfig().payload_type);
4459 EXPECT_EQ(kFlexfecSsrc, stream->GetConfig().remote_ssrc);
4460 ASSERT_EQ(1U, stream->GetConfig().protected_media_ssrcs.size());
4461 EXPECT_EQ(kSsrcs1[0], stream->GetConfig().protected_media_ssrcs[0]);
brandtr468da7c2016-11-22 02:16:47 -08004462
4463 cricket::VideoRecvParameters recv_parameters;
4464 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
4465 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
4466 EXPECT_TRUE(streams.empty())
4467 << "SetSendCodec without FlexFEC should disable current FlexFEC.";
pbos@webrtc.org269605c2014-06-26 08:49:03 +00004468}
4469
eladalonf1841382017-06-12 01:16:46 -07004470TEST_F(WebRtcVideoChannelTest, SetSendParamsWithFecEnablesFec) {
Stefan Holmer2b1f6512016-05-17 16:33:30 +02004471 FakeVideoReceiveStream* stream = AddRecvStream();
magjed509e4fe2016-11-18 01:34:11 -08004472 EXPECT_EQ(GetEngineCodec("ulpfec").id,
nisse3b3622f2017-09-26 02:49:21 -07004473 stream->GetConfig().rtp.ulpfec_payload_type);
Stefan Holmer2b1f6512016-05-17 16:33:30 +02004474
4475 cricket::VideoRecvParameters recv_parameters;
magjed509e4fe2016-11-18 01:34:11 -08004476 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
4477 recv_parameters.codecs.push_back(GetEngineCodec("red"));
4478 recv_parameters.codecs.push_back(GetEngineCodec("ulpfec"));
Stefan Holmer2b1f6512016-05-17 16:33:30 +02004479 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
4480 stream = fake_call_->GetVideoReceiveStreams()[0];
brandtr468da7c2016-11-22 02:16:47 -08004481 ASSERT_TRUE(stream != nullptr);
magjed509e4fe2016-11-18 01:34:11 -08004482 EXPECT_EQ(GetEngineCodec("ulpfec").id,
nisse3b3622f2017-09-26 02:49:21 -07004483 stream->GetConfig().rtp.ulpfec_payload_type)
brandtr468da7c2016-11-22 02:16:47 -08004484 << "ULPFEC should be enabled on the receive stream.";
Stefan Holmer2b1f6512016-05-17 16:33:30 +02004485
4486 cricket::VideoSendParameters send_parameters;
magjed509e4fe2016-11-18 01:34:11 -08004487 send_parameters.codecs.push_back(GetEngineCodec("VP8"));
4488 send_parameters.codecs.push_back(GetEngineCodec("red"));
4489 send_parameters.codecs.push_back(GetEngineCodec("ulpfec"));
Stefan Holmer2b1f6512016-05-17 16:33:30 +02004490 ASSERT_TRUE(channel_->SetSendParameters(send_parameters));
4491 stream = fake_call_->GetVideoReceiveStreams()[0];
magjed509e4fe2016-11-18 01:34:11 -08004492 EXPECT_EQ(GetEngineCodec("ulpfec").id,
nisse3b3622f2017-09-26 02:49:21 -07004493 stream->GetConfig().rtp.ulpfec_payload_type)
brandtr468da7c2016-11-22 02:16:47 -08004494 << "ULPFEC should be enabled on the receive stream.";
4495}
4496
eladalonf1841382017-06-12 01:16:46 -07004497TEST_F(WebRtcVideoChannelFlexfecSendRecvTest,
brandtr31bd2242017-05-19 05:47:46 -07004498 SetSendRecvParamsWithFecEnablesFec) {
brandtr468da7c2016-11-22 02:16:47 -08004499 AddRecvStream(
4500 CreatePrimaryWithFecFrStreamParams("cname", kSsrcs1[0], kFlexfecSsrc));
brandtr9c3d4c42017-01-23 06:59:13 -08004501 const std::vector<FakeFlexfecReceiveStream*>& streams =
brandtr468da7c2016-11-22 02:16:47 -08004502 fake_call_->GetFlexfecReceiveStreams();
4503
4504 cricket::VideoRecvParameters recv_parameters;
4505 recv_parameters.codecs.push_back(GetEngineCodec("VP8"));
4506 recv_parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
4507 ASSERT_TRUE(channel_->SetRecvParameters(recv_parameters));
4508 ASSERT_EQ(1U, streams.size());
brandtr9c3d4c42017-01-23 06:59:13 -08004509 const FakeFlexfecReceiveStream* stream_with_recv_params = streams.front();
brandtr468da7c2016-11-22 02:16:47 -08004510 EXPECT_EQ(GetEngineCodec("flexfec-03").id,
brandtr9c3d4c42017-01-23 06:59:13 -08004511 stream_with_recv_params->GetConfig().payload_type);
4512 EXPECT_EQ(kFlexfecSsrc, stream_with_recv_params->GetConfig().remote_ssrc);
brandtr468da7c2016-11-22 02:16:47 -08004513 EXPECT_EQ(1U,
brandtr9c3d4c42017-01-23 06:59:13 -08004514 stream_with_recv_params->GetConfig().protected_media_ssrcs.size());
brandtr468da7c2016-11-22 02:16:47 -08004515 EXPECT_EQ(kSsrcs1[0],
brandtr9c3d4c42017-01-23 06:59:13 -08004516 stream_with_recv_params->GetConfig().protected_media_ssrcs[0]);
brandtr468da7c2016-11-22 02:16:47 -08004517
4518 cricket::VideoSendParameters send_parameters;
4519 send_parameters.codecs.push_back(GetEngineCodec("VP8"));
4520 send_parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
4521 ASSERT_TRUE(channel_->SetSendParameters(send_parameters));
4522 ASSERT_EQ(1U, streams.size());
brandtr9c3d4c42017-01-23 06:59:13 -08004523 const FakeFlexfecReceiveStream* stream_with_send_params = streams.front();
brandtr468da7c2016-11-22 02:16:47 -08004524 EXPECT_EQ(GetEngineCodec("flexfec-03").id,
brandtr9c3d4c42017-01-23 06:59:13 -08004525 stream_with_send_params->GetConfig().payload_type);
4526 EXPECT_EQ(kFlexfecSsrc, stream_with_send_params->GetConfig().remote_ssrc);
brandtr468da7c2016-11-22 02:16:47 -08004527 EXPECT_EQ(1U,
brandtr9c3d4c42017-01-23 06:59:13 -08004528 stream_with_send_params->GetConfig().protected_media_ssrcs.size());
brandtr468da7c2016-11-22 02:16:47 -08004529 EXPECT_EQ(kSsrcs1[0],
brandtr9c3d4c42017-01-23 06:59:13 -08004530 stream_with_send_params->GetConfig().protected_media_ssrcs[0]);
Stefan Holmer2b1f6512016-05-17 16:33:30 +02004531}
4532
eladalonf1841382017-06-12 01:16:46 -07004533TEST_F(WebRtcVideoChannelTest, SetRecvCodecsRejectDuplicateFecPayloads) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004534 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004535 parameters.codecs.push_back(GetEngineCodec("VP8"));
4536 parameters.codecs.push_back(GetEngineCodec("red"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004537 parameters.codecs[1].id = parameters.codecs[0].id;
4538 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004539}
4540
eladalonf1841382017-06-12 01:16:46 -07004541TEST_F(WebRtcVideoChannelFlexfecRecvTest,
brandtr31bd2242017-05-19 05:47:46 -07004542 SetRecvCodecsRejectDuplicateFecPayloads) {
brandtr468da7c2016-11-22 02:16:47 -08004543 cricket::VideoRecvParameters parameters;
4544 parameters.codecs.push_back(GetEngineCodec("VP8"));
4545 parameters.codecs.push_back(GetEngineCodec("flexfec-03"));
4546 parameters.codecs[1].id = parameters.codecs[0].id;
4547 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
4548}
4549
eladalonf1841382017-06-12 01:16:46 -07004550TEST_F(WebRtcVideoChannelTest, SetRecvCodecsRejectDuplicateCodecPayloads) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004551 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004552 parameters.codecs.push_back(GetEngineCodec("VP8"));
4553 parameters.codecs.push_back(GetEngineCodec("VP9"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004554 parameters.codecs[1].id = parameters.codecs[0].id;
4555 EXPECT_FALSE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004556}
4557
eladalonf1841382017-06-12 01:16:46 -07004558TEST_F(WebRtcVideoChannelTest,
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004559 SetRecvCodecsAcceptSameCodecOnMultiplePayloadTypes) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004560 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004561 parameters.codecs.push_back(GetEngineCodec("VP8"));
4562 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004563 parameters.codecs[1].id += 1;
4564 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004565}
4566
deadbeef67cf2c12016-04-13 10:07:16 -07004567// Test that setting the same codecs but with a different order
deadbeef874ca3a2015-08-20 17:19:20 -07004568// doesn't result in the stream being recreated.
eladalonf1841382017-06-12 01:16:46 -07004569TEST_F(WebRtcVideoChannelTest,
deadbeef67cf2c12016-04-13 10:07:16 -07004570 SetRecvCodecsDifferentOrderDoesntRecreateStream) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004571 cricket::VideoRecvParameters parameters1;
magjed509e4fe2016-11-18 01:34:11 -08004572 parameters1.codecs.push_back(GetEngineCodec("VP8"));
4573 parameters1.codecs.push_back(GetEngineCodec("red"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004574 EXPECT_TRUE(channel_->SetRecvParameters(parameters1));
deadbeef874ca3a2015-08-20 17:19:20 -07004575
4576 AddRecvStream(cricket::StreamParams::CreateLegacy(123));
4577 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
4578
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004579 cricket::VideoRecvParameters parameters2;
magjed509e4fe2016-11-18 01:34:11 -08004580 parameters2.codecs.push_back(GetEngineCodec("red"));
4581 parameters2.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004582 EXPECT_TRUE(channel_->SetRecvParameters(parameters2));
deadbeef874ca3a2015-08-20 17:19:20 -07004583 EXPECT_EQ(1, fake_call_->GetNumCreatedReceiveStreams());
4584}
4585
eladalonf1841382017-06-12 01:16:46 -07004586TEST_F(WebRtcVideoChannelTest, SendStreamNotSendingByDefault) {
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004587 EXPECT_FALSE(AddSendStream()->IsSending());
4588}
4589
eladalonf1841382017-06-12 01:16:46 -07004590TEST_F(WebRtcVideoChannelTest, ReceiveStreamReceivingByDefault) {
pbos@webrtc.org85f42942014-07-22 09:14:58 +00004591 EXPECT_TRUE(AddRecvStream()->IsReceiving());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004592}
4593
eladalonf1841382017-06-12 01:16:46 -07004594TEST_F(WebRtcVideoChannelTest, SetSend) {
pbos@webrtc.org5301b0f2014-07-17 08:51:46 +00004595 FakeVideoSendStream* stream = AddSendStream();
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004596 EXPECT_FALSE(stream->IsSending());
4597
4598 // false->true
4599 EXPECT_TRUE(channel_->SetSend(true));
4600 EXPECT_TRUE(stream->IsSending());
4601 // true->true
4602 EXPECT_TRUE(channel_->SetSend(true));
4603 EXPECT_TRUE(stream->IsSending());
4604 // true->false
4605 EXPECT_TRUE(channel_->SetSend(false));
4606 EXPECT_FALSE(stream->IsSending());
4607 // false->false
4608 EXPECT_TRUE(channel_->SetSend(false));
4609 EXPECT_FALSE(stream->IsSending());
4610
4611 EXPECT_TRUE(channel_->SetSend(true));
4612 FakeVideoSendStream* new_stream = AddSendStream();
4613 EXPECT_TRUE(new_stream->IsSending())
4614 << "Send stream created after SetSend(true) not sending initially.";
4615}
4616
pbos@webrtc.orgd8198032014-11-10 14:41:43 +00004617// This test verifies DSCP settings are properly applied on video media channel.
eladalonf1841382017-06-12 01:16:46 -07004618TEST_F(WebRtcVideoChannelTest, TestSetDscpOptions) {
kwiberg686a8ef2016-02-26 03:00:35 -08004619 std::unique_ptr<cricket::FakeNetworkInterface> network_interface(
pbos@webrtc.orgd8198032014-11-10 14:41:43 +00004620 new cricket::FakeNetworkInterface);
nisse51542be2016-02-12 02:27:06 -08004621 MediaConfig config;
Tim Haloun6ca98362018-09-17 17:06:08 -07004622 std::unique_ptr<cricket::WebRtcVideoChannel> channel;
Tim Haloun648d28a2018-10-18 16:52:22 -07004623 webrtc::RtpParameters parameters;
nisse51542be2016-02-12 02:27:06 -08004624
Sebastian Jansson84848f22018-11-16 10:40:36 +01004625 channel.reset(
4626 static_cast<cricket::WebRtcVideoChannel*>(engine_.CreateMediaChannel(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02004627 call_.get(), config, VideoOptions(), webrtc::CryptoOptions(),
4628 video_bitrate_allocator_factory_.get())));
Anton Sukhanov4f08faa2019-05-21 11:12:57 -07004629 channel->SetInterface(network_interface.get(),
4630 webrtc::MediaTransportConfig());
nisse51542be2016-02-12 02:27:06 -08004631 // Default value when DSCP is disabled should be DSCP_DEFAULT.
pbos@webrtc.orgd8198032014-11-10 14:41:43 +00004632 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface->dscp());
nisse51542be2016-02-12 02:27:06 -08004633
Tim Haloun648d28a2018-10-18 16:52:22 -07004634 // Default value when DSCP is enabled is also DSCP_DEFAULT, until it is set
4635 // through rtp parameters.
nisse51542be2016-02-12 02:27:06 -08004636 config.enable_dscp = true;
Sebastian Jansson84848f22018-11-16 10:40:36 +01004637 channel.reset(
4638 static_cast<cricket::WebRtcVideoChannel*>(engine_.CreateMediaChannel(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02004639 call_.get(), config, VideoOptions(), webrtc::CryptoOptions(),
4640 video_bitrate_allocator_factory_.get())));
Anton Sukhanov4f08faa2019-05-21 11:12:57 -07004641 channel->SetInterface(network_interface.get(),
4642 webrtc::MediaTransportConfig());
Tim Haloun648d28a2018-10-18 16:52:22 -07004643 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface->dscp());
4644
4645 // Create a send stream to configure
4646 EXPECT_TRUE(channel->AddSendStream(StreamParams::CreateLegacy(kSsrc)));
4647 parameters = channel->GetRtpSendParameters(kSsrc);
4648 ASSERT_FALSE(parameters.encodings.empty());
4649
4650 // Various priorities map to various dscp values.
4651 parameters.encodings[0].network_priority = 4.0;
4652 ASSERT_TRUE(channel->SetRtpSendParameters(kSsrc, parameters).ok());
nisse51542be2016-02-12 02:27:06 -08004653 EXPECT_EQ(rtc::DSCP_AF41, network_interface->dscp());
Tim Haloun648d28a2018-10-18 16:52:22 -07004654 parameters.encodings[0].network_priority = 0.5;
4655 ASSERT_TRUE(channel->SetRtpSendParameters(kSsrc, parameters).ok());
4656 EXPECT_EQ(rtc::DSCP_CS1, network_interface->dscp());
4657
4658 // A bad priority does not change the dscp value.
4659 parameters.encodings[0].network_priority = 0.0;
4660 ASSERT_FALSE(channel->SetRtpSendParameters(kSsrc, parameters).ok());
4661 EXPECT_EQ(rtc::DSCP_CS1, network_interface->dscp());
nisse51542be2016-02-12 02:27:06 -08004662
Tim Haloun6ca98362018-09-17 17:06:08 -07004663 // Packets should also self-identify their dscp in PacketOptions.
4664 const uint8_t kData[10] = {0};
4665 EXPECT_TRUE(static_cast<webrtc::Transport*>(channel.get())
4666 ->SendRtcp(kData, sizeof(kData)));
Tim Haloun648d28a2018-10-18 16:52:22 -07004667 EXPECT_EQ(rtc::DSCP_CS1, network_interface->options().dscp);
Tim Haloun6ca98362018-09-17 17:06:08 -07004668
nisse51542be2016-02-12 02:27:06 -08004669 // Verify that setting the option to false resets the
4670 // DiffServCodePoint.
4671 config.enable_dscp = false;
Sebastian Jansson84848f22018-11-16 10:40:36 +01004672 channel.reset(
4673 static_cast<cricket::WebRtcVideoChannel*>(engine_.CreateMediaChannel(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02004674 call_.get(), config, VideoOptions(), webrtc::CryptoOptions(),
4675 video_bitrate_allocator_factory_.get())));
Anton Sukhanov4f08faa2019-05-21 11:12:57 -07004676 channel->SetInterface(network_interface.get(),
4677 webrtc::MediaTransportConfig());
nisse51542be2016-02-12 02:27:06 -08004678 EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface->dscp());
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004679}
4680
deadbeef13871492015-12-09 12:37:51 -08004681// This test verifies that the RTCP reduced size mode is properly applied to
4682// send video streams.
eladalonf1841382017-06-12 01:16:46 -07004683TEST_F(WebRtcVideoChannelTest, TestSetSendRtcpReducedSize) {
deadbeef13871492015-12-09 12:37:51 -08004684 // Create stream, expecting that default mode is "compound".
4685 FakeVideoSendStream* stream1 = AddSendStream();
4686 EXPECT_EQ(webrtc::RtcpMode::kCompound, stream1->GetConfig().rtp.rtcp_mode);
Florent Castellidacec712018-05-24 16:24:21 +02004687 webrtc::RtpParameters rtp_parameters =
4688 channel_->GetRtpSendParameters(last_ssrc_);
4689 EXPECT_FALSE(rtp_parameters.rtcp.reduced_size);
deadbeef13871492015-12-09 12:37:51 -08004690
4691 // Now enable reduced size mode.
4692 send_parameters_.rtcp.reduced_size = true;
4693 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
4694 stream1 = fake_call_->GetVideoSendStreams()[0];
4695 EXPECT_EQ(webrtc::RtcpMode::kReducedSize, stream1->GetConfig().rtp.rtcp_mode);
Florent Castellidacec712018-05-24 16:24:21 +02004696 rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
4697 EXPECT_TRUE(rtp_parameters.rtcp.reduced_size);
deadbeef13871492015-12-09 12:37:51 -08004698
4699 // Create a new stream and ensure it picks up the reduced size mode.
4700 FakeVideoSendStream* stream2 = AddSendStream();
4701 EXPECT_EQ(webrtc::RtcpMode::kReducedSize, stream2->GetConfig().rtp.rtcp_mode);
4702}
4703
4704// This test verifies that the RTCP reduced size mode is properly applied to
4705// receive video streams.
eladalonf1841382017-06-12 01:16:46 -07004706TEST_F(WebRtcVideoChannelTest, TestSetRecvRtcpReducedSize) {
deadbeef13871492015-12-09 12:37:51 -08004707 // Create stream, expecting that default mode is "compound".
4708 FakeVideoReceiveStream* stream1 = AddRecvStream();
4709 EXPECT_EQ(webrtc::RtcpMode::kCompound, stream1->GetConfig().rtp.rtcp_mode);
4710
4711 // Now enable reduced size mode.
Taylor Brandstetter5f0b83b2016-03-18 15:02:07 -07004712 // TODO(deadbeef): Once "recv_parameters" becomes "receiver_parameters",
4713 // the reduced_size flag should come from that.
4714 send_parameters_.rtcp.reduced_size = true;
4715 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
deadbeef13871492015-12-09 12:37:51 -08004716 stream1 = fake_call_->GetVideoReceiveStreams()[0];
4717 EXPECT_EQ(webrtc::RtcpMode::kReducedSize, stream1->GetConfig().rtp.rtcp_mode);
4718
4719 // Create a new stream and ensure it picks up the reduced size mode.
4720 FakeVideoReceiveStream* stream2 = AddRecvStream();
4721 EXPECT_EQ(webrtc::RtcpMode::kReducedSize, stream2->GetConfig().rtp.rtcp_mode);
4722}
4723
eladalonf1841382017-06-12 01:16:46 -07004724TEST_F(WebRtcVideoChannelTest, OnReadyToSendSignalsNetworkState) {
skvlad7a43d252016-03-22 15:32:27 -07004725 EXPECT_EQ(webrtc::kNetworkUp,
4726 fake_call_->GetNetworkState(webrtc::MediaType::VIDEO));
4727 EXPECT_EQ(webrtc::kNetworkUp,
4728 fake_call_->GetNetworkState(webrtc::MediaType::AUDIO));
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00004729
4730 channel_->OnReadyToSend(false);
skvlad7a43d252016-03-22 15:32:27 -07004731 EXPECT_EQ(webrtc::kNetworkDown,
4732 fake_call_->GetNetworkState(webrtc::MediaType::VIDEO));
4733 EXPECT_EQ(webrtc::kNetworkUp,
4734 fake_call_->GetNetworkState(webrtc::MediaType::AUDIO));
pbos@webrtc.org26c0c412014-09-03 16:17:12 +00004735
4736 channel_->OnReadyToSend(true);
skvlad7a43d252016-03-22 15:32:27 -07004737 EXPECT_EQ(webrtc::kNetworkUp,
4738 fake_call_->GetNetworkState(webrtc::MediaType::VIDEO));
4739 EXPECT_EQ(webrtc::kNetworkUp,
4740 fake_call_->GetNetworkState(webrtc::MediaType::AUDIO));
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00004741}
4742
eladalonf1841382017-06-12 01:16:46 -07004743TEST_F(WebRtcVideoChannelTest, GetStatsReportsSentCodecName) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004744 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08004745 parameters.codecs.push_back(GetEngineCodec("VP8"));
Fredrik Solenbergb071a192015-09-17 16:42:56 +02004746 EXPECT_TRUE(channel_->SetSendParameters(parameters));
Peter Boström74d9ed72015-03-26 16:28:31 +01004747
4748 AddSendStream();
4749
4750 cricket::VideoMediaInfo info;
4751 ASSERT_TRUE(channel_->GetStats(&info));
magjed509e4fe2016-11-18 01:34:11 -08004752 EXPECT_EQ("VP8", info.senders[0].codec_name);
Peter Boström74d9ed72015-03-26 16:28:31 +01004753}
4754
eladalonf1841382017-06-12 01:16:46 -07004755TEST_F(WebRtcVideoChannelTest, GetStatsReportsEncoderImplementationName) {
Peter Boströmb7d9a972015-12-18 16:01:11 +01004756 FakeVideoSendStream* stream = AddSendStream();
4757 webrtc::VideoSendStream::Stats stats;
4758 stats.encoder_implementation_name = "encoder_implementation_name";
4759 stream->SetStats(stats);
4760
4761 cricket::VideoMediaInfo info;
4762 ASSERT_TRUE(channel_->GetStats(&info));
4763 EXPECT_EQ(stats.encoder_implementation_name,
4764 info.senders[0].encoder_implementation_name);
4765}
4766
eladalonf1841382017-06-12 01:16:46 -07004767TEST_F(WebRtcVideoChannelTest, GetStatsReportsCpuOveruseMetrics) {
pbos@webrtc.org3e6e2712015-02-26 12:19:31 +00004768 FakeVideoSendStream* stream = AddSendStream();
4769 webrtc::VideoSendStream::Stats stats;
4770 stats.avg_encode_time_ms = 13;
4771 stats.encode_usage_percent = 42;
4772 stream->SetStats(stats);
4773
4774 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00004775 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org3e6e2712015-02-26 12:19:31 +00004776 EXPECT_EQ(stats.avg_encode_time_ms, info.senders[0].avg_encode_ms);
4777 EXPECT_EQ(stats.encode_usage_percent, info.senders[0].encode_usage_percent);
4778}
4779
eladalonf1841382017-06-12 01:16:46 -07004780TEST_F(WebRtcVideoChannelTest, GetStatsReportsFramesEncoded) {
sakal43536c32016-10-24 01:46:43 -07004781 FakeVideoSendStream* stream = AddSendStream();
4782 webrtc::VideoSendStream::Stats stats;
4783 stats.frames_encoded = 13;
4784 stream->SetStats(stats);
4785
4786 cricket::VideoMediaInfo info;
4787 ASSERT_TRUE(channel_->GetStats(&info));
4788 EXPECT_EQ(stats.frames_encoded, info.senders[0].frames_encoded);
4789}
4790
eladalonf1841382017-06-12 01:16:46 -07004791TEST_F(WebRtcVideoChannelTest, GetStatsReportsQpSum) {
sakal87da4042016-10-31 06:53:47 -07004792 FakeVideoSendStream* stream = AddSendStream();
4793 webrtc::VideoSendStream::Stats stats;
Oskar Sundbom78807582017-11-16 11:09:55 +01004794 stats.qp_sum = 13;
sakal87da4042016-10-31 06:53:47 -07004795 stream->SetStats(stats);
4796
4797 cricket::VideoMediaInfo info;
4798 ASSERT_TRUE(channel_->GetStats(&info));
4799 EXPECT_EQ(stats.qp_sum, info.senders[0].qp_sum);
4800}
4801
eladalonf1841382017-06-12 01:16:46 -07004802TEST_F(WebRtcVideoChannelTest, GetStatsReportsUpperResolution) {
pbos@webrtc.org273a4142014-12-01 15:23:21 +00004803 FakeVideoSendStream* stream = AddSendStream();
4804 webrtc::VideoSendStream::Stats stats;
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00004805 stats.substreams[17].width = 123;
4806 stats.substreams[17].height = 40;
4807 stats.substreams[42].width = 80;
4808 stats.substreams[42].height = 31;
4809 stats.substreams[11].width = 20;
4810 stats.substreams[11].height = 90;
pbos@webrtc.org273a4142014-12-01 15:23:21 +00004811 stream->SetStats(stats);
4812
4813 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00004814 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org273a4142014-12-01 15:23:21 +00004815 ASSERT_EQ(1u, info.senders.size());
4816 EXPECT_EQ(123, info.senders[0].send_frame_width);
4817 EXPECT_EQ(90, info.senders[0].send_frame_height);
4818}
4819
eladalonf1841382017-06-12 01:16:46 -07004820TEST_F(WebRtcVideoChannelTest, GetStatsReportsCpuAdaptationStats) {
perkj803d97f2016-11-01 11:45:46 -07004821 FakeVideoSendStream* stream = AddSendStream();
4822 webrtc::VideoSendStream::Stats stats;
4823 stats.number_of_cpu_adapt_changes = 2;
4824 stats.cpu_limited_resolution = true;
4825 stream->SetStats(stats);
pbos@webrtc.org9a4410e2015-02-26 10:03:39 +00004826
pbos@webrtc.org9a4410e2015-02-26 10:03:39 +00004827 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00004828 EXPECT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org9a4410e2015-02-26 10:03:39 +00004829 ASSERT_EQ(1U, info.senders.size());
eladalonf1841382017-06-12 01:16:46 -07004830 EXPECT_EQ(WebRtcVideoChannel::ADAPTREASON_CPU, info.senders[0].adapt_reason);
perkj803d97f2016-11-01 11:45:46 -07004831 EXPECT_EQ(stats.number_of_cpu_adapt_changes, info.senders[0].adapt_changes);
pbos@webrtc.org9a4410e2015-02-26 10:03:39 +00004832}
4833
eladalonf1841382017-06-12 01:16:46 -07004834TEST_F(WebRtcVideoChannelTest, GetStatsReportsAdaptationAndBandwidthStats) {
perkj803d97f2016-11-01 11:45:46 -07004835 FakeVideoSendStream* stream = AddSendStream();
asapersson17821db2015-12-14 02:08:12 -08004836 webrtc::VideoSendStream::Stats stats;
perkj803d97f2016-11-01 11:45:46 -07004837 stats.number_of_cpu_adapt_changes = 2;
4838 stats.cpu_limited_resolution = true;
asapersson17821db2015-12-14 02:08:12 -08004839 stats.bw_limited_resolution = true;
perkj803d97f2016-11-01 11:45:46 -07004840 stream->SetStats(stats);
4841
4842 cricket::VideoMediaInfo info;
asapersson17821db2015-12-14 02:08:12 -08004843 EXPECT_TRUE(channel_->GetStats(&info));
4844 ASSERT_EQ(1U, info.senders.size());
eladalonf1841382017-06-12 01:16:46 -07004845 EXPECT_EQ(WebRtcVideoChannel::ADAPTREASON_CPU |
4846 WebRtcVideoChannel::ADAPTREASON_BANDWIDTH,
asapersson17821db2015-12-14 02:08:12 -08004847 info.senders[0].adapt_reason);
perkj803d97f2016-11-01 11:45:46 -07004848 EXPECT_EQ(stats.number_of_cpu_adapt_changes, info.senders[0].adapt_changes);
asapersson17821db2015-12-14 02:08:12 -08004849}
4850
eladalonf1841382017-06-12 01:16:46 -07004851TEST_F(WebRtcVideoChannelTest,
asapersson17821db2015-12-14 02:08:12 -08004852 GetStatsTranslatesBandwidthLimitedResolutionCorrectly) {
4853 FakeVideoSendStream* stream = AddSendStream();
4854 webrtc::VideoSendStream::Stats stats;
4855 stats.bw_limited_resolution = true;
4856 stream->SetStats(stats);
4857
4858 cricket::VideoMediaInfo info;
4859 EXPECT_TRUE(channel_->GetStats(&info));
4860 ASSERT_EQ(1U, info.senders.size());
eladalonf1841382017-06-12 01:16:46 -07004861 EXPECT_EQ(WebRtcVideoChannel::ADAPTREASON_BANDWIDTH,
asapersson17821db2015-12-14 02:08:12 -08004862 info.senders[0].adapt_reason);
4863}
4864
Yves Gerey665174f2018-06-19 15:03:05 +02004865TEST_F(WebRtcVideoChannelTest, GetStatsTranslatesSendRtcpPacketTypesCorrectly) {
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00004866 FakeVideoSendStream* stream = AddSendStream();
4867 webrtc::VideoSendStream::Stats stats;
4868 stats.substreams[17].rtcp_packet_type_counts.fir_packets = 2;
4869 stats.substreams[17].rtcp_packet_type_counts.nack_packets = 3;
4870 stats.substreams[17].rtcp_packet_type_counts.pli_packets = 4;
4871
4872 stats.substreams[42].rtcp_packet_type_counts.fir_packets = 5;
4873 stats.substreams[42].rtcp_packet_type_counts.nack_packets = 7;
4874 stats.substreams[42].rtcp_packet_type_counts.pli_packets = 9;
4875
4876 stream->SetStats(stats);
4877
4878 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00004879 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00004880 EXPECT_EQ(7, info.senders[0].firs_rcvd);
4881 EXPECT_EQ(10, info.senders[0].nacks_rcvd);
4882 EXPECT_EQ(13, info.senders[0].plis_rcvd);
4883}
4884
eladalonf1841382017-06-12 01:16:46 -07004885TEST_F(WebRtcVideoChannelTest,
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00004886 GetStatsTranslatesReceiveRtcpPacketTypesCorrectly) {
4887 FakeVideoReceiveStream* stream = AddRecvStream();
4888 webrtc::VideoReceiveStream::Stats stats;
4889 stats.rtcp_packet_type_counts.fir_packets = 2;
4890 stats.rtcp_packet_type_counts.nack_packets = 3;
4891 stats.rtcp_packet_type_counts.pli_packets = 4;
4892 stream->SetStats(stats);
4893
4894 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00004895 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00004896 EXPECT_EQ(stats.rtcp_packet_type_counts.fir_packets,
Mirko Bonadeif859e552018-05-30 15:31:29 +02004897 rtc::checked_cast<unsigned int>(info.receivers[0].firs_sent));
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00004898 EXPECT_EQ(stats.rtcp_packet_type_counts.nack_packets,
Mirko Bonadeif859e552018-05-30 15:31:29 +02004899 rtc::checked_cast<unsigned int>(info.receivers[0].nacks_sent));
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00004900 EXPECT_EQ(stats.rtcp_packet_type_counts.pli_packets,
Mirko Bonadeif859e552018-05-30 15:31:29 +02004901 rtc::checked_cast<unsigned int>(info.receivers[0].plis_sent));
pbos@webrtc.org1d0fa5d2015-02-19 12:47:00 +00004902}
4903
eladalonf1841382017-06-12 01:16:46 -07004904TEST_F(WebRtcVideoChannelTest, GetStatsTranslatesDecodeStatsCorrectly) {
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00004905 FakeVideoReceiveStream* stream = AddRecvStream();
4906 webrtc::VideoReceiveStream::Stats stats;
Peter Boströmb7d9a972015-12-18 16:01:11 +01004907 stats.decoder_implementation_name = "decoder_implementation_name";
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00004908 stats.decode_ms = 2;
4909 stats.max_decode_ms = 3;
4910 stats.current_delay_ms = 4;
4911 stats.target_delay_ms = 5;
4912 stats.jitter_buffer_ms = 6;
4913 stats.min_playout_delay_ms = 7;
4914 stats.render_delay_ms = 8;
asapersson26dd92b2016-08-30 00:45:45 -07004915 stats.width = 9;
4916 stats.height = 10;
hbos42f6d2f2017-01-20 03:56:50 -08004917 stats.frame_counts.key_frames = 11;
4918 stats.frame_counts.delta_frames = 12;
hbos50cfe1f2017-01-23 07:21:55 -08004919 stats.frames_rendered = 13;
4920 stats.frames_decoded = 14;
Oskar Sundbom78807582017-11-16 11:09:55 +01004921 stats.qp_sum = 15;
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00004922 stream->SetStats(stats);
4923
4924 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00004925 ASSERT_TRUE(channel_->GetStats(&info));
Peter Boströmb7d9a972015-12-18 16:01:11 +01004926 EXPECT_EQ(stats.decoder_implementation_name,
4927 info.receivers[0].decoder_implementation_name);
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00004928 EXPECT_EQ(stats.decode_ms, info.receivers[0].decode_ms);
4929 EXPECT_EQ(stats.max_decode_ms, info.receivers[0].max_decode_ms);
4930 EXPECT_EQ(stats.current_delay_ms, info.receivers[0].current_delay_ms);
4931 EXPECT_EQ(stats.target_delay_ms, info.receivers[0].target_delay_ms);
4932 EXPECT_EQ(stats.jitter_buffer_ms, info.receivers[0].jitter_buffer_ms);
4933 EXPECT_EQ(stats.min_playout_delay_ms, info.receivers[0].min_playout_delay_ms);
4934 EXPECT_EQ(stats.render_delay_ms, info.receivers[0].render_delay_ms);
asapersson26dd92b2016-08-30 00:45:45 -07004935 EXPECT_EQ(stats.width, info.receivers[0].frame_width);
4936 EXPECT_EQ(stats.height, info.receivers[0].frame_height);
Mirko Bonadeif859e552018-05-30 15:31:29 +02004937 EXPECT_EQ(rtc::checked_cast<unsigned int>(stats.frame_counts.key_frames +
4938 stats.frame_counts.delta_frames),
hbos42f6d2f2017-01-20 03:56:50 -08004939 info.receivers[0].frames_received);
hbos50cfe1f2017-01-23 07:21:55 -08004940 EXPECT_EQ(stats.frames_rendered, info.receivers[0].frames_rendered);
sakale5ba44e2016-10-26 07:09:24 -07004941 EXPECT_EQ(stats.frames_decoded, info.receivers[0].frames_decoded);
sakalcc452e12017-02-09 04:53:45 -08004942 EXPECT_EQ(stats.qp_sum, info.receivers[0].qp_sum);
pbos@webrtc.org09c77b92015-02-25 10:42:16 +00004943}
4944
eladalonf1841382017-06-12 01:16:46 -07004945TEST_F(WebRtcVideoChannelTest, GetStatsTranslatesReceivePacketStatsCorrectly) {
Peter Boström393347f2015-04-22 14:52:45 +02004946 FakeVideoReceiveStream* stream = AddRecvStream();
4947 webrtc::VideoReceiveStream::Stats stats;
4948 stats.rtp_stats.transmitted.payload_bytes = 2;
4949 stats.rtp_stats.transmitted.header_bytes = 3;
4950 stats.rtp_stats.transmitted.padding_bytes = 4;
4951 stats.rtp_stats.transmitted.packets = 5;
srte186d9c32017-08-04 05:03:53 -07004952 stats.rtcp_stats.packets_lost = 6;
Peter Boström393347f2015-04-22 14:52:45 +02004953 stats.rtcp_stats.fraction_lost = 7;
4954 stream->SetStats(stats);
4955
4956 cricket::VideoMediaInfo info;
4957 ASSERT_TRUE(channel_->GetStats(&info));
4958 EXPECT_EQ(stats.rtp_stats.transmitted.payload_bytes +
4959 stats.rtp_stats.transmitted.header_bytes +
4960 stats.rtp_stats.transmitted.padding_bytes,
Mirko Bonadeif859e552018-05-30 15:31:29 +02004961 rtc::checked_cast<size_t>(info.receivers[0].bytes_rcvd));
Peter Boström393347f2015-04-22 14:52:45 +02004962 EXPECT_EQ(stats.rtp_stats.transmitted.packets,
Mirko Bonadeif859e552018-05-30 15:31:29 +02004963 rtc::checked_cast<unsigned int>(info.receivers[0].packets_rcvd));
srte186d9c32017-08-04 05:03:53 -07004964 EXPECT_EQ(stats.rtcp_stats.packets_lost, info.receivers[0].packets_lost);
Mirko Bonadeif859e552018-05-30 15:31:29 +02004965 EXPECT_EQ(rtc::checked_cast<float>(stats.rtcp_stats.fraction_lost) / (1 << 8),
Peter Boström393347f2015-04-22 14:52:45 +02004966 info.receivers[0].fraction_lost);
4967}
4968
eladalonf1841382017-06-12 01:16:46 -07004969TEST_F(WebRtcVideoChannelTest, TranslatesCallStatsCorrectly) {
pbos@webrtc.org2b19f062014-12-11 13:26:09 +00004970 AddSendStream();
4971 AddSendStream();
4972 webrtc::Call::Stats stats;
4973 stats.rtt_ms = 123;
4974 fake_call_->SetStats(stats);
4975
4976 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00004977 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org2b19f062014-12-11 13:26:09 +00004978 ASSERT_EQ(2u, info.senders.size());
4979 EXPECT_EQ(stats.rtt_ms, info.senders[0].rtt_ms);
4980 EXPECT_EQ(stats.rtt_ms, info.senders[1].rtt_ms);
4981}
4982
eladalonf1841382017-06-12 01:16:46 -07004983TEST_F(WebRtcVideoChannelTest, TranslatesSenderBitrateStatsCorrectly) {
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00004984 FakeVideoSendStream* stream = AddSendStream();
4985 webrtc::VideoSendStream::Stats stats;
pbos@webrtc.org891d4832015-02-26 13:15:22 +00004986 stats.target_media_bitrate_bps = 156;
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00004987 stats.media_bitrate_bps = 123;
4988 stats.substreams[17].total_bitrate_bps = 1;
4989 stats.substreams[17].retransmit_bitrate_bps = 2;
4990 stats.substreams[42].total_bitrate_bps = 3;
4991 stats.substreams[42].retransmit_bitrate_bps = 4;
4992 stream->SetStats(stats);
4993
4994 FakeVideoSendStream* stream2 = AddSendStream();
4995 webrtc::VideoSendStream::Stats stats2;
pbos@webrtc.org891d4832015-02-26 13:15:22 +00004996 stats2.target_media_bitrate_bps = 200;
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00004997 stats2.media_bitrate_bps = 321;
4998 stats2.substreams[13].total_bitrate_bps = 5;
4999 stats2.substreams[13].retransmit_bitrate_bps = 6;
5000 stats2.substreams[21].total_bitrate_bps = 7;
5001 stats2.substreams[21].retransmit_bitrate_bps = 8;
5002 stream2->SetStats(stats2);
5003
5004 cricket::VideoMediaInfo info;
pbos@webrtc.org058b1f12015-03-04 08:54:32 +00005005 ASSERT_TRUE(channel_->GetStats(&info));
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00005006 ASSERT_EQ(2u, info.senders.size());
stefanf79ade12017-06-02 06:44:03 -07005007 BandwidthEstimationInfo bwe_info;
5008 channel_->FillBitrateInfo(&bwe_info);
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00005009 // Assuming stream and stream2 corresponds to senders[0] and [1] respectively
5010 // is OK as std::maps are sorted and AddSendStream() gives increasing SSRCs.
5011 EXPECT_EQ(stats.media_bitrate_bps, info.senders[0].nominal_bitrate);
5012 EXPECT_EQ(stats2.media_bitrate_bps, info.senders[1].nominal_bitrate);
pbos@webrtc.org891d4832015-02-26 13:15:22 +00005013 EXPECT_EQ(stats.target_media_bitrate_bps + stats2.target_media_bitrate_bps,
stefanf79ade12017-06-02 06:44:03 -07005014 bwe_info.target_enc_bitrate);
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00005015 EXPECT_EQ(stats.media_bitrate_bps + stats2.media_bitrate_bps,
stefanf79ade12017-06-02 06:44:03 -07005016 bwe_info.actual_enc_bitrate);
5017 EXPECT_EQ(1 + 3 + 5 + 7, bwe_info.transmit_bitrate)
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00005018 << "Bandwidth stats should take all streams into account.";
stefanf79ade12017-06-02 06:44:03 -07005019 EXPECT_EQ(2 + 4 + 6 + 8, bwe_info.retransmit_bitrate)
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00005020 << "Bandwidth stats should take all streams into account.";
5021}
5022
eladalonf1841382017-06-12 01:16:46 -07005023TEST_F(WebRtcVideoChannelTest, DefaultReceiveStreamReconfiguresToUseRtx) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02005024 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
pbos@webrtc.orga2a6fe62015-03-06 15:35:19 +00005025
Peter Boström0c4e06b2015-10-07 12:23:21 +02005026 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
5027 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
pbos@webrtc.orga2a6fe62015-03-06 15:35:19 +00005028
5029 ASSERT_EQ(0u, fake_call_->GetVideoReceiveStreams().size());
5030 const size_t kDataLength = 12;
5031 uint8_t data[kDataLength];
5032 memset(data, 0, sizeof(data));
5033 rtc::SetBE32(&data[8], ssrcs[0]);
jbaucheec21bd2016-03-20 06:15:43 -07005034 rtc::CopyOnWriteBuffer packet(data, kDataLength);
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07005035 channel_->OnPacketReceived(packet, /* packet_time_us */ -1);
pbos@webrtc.orga2a6fe62015-03-06 15:35:19 +00005036
5037 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size())
5038 << "No default receive stream created.";
5039 FakeVideoReceiveStream* recv_stream = fake_call_->GetVideoReceiveStreams()[0];
brandtr14742122017-01-27 04:53:07 -08005040 EXPECT_EQ(0u, recv_stream->GetConfig().rtp.rtx_ssrc)
pbos@webrtc.orga2a6fe62015-03-06 15:35:19 +00005041 << "Default receive stream should not have configured RTX";
5042
5043 EXPECT_TRUE(channel_->AddRecvStream(
5044 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs)));
5045 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size())
brandtr14742122017-01-27 04:53:07 -08005046 << "AddRecvStream should have reconfigured, not added a new receiver.";
pbos@webrtc.orga2a6fe62015-03-06 15:35:19 +00005047 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
nisse26e3abb2017-08-25 04:44:25 -07005048 EXPECT_FALSE(
5049 recv_stream->GetConfig().rtp.rtx_associated_payload_types.empty());
nisseca5706d2017-09-11 02:32:16 -07005050 EXPECT_TRUE(VerifyRtxReceiveAssociations(recv_stream->GetConfig()))
Peter Boströmd8b01092016-05-12 16:44:36 +02005051 << "RTX should be mapped for all decoders/payload types.";
nisseca5706d2017-09-11 02:32:16 -07005052 EXPECT_TRUE(HasRtxReceiveAssociation(recv_stream->GetConfig(),
Yves Gerey665174f2018-06-19 15:03:05 +02005053 GetEngineCodec("red").id))
nisseca5706d2017-09-11 02:32:16 -07005054 << "RTX should be mapped also for the RED payload type";
brandtr14742122017-01-27 04:53:07 -08005055 EXPECT_EQ(rtx_ssrcs[0], recv_stream->GetConfig().rtp.rtx_ssrc);
pbos@webrtc.orga2a6fe62015-03-06 15:35:19 +00005056}
5057
eladalonf1841382017-06-12 01:16:46 -07005058TEST_F(WebRtcVideoChannelTest, RejectsAddingStreamsWithMissingSsrcsForRtx) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02005059 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Peter Boströmd4362cd2015-03-25 14:17:23 +01005060
Peter Boström0c4e06b2015-10-07 12:23:21 +02005061 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
5062 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
Peter Boströmd4362cd2015-03-25 14:17:23 +01005063
5064 StreamParams sp =
5065 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs);
5066 sp.ssrcs = ssrcs; // Without RTXs, this is the important part.
5067
5068 EXPECT_FALSE(channel_->AddSendStream(sp));
5069 EXPECT_FALSE(channel_->AddRecvStream(sp));
5070}
5071
eladalonf1841382017-06-12 01:16:46 -07005072TEST_F(WebRtcVideoChannelTest, RejectsAddingStreamsWithOverlappingRtxSsrcs) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02005073 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Peter Boströmd6f4c252015-03-26 16:23:04 +01005074
Peter Boström0c4e06b2015-10-07 12:23:21 +02005075 const std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs1);
5076 const std::vector<uint32_t> rtx_ssrcs = MAKE_VECTOR(kRtxSsrcs1);
Peter Boströmd6f4c252015-03-26 16:23:04 +01005077
5078 StreamParams sp =
5079 cricket::CreateSimWithRtxStreamParams("cname", ssrcs, rtx_ssrcs);
5080
5081 EXPECT_TRUE(channel_->AddSendStream(sp));
5082 EXPECT_TRUE(channel_->AddRecvStream(sp));
5083
5084 // The RTX SSRC is already used in previous streams, using it should fail.
5085 sp = cricket::StreamParams::CreateLegacy(rtx_ssrcs[0]);
5086 EXPECT_FALSE(channel_->AddSendStream(sp));
5087 EXPECT_FALSE(channel_->AddRecvStream(sp));
5088
5089 // After removing the original stream this should be fine to add (makes sure
5090 // that RTX ssrcs are not forever taken).
5091 EXPECT_TRUE(channel_->RemoveSendStream(ssrcs[0]));
5092 EXPECT_TRUE(channel_->RemoveRecvStream(ssrcs[0]));
5093 EXPECT_TRUE(channel_->AddSendStream(sp));
5094 EXPECT_TRUE(channel_->AddRecvStream(sp));
5095}
5096
eladalonf1841382017-06-12 01:16:46 -07005097TEST_F(WebRtcVideoChannelTest,
Peter Boströmd6f4c252015-03-26 16:23:04 +01005098 RejectsAddingStreamsWithOverlappingSimulcastSsrcs) {
Peter Boström0c4e06b2015-10-07 12:23:21 +02005099 static const uint32_t kFirstStreamSsrcs[] = {1, 2, 3};
5100 static const uint32_t kOverlappingStreamSsrcs[] = {4, 3, 5};
Fredrik Solenbergb071a192015-09-17 16:42:56 +02005101 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Peter Boströmd6f4c252015-03-26 16:23:04 +01005102
Peter Boströmd6f4c252015-03-26 16:23:04 +01005103 StreamParams sp =
5104 cricket::CreateSimStreamParams("cname", MAKE_VECTOR(kFirstStreamSsrcs));
5105
5106 EXPECT_TRUE(channel_->AddSendStream(sp));
5107 EXPECT_TRUE(channel_->AddRecvStream(sp));
5108
5109 // One of the SSRCs is already used in previous streams, using it should fail.
5110 sp = cricket::CreateSimStreamParams("cname",
5111 MAKE_VECTOR(kOverlappingStreamSsrcs));
5112 EXPECT_FALSE(channel_->AddSendStream(sp));
5113 EXPECT_FALSE(channel_->AddRecvStream(sp));
5114
5115 // After removing the original stream this should be fine to add (makes sure
5116 // that RTX ssrcs are not forever taken).
Peter Boström3548dd22015-05-22 18:48:36 +02005117 EXPECT_TRUE(channel_->RemoveSendStream(kFirstStreamSsrcs[0]));
5118 EXPECT_TRUE(channel_->RemoveRecvStream(kFirstStreamSsrcs[0]));
Peter Boströmd6f4c252015-03-26 16:23:04 +01005119 EXPECT_TRUE(channel_->AddSendStream(sp));
5120 EXPECT_TRUE(channel_->AddRecvStream(sp));
5121}
5122
eladalonf1841382017-06-12 01:16:46 -07005123TEST_F(WebRtcVideoChannelTest, ReportsSsrcGroupsInStats) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02005124 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Peter Boström259bd202015-05-28 13:39:50 +02005125
5126 static const uint32_t kSenderSsrcs[] = {4, 7, 10};
5127 static const uint32_t kSenderRtxSsrcs[] = {5, 8, 11};
5128
5129 StreamParams sender_sp = cricket::CreateSimWithRtxStreamParams(
5130 "cname", MAKE_VECTOR(kSenderSsrcs), MAKE_VECTOR(kSenderRtxSsrcs));
5131
5132 EXPECT_TRUE(channel_->AddSendStream(sender_sp));
5133
5134 static const uint32_t kReceiverSsrcs[] = {3};
5135 static const uint32_t kReceiverRtxSsrcs[] = {2};
5136
5137 StreamParams receiver_sp = cricket::CreateSimWithRtxStreamParams(
5138 "cname", MAKE_VECTOR(kReceiverSsrcs), MAKE_VECTOR(kReceiverRtxSsrcs));
5139 EXPECT_TRUE(channel_->AddRecvStream(receiver_sp));
5140
5141 cricket::VideoMediaInfo info;
5142 ASSERT_TRUE(channel_->GetStats(&info));
5143
5144 ASSERT_EQ(1u, info.senders.size());
5145 ASSERT_EQ(1u, info.receivers.size());
5146
5147 EXPECT_NE(sender_sp.ssrc_groups, receiver_sp.ssrc_groups);
5148 EXPECT_EQ(sender_sp.ssrc_groups, info.senders[0].ssrc_groups);
5149 EXPECT_EQ(receiver_sp.ssrc_groups, info.receivers[0].ssrc_groups);
5150}
5151
eladalonf1841382017-06-12 01:16:46 -07005152TEST_F(WebRtcVideoChannelTest, MapsReceivedPayloadTypeToCodecName) {
pbosf42376c2015-08-28 07:35:32 -07005153 FakeVideoReceiveStream* stream = AddRecvStream();
5154 webrtc::VideoReceiveStream::Stats stats;
5155 cricket::VideoMediaInfo info;
5156
5157 // Report no codec name before receiving.
5158 stream->SetStats(stats);
5159 ASSERT_TRUE(channel_->GetStats(&info));
5160 EXPECT_STREQ("", info.receivers[0].codec_name.c_str());
5161
5162 // Report VP8 if we're receiving it.
magjed509e4fe2016-11-18 01:34:11 -08005163 stats.current_payload_type = GetEngineCodec("VP8").id;
pbosf42376c2015-08-28 07:35:32 -07005164 stream->SetStats(stats);
5165 ASSERT_TRUE(channel_->GetStats(&info));
5166 EXPECT_STREQ(kVp8CodecName, info.receivers[0].codec_name.c_str());
5167
5168 // Report no codec name for unknown playload types.
5169 stats.current_payload_type = 3;
5170 stream->SetStats(stats);
5171 ASSERT_TRUE(channel_->GetStats(&info));
5172 EXPECT_STREQ("", info.receivers[0].codec_name.c_str());
5173}
5174
Seth Hampson5897a6e2018-04-03 11:16:33 -07005175// Tests that when we add a stream without SSRCs, but contains a stream_id
5176// that it is stored and its stream id is later used when the first packet
5177// arrives to properly create a receive stream with a sync label.
5178TEST_F(WebRtcVideoChannelTest, RecvUnsignaledSsrcWithSignaledStreamId) {
5179 const char kSyncLabel[] = "sync_label";
5180 cricket::StreamParams unsignaled_stream;
5181 unsignaled_stream.set_stream_ids({kSyncLabel});
5182 ASSERT_TRUE(channel_->AddRecvStream(unsignaled_stream));
5183 // The stream shouldn't have been created at this point because it doesn't
5184 // have any SSRCs.
Mirko Bonadeif859e552018-05-30 15:31:29 +02005185 EXPECT_EQ(0u, fake_call_->GetVideoReceiveStreams().size());
Seth Hampson5897a6e2018-04-03 11:16:33 -07005186
5187 // Create and deliver packet.
5188 const size_t kDataLength = 12;
5189 uint8_t data[kDataLength];
5190 memset(data, 0, sizeof(data));
5191 rtc::SetBE32(&data[8], kIncomingUnsignalledSsrc);
5192 rtc::CopyOnWriteBuffer packet(data, kDataLength);
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07005193 channel_->OnPacketReceived(packet, /* packet_time_us */ -1);
Seth Hampson5897a6e2018-04-03 11:16:33 -07005194
5195 // The stream should now be created with the appropriate sync label.
5196 EXPECT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
5197 EXPECT_EQ(kSyncLabel,
5198 fake_call_->GetVideoReceiveStreams()[0]->GetConfig().sync_group);
5199
5200 // Removing the unsignaled stream should clear the cache. This time when
5201 // a default video receive stream is created it won't have a sync_group.
5202 ASSERT_TRUE(channel_->RemoveRecvStream(0));
5203 ASSERT_TRUE(channel_->RemoveRecvStream(kIncomingUnsignalledSsrc));
5204 EXPECT_EQ(0u, fake_call_->GetVideoReceiveStreams().size());
5205
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07005206 channel_->OnPacketReceived(packet, /* packet_time_us */ -1);
Seth Hampson5897a6e2018-04-03 11:16:33 -07005207 EXPECT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
5208 EXPECT_TRUE(
5209 fake_call_->GetVideoReceiveStreams()[0]->GetConfig().sync_group.empty());
5210}
5211
Ruslan Burakov493a6502019-02-27 15:32:48 +01005212// Test BaseMinimumPlayoutDelayMs on receive streams.
5213TEST_F(WebRtcVideoChannelTest, BaseMinimumPlayoutDelayMs) {
5214 // Test that set won't work for non-existing receive streams.
5215 EXPECT_FALSE(channel_->SetBaseMinimumPlayoutDelayMs(kSsrc + 2, 200));
5216 // Test that get won't work for non-existing receive streams.
5217 EXPECT_FALSE(channel_->GetBaseMinimumPlayoutDelayMs(kSsrc + 2));
5218
5219 EXPECT_TRUE(AddRecvStream());
5220 // Test that set works for the existing receive stream.
5221 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(last_ssrc_, 200));
5222 auto* recv_stream = fake_call_->GetVideoReceiveStream(last_ssrc_);
5223 EXPECT_TRUE(recv_stream);
5224 EXPECT_EQ(recv_stream->base_mininum_playout_delay_ms(), 200);
5225 EXPECT_EQ(channel_->GetBaseMinimumPlayoutDelayMs(last_ssrc_).value_or(0),
5226 200);
5227}
5228
5229// Test BaseMinimumPlayoutDelayMs on unsignaled receive streams.
5230TEST_F(WebRtcVideoChannelTest, BaseMinimumPlayoutDelayMsUnsignaledRecvStream) {
5231 absl::optional<int> delay_ms;
5232 const FakeVideoReceiveStream* recv_stream;
5233
5234 // Set default stream with SSRC 0
5235 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(0, 200));
5236 EXPECT_EQ(200, channel_->GetBaseMinimumPlayoutDelayMs(0).value_or(0));
5237
5238 // Spawn an unsignaled stream by sending a packet, it should inherit
5239 // default delay 200.
5240 const size_t kDataLength = 12;
5241 uint8_t data[kDataLength];
5242 memset(data, 0, sizeof(data));
5243 rtc::SetBE32(&data[8], kIncomingUnsignalledSsrc);
5244 rtc::CopyOnWriteBuffer packet(data, kDataLength);
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07005245 channel_->OnPacketReceived(packet, /* packet_time_us */ -1);
Ruslan Burakov493a6502019-02-27 15:32:48 +01005246
5247 recv_stream = fake_call_->GetVideoReceiveStream(kIncomingUnsignalledSsrc);
5248 EXPECT_EQ(recv_stream->base_mininum_playout_delay_ms(), 200);
5249 delay_ms = channel_->GetBaseMinimumPlayoutDelayMs(kIncomingUnsignalledSsrc);
5250 EXPECT_EQ(200, delay_ms.value_or(0));
5251
5252 // Check that now if we change delay for SSRC 0 it will change delay for the
5253 // default receiving stream as well.
5254 EXPECT_TRUE(channel_->SetBaseMinimumPlayoutDelayMs(0, 300));
5255 EXPECT_EQ(300, channel_->GetBaseMinimumPlayoutDelayMs(0).value_or(0));
5256 delay_ms = channel_->GetBaseMinimumPlayoutDelayMs(kIncomingUnsignalledSsrc);
5257 EXPECT_EQ(300, delay_ms.value_or(0));
5258 recv_stream = fake_call_->GetVideoReceiveStream(kIncomingUnsignalledSsrc);
5259 EXPECT_EQ(recv_stream->base_mininum_playout_delay_ms(), 300);
5260}
5261
eladalonf1841382017-06-12 01:16:46 -07005262void WebRtcVideoChannelTest::TestReceiveUnsignaledSsrcPacket(
noahricd10a68e2015-07-10 11:27:55 -07005263 uint8_t payload_type,
5264 bool expect_created_receive_stream) {
magjed509e4fe2016-11-18 01:34:11 -08005265 // kRedRtxPayloadType must currently be unused.
5266 EXPECT_FALSE(FindCodecById(engine_.codecs(), kRedRtxPayloadType));
5267
noahricd10a68e2015-07-10 11:27:55 -07005268 // Add a RED RTX codec.
5269 VideoCodec red_rtx_codec =
magjed509e4fe2016-11-18 01:34:11 -08005270 VideoCodec::CreateRtxCodec(kRedRtxPayloadType, GetEngineCodec("red").id);
Fredrik Solenbergb071a192015-09-17 16:42:56 +02005271 recv_parameters_.codecs.push_back(red_rtx_codec);
5272 EXPECT_TRUE(channel_->SetRecvParameters(recv_parameters_));
noahricd10a68e2015-07-10 11:27:55 -07005273
5274 ASSERT_EQ(0u, fake_call_->GetVideoReceiveStreams().size());
5275 const size_t kDataLength = 12;
5276 uint8_t data[kDataLength];
5277 memset(data, 0, sizeof(data));
5278
5279 rtc::Set8(data, 1, payload_type);
5280 rtc::SetBE32(&data[8], kIncomingUnsignalledSsrc);
jbaucheec21bd2016-03-20 06:15:43 -07005281 rtc::CopyOnWriteBuffer packet(data, kDataLength);
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07005282 channel_->OnPacketReceived(packet, /* packet_time_us */ -1);
noahricd10a68e2015-07-10 11:27:55 -07005283
5284 if (expect_created_receive_stream) {
5285 EXPECT_EQ(1u, fake_call_->GetVideoReceiveStreams().size())
5286 << "Should have created a receive stream for payload type: "
5287 << payload_type;
5288 } else {
5289 EXPECT_EQ(0u, fake_call_->GetVideoReceiveStreams().size())
5290 << "Shouldn't have created a receive stream for payload type: "
5291 << payload_type;
5292 }
5293}
5294
Åsa Persson2c7149b2018-10-15 09:36:10 +02005295class WebRtcVideoChannelDiscardUnknownSsrcTest : public WebRtcVideoChannelTest {
5296 public:
5297 WebRtcVideoChannelDiscardUnknownSsrcTest()
5298 : WebRtcVideoChannelTest(
5299 "WebRTC-Video-DiscardPacketsWithUnknownSsrc/Enabled/") {}
5300};
5301
5302TEST_F(WebRtcVideoChannelDiscardUnknownSsrcTest, NoUnsignalledStreamCreated) {
5303 TestReceiveUnsignaledSsrcPacket(GetEngineCodec("VP8").id,
5304 false /* expect_created_receive_stream */);
5305}
5306
eladalonf1841382017-06-12 01:16:46 -07005307TEST_F(WebRtcVideoChannelTest, Vp8PacketCreatesUnsignalledStream) {
magjed509e4fe2016-11-18 01:34:11 -08005308 TestReceiveUnsignaledSsrcPacket(GetEngineCodec("VP8").id,
5309 true /* expect_created_receive_stream */);
noahricd10a68e2015-07-10 11:27:55 -07005310}
5311
eladalonf1841382017-06-12 01:16:46 -07005312TEST_F(WebRtcVideoChannelTest, Vp9PacketCreatesUnsignalledStream) {
magjed509e4fe2016-11-18 01:34:11 -08005313 TestReceiveUnsignaledSsrcPacket(GetEngineCodec("VP9").id,
5314 true /* expect_created_receive_stream */);
noahricd10a68e2015-07-10 11:27:55 -07005315}
5316
eladalonf1841382017-06-12 01:16:46 -07005317TEST_F(WebRtcVideoChannelTest, RtxPacketDoesntCreateUnsignalledStream) {
Anders Carlsson5f2bb622018-05-14 09:48:06 +02005318 AssignDefaultAptRtxTypes();
magjed509e4fe2016-11-18 01:34:11 -08005319 const cricket::VideoCodec vp8 = GetEngineCodec("VP8");
5320 const int rtx_vp8_payload_type = default_apt_rtx_types_[vp8.id];
5321 TestReceiveUnsignaledSsrcPacket(rtx_vp8_payload_type,
5322 false /* expect_created_receive_stream */);
noahricd10a68e2015-07-10 11:27:55 -07005323}
5324
eladalonf1841382017-06-12 01:16:46 -07005325TEST_F(WebRtcVideoChannelTest, UlpfecPacketDoesntCreateUnsignalledStream) {
magjed509e4fe2016-11-18 01:34:11 -08005326 TestReceiveUnsignaledSsrcPacket(GetEngineCodec("ulpfec").id,
5327 false /* expect_created_receive_stream */);
noahricd10a68e2015-07-10 11:27:55 -07005328}
5329
eladalonf1841382017-06-12 01:16:46 -07005330TEST_F(WebRtcVideoChannelFlexfecRecvTest,
brandtr468da7c2016-11-22 02:16:47 -08005331 FlexfecPacketDoesntCreateUnsignalledStream) {
5332 TestReceiveUnsignaledSsrcPacket(GetEngineCodec("flexfec-03").id,
5333 false /* expect_created_receive_stream */);
5334}
5335
eladalonf1841382017-06-12 01:16:46 -07005336TEST_F(WebRtcVideoChannelTest, RedRtxPacketDoesntCreateUnsignalledStream) {
magjed509e4fe2016-11-18 01:34:11 -08005337 TestReceiveUnsignaledSsrcPacket(kRedRtxPayloadType,
5338 false /* expect_created_receive_stream */);
noahricd10a68e2015-07-10 11:27:55 -07005339}
5340
mzanaty8a855d62017-02-17 15:46:43 -08005341// Test that receiving any unsignalled SSRC works even if it changes.
5342// The first unsignalled SSRC received will create a default receive stream.
5343// Any different unsignalled SSRC received will replace the default.
eladalonf1841382017-06-12 01:16:46 -07005344TEST_F(WebRtcVideoChannelTest, ReceiveDifferentUnsignaledSsrc) {
mzanaty8a855d62017-02-17 15:46:43 -08005345 // Allow receiving VP8, VP9, H264 (if enabled).
5346 cricket::VideoRecvParameters parameters;
5347 parameters.codecs.push_back(GetEngineCodec("VP8"));
5348 parameters.codecs.push_back(GetEngineCodec("VP9"));
5349
5350#if defined(WEBRTC_USE_H264)
5351 cricket::VideoCodec H264codec(126, "H264");
5352 parameters.codecs.push_back(H264codec);
5353#endif
5354
5355 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
5356 // No receive streams yet.
5357 ASSERT_EQ(0u, fake_call_->GetVideoReceiveStreams().size());
5358 cricket::FakeVideoRenderer renderer;
5359 EXPECT_TRUE(channel_->SetSink(kDefaultRecvSsrc, &renderer));
5360
5361 // Receive VP8 packet on first SSRC.
5362 uint8_t data[kMinRtpPacketLen];
5363 cricket::RtpHeader rtpHeader;
5364 rtpHeader.payload_type = GetEngineCodec("VP8").id;
5365 rtpHeader.seq_num = rtpHeader.timestamp = 0;
Yves Gerey665174f2018-06-19 15:03:05 +02005366 rtpHeader.ssrc = kIncomingUnsignalledSsrc + 1;
mzanaty8a855d62017-02-17 15:46:43 -08005367 cricket::SetRtpHeader(data, sizeof(data), rtpHeader);
5368 rtc::CopyOnWriteBuffer packet(data, sizeof(data));
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07005369 channel_->OnPacketReceived(packet, /* packet_time_us */ -1);
mzanaty8a855d62017-02-17 15:46:43 -08005370 // VP8 packet should create default receive stream.
5371 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
Yves Gerey665174f2018-06-19 15:03:05 +02005372 FakeVideoReceiveStream* recv_stream = fake_call_->GetVideoReceiveStreams()[0];
mzanaty8a855d62017-02-17 15:46:43 -08005373 EXPECT_EQ(rtpHeader.ssrc, recv_stream->GetConfig().rtp.remote_ssrc);
5374 // Verify that the receive stream sinks to a renderer.
Artem Titov1ebfb6a2019-01-03 23:49:37 +01005375 webrtc::VideoFrame video_frame =
5376 webrtc::VideoFrame::Builder()
5377 .set_video_frame_buffer(CreateBlackFrameBuffer(4, 4))
5378 .set_timestamp_rtp(100)
5379 .set_timestamp_us(0)
5380 .set_rotation(webrtc::kVideoRotation_0)
5381 .build();
mzanaty8a855d62017-02-17 15:46:43 -08005382 recv_stream->InjectFrame(video_frame);
5383 EXPECT_EQ(1, renderer.num_rendered_frames());
5384
5385 // Receive VP9 packet on second SSRC.
5386 rtpHeader.payload_type = GetEngineCodec("VP9").id;
Yves Gerey665174f2018-06-19 15:03:05 +02005387 rtpHeader.ssrc = kIncomingUnsignalledSsrc + 2;
mzanaty8a855d62017-02-17 15:46:43 -08005388 cricket::SetRtpHeader(data, sizeof(data), rtpHeader);
5389 rtc::CopyOnWriteBuffer packet2(data, sizeof(data));
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07005390 channel_->OnPacketReceived(packet2, /* packet_time_us */ -1);
mzanaty8a855d62017-02-17 15:46:43 -08005391 // VP9 packet should replace the default receive SSRC.
5392 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
5393 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
5394 EXPECT_EQ(rtpHeader.ssrc, recv_stream->GetConfig().rtp.remote_ssrc);
5395 // Verify that the receive stream sinks to a renderer.
Artem Titov1ebfb6a2019-01-03 23:49:37 +01005396 webrtc::VideoFrame video_frame2 =
5397 webrtc::VideoFrame::Builder()
5398 .set_video_frame_buffer(CreateBlackFrameBuffer(4, 4))
5399 .set_timestamp_rtp(200)
5400 .set_timestamp_us(0)
5401 .set_rotation(webrtc::kVideoRotation_0)
5402 .build();
mzanaty8a855d62017-02-17 15:46:43 -08005403 recv_stream->InjectFrame(video_frame2);
5404 EXPECT_EQ(2, renderer.num_rendered_frames());
5405
5406#if defined(WEBRTC_USE_H264)
5407 // Receive H264 packet on third SSRC.
5408 rtpHeader.payload_type = 126;
Yves Gerey665174f2018-06-19 15:03:05 +02005409 rtpHeader.ssrc = kIncomingUnsignalledSsrc + 3;
mzanaty8a855d62017-02-17 15:46:43 -08005410 cricket::SetRtpHeader(data, sizeof(data), rtpHeader);
5411 rtc::CopyOnWriteBuffer packet3(data, sizeof(data));
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07005412 channel_->OnPacketReceived(packet3, /* packet_time_us */ -1);
mzanaty8a855d62017-02-17 15:46:43 -08005413 // H264 packet should replace the default receive SSRC.
5414 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
5415 recv_stream = fake_call_->GetVideoReceiveStreams()[0];
5416 EXPECT_EQ(rtpHeader.ssrc, recv_stream->GetConfig().rtp.remote_ssrc);
5417 // Verify that the receive stream sinks to a renderer.
Artem Titov1ebfb6a2019-01-03 23:49:37 +01005418 webrtc::VideoFrame video_frame3 =
5419 webrtc::VideoFrame::Builder()
5420 .set_video_frame_buffer(CreateBlackFrameBuffer(4, 4))
5421 .set_timestamp_rtp(300)
5422 .set_timestamp_us(0)
5423 .set_rotation(webrtc::kVideoRotation_0)
5424 .build();
mzanaty8a855d62017-02-17 15:46:43 -08005425 recv_stream->InjectFrame(video_frame3);
5426 EXPECT_EQ(3, renderer.num_rendered_frames());
5427#endif
5428}
5429
brandtr0dc57ea2017-05-29 23:33:31 -07005430// This test verifies that when a new default stream is created for a new
5431// unsignaled SSRC, the new stream does not overwrite any old stream that had
5432// been the default receive stream before being properly signaled.
eladalonf1841382017-06-12 01:16:46 -07005433TEST_F(WebRtcVideoChannelTest,
brandtr0dc57ea2017-05-29 23:33:31 -07005434 NewUnsignaledStreamDoesNotDestroyPreviouslyUnsignaledStream) {
5435 cricket::VideoRecvParameters parameters;
5436 parameters.codecs.push_back(GetEngineCodec("VP8"));
5437 ASSERT_TRUE(channel_->SetRecvParameters(parameters));
5438
5439 // No streams signaled and no packets received, so we should not have any
5440 // stream objects created yet.
5441 EXPECT_EQ(0u, fake_call_->GetVideoReceiveStreams().size());
5442
5443 // Receive packet on an unsignaled SSRC.
5444 uint8_t data[kMinRtpPacketLen];
5445 cricket::RtpHeader rtp_header;
5446 rtp_header.payload_type = GetEngineCodec("VP8").id;
5447 rtp_header.seq_num = rtp_header.timestamp = 0;
5448 rtp_header.ssrc = kSsrcs3[0];
5449 cricket::SetRtpHeader(data, sizeof(data), rtp_header);
5450 rtc::CopyOnWriteBuffer packet(data, sizeof(data));
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07005451 channel_->OnPacketReceived(packet, /* packet_time_us */ -1);
brandtr0dc57ea2017-05-29 23:33:31 -07005452 // Default receive stream should be created.
5453 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
5454 FakeVideoReceiveStream* recv_stream0 =
5455 fake_call_->GetVideoReceiveStreams()[0];
5456 EXPECT_EQ(kSsrcs3[0], recv_stream0->GetConfig().rtp.remote_ssrc);
5457
5458 // Signal the SSRC.
5459 EXPECT_TRUE(
5460 channel_->AddRecvStream(cricket::StreamParams::CreateLegacy(kSsrcs3[0])));
5461 ASSERT_EQ(1u, fake_call_->GetVideoReceiveStreams().size());
5462 recv_stream0 = fake_call_->GetVideoReceiveStreams()[0];
5463 EXPECT_EQ(kSsrcs3[0], recv_stream0->GetConfig().rtp.remote_ssrc);
5464
5465 // Receive packet on a different unsignaled SSRC.
5466 rtp_header.ssrc = kSsrcs3[1];
5467 cricket::SetRtpHeader(data, sizeof(data), rtp_header);
5468 packet.SetData(data, sizeof(data));
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07005469 channel_->OnPacketReceived(packet, /* packet_time_us */ -1);
brandtr0dc57ea2017-05-29 23:33:31 -07005470 // New default receive stream should be created, but old stream should remain.
5471 ASSERT_EQ(2u, fake_call_->GetVideoReceiveStreams().size());
5472 EXPECT_EQ(recv_stream0, fake_call_->GetVideoReceiveStreams()[0]);
5473 FakeVideoReceiveStream* recv_stream1 =
5474 fake_call_->GetVideoReceiveStreams()[1];
5475 EXPECT_EQ(kSsrcs3[1], recv_stream1->GetConfig().rtp.remote_ssrc);
5476}
5477
Seth Hampson7c682e02018-05-04 16:28:15 -07005478TEST_F(WebRtcVideoChannelTest, CanSetMaxBitrateForExistingStream) {
skvladdc1c62c2016-03-16 19:07:43 -07005479 AddSendStream();
5480
Niels Möller805a27e2019-01-21 12:21:27 +01005481 webrtc::test::FrameForwarder frame_forwarder;
5482 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));
skvladdc1c62c2016-03-16 19:07:43 -07005483 EXPECT_TRUE(channel_->SetSend(true));
Niels Möller805a27e2019-01-21 12:21:27 +01005484 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
skvladdc1c62c2016-03-16 19:07:43 -07005485
perkjfa10b552016-10-02 23:45:26 -07005486 int default_encoder_bitrate = GetMaxEncoderBitrate();
brandtr468da7c2016-11-22 02:16:47 -08005487 EXPECT_GT(default_encoder_bitrate, 1000);
skvladdc1c62c2016-03-16 19:07:43 -07005488
5489 // TODO(skvlad): Resolve the inconsistency between the interpretation
5490 // of the global bitrate limit for audio and video:
5491 // - Audio: max_bandwidth_bps = 0 - fail the operation,
5492 // max_bandwidth_bps = -1 - remove the bandwidth limit
5493 // - Video: max_bandwidth_bps = 0 - remove the bandwidth limit,
pbos5c7760a2017-03-10 11:23:12 -08005494 // max_bandwidth_bps = -1 - remove the bandwidth limit
skvladdc1c62c2016-03-16 19:07:43 -07005495
perkjfa10b552016-10-02 23:45:26 -07005496 SetAndExpectMaxBitrate(1000, 0, 1000);
5497 SetAndExpectMaxBitrate(1000, 800, 800);
5498 SetAndExpectMaxBitrate(600, 800, 600);
5499 SetAndExpectMaxBitrate(0, 800, 800);
5500 SetAndExpectMaxBitrate(0, 0, default_encoder_bitrate);
skvladdc1c62c2016-03-16 19:07:43 -07005501
Niels Möllerff40b142018-04-09 08:49:14 +02005502 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
skvladdc1c62c2016-03-16 19:07:43 -07005503}
5504
eladalonf1841382017-06-12 01:16:46 -07005505TEST_F(WebRtcVideoChannelTest, CannotSetMaxBitrateForNonexistentStream) {
skvladdc1c62c2016-03-16 19:07:43 -07005506 webrtc::RtpParameters nonexistent_parameters =
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07005507 channel_->GetRtpSendParameters(last_ssrc_);
Mirko Bonadeif859e552018-05-30 15:31:29 +02005508 EXPECT_EQ(0u, nonexistent_parameters.encodings.size());
skvladdc1c62c2016-03-16 19:07:43 -07005509
5510 nonexistent_parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07005511 EXPECT_FALSE(
Zach Steinba37b4b2018-01-23 15:02:36 -08005512 channel_->SetRtpSendParameters(last_ssrc_, nonexistent_parameters).ok());
skvladdc1c62c2016-03-16 19:07:43 -07005513}
5514
eladalonf1841382017-06-12 01:16:46 -07005515TEST_F(WebRtcVideoChannelTest,
Seth Hampson7c682e02018-05-04 16:28:15 -07005516 SetLowMaxBitrateOverwritesVideoStreamMinBitrate) {
Åsa Perssonbdee46d2018-06-25 11:28:06 +02005517 FakeVideoSendStream* stream = AddSendStream();
5518
Seth Hampson7c682e02018-05-04 16:28:15 -07005519 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
5520 EXPECT_EQ(1UL, parameters.encodings.size());
5521 EXPECT_FALSE(parameters.encodings[0].max_bitrate_bps.has_value());
5522 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
5523
5524 // Note that this is testing the behavior of the FakeVideoSendStream, which
5525 // also calls to CreateEncoderStreams to get the VideoStreams, so essentially
5526 // we are just testing the behavior of
5527 // EncoderStreamFactory::CreateEncoderStreams.
Åsa Perssonbdee46d2018-06-25 11:28:06 +02005528 ASSERT_EQ(1UL, stream->GetVideoStreams().size());
5529 EXPECT_EQ(kMinVideoBitrateBps, stream->GetVideoStreams()[0].min_bitrate_bps);
Seth Hampson7c682e02018-05-04 16:28:15 -07005530
5531 // Set a low max bitrate & check that VideoStream.min_bitrate_bps is limited
5532 // by this amount.
5533 parameters = channel_->GetRtpSendParameters(last_ssrc_);
5534 int low_max_bitrate_bps = kMinVideoBitrateBps - 1000;
5535 parameters.encodings[0].max_bitrate_bps = low_max_bitrate_bps;
5536 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
5537
Åsa Perssonbdee46d2018-06-25 11:28:06 +02005538 ASSERT_EQ(1UL, stream->GetVideoStreams().size());
5539 EXPECT_EQ(low_max_bitrate_bps, stream->GetVideoStreams()[0].min_bitrate_bps);
5540 EXPECT_EQ(low_max_bitrate_bps, stream->GetVideoStreams()[0].max_bitrate_bps);
5541}
5542
5543TEST_F(WebRtcVideoChannelTest,
5544 SetHighMinBitrateOverwritesVideoStreamMaxBitrate) {
5545 FakeVideoSendStream* stream = AddSendStream();
5546
5547 // Note that this is testing the behavior of the FakeVideoSendStream, which
5548 // also calls to CreateEncoderStreams to get the VideoStreams, so essentially
5549 // we are just testing the behavior of
5550 // EncoderStreamFactory::CreateEncoderStreams.
5551 ASSERT_EQ(1UL, stream->GetVideoStreams().size());
5552 int high_min_bitrate_bps = stream->GetVideoStreams()[0].max_bitrate_bps + 1;
5553
5554 // Set a high min bitrate and check that max_bitrate_bps is adjusted up.
5555 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
5556 EXPECT_EQ(1UL, parameters.encodings.size());
5557 parameters.encodings[0].min_bitrate_bps = high_min_bitrate_bps;
5558 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
5559
5560 ASSERT_EQ(1UL, stream->GetVideoStreams().size());
5561 EXPECT_EQ(high_min_bitrate_bps, stream->GetVideoStreams()[0].min_bitrate_bps);
5562 EXPECT_EQ(high_min_bitrate_bps, stream->GetVideoStreams()[0].max_bitrate_bps);
5563}
5564
5565TEST_F(WebRtcVideoChannelTest,
5566 SetMinBitrateAboveMaxBitrateLimitAdjustsMinBitrateDown) {
5567 send_parameters_.max_bandwidth_bps = 99999;
5568 FakeVideoSendStream* stream = AddSendStream();
5569 ExpectSetMaxBitrate(send_parameters_.max_bandwidth_bps);
5570 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
5571 ASSERT_EQ(1UL, stream->GetVideoStreams().size());
5572 EXPECT_EQ(kMinVideoBitrateBps, stream->GetVideoStreams()[0].min_bitrate_bps);
5573 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
5574 stream->GetVideoStreams()[0].max_bitrate_bps);
5575
5576 // Set min bitrate above global max bitrate and check that min_bitrate_bps is
5577 // adjusted down.
5578 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
5579 EXPECT_EQ(1UL, parameters.encodings.size());
5580 parameters.encodings[0].min_bitrate_bps = 99999 + 1;
5581 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
5582 ASSERT_EQ(1UL, stream->GetVideoStreams().size());
5583 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
5584 stream->GetVideoStreams()[0].min_bitrate_bps);
5585 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
5586 stream->GetVideoStreams()[0].max_bitrate_bps);
Seth Hampson7c682e02018-05-04 16:28:15 -07005587}
5588
Åsa Persson8c1bf952018-09-13 10:42:19 +02005589TEST_F(WebRtcVideoChannelTest, SetMaxFramerateOneStream) {
5590 FakeVideoSendStream* stream = AddSendStream();
5591
5592 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
5593 EXPECT_EQ(1UL, parameters.encodings.size());
5594 EXPECT_FALSE(parameters.encodings[0].max_framerate.has_value());
5595 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
5596
5597 // Note that this is testing the behavior of the FakeVideoSendStream, which
5598 // also calls to CreateEncoderStreams to get the VideoStreams, so essentially
5599 // we are just testing the behavior of
5600 // EncoderStreamFactory::CreateEncoderStreams.
5601 ASSERT_EQ(1UL, stream->GetVideoStreams().size());
5602 EXPECT_EQ(kDefaultVideoMaxFramerate,
5603 stream->GetVideoStreams()[0].max_framerate);
5604
5605 // Set max framerate and check that VideoStream.max_framerate is set.
5606 const int kNewMaxFramerate = kDefaultVideoMaxFramerate - 1;
5607 parameters = channel_->GetRtpSendParameters(last_ssrc_);
5608 parameters.encodings[0].max_framerate = kNewMaxFramerate;
5609 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
5610
5611 ASSERT_EQ(1UL, stream->GetVideoStreams().size());
5612 EXPECT_EQ(kNewMaxFramerate, stream->GetVideoStreams()[0].max_framerate);
5613}
5614
Åsa Persson23eba222018-10-02 14:47:06 +02005615TEST_F(WebRtcVideoChannelTest, SetNumTemporalLayersForSingleStream) {
5616 FakeVideoSendStream* stream = AddSendStream();
5617
5618 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
5619 EXPECT_EQ(1UL, parameters.encodings.size());
5620 EXPECT_FALSE(parameters.encodings[0].num_temporal_layers.has_value());
5621 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
5622
5623 // Note that this is testing the behavior of the FakeVideoSendStream, which
5624 // also calls to CreateEncoderStreams to get the VideoStreams, so essentially
5625 // we are just testing the behavior of
5626 // EncoderStreamFactory::CreateEncoderStreams.
5627 ASSERT_EQ(1UL, stream->GetVideoStreams().size());
5628 EXPECT_FALSE(stream->GetVideoStreams()[0].num_temporal_layers.has_value());
5629
5630 // Set temporal layers and check that VideoStream.num_temporal_layers is set.
5631 parameters = channel_->GetRtpSendParameters(last_ssrc_);
5632 parameters.encodings[0].num_temporal_layers = 2;
5633 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
5634
5635 ASSERT_EQ(1UL, stream->GetVideoStreams().size());
5636 EXPECT_EQ(2UL, stream->GetVideoStreams()[0].num_temporal_layers);
5637}
5638
Seth Hampson7c682e02018-05-04 16:28:15 -07005639TEST_F(WebRtcVideoChannelTest,
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07005640 CannotSetRtpSendParametersWithIncorrectNumberOfEncodings) {
skvladdc1c62c2016-03-16 19:07:43 -07005641 AddSendStream();
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07005642 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
skvladdc1c62c2016-03-16 19:07:43 -07005643 // Two or more encodings should result in failure.
5644 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08005645 EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08005646 // Zero encodings should also fail.
5647 parameters.encodings.clear();
Zach Steinba37b4b2018-01-23 15:02:36 -08005648 EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
deadbeeffb2aced2017-01-06 23:05:37 -08005649}
5650
Zach Stein3ca452b2018-01-18 10:01:24 -08005651TEST_F(WebRtcVideoChannelTest,
5652 CannotSetSimulcastRtpSendParametersWithIncorrectNumberOfEncodings) {
5653 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
5654 StreamParams sp = CreateSimStreamParams("cname", ssrcs);
5655 AddSendStream(sp);
5656
5657 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
5658
5659 // Additional encodings should result in failure.
5660 parameters.encodings.push_back(webrtc::RtpEncodingParameters());
Zach Steinba37b4b2018-01-23 15:02:36 -08005661 EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
Zach Stein3ca452b2018-01-18 10:01:24 -08005662 // Zero encodings should also fail.
5663 parameters.encodings.clear();
Zach Steinba37b4b2018-01-23 15:02:36 -08005664 EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
Zach Stein3ca452b2018-01-18 10:01:24 -08005665}
5666
deadbeeffb2aced2017-01-06 23:05:37 -08005667// Changing the SSRC through RtpParameters is not allowed.
eladalonf1841382017-06-12 01:16:46 -07005668TEST_F(WebRtcVideoChannelTest, CannotSetSsrcInRtpSendParameters) {
deadbeeffb2aced2017-01-06 23:05:37 -08005669 AddSendStream();
5670 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
Oskar Sundbom78807582017-11-16 11:09:55 +01005671 parameters.encodings[0].ssrc = 0xdeadbeef;
Zach Steinba37b4b2018-01-23 15:02:36 -08005672 EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
skvladdc1c62c2016-03-16 19:07:43 -07005673}
5674
Seth Hampson24722b32017-12-22 09:36:42 -08005675// Tests that when RTCRtpEncodingParameters.bitrate_priority gets set to
5676// a value <= 0, setting the parameters returns false.
5677TEST_F(WebRtcVideoChannelTest, SetRtpSendParametersInvalidBitratePriority) {
5678 AddSendStream();
5679 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
5680 EXPECT_EQ(1UL, parameters.encodings.size());
5681 EXPECT_EQ(webrtc::kDefaultBitratePriority,
5682 parameters.encodings[0].bitrate_priority);
5683
5684 parameters.encodings[0].bitrate_priority = 0;
Zach Steinba37b4b2018-01-23 15:02:36 -08005685 EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08005686 parameters.encodings[0].bitrate_priority = -2;
Zach Steinba37b4b2018-01-23 15:02:36 -08005687 EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08005688}
5689
5690// Tests when the the RTCRtpEncodingParameters.bitrate_priority gets set
5691// properly on the VideoChannel and propogates down to the video encoder.
5692TEST_F(WebRtcVideoChannelTest, SetRtpSendParametersPriorityOneStream) {
5693 AddSendStream();
5694 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
5695 EXPECT_EQ(1UL, parameters.encodings.size());
5696 EXPECT_EQ(webrtc::kDefaultBitratePriority,
5697 parameters.encodings[0].bitrate_priority);
5698
5699 // Change the value and set it on the VideoChannel.
5700 double new_bitrate_priority = 2.0;
5701 parameters.encodings[0].bitrate_priority = new_bitrate_priority;
Zach Steinba37b4b2018-01-23 15:02:36 -08005702 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08005703
5704 // Verify that the encoding parameters bitrate_priority is set for the
5705 // VideoChannel.
5706 parameters = channel_->GetRtpSendParameters(last_ssrc_);
5707 EXPECT_EQ(1UL, parameters.encodings.size());
5708 EXPECT_EQ(new_bitrate_priority, parameters.encodings[0].bitrate_priority);
5709
5710 // Verify that the new value propagated down to the encoder.
5711 std::vector<FakeVideoSendStream*> video_send_streams =
5712 fake_call_->GetVideoSendStreams();
5713 EXPECT_EQ(1UL, video_send_streams.size());
5714 FakeVideoSendStream* video_send_stream = video_send_streams.front();
5715 // Check that the WebRtcVideoSendStream updated the VideoEncoderConfig
5716 // appropriately.
5717 EXPECT_EQ(new_bitrate_priority,
5718 video_send_stream->GetEncoderConfig().bitrate_priority);
5719 // Check that the vector of VideoStreams also was propagated correctly. Note
5720 // that this is testing the behavior of the FakeVideoSendStream, which mimics
5721 // the calls to CreateEncoderStreams to get the VideoStreams.
Danil Chapovalov00c71832018-06-15 15:58:38 +02005722 EXPECT_EQ(absl::optional<double>(new_bitrate_priority),
Seth Hampson24722b32017-12-22 09:36:42 -08005723 video_send_stream->GetVideoStreams()[0].bitrate_priority);
5724}
5725
5726// Tests that the RTCRtpEncodingParameters.bitrate_priority is set for the
5727// VideoChannel and the value propogates to the video encoder with all simulcast
5728// streams.
5729TEST_F(WebRtcVideoChannelTest, SetRtpSendParametersPrioritySimulcastStreams) {
5730 // Create the stream params with multiple ssrcs for simulcast.
Åsa Persson31cb8f92018-06-27 10:44:56 +02005731 const size_t kNumSimulcastStreams = 3;
Seth Hampson24722b32017-12-22 09:36:42 -08005732 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
5733 StreamParams stream_params = CreateSimStreamParams("cname", ssrcs);
5734 AddSendStream(stream_params);
5735 uint32_t primary_ssrc = stream_params.first_ssrc();
5736
Niels Möller805a27e2019-01-21 12:21:27 +01005737 // Using the FrameForwarder, we manually send a full size
Tommi85959932018-02-07 19:26:06 +01005738 // frame. This creates multiple VideoStreams for all simulcast layers when
5739 // reconfiguring, and allows us to test this behavior.
Niels Möller805a27e2019-01-21 12:21:27 +01005740 webrtc::test::FrameForwarder frame_forwarder;
Seth Hampson24722b32017-12-22 09:36:42 -08005741 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01005742 EXPECT_TRUE(channel_->SetVideoSend(primary_ssrc, &options, &frame_forwarder));
Seth Hampson24722b32017-12-22 09:36:42 -08005743 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01005744 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame(
5745 1920, 1080, webrtc::VideoRotation::kVideoRotation_0,
5746 rtc::kNumMicrosecsPerSec / 30));
5747
Seth Hampson24722b32017-12-22 09:36:42 -08005748 // Get and set the rtp encoding parameters.
5749 webrtc::RtpParameters parameters =
5750 channel_->GetRtpSendParameters(primary_ssrc);
Åsa Persson31cb8f92018-06-27 10:44:56 +02005751 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
Seth Hampson24722b32017-12-22 09:36:42 -08005752 EXPECT_EQ(webrtc::kDefaultBitratePriority,
5753 parameters.encodings[0].bitrate_priority);
5754 // Change the value and set it on the VideoChannel.
5755 double new_bitrate_priority = 2.0;
5756 parameters.encodings[0].bitrate_priority = new_bitrate_priority;
Zach Steinba37b4b2018-01-23 15:02:36 -08005757 EXPECT_TRUE(channel_->SetRtpSendParameters(primary_ssrc, parameters).ok());
Seth Hampson24722b32017-12-22 09:36:42 -08005758
5759 // Verify that the encoding parameters priority is set on the VideoChannel.
5760 parameters = channel_->GetRtpSendParameters(primary_ssrc);
Åsa Persson31cb8f92018-06-27 10:44:56 +02005761 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
Seth Hampson24722b32017-12-22 09:36:42 -08005762 EXPECT_EQ(new_bitrate_priority, parameters.encodings[0].bitrate_priority);
5763
5764 // Verify that the new value propagated down to the encoder.
5765 std::vector<FakeVideoSendStream*> video_send_streams =
5766 fake_call_->GetVideoSendStreams();
5767 EXPECT_EQ(1UL, video_send_streams.size());
5768 FakeVideoSendStream* video_send_stream = video_send_streams.front();
5769 // Check that the WebRtcVideoSendStream updated the VideoEncoderConfig
5770 // appropriately.
Åsa Persson31cb8f92018-06-27 10:44:56 +02005771 EXPECT_EQ(kNumSimulcastStreams,
Seth Hampson24722b32017-12-22 09:36:42 -08005772 video_send_stream->GetEncoderConfig().number_of_streams);
5773 EXPECT_EQ(new_bitrate_priority,
5774 video_send_stream->GetEncoderConfig().bitrate_priority);
5775 // Check that the vector of VideoStreams also propagated correctly. The
5776 // FakeVideoSendStream calls CreateEncoderStreams, and we are testing that
5777 // these are created appropriately for the simulcast case.
Åsa Persson31cb8f92018-06-27 10:44:56 +02005778 EXPECT_EQ(kNumSimulcastStreams, video_send_stream->GetVideoStreams().size());
Danil Chapovalov00c71832018-06-15 15:58:38 +02005779 EXPECT_EQ(absl::optional<double>(new_bitrate_priority),
Seth Hampson24722b32017-12-22 09:36:42 -08005780 video_send_stream->GetVideoStreams()[0].bitrate_priority);
5781 // Since we are only setting bitrate priority per-sender, the other
5782 // VideoStreams should have a bitrate priority of 0.
Danil Chapovalov00c71832018-06-15 15:58:38 +02005783 EXPECT_EQ(absl::nullopt,
Seth Hampson24722b32017-12-22 09:36:42 -08005784 video_send_stream->GetVideoStreams()[1].bitrate_priority);
Danil Chapovalov00c71832018-06-15 15:58:38 +02005785 EXPECT_EQ(absl::nullopt,
Seth Hampson24722b32017-12-22 09:36:42 -08005786 video_send_stream->GetVideoStreams()[2].bitrate_priority);
Niels Möllerff40b142018-04-09 08:49:14 +02005787 EXPECT_TRUE(channel_->SetVideoSend(primary_ssrc, nullptr, nullptr));
Seth Hampson24722b32017-12-22 09:36:42 -08005788}
5789
Tim Haloun648d28a2018-10-18 16:52:22 -07005790// RTCRtpEncodingParameters.network_priority must be one of a few values
5791// derived from the default priority, corresponding to very-low, low, medium,
5792// or high.
5793TEST_F(WebRtcVideoChannelTest, SetRtpSendParametersInvalidNetworkPriority) {
5794 AddSendStream();
5795 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
5796 EXPECT_EQ(1UL, parameters.encodings.size());
5797 EXPECT_EQ(webrtc::kDefaultBitratePriority,
5798 parameters.encodings[0].network_priority);
5799
5800 double good_values[] = {0.5, 1.0, 2.0, 4.0};
5801 double bad_values[] = {-1.0, 0.0, 0.49, 0.51, 1.1, 3.99, 4.1, 5.0};
5802 for (auto it : good_values) {
5803 parameters.encodings[0].network_priority = it;
5804 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
5805 }
5806 for (auto it : bad_values) {
5807 parameters.encodings[0].network_priority = it;
5808 EXPECT_FALSE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
5809 }
5810}
5811
Florent Castellic1a0bcb2019-01-29 14:26:48 +01005812TEST_F(WebRtcVideoChannelTest,
5813 GetAndSetRtpSendParametersScaleResolutionDownByVP8) {
Rasmus Brandt9387b522019-02-05 14:23:26 +01005814 VideoSendParameters parameters;
5815 parameters.codecs.push_back(VideoCodec(kVp8CodecName));
Florent Castellic1a0bcb2019-01-29 14:26:48 +01005816 ASSERT_TRUE(channel_->SetSendParameters(parameters));
5817 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
5818
5819 webrtc::test::FrameForwarder frame_forwarder;
Rasmus Brandt9387b522019-02-05 14:23:26 +01005820 FakeFrameSource frame_source(1280, 720, rtc::kNumMicrosecsPerSec / 30);
Florent Castellic1a0bcb2019-01-29 14:26:48 +01005821
5822 VideoOptions options;
5823 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
5824 channel_->SetSend(true);
5825
5826 // Try layers in natural order (smallest to largest).
5827 {
5828 auto rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
5829 ASSERT_EQ(3u, rtp_parameters.encodings.size());
5830 rtp_parameters.encodings[0].scale_resolution_down_by = 4.0;
5831 rtp_parameters.encodings[1].scale_resolution_down_by = 2.0;
5832 rtp_parameters.encodings[2].scale_resolution_down_by = 1.0;
5833 auto result = channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
5834 ASSERT_TRUE(result.ok());
5835
5836 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
5837
5838 std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
5839 ASSERT_EQ(3u, video_streams.size());
5840 EXPECT_EQ(320u, video_streams[0].width);
5841 EXPECT_EQ(180u, video_streams[0].height);
5842 EXPECT_EQ(640u, video_streams[1].width);
5843 EXPECT_EQ(360u, video_streams[1].height);
5844 EXPECT_EQ(1280u, video_streams[2].width);
5845 EXPECT_EQ(720u, video_streams[2].height);
5846 }
5847
5848 // Try layers in reverse natural order (largest to smallest).
5849 {
5850 auto rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
5851 ASSERT_EQ(3u, rtp_parameters.encodings.size());
5852 rtp_parameters.encodings[0].scale_resolution_down_by = 1.0;
5853 rtp_parameters.encodings[1].scale_resolution_down_by = 2.0;
5854 rtp_parameters.encodings[2].scale_resolution_down_by = 4.0;
5855 auto result = channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
5856 ASSERT_TRUE(result.ok());
5857
5858 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
5859
5860 std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
5861 ASSERT_EQ(3u, video_streams.size());
5862 EXPECT_EQ(1280u, video_streams[0].width);
5863 EXPECT_EQ(720u, video_streams[0].height);
5864 EXPECT_EQ(640u, video_streams[1].width);
5865 EXPECT_EQ(360u, video_streams[1].height);
5866 EXPECT_EQ(320u, video_streams[2].width);
5867 EXPECT_EQ(180u, video_streams[2].height);
5868 }
5869
5870 // Try layers in mixed order.
5871 {
5872 auto rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
5873 ASSERT_EQ(3u, rtp_parameters.encodings.size());
5874 rtp_parameters.encodings[0].scale_resolution_down_by = 10.0;
5875 rtp_parameters.encodings[1].scale_resolution_down_by = 2.0;
5876 rtp_parameters.encodings[2].scale_resolution_down_by = 4.0;
5877 auto result = channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
5878 ASSERT_TRUE(result.ok());
5879
5880 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
5881
5882 std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
5883 ASSERT_EQ(3u, video_streams.size());
5884 EXPECT_EQ(128u, video_streams[0].width);
5885 EXPECT_EQ(72u, video_streams[0].height);
5886 EXPECT_EQ(640u, video_streams[1].width);
5887 EXPECT_EQ(360u, video_streams[1].height);
5888 EXPECT_EQ(320u, video_streams[2].width);
5889 EXPECT_EQ(180u, video_streams[2].height);
5890 }
5891
5892 // Try with a missing scale setting, defaults to 1.0 if any other is set.
5893 {
5894 auto rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
5895 ASSERT_EQ(3u, rtp_parameters.encodings.size());
5896 rtp_parameters.encodings[0].scale_resolution_down_by = 1.0;
5897 rtp_parameters.encodings[1].scale_resolution_down_by.reset();
5898 rtp_parameters.encodings[2].scale_resolution_down_by = 4.0;
5899 auto result = channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
5900 ASSERT_TRUE(result.ok());
5901
5902 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
5903
5904 std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
5905 ASSERT_EQ(3u, video_streams.size());
5906 EXPECT_EQ(1280u, video_streams[0].width);
5907 EXPECT_EQ(720u, video_streams[0].height);
5908 EXPECT_EQ(1280u, video_streams[1].width);
5909 EXPECT_EQ(720u, video_streams[1].height);
5910 EXPECT_EQ(320u, video_streams[2].width);
5911 EXPECT_EQ(180u, video_streams[2].height);
5912 }
5913
5914 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
5915}
5916
5917TEST_F(WebRtcVideoChannelTest,
Rasmus Brandt9387b522019-02-05 14:23:26 +01005918 GetAndSetRtpSendParametersScaleResolutionDownByVP8WithOddResolution) {
5919 // Ensure that the top layer has width and height divisible by 2^3,
5920 // so that the bottom layer has width and height divisible by 2.
5921 // TODO(bugs.webrtc.org/8785): Remove this field trial when we fully trust
5922 // the number of simulcast layers set by the app.
5923 webrtc::test::ScopedFieldTrials field_trial(
5924 "WebRTC-NormalizeSimulcastResolution/Enabled-3/");
5925
5926 // Set up WebRtcVideoChannel for 3-layer VP8 simulcast.
5927 VideoSendParameters parameters;
5928 parameters.codecs.push_back(VideoCodec(kVp8CodecName));
5929 ASSERT_TRUE(channel_->SetSendParameters(parameters));
5930 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
5931 webrtc::test::FrameForwarder frame_forwarder;
5932 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, /*options=*/nullptr,
5933 &frame_forwarder));
5934 channel_->SetSend(true);
5935
5936 // Set |scale_resolution_down_by|'s.
5937 auto rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
5938 ASSERT_EQ(rtp_parameters.encodings.size(), 3u);
5939 rtp_parameters.encodings[0].scale_resolution_down_by = 1.0;
5940 rtp_parameters.encodings[1].scale_resolution_down_by = 2.0;
5941 rtp_parameters.encodings[2].scale_resolution_down_by = 4.0;
5942 const auto result =
5943 channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
5944 ASSERT_TRUE(result.ok());
5945
5946 // Use a capture resolution whose width and height are not divisible by 2^3.
5947 // (See field trial set at the top of the test.)
5948 FakeFrameSource frame_source(2007, 1207, rtc::kNumMicrosecsPerSec / 30);
5949 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
5950
5951 // Ensure the scaling is correct.
5952 const auto video_streams = stream->GetVideoStreams();
5953 ASSERT_EQ(video_streams.size(), 3u);
5954 // Ensure that we round the capture resolution down for the top layer...
5955 EXPECT_EQ(video_streams[0].width, 2000u);
5956 EXPECT_EQ(video_streams[0].height, 1200u);
5957 EXPECT_EQ(video_streams[1].width, 1000u);
5958 EXPECT_EQ(video_streams[1].height, 600u);
5959 // ...and that the bottom layer has a width/height divisible by 2.
5960 EXPECT_EQ(video_streams[2].width, 500u);
5961 EXPECT_EQ(video_streams[2].height, 300u);
5962
5963 // Tear down.
5964 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
5965}
5966
5967TEST_F(WebRtcVideoChannelTest,
Florent Castellic1a0bcb2019-01-29 14:26:48 +01005968 GetAndSetRtpSendParametersScaleResolutionDownByH264) {
Rasmus Brandt9387b522019-02-05 14:23:26 +01005969 encoder_factory_->AddSupportedVideoCodecType(kH264CodecName);
5970 VideoSendParameters parameters;
5971 parameters.codecs.push_back(VideoCodec(kH264CodecName));
Florent Castellic1a0bcb2019-01-29 14:26:48 +01005972 ASSERT_TRUE(channel_->SetSendParameters(parameters));
5973 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
5974
5975 webrtc::test::FrameForwarder frame_forwarder;
Rasmus Brandt9387b522019-02-05 14:23:26 +01005976 FakeFrameSource frame_source(1280, 720, rtc::kNumMicrosecsPerSec / 30);
Florent Castellic1a0bcb2019-01-29 14:26:48 +01005977
5978 VideoOptions options;
5979 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
5980 channel_->SetSend(true);
5981
5982 // Try layers in natural order (smallest to largest).
5983 {
5984 auto rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
5985 ASSERT_EQ(3u, rtp_parameters.encodings.size());
5986 rtp_parameters.encodings[0].scale_resolution_down_by = 4.0;
5987 rtp_parameters.encodings[1].scale_resolution_down_by = 2.0;
5988 rtp_parameters.encodings[2].scale_resolution_down_by = 1.0;
5989 auto result = channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
5990 ASSERT_TRUE(result.ok());
5991
5992 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
5993
5994 std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
5995 ASSERT_EQ(3u, video_streams.size());
5996 EXPECT_EQ(320u, video_streams[0].width);
5997 EXPECT_EQ(180u, video_streams[0].height);
5998 EXPECT_EQ(640u, video_streams[1].width);
5999 EXPECT_EQ(360u, video_streams[1].height);
6000 EXPECT_EQ(1280u, video_streams[2].width);
6001 EXPECT_EQ(720u, video_streams[2].height);
6002 }
6003
6004 // Try layers in reverse natural order (largest to smallest).
6005 {
6006 auto rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
6007 ASSERT_EQ(3u, rtp_parameters.encodings.size());
6008 rtp_parameters.encodings[0].scale_resolution_down_by = 1.0;
6009 rtp_parameters.encodings[1].scale_resolution_down_by = 2.0;
6010 rtp_parameters.encodings[2].scale_resolution_down_by = 4.0;
6011 auto result = channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
6012 ASSERT_TRUE(result.ok());
6013
6014 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
6015
6016 std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
6017 ASSERT_EQ(3u, video_streams.size());
6018 EXPECT_EQ(1280u, video_streams[0].width);
6019 EXPECT_EQ(720u, video_streams[0].height);
6020 EXPECT_EQ(640u, video_streams[1].width);
6021 EXPECT_EQ(360u, video_streams[1].height);
6022 EXPECT_EQ(320u, video_streams[2].width);
6023 EXPECT_EQ(180u, video_streams[2].height);
6024 }
6025
6026 // Try layers in mixed order.
6027 {
6028 auto rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
6029 ASSERT_EQ(3u, rtp_parameters.encodings.size());
6030 rtp_parameters.encodings[0].scale_resolution_down_by = 10.0;
6031 rtp_parameters.encodings[1].scale_resolution_down_by = 2.0;
6032 rtp_parameters.encodings[2].scale_resolution_down_by = 4.0;
6033 auto result = channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
6034 ASSERT_TRUE(result.ok());
6035
6036 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
6037
6038 std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
6039 ASSERT_EQ(3u, video_streams.size());
6040 EXPECT_EQ(128u, video_streams[0].width);
6041 EXPECT_EQ(72u, video_streams[0].height);
6042 EXPECT_EQ(640u, video_streams[1].width);
6043 EXPECT_EQ(360u, video_streams[1].height);
6044 EXPECT_EQ(320u, video_streams[2].width);
6045 EXPECT_EQ(180u, video_streams[2].height);
6046 }
6047
6048 // Try with a missing scale setting, defaults to 1.0 if any other is set.
6049 {
6050 auto rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
6051 ASSERT_EQ(3u, rtp_parameters.encodings.size());
6052 rtp_parameters.encodings[0].scale_resolution_down_by = 1.0;
6053 rtp_parameters.encodings[1].scale_resolution_down_by.reset();
6054 rtp_parameters.encodings[2].scale_resolution_down_by = 4.0;
6055 auto result = channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
6056 ASSERT_TRUE(result.ok());
6057
6058 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
6059
6060 std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
6061 ASSERT_EQ(3u, video_streams.size());
6062 EXPECT_EQ(1280u, video_streams[0].width);
6063 EXPECT_EQ(720u, video_streams[0].height);
6064 EXPECT_EQ(1280u, video_streams[1].width);
6065 EXPECT_EQ(720u, video_streams[1].height);
6066 EXPECT_EQ(320u, video_streams[2].width);
6067 EXPECT_EQ(180u, video_streams[2].height);
6068 }
6069 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
6070}
6071
Rasmus Brandt9387b522019-02-05 14:23:26 +01006072TEST_F(WebRtcVideoChannelTest,
6073 GetAndSetRtpSendParametersScaleResolutionDownByH264WithOddResolution) {
6074 // Ensure that the top layer has width and height divisible by 2^3,
6075 // so that the bottom layer has width and height divisible by 2.
6076 // TODO(bugs.webrtc.org/8785): Remove this field trial when we fully trust
6077 // the number of simulcast layers set by the app.
6078 webrtc::test::ScopedFieldTrials field_trial(
6079 "WebRTC-NormalizeSimulcastResolution/Enabled-3/");
6080
6081 // Set up WebRtcVideoChannel for 3-layer H264 simulcast.
6082 encoder_factory_->AddSupportedVideoCodecType(kH264CodecName);
6083 VideoSendParameters parameters;
6084 parameters.codecs.push_back(VideoCodec(kH264CodecName));
6085 ASSERT_TRUE(channel_->SetSendParameters(parameters));
6086 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
6087 webrtc::test::FrameForwarder frame_forwarder;
6088 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, /*options=*/nullptr,
6089 &frame_forwarder));
6090 channel_->SetSend(true);
6091
6092 // Set |scale_resolution_down_by|'s.
6093 auto rtp_parameters = channel_->GetRtpSendParameters(last_ssrc_);
6094 ASSERT_EQ(rtp_parameters.encodings.size(), 3u);
6095 rtp_parameters.encodings[0].scale_resolution_down_by = 1.0;
6096 rtp_parameters.encodings[1].scale_resolution_down_by = 2.0;
6097 rtp_parameters.encodings[2].scale_resolution_down_by = 4.0;
6098 const auto result =
6099 channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
6100 ASSERT_TRUE(result.ok());
6101
6102 // Use a capture resolution whose width and height are not divisible by 2^3.
6103 // (See field trial set at the top of the test.)
6104 FakeFrameSource frame_source(2007, 1207, rtc::kNumMicrosecsPerSec / 30);
6105 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
6106
6107 // Ensure the scaling is correct.
6108 const auto video_streams = stream->GetVideoStreams();
6109 ASSERT_EQ(video_streams.size(), 3u);
6110 // Ensure that we round the capture resolution down for the top layer...
6111 EXPECT_EQ(video_streams[0].width, 2000u);
6112 EXPECT_EQ(video_streams[0].height, 1200u);
6113 EXPECT_EQ(video_streams[1].width, 1000u);
6114 EXPECT_EQ(video_streams[1].height, 600u);
6115 // ...and that the bottom layer has a width/height divisible by 2.
6116 EXPECT_EQ(video_streams[2].width, 500u);
6117 EXPECT_EQ(video_streams[2].height, 300u);
6118
6119 // Tear down.
6120 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
6121}
6122
Åsa Persson8c1bf952018-09-13 10:42:19 +02006123TEST_F(WebRtcVideoChannelTest, GetAndSetRtpSendParametersMaxFramerate) {
6124 const size_t kNumSimulcastStreams = 3;
6125 SetUpSimulcast(true, false);
6126
6127 // Get and set the rtp encoding parameters.
6128 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6129 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6130 for (const auto& encoding : parameters.encodings) {
6131 EXPECT_FALSE(encoding.max_framerate);
6132 }
6133
6134 // Change the value and set it on the VideoChannel.
6135 parameters.encodings[0].max_framerate = 10;
6136 parameters.encodings[1].max_framerate = 20;
6137 parameters.encodings[2].max_framerate = 25;
6138 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6139
6140 // Verify that the bitrates are set on the VideoChannel.
6141 parameters = channel_->GetRtpSendParameters(last_ssrc_);
6142 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6143 EXPECT_EQ(10, parameters.encodings[0].max_framerate);
6144 EXPECT_EQ(20, parameters.encodings[1].max_framerate);
6145 EXPECT_EQ(25, parameters.encodings[2].max_framerate);
6146}
6147
Åsa Persson23eba222018-10-02 14:47:06 +02006148TEST_F(WebRtcVideoChannelTest,
6149 SetRtpSendParametersNumTemporalLayersFailsForInvalidRange) {
6150 const size_t kNumSimulcastStreams = 3;
6151 SetUpSimulcast(true, false);
6152
6153 // Get and set the rtp encoding parameters.
6154 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6155 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6156
6157 // Num temporal layers should be in the range [1, kMaxTemporalStreams].
6158 parameters.encodings[0].num_temporal_layers = 0;
6159 EXPECT_EQ(webrtc::RTCErrorType::INVALID_RANGE,
6160 channel_->SetRtpSendParameters(last_ssrc_, parameters).type());
6161 parameters.encodings[0].num_temporal_layers = webrtc::kMaxTemporalStreams + 1;
6162 EXPECT_EQ(webrtc::RTCErrorType::INVALID_RANGE,
6163 channel_->SetRtpSendParameters(last_ssrc_, parameters).type());
6164}
6165
6166TEST_F(WebRtcVideoChannelTest,
6167 SetRtpSendParametersNumTemporalLayersFailsForInvalidModification) {
6168 const size_t kNumSimulcastStreams = 3;
6169 SetUpSimulcast(true, false);
6170
6171 // Get and set the rtp encoding parameters.
6172 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6173 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6174
6175 // No/all layers should be set.
6176 parameters.encodings[0].num_temporal_layers = 1;
6177 EXPECT_EQ(webrtc::RTCErrorType::INVALID_MODIFICATION,
6178 channel_->SetRtpSendParameters(last_ssrc_, parameters).type());
6179
6180 // Different values not supported.
6181 parameters.encodings[0].num_temporal_layers = 1;
6182 parameters.encodings[1].num_temporal_layers = 2;
6183 parameters.encodings[2].num_temporal_layers = 2;
6184 EXPECT_EQ(webrtc::RTCErrorType::INVALID_MODIFICATION,
6185 channel_->SetRtpSendParameters(last_ssrc_, parameters).type());
6186}
6187
6188TEST_F(WebRtcVideoChannelTest, GetAndSetRtpSendParametersNumTemporalLayers) {
6189 const size_t kNumSimulcastStreams = 3;
6190 SetUpSimulcast(true, false);
6191
6192 // Get and set the rtp encoding parameters.
6193 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6194 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6195 for (const auto& encoding : parameters.encodings)
6196 EXPECT_FALSE(encoding.num_temporal_layers);
6197
6198 // Change the value and set it on the VideoChannel.
6199 parameters.encodings[0].num_temporal_layers = 3;
6200 parameters.encodings[1].num_temporal_layers = 3;
6201 parameters.encodings[2].num_temporal_layers = 3;
6202 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6203
6204 // Verify that the number of temporal layers are set on the VideoChannel.
6205 parameters = channel_->GetRtpSendParameters(last_ssrc_);
6206 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6207 EXPECT_EQ(3, parameters.encodings[0].num_temporal_layers);
6208 EXPECT_EQ(3, parameters.encodings[1].num_temporal_layers);
6209 EXPECT_EQ(3, parameters.encodings[2].num_temporal_layers);
6210}
6211
6212TEST_F(WebRtcVideoChannelTest, NumTemporalLayersPropagatedToEncoder) {
6213 const size_t kNumSimulcastStreams = 3;
6214 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
6215
6216 // Send a full size frame so all simulcast layers are used when reconfiguring.
Niels Möller805a27e2019-01-21 12:21:27 +01006217 webrtc::test::FrameForwarder frame_forwarder;
Åsa Persson23eba222018-10-02 14:47:06 +02006218 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01006219 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
Åsa Persson23eba222018-10-02 14:47:06 +02006220 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01006221 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Åsa Persson23eba222018-10-02 14:47:06 +02006222
6223 // Get and set the rtp encoding parameters.
6224 // Change the value and set it on the VideoChannel.
6225 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6226 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6227 parameters.encodings[0].num_temporal_layers = 2;
6228 parameters.encodings[1].num_temporal_layers = 2;
6229 parameters.encodings[2].num_temporal_layers = 2;
6230 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6231
6232 // Verify that the new value is propagated down to the encoder.
6233 // Check that WebRtcVideoSendStream updates VideoEncoderConfig correctly.
6234 EXPECT_EQ(2, stream->num_encoder_reconfigurations());
6235 webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
6236 EXPECT_EQ(kNumSimulcastStreams, encoder_config.number_of_streams);
6237 EXPECT_EQ(kNumSimulcastStreams, encoder_config.simulcast_layers.size());
6238 EXPECT_EQ(2UL, encoder_config.simulcast_layers[0].num_temporal_layers);
6239 EXPECT_EQ(2UL, encoder_config.simulcast_layers[1].num_temporal_layers);
6240 EXPECT_EQ(2UL, encoder_config.simulcast_layers[2].num_temporal_layers);
6241
6242 // FakeVideoSendStream calls CreateEncoderStreams, test that the vector of
6243 // VideoStreams are created appropriately for the simulcast case.
6244 EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
6245 EXPECT_EQ(2UL, stream->GetVideoStreams()[0].num_temporal_layers);
6246 EXPECT_EQ(2UL, stream->GetVideoStreams()[1].num_temporal_layers);
6247 EXPECT_EQ(2UL, stream->GetVideoStreams()[2].num_temporal_layers);
6248
6249 // No parameter changed, encoder should not be reconfigured.
6250 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6251 EXPECT_EQ(2, stream->num_encoder_reconfigurations());
6252
6253 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
6254}
6255
6256TEST_F(WebRtcVideoChannelTest,
6257 DefaultValuePropagatedToEncoderForUnsetNumTemporalLayers) {
6258 const size_t kDefaultNumTemporalLayers = 3;
6259 const size_t kNumSimulcastStreams = 3;
6260 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
6261
6262 // Send a full size frame so all simulcast layers are used when reconfiguring.
Niels Möller805a27e2019-01-21 12:21:27 +01006263 webrtc::test::FrameForwarder frame_forwarder;
Åsa Persson23eba222018-10-02 14:47:06 +02006264 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01006265 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
Åsa Persson23eba222018-10-02 14:47:06 +02006266 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01006267 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Åsa Persson23eba222018-10-02 14:47:06 +02006268
6269 // Change rtp encoding parameters, num_temporal_layers not changed.
6270 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6271 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6272 parameters.encodings[0].min_bitrate_bps = 33000;
6273 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6274
6275 // Verify that no value is propagated down to the encoder.
6276 webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
6277 EXPECT_EQ(kNumSimulcastStreams, encoder_config.number_of_streams);
6278 EXPECT_EQ(kNumSimulcastStreams, encoder_config.simulcast_layers.size());
6279 EXPECT_FALSE(encoder_config.simulcast_layers[0].num_temporal_layers);
6280 EXPECT_FALSE(encoder_config.simulcast_layers[1].num_temporal_layers);
6281 EXPECT_FALSE(encoder_config.simulcast_layers[2].num_temporal_layers);
6282
6283 // FakeVideoSendStream calls CreateEncoderStreams, test that the vector of
6284 // VideoStreams are created appropriately for the simulcast case.
6285 EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
6286 EXPECT_EQ(kDefaultNumTemporalLayers,
6287 stream->GetVideoStreams()[0].num_temporal_layers);
6288 EXPECT_EQ(kDefaultNumTemporalLayers,
6289 stream->GetVideoStreams()[1].num_temporal_layers);
6290 EXPECT_EQ(kDefaultNumTemporalLayers,
6291 stream->GetVideoStreams()[2].num_temporal_layers);
6292
6293 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
6294}
6295
Åsa Persson8c1bf952018-09-13 10:42:19 +02006296TEST_F(WebRtcVideoChannelTest, MaxSimulcastFrameratePropagatedToEncoder) {
6297 const size_t kNumSimulcastStreams = 3;
6298 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
6299
6300 // Send a full size frame so all simulcast layers are used when reconfiguring.
Niels Möller805a27e2019-01-21 12:21:27 +01006301 webrtc::test::FrameForwarder frame_forwarder;
Åsa Persson8c1bf952018-09-13 10:42:19 +02006302 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01006303 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
Åsa Persson8c1bf952018-09-13 10:42:19 +02006304 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01006305 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Åsa Persson8c1bf952018-09-13 10:42:19 +02006306
6307 // Get and set the rtp encoding parameters.
6308 // Change the value and set it on the VideoChannel.
6309 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6310 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6311 parameters.encodings[0].max_framerate = 15;
6312 parameters.encodings[1].max_framerate = 25;
6313 parameters.encodings[2].max_framerate = 20;
6314 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6315
6316 // Verify that the new value propagated down to the encoder.
6317 // Check that WebRtcVideoSendStream updates VideoEncoderConfig correctly.
6318 EXPECT_EQ(2, stream->num_encoder_reconfigurations());
6319 webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
6320 EXPECT_EQ(kNumSimulcastStreams, encoder_config.number_of_streams);
6321 EXPECT_EQ(kNumSimulcastStreams, encoder_config.simulcast_layers.size());
6322 EXPECT_EQ(15, encoder_config.simulcast_layers[0].max_framerate);
6323 EXPECT_EQ(25, encoder_config.simulcast_layers[1].max_framerate);
6324 EXPECT_EQ(20, encoder_config.simulcast_layers[2].max_framerate);
6325
6326 // FakeVideoSendStream calls CreateEncoderStreams, test that the vector of
6327 // VideoStreams are created appropriately for the simulcast case.
6328 // Currently the maximum |max_framerate| is used.
6329 EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
6330 EXPECT_EQ(25, stream->GetVideoStreams()[0].max_framerate);
6331 EXPECT_EQ(25, stream->GetVideoStreams()[1].max_framerate);
6332 EXPECT_EQ(25, stream->GetVideoStreams()[2].max_framerate);
6333
6334 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
6335}
6336
6337TEST_F(WebRtcVideoChannelTest,
6338 DefaultValuePropagatedToEncoderForUnsetFramerate) {
6339 const size_t kNumSimulcastStreams = 3;
6340 const std::vector<webrtc::VideoStream> kDefault = GetSimulcastBitrates720p();
6341 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
6342
6343 // Send a full size frame so all simulcast layers are used when reconfiguring.
Niels Möller805a27e2019-01-21 12:21:27 +01006344 webrtc::test::FrameForwarder frame_forwarder;
Åsa Persson8c1bf952018-09-13 10:42:19 +02006345 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01006346 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
Åsa Persson8c1bf952018-09-13 10:42:19 +02006347 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01006348 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Åsa Persson8c1bf952018-09-13 10:42:19 +02006349
6350 // Get and set the rtp encoding parameters.
6351 // Change the value and set it on the VideoChannel.
6352 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6353 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6354 parameters.encodings[0].max_framerate = 15;
6355 parameters.encodings[2].max_framerate = 20;
6356 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6357
6358 // Verify that the new value propagated down to the encoder.
6359 // Check that WebRtcVideoSendStream updates VideoEncoderConfig correctly.
6360 webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
6361 EXPECT_EQ(kNumSimulcastStreams, encoder_config.number_of_streams);
6362 EXPECT_EQ(kNumSimulcastStreams, encoder_config.simulcast_layers.size());
6363 EXPECT_EQ(15, encoder_config.simulcast_layers[0].max_framerate);
6364 EXPECT_EQ(-1, encoder_config.simulcast_layers[1].max_framerate);
6365 EXPECT_EQ(20, encoder_config.simulcast_layers[2].max_framerate);
6366
6367 // FakeVideoSendStream calls CreateEncoderStreams, test that the vector of
6368 // VideoStreams are created appropriately for the simulcast case.
6369 // The maximum |max_framerate| is used, kDefaultVideoMaxFramerate: 60.
6370 EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
6371 EXPECT_EQ(kDefaultVideoMaxFramerate,
6372 stream->GetVideoStreams()[0].max_framerate);
6373 EXPECT_EQ(kDefaultVideoMaxFramerate,
6374 stream->GetVideoStreams()[1].max_framerate);
6375 EXPECT_EQ(kDefaultVideoMaxFramerate,
6376 stream->GetVideoStreams()[2].max_framerate);
6377
6378 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
6379}
6380
Åsa Persson55659812018-06-18 17:51:32 +02006381TEST_F(WebRtcVideoChannelTest, GetAndSetRtpSendParametersMinAndMaxBitrate) {
6382 const size_t kNumSimulcastStreams = 3;
6383 SetUpSimulcast(true, false);
6384
6385 // Get and set the rtp encoding parameters.
6386 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6387 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6388 for (const auto& encoding : parameters.encodings) {
6389 EXPECT_FALSE(encoding.min_bitrate_bps);
6390 EXPECT_FALSE(encoding.max_bitrate_bps);
6391 }
6392
6393 // Change the value and set it on the VideoChannel.
6394 parameters.encodings[0].min_bitrate_bps = 100000;
6395 parameters.encodings[0].max_bitrate_bps = 200000;
6396 parameters.encodings[1].min_bitrate_bps = 300000;
6397 parameters.encodings[1].max_bitrate_bps = 400000;
6398 parameters.encodings[2].min_bitrate_bps = 500000;
6399 parameters.encodings[2].max_bitrate_bps = 600000;
6400 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6401
6402 // Verify that the bitrates are set on the VideoChannel.
6403 parameters = channel_->GetRtpSendParameters(last_ssrc_);
6404 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6405 EXPECT_EQ(100000, parameters.encodings[0].min_bitrate_bps);
6406 EXPECT_EQ(200000, parameters.encodings[0].max_bitrate_bps);
6407 EXPECT_EQ(300000, parameters.encodings[1].min_bitrate_bps);
6408 EXPECT_EQ(400000, parameters.encodings[1].max_bitrate_bps);
6409 EXPECT_EQ(500000, parameters.encodings[2].min_bitrate_bps);
6410 EXPECT_EQ(600000, parameters.encodings[2].max_bitrate_bps);
6411}
6412
6413TEST_F(WebRtcVideoChannelTest, SetRtpSendParametersFailsWithIncorrectBitrate) {
6414 const size_t kNumSimulcastStreams = 3;
6415 SetUpSimulcast(true, false);
6416
6417 // Get and set the rtp encoding parameters.
6418 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6419 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6420
6421 // Max bitrate lower than min bitrate should fail.
6422 parameters.encodings[2].min_bitrate_bps = 100000;
6423 parameters.encodings[2].max_bitrate_bps = 100000 - 1;
6424 EXPECT_EQ(webrtc::RTCErrorType::INVALID_RANGE,
6425 channel_->SetRtpSendParameters(last_ssrc_, parameters).type());
6426}
6427
6428// Test that min and max bitrate values set via RtpParameters are correctly
6429// propagated to the underlying encoder, and that the target is set to 3/4 of
6430// the maximum (3/4 was chosen because it's similar to the simulcast defaults
6431// that are used if no min/max are specified).
6432TEST_F(WebRtcVideoChannelTest, MinAndMaxSimulcastBitratePropagatedToEncoder) {
6433 const size_t kNumSimulcastStreams = 3;
6434 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
6435
6436 // Send a full size frame so all simulcast layers are used when reconfiguring.
Niels Möller805a27e2019-01-21 12:21:27 +01006437 webrtc::test::FrameForwarder frame_forwarder;
Åsa Persson55659812018-06-18 17:51:32 +02006438 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01006439 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
Åsa Persson55659812018-06-18 17:51:32 +02006440 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01006441 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Åsa Persson55659812018-06-18 17:51:32 +02006442
6443 // Get and set the rtp encoding parameters.
6444 // Change the value and set it on the VideoChannel.
6445 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6446 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6447 parameters.encodings[0].min_bitrate_bps = 100000;
6448 parameters.encodings[0].max_bitrate_bps = 200000;
6449 parameters.encodings[1].min_bitrate_bps = 300000;
6450 parameters.encodings[1].max_bitrate_bps = 400000;
6451 parameters.encodings[2].min_bitrate_bps = 500000;
6452 parameters.encodings[2].max_bitrate_bps = 600000;
6453 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6454
6455 // Verify that the new value propagated down to the encoder.
6456 // Check that WebRtcVideoSendStream updates VideoEncoderConfig correctly.
6457 EXPECT_EQ(2, stream->num_encoder_reconfigurations());
6458 webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
6459 EXPECT_EQ(kNumSimulcastStreams, encoder_config.number_of_streams);
6460 EXPECT_EQ(kNumSimulcastStreams, encoder_config.simulcast_layers.size());
6461 EXPECT_EQ(100000, encoder_config.simulcast_layers[0].min_bitrate_bps);
6462 EXPECT_EQ(200000, encoder_config.simulcast_layers[0].max_bitrate_bps);
6463 EXPECT_EQ(300000, encoder_config.simulcast_layers[1].min_bitrate_bps);
6464 EXPECT_EQ(400000, encoder_config.simulcast_layers[1].max_bitrate_bps);
6465 EXPECT_EQ(500000, encoder_config.simulcast_layers[2].min_bitrate_bps);
6466 EXPECT_EQ(600000, encoder_config.simulcast_layers[2].max_bitrate_bps);
6467
6468 // FakeVideoSendStream calls CreateEncoderStreams, test that the vector of
6469 // VideoStreams are created appropriately for the simulcast case.
6470 EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
6471 // Target bitrate: 200000 * 3 / 4 = 150000.
6472 EXPECT_EQ(100000, stream->GetVideoStreams()[0].min_bitrate_bps);
6473 EXPECT_EQ(150000, stream->GetVideoStreams()[0].target_bitrate_bps);
6474 EXPECT_EQ(200000, stream->GetVideoStreams()[0].max_bitrate_bps);
6475 // Target bitrate: 400000 * 3 / 4 = 300000.
6476 EXPECT_EQ(300000, stream->GetVideoStreams()[1].min_bitrate_bps);
6477 EXPECT_EQ(300000, stream->GetVideoStreams()[1].target_bitrate_bps);
6478 EXPECT_EQ(400000, stream->GetVideoStreams()[1].max_bitrate_bps);
6479 // Target bitrate: 600000 * 3 / 4 = 450000, less than min -> max.
6480 EXPECT_EQ(500000, stream->GetVideoStreams()[2].min_bitrate_bps);
6481 EXPECT_EQ(600000, stream->GetVideoStreams()[2].target_bitrate_bps);
6482 EXPECT_EQ(600000, stream->GetVideoStreams()[2].max_bitrate_bps);
6483
6484 // No parameter changed, encoder should not be reconfigured.
6485 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6486 EXPECT_EQ(2, stream->num_encoder_reconfigurations());
6487
6488 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
6489}
6490
6491// Test to only specify the min or max bitrate value for a layer via
6492// RtpParameters. The unspecified min/max and target value should be set to the
6493// simulcast default that is used if no min/max are specified.
6494TEST_F(WebRtcVideoChannelTest, MinOrMaxSimulcastBitratePropagatedToEncoder) {
6495 const size_t kNumSimulcastStreams = 3;
6496 const std::vector<webrtc::VideoStream> kDefault = GetSimulcastBitrates720p();
6497 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
6498
6499 // Send a full size frame so all simulcast layers are used when reconfiguring.
Niels Möller805a27e2019-01-21 12:21:27 +01006500 webrtc::test::FrameForwarder frame_forwarder;
Åsa Persson55659812018-06-18 17:51:32 +02006501 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01006502 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
Åsa Persson55659812018-06-18 17:51:32 +02006503 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01006504 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Åsa Persson55659812018-06-18 17:51:32 +02006505
6506 // Get and set the rtp encoding parameters.
6507 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6508 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6509
6510 // Change the value and set it on the VideoChannel.
6511 // Layer 0: only configure min bitrate.
6512 const int kMinBpsLayer0 = kDefault[0].min_bitrate_bps + 1;
6513 parameters.encodings[0].min_bitrate_bps = kMinBpsLayer0;
6514 // Layer 1: only configure max bitrate.
6515 const int kMaxBpsLayer1 = kDefault[1].max_bitrate_bps - 1;
6516 parameters.encodings[1].max_bitrate_bps = kMaxBpsLayer1;
6517 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6518
6519 // Verify that the new value propagated down to the encoder.
6520 // Check that WebRtcVideoSendStream updates VideoEncoderConfig correctly.
6521 webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
6522 EXPECT_EQ(kNumSimulcastStreams, encoder_config.number_of_streams);
6523 EXPECT_EQ(kNumSimulcastStreams, encoder_config.simulcast_layers.size());
6524 EXPECT_EQ(kMinBpsLayer0, encoder_config.simulcast_layers[0].min_bitrate_bps);
6525 EXPECT_EQ(-1, encoder_config.simulcast_layers[0].max_bitrate_bps);
6526 EXPECT_EQ(-1, encoder_config.simulcast_layers[1].min_bitrate_bps);
6527 EXPECT_EQ(kMaxBpsLayer1, encoder_config.simulcast_layers[1].max_bitrate_bps);
6528 EXPECT_EQ(-1, encoder_config.simulcast_layers[2].min_bitrate_bps);
6529 EXPECT_EQ(-1, encoder_config.simulcast_layers[2].max_bitrate_bps);
6530
6531 // FakeVideoSendStream calls CreateEncoderStreams, test that the vector of
6532 // VideoStreams are created appropriately for the simulcast case.
6533 EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
6534 // Layer 0: min configured bitrate should overwrite min default.
6535 EXPECT_EQ(kMinBpsLayer0, stream->GetVideoStreams()[0].min_bitrate_bps);
6536 EXPECT_EQ(kDefault[0].target_bitrate_bps,
6537 stream->GetVideoStreams()[0].target_bitrate_bps);
6538 EXPECT_EQ(kDefault[0].max_bitrate_bps,
6539 stream->GetVideoStreams()[0].max_bitrate_bps);
6540 // Layer 1: max configured bitrate should overwrite max default.
6541 EXPECT_EQ(kDefault[1].min_bitrate_bps,
6542 stream->GetVideoStreams()[1].min_bitrate_bps);
6543 EXPECT_EQ(kDefault[1].target_bitrate_bps,
6544 stream->GetVideoStreams()[1].target_bitrate_bps);
6545 EXPECT_EQ(kMaxBpsLayer1, stream->GetVideoStreams()[1].max_bitrate_bps);
6546 // Layer 2: min and max bitrate not configured, default expected.
6547 EXPECT_EQ(kDefault[2].min_bitrate_bps,
6548 stream->GetVideoStreams()[2].min_bitrate_bps);
6549 EXPECT_EQ(kDefault[2].target_bitrate_bps,
6550 stream->GetVideoStreams()[2].target_bitrate_bps);
6551 EXPECT_EQ(kDefault[2].max_bitrate_bps,
6552 stream->GetVideoStreams()[2].max_bitrate_bps);
6553
6554 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
6555}
6556
6557// Test that specifying the min (or max) bitrate value for a layer via
6558// RtpParameters above (or below) the simulcast default max (or min) adjusts the
6559// unspecified values accordingly.
6560TEST_F(WebRtcVideoChannelTest, SetMinAndMaxSimulcastBitrateAboveBelowDefault) {
6561 const size_t kNumSimulcastStreams = 3;
6562 const std::vector<webrtc::VideoStream> kDefault = GetSimulcastBitrates720p();
6563 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
6564
6565 // Send a full size frame so all simulcast layers are used when reconfiguring.
Niels Möller805a27e2019-01-21 12:21:27 +01006566 webrtc::test::FrameForwarder frame_forwarder;
Åsa Persson55659812018-06-18 17:51:32 +02006567 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01006568 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
Åsa Persson55659812018-06-18 17:51:32 +02006569 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01006570 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Åsa Persson55659812018-06-18 17:51:32 +02006571
6572 // Get and set the rtp encoding parameters.
6573 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6574 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6575
6576 // Change the value and set it on the VideoChannel.
6577 // For layer 0, set the min bitrate above the default max.
6578 const int kMinBpsLayer0 = kDefault[0].max_bitrate_bps + 1;
6579 parameters.encodings[0].min_bitrate_bps = kMinBpsLayer0;
6580 // For layer 1, set the max bitrate below the default min.
6581 const int kMaxBpsLayer1 = kDefault[1].min_bitrate_bps - 1;
6582 parameters.encodings[1].max_bitrate_bps = kMaxBpsLayer1;
6583 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6584
6585 // Verify that the new value propagated down to the encoder.
6586 // FakeVideoSendStream calls CreateEncoderStreams, test that the vector of
6587 // VideoStreams are created appropriately for the simulcast case.
6588 EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
6589 // Layer 0: Min bitrate above default max (target/max should be adjusted).
6590 EXPECT_EQ(kMinBpsLayer0, stream->GetVideoStreams()[0].min_bitrate_bps);
6591 EXPECT_EQ(kMinBpsLayer0, stream->GetVideoStreams()[0].target_bitrate_bps);
6592 EXPECT_EQ(kMinBpsLayer0, stream->GetVideoStreams()[0].max_bitrate_bps);
6593 // Layer 1: Max bitrate below default min (min/target should be adjusted).
6594 EXPECT_EQ(kMaxBpsLayer1, stream->GetVideoStreams()[1].min_bitrate_bps);
6595 EXPECT_EQ(kMaxBpsLayer1, stream->GetVideoStreams()[1].target_bitrate_bps);
6596 EXPECT_EQ(kMaxBpsLayer1, stream->GetVideoStreams()[1].max_bitrate_bps);
6597 // Layer 2: min and max bitrate not configured, default expected.
6598 EXPECT_EQ(kDefault[2].min_bitrate_bps,
6599 stream->GetVideoStreams()[2].min_bitrate_bps);
6600 EXPECT_EQ(kDefault[2].target_bitrate_bps,
6601 stream->GetVideoStreams()[2].target_bitrate_bps);
6602 EXPECT_EQ(kDefault[2].max_bitrate_bps,
6603 stream->GetVideoStreams()[2].max_bitrate_bps);
6604
6605 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
6606}
6607
6608TEST_F(WebRtcVideoChannelTest, BandwidthAboveTotalMaxBitrateGivenToMaxLayer) {
6609 const size_t kNumSimulcastStreams = 3;
6610 const std::vector<webrtc::VideoStream> kDefault = GetSimulcastBitrates720p();
6611 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
6612
6613 // Send a full size frame so all simulcast layers are used when reconfiguring.
Niels Möller805a27e2019-01-21 12:21:27 +01006614 webrtc::test::FrameForwarder frame_forwarder;
Åsa Persson55659812018-06-18 17:51:32 +02006615 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01006616 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
Åsa Persson55659812018-06-18 17:51:32 +02006617 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01006618 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Åsa Persson55659812018-06-18 17:51:32 +02006619
6620 // Set max bitrate for all but the highest layer.
6621 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6622 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6623 parameters.encodings[0].max_bitrate_bps = kDefault[0].max_bitrate_bps;
6624 parameters.encodings[1].max_bitrate_bps = kDefault[1].max_bitrate_bps;
6625 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6626
6627 // Set max bandwidth equal to total max bitrate.
6628 send_parameters_.max_bandwidth_bps =
6629 GetTotalMaxBitrateBps(stream->GetVideoStreams());
6630 ExpectSetMaxBitrate(send_parameters_.max_bandwidth_bps);
6631 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
6632
6633 // No bitrate above the total max to give to the highest layer.
6634 EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
6635 EXPECT_EQ(kDefault[2].max_bitrate_bps,
6636 stream->GetVideoStreams()[2].max_bitrate_bps);
6637
6638 // Set max bandwidth above the total max bitrate.
6639 send_parameters_.max_bandwidth_bps =
6640 GetTotalMaxBitrateBps(stream->GetVideoStreams()) + 1;
6641 ExpectSetMaxBitrate(send_parameters_.max_bandwidth_bps);
6642 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
6643
6644 // The highest layer has no max bitrate set -> the bitrate above the total
6645 // max should be given to the highest layer.
6646 EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
6647 EXPECT_EQ(send_parameters_.max_bandwidth_bps,
6648 GetTotalMaxBitrateBps(stream->GetVideoStreams()));
6649 EXPECT_EQ(kDefault[2].max_bitrate_bps + 1,
6650 stream->GetVideoStreams()[2].max_bitrate_bps);
6651
6652 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
6653}
6654
6655TEST_F(WebRtcVideoChannelTest,
6656 BandwidthAboveTotalMaxBitrateNotGivenToMaxLayerIfMaxBitrateSet) {
6657 const size_t kNumSimulcastStreams = 3;
6658 const std::vector<webrtc::VideoStream> kDefault = GetSimulcastBitrates720p();
6659 EXPECT_EQ(kNumSimulcastStreams, kDefault.size());
6660 FakeVideoSendStream* stream = SetUpSimulcast(true, false);
6661
6662 // Send a full size frame so all simulcast layers are used when reconfiguring.
Niels Möller805a27e2019-01-21 12:21:27 +01006663 webrtc::test::FrameForwarder frame_forwarder;
Åsa Persson55659812018-06-18 17:51:32 +02006664 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01006665 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
Åsa Persson55659812018-06-18 17:51:32 +02006666 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01006667 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
Åsa Persson55659812018-06-18 17:51:32 +02006668
6669 // Set max bitrate for the highest layer.
6670 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6671 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
6672 parameters.encodings[2].max_bitrate_bps = kDefault[2].max_bitrate_bps;
6673 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6674
6675 // Set max bandwidth above the total max bitrate.
6676 send_parameters_.max_bandwidth_bps =
6677 GetTotalMaxBitrateBps(stream->GetVideoStreams()) + 1;
6678 ExpectSetMaxBitrate(send_parameters_.max_bandwidth_bps);
6679 ASSERT_TRUE(channel_->SetSendParameters(send_parameters_));
6680
6681 // The highest layer has the max bitrate set -> the bitrate above the total
6682 // max should not be given to the highest layer.
6683 EXPECT_EQ(kNumSimulcastStreams, stream->GetVideoStreams().size());
6684 EXPECT_EQ(*parameters.encodings[2].max_bitrate_bps,
6685 stream->GetVideoStreams()[2].max_bitrate_bps);
6686
6687 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
6688}
6689
Åsa Perssonbdee46d2018-06-25 11:28:06 +02006690// Test that min and max bitrate values set via RtpParameters are correctly
6691// propagated to the underlying encoder for a single stream.
6692TEST_F(WebRtcVideoChannelTest, MinAndMaxBitratePropagatedToEncoder) {
6693 FakeVideoSendStream* stream = AddSendStream();
6694 EXPECT_TRUE(channel_->SetSend(true));
6695 EXPECT_TRUE(stream->IsSending());
6696
6697 // Set min and max bitrate.
6698 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6699 EXPECT_EQ(1u, parameters.encodings.size());
6700 parameters.encodings[0].min_bitrate_bps = 80000;
6701 parameters.encodings[0].max_bitrate_bps = 150000;
6702 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
6703
6704 // Check that WebRtcVideoSendStream updates VideoEncoderConfig correctly.
6705 webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
6706 EXPECT_EQ(1u, encoder_config.number_of_streams);
6707 EXPECT_EQ(1u, encoder_config.simulcast_layers.size());
6708 EXPECT_EQ(80000, encoder_config.simulcast_layers[0].min_bitrate_bps);
6709 EXPECT_EQ(150000, encoder_config.simulcast_layers[0].max_bitrate_bps);
6710
6711 // FakeVideoSendStream calls CreateEncoderStreams, test that the vector of
6712 // VideoStreams are created appropriately.
6713 EXPECT_EQ(1u, stream->GetVideoStreams().size());
6714 EXPECT_EQ(80000, stream->GetVideoStreams()[0].min_bitrate_bps);
6715 EXPECT_EQ(150000, stream->GetVideoStreams()[0].target_bitrate_bps);
6716 EXPECT_EQ(150000, stream->GetVideoStreams()[0].max_bitrate_bps);
6717}
6718
6719// Test the default min and max bitrate value are correctly propagated to the
6720// underlying encoder for a single stream (when the values are not set via
6721// RtpParameters).
6722TEST_F(WebRtcVideoChannelTest, DefaultMinAndMaxBitratePropagatedToEncoder) {
6723 FakeVideoSendStream* stream = AddSendStream();
6724 EXPECT_TRUE(channel_->SetSend(true));
6725 EXPECT_TRUE(stream->IsSending());
6726
6727 // Check that WebRtcVideoSendStream updates VideoEncoderConfig correctly.
6728 webrtc::VideoEncoderConfig encoder_config = stream->GetEncoderConfig().Copy();
6729 EXPECT_EQ(1u, encoder_config.number_of_streams);
6730 EXPECT_EQ(1u, encoder_config.simulcast_layers.size());
6731 EXPECT_EQ(-1, encoder_config.simulcast_layers[0].min_bitrate_bps);
6732 EXPECT_EQ(-1, encoder_config.simulcast_layers[0].max_bitrate_bps);
6733
6734 // FakeVideoSendStream calls CreateEncoderStreams, test that the vector of
6735 // VideoStreams are created appropriately.
6736 EXPECT_EQ(1u, stream->GetVideoStreams().size());
6737 EXPECT_EQ(cricket::kMinVideoBitrateBps,
6738 stream->GetVideoStreams()[0].min_bitrate_bps);
6739 EXPECT_GT(stream->GetVideoStreams()[0].max_bitrate_bps,
6740 stream->GetVideoStreams()[0].min_bitrate_bps);
6741 EXPECT_EQ(stream->GetVideoStreams()[0].max_bitrate_bps,
6742 stream->GetVideoStreams()[0].target_bitrate_bps);
6743}
6744
Taylor Brandstetter14b9d792016-09-07 17:16:54 -07006745// Test that a stream will not be sending if its encoding is made inactive
6746// through SetRtpSendParameters.
Seth Hampson8234ead2018-02-02 15:16:24 -08006747TEST_F(WebRtcVideoChannelTest, SetRtpSendParametersOneEncodingActive) {
deadbeefdbe2b872016-03-22 15:42:00 -07006748 FakeVideoSendStream* stream = AddSendStream();
6749 EXPECT_TRUE(channel_->SetSend(true));
6750 EXPECT_TRUE(stream->IsSending());
6751
6752 // Get current parameters and change "active" to false.
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07006753 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
deadbeefdbe2b872016-03-22 15:42:00 -07006754 ASSERT_EQ(1u, parameters.encodings.size());
6755 ASSERT_TRUE(parameters.encodings[0].active);
6756 parameters.encodings[0].active = false;
Zach Steinba37b4b2018-01-23 15:02:36 -08006757 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
deadbeefdbe2b872016-03-22 15:42:00 -07006758 EXPECT_FALSE(stream->IsSending());
6759
6760 // Now change it back to active and verify we resume sending.
6761 parameters.encodings[0].active = true;
Zach Steinba37b4b2018-01-23 15:02:36 -08006762 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
deadbeefdbe2b872016-03-22 15:42:00 -07006763 EXPECT_TRUE(stream->IsSending());
6764}
6765
Seth Hampson8234ead2018-02-02 15:16:24 -08006766// Tests that when active is updated for any simulcast layer then the send
6767// stream's sending state will be updated and it will be reconfigured with the
6768// new appropriate active simulcast streams.
6769TEST_F(WebRtcVideoChannelTest, SetRtpSendParametersMultipleEncodingsActive) {
6770 // Create the stream params with multiple ssrcs for simulcast.
Åsa Persson31cb8f92018-06-27 10:44:56 +02006771 const size_t kNumSimulcastStreams = 3;
Seth Hampson8234ead2018-02-02 15:16:24 -08006772 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
6773 StreamParams stream_params = CreateSimStreamParams("cname", ssrcs);
6774 FakeVideoSendStream* fake_video_send_stream = AddSendStream(stream_params);
6775 uint32_t primary_ssrc = stream_params.first_ssrc();
6776
Niels Möller805a27e2019-01-21 12:21:27 +01006777 // Using the FrameForwarder, we manually send a full size
Tommi85959932018-02-07 19:26:06 +01006778 // frame. This allows us to test that ReconfigureEncoder is called
6779 // appropriately.
Niels Möller805a27e2019-01-21 12:21:27 +01006780 webrtc::test::FrameForwarder frame_forwarder;
Seth Hampson8234ead2018-02-02 15:16:24 -08006781 VideoOptions options;
Niels Möller805a27e2019-01-21 12:21:27 +01006782 EXPECT_TRUE(channel_->SetVideoSend(primary_ssrc, &options, &frame_forwarder));
Seth Hampson8234ead2018-02-02 15:16:24 -08006783 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01006784 frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame(
6785 1920, 1080, webrtc::VideoRotation::kVideoRotation_0,
6786 rtc::kNumMicrosecsPerSec / 30));
Seth Hampson8234ead2018-02-02 15:16:24 -08006787
6788 // Check that all encodings are initially active.
6789 webrtc::RtpParameters parameters =
6790 channel_->GetRtpSendParameters(primary_ssrc);
Åsa Persson31cb8f92018-06-27 10:44:56 +02006791 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
Seth Hampson8234ead2018-02-02 15:16:24 -08006792 EXPECT_TRUE(parameters.encodings[0].active);
6793 EXPECT_TRUE(parameters.encodings[1].active);
6794 EXPECT_TRUE(parameters.encodings[2].active);
6795 EXPECT_TRUE(fake_video_send_stream->IsSending());
6796
6797 // Only turn on only the middle stream.
6798 parameters.encodings[0].active = false;
6799 parameters.encodings[1].active = true;
6800 parameters.encodings[2].active = false;
6801 EXPECT_TRUE(channel_->SetRtpSendParameters(primary_ssrc, parameters).ok());
6802 // Verify that the active fields are set on the VideoChannel.
6803 parameters = channel_->GetRtpSendParameters(primary_ssrc);
Åsa Persson31cb8f92018-06-27 10:44:56 +02006804 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
Seth Hampson8234ead2018-02-02 15:16:24 -08006805 EXPECT_FALSE(parameters.encodings[0].active);
6806 EXPECT_TRUE(parameters.encodings[1].active);
6807 EXPECT_FALSE(parameters.encodings[2].active);
6808 // Check that the VideoSendStream is updated appropriately. This means its
6809 // send state was updated and it was reconfigured.
6810 EXPECT_TRUE(fake_video_send_stream->IsSending());
6811 std::vector<webrtc::VideoStream> simulcast_streams =
6812 fake_video_send_stream->GetVideoStreams();
Åsa Persson31cb8f92018-06-27 10:44:56 +02006813 EXPECT_EQ(kNumSimulcastStreams, simulcast_streams.size());
Seth Hampson8234ead2018-02-02 15:16:24 -08006814 EXPECT_FALSE(simulcast_streams[0].active);
6815 EXPECT_TRUE(simulcast_streams[1].active);
6816 EXPECT_FALSE(simulcast_streams[2].active);
6817
6818 // Turn off all streams.
6819 parameters.encodings[0].active = false;
6820 parameters.encodings[1].active = false;
6821 parameters.encodings[2].active = false;
6822 EXPECT_TRUE(channel_->SetRtpSendParameters(primary_ssrc, parameters).ok());
6823 // Verify that the active fields are set on the VideoChannel.
6824 parameters = channel_->GetRtpSendParameters(primary_ssrc);
Åsa Persson31cb8f92018-06-27 10:44:56 +02006825 EXPECT_EQ(kNumSimulcastStreams, parameters.encodings.size());
Seth Hampson8234ead2018-02-02 15:16:24 -08006826 EXPECT_FALSE(parameters.encodings[0].active);
6827 EXPECT_FALSE(parameters.encodings[1].active);
6828 EXPECT_FALSE(parameters.encodings[2].active);
6829 // Check that the VideoSendStream is off.
6830 EXPECT_FALSE(fake_video_send_stream->IsSending());
6831 simulcast_streams = fake_video_send_stream->GetVideoStreams();
Åsa Persson31cb8f92018-06-27 10:44:56 +02006832 EXPECT_EQ(kNumSimulcastStreams, simulcast_streams.size());
Seth Hampson8234ead2018-02-02 15:16:24 -08006833 EXPECT_FALSE(simulcast_streams[0].active);
6834 EXPECT_FALSE(simulcast_streams[1].active);
6835 EXPECT_FALSE(simulcast_streams[2].active);
6836
Niels Möllerff40b142018-04-09 08:49:14 +02006837 EXPECT_TRUE(channel_->SetVideoSend(primary_ssrc, nullptr, nullptr));
Seth Hampson8234ead2018-02-02 15:16:24 -08006838}
6839
Taylor Brandstetter14b9d792016-09-07 17:16:54 -07006840// Test that if a stream is reconfigured (due to a codec change or other
6841// change) while its encoding is still inactive, it doesn't start sending.
eladalonf1841382017-06-12 01:16:46 -07006842TEST_F(WebRtcVideoChannelTest,
Taylor Brandstetter14b9d792016-09-07 17:16:54 -07006843 InactiveStreamDoesntStartSendingWhenReconfigured) {
6844 // Set an initial codec list, which will be modified later.
6845 cricket::VideoSendParameters parameters1;
magjed509e4fe2016-11-18 01:34:11 -08006846 parameters1.codecs.push_back(GetEngineCodec("VP8"));
6847 parameters1.codecs.push_back(GetEngineCodec("VP9"));
Taylor Brandstetter14b9d792016-09-07 17:16:54 -07006848 EXPECT_TRUE(channel_->SetSendParameters(parameters1));
6849
6850 FakeVideoSendStream* stream = AddSendStream();
6851 EXPECT_TRUE(channel_->SetSend(true));
6852 EXPECT_TRUE(stream->IsSending());
6853
6854 // Get current parameters and change "active" to false.
6855 webrtc::RtpParameters parameters = channel_->GetRtpSendParameters(last_ssrc_);
6856 ASSERT_EQ(1u, parameters.encodings.size());
6857 ASSERT_TRUE(parameters.encodings[0].active);
6858 parameters.encodings[0].active = false;
6859 EXPECT_EQ(1u, GetFakeSendStreams().size());
6860 EXPECT_EQ(1, fake_call_->GetNumCreatedSendStreams());
Zach Steinba37b4b2018-01-23 15:02:36 -08006861 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, parameters).ok());
Taylor Brandstetter14b9d792016-09-07 17:16:54 -07006862 EXPECT_FALSE(stream->IsSending());
6863
6864 // Reorder the codec list, causing the stream to be reconfigured.
6865 cricket::VideoSendParameters parameters2;
magjed509e4fe2016-11-18 01:34:11 -08006866 parameters2.codecs.push_back(GetEngineCodec("VP9"));
6867 parameters2.codecs.push_back(GetEngineCodec("VP8"));
Taylor Brandstetter14b9d792016-09-07 17:16:54 -07006868 EXPECT_TRUE(channel_->SetSendParameters(parameters2));
6869 auto new_streams = GetFakeSendStreams();
6870 // Assert that a new underlying stream was created due to the codec change.
6871 // Otherwise, this test isn't testing what it set out to test.
6872 EXPECT_EQ(1u, GetFakeSendStreams().size());
6873 EXPECT_EQ(2, fake_call_->GetNumCreatedSendStreams());
6874
6875 // Verify that we still are not sending anything, due to the inactive
6876 // encoding.
6877 EXPECT_FALSE(new_streams[0]->IsSending());
6878}
6879
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07006880// Test that GetRtpSendParameters returns the currently configured codecs.
eladalonf1841382017-06-12 01:16:46 -07006881TEST_F(WebRtcVideoChannelTest, GetRtpSendParametersCodecs) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07006882 AddSendStream();
6883 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08006884 parameters.codecs.push_back(GetEngineCodec("VP8"));
6885 parameters.codecs.push_back(GetEngineCodec("VP9"));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07006886 EXPECT_TRUE(channel_->SetSendParameters(parameters));
6887
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07006888 webrtc::RtpParameters rtp_parameters =
6889 channel_->GetRtpSendParameters(last_ssrc_);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07006890 ASSERT_EQ(2u, rtp_parameters.codecs.size());
magjed509e4fe2016-11-18 01:34:11 -08006891 EXPECT_EQ(GetEngineCodec("VP8").ToCodecParameters(),
6892 rtp_parameters.codecs[0]);
6893 EXPECT_EQ(GetEngineCodec("VP9").ToCodecParameters(),
6894 rtp_parameters.codecs[1]);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07006895}
6896
Florent Castellidacec712018-05-24 16:24:21 +02006897// Test that GetRtpSendParameters returns the currently configured RTCP CNAME.
6898TEST_F(WebRtcVideoChannelTest, GetRtpSendParametersRtcpCname) {
6899 StreamParams params = StreamParams::CreateLegacy(kSsrc);
6900 params.cname = "rtcpcname";
6901 AddSendStream(params);
6902
6903 webrtc::RtpParameters rtp_parameters = channel_->GetRtpSendParameters(kSsrc);
6904 EXPECT_STREQ("rtcpcname", rtp_parameters.rtcp.cname.c_str());
6905}
6906
deadbeeffb2aced2017-01-06 23:05:37 -08006907// Test that RtpParameters for send stream has one encoding and it has
6908// the correct SSRC.
eladalonf1841382017-06-12 01:16:46 -07006909TEST_F(WebRtcVideoChannelTest, GetRtpSendParametersSsrc) {
deadbeeffb2aced2017-01-06 23:05:37 -08006910 AddSendStream();
6911
6912 webrtc::RtpParameters rtp_parameters =
6913 channel_->GetRtpSendParameters(last_ssrc_);
6914 ASSERT_EQ(1u, rtp_parameters.encodings.size());
Oskar Sundbom78807582017-11-16 11:09:55 +01006915 EXPECT_EQ(last_ssrc_, rtp_parameters.encodings[0].ssrc);
deadbeeffb2aced2017-01-06 23:05:37 -08006916}
6917
Florent Castelliabe301f2018-06-12 18:33:49 +02006918TEST_F(WebRtcVideoChannelTest, DetectRtpSendParameterHeaderExtensionsChange) {
6919 AddSendStream();
6920
6921 webrtc::RtpParameters rtp_parameters =
6922 channel_->GetRtpSendParameters(last_ssrc_);
6923 rtp_parameters.header_extensions.emplace_back();
6924
6925 EXPECT_NE(0u, rtp_parameters.header_extensions.size());
6926
6927 webrtc::RTCError result =
6928 channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters);
6929 EXPECT_EQ(webrtc::RTCErrorType::INVALID_MODIFICATION, result.type());
6930}
6931
Florent Castelli87b3c512018-07-18 16:00:28 +02006932TEST_F(WebRtcVideoChannelTest, GetRtpSendParametersDegradationPreference) {
6933 AddSendStream();
6934
Niels Möller805a27e2019-01-21 12:21:27 +01006935 webrtc::test::FrameForwarder frame_forwarder;
6936 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, &frame_forwarder));
Florent Castelli87b3c512018-07-18 16:00:28 +02006937
6938 webrtc::RtpParameters rtp_parameters =
6939 channel_->GetRtpSendParameters(last_ssrc_);
6940 EXPECT_EQ(rtp_parameters.degradation_preference,
6941 webrtc::DegradationPreference::BALANCED);
6942 rtp_parameters.degradation_preference =
6943 webrtc::DegradationPreference::MAINTAIN_FRAMERATE;
6944
6945 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, rtp_parameters).ok());
6946
6947 webrtc::RtpParameters updated_rtp_parameters =
6948 channel_->GetRtpSendParameters(last_ssrc_);
6949 EXPECT_EQ(updated_rtp_parameters.degradation_preference,
6950 webrtc::DegradationPreference::MAINTAIN_FRAMERATE);
6951
6952 // Remove the source since it will be destroyed before the channel
6953 EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
6954}
6955
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07006956// Test that if we set/get parameters multiple times, we get the same results.
eladalonf1841382017-06-12 01:16:46 -07006957TEST_F(WebRtcVideoChannelTest, SetAndGetRtpSendParameters) {
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07006958 AddSendStream();
6959 cricket::VideoSendParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08006960 parameters.codecs.push_back(GetEngineCodec("VP8"));
6961 parameters.codecs.push_back(GetEngineCodec("VP9"));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07006962 EXPECT_TRUE(channel_->SetSendParameters(parameters));
6963
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07006964 webrtc::RtpParameters initial_params =
6965 channel_->GetRtpSendParameters(last_ssrc_);
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07006966
6967 // We should be able to set the params we just got.
Zach Steinba37b4b2018-01-23 15:02:36 -08006968 EXPECT_TRUE(channel_->SetRtpSendParameters(last_ssrc_, initial_params).ok());
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07006969
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07006970 // ... And this shouldn't change the params returned by GetRtpSendParameters.
6971 EXPECT_EQ(initial_params, channel_->GetRtpSendParameters(last_ssrc_));
6972}
6973
6974// Test that GetRtpReceiveParameters returns the currently configured codecs.
eladalonf1841382017-06-12 01:16:46 -07006975TEST_F(WebRtcVideoChannelTest, GetRtpReceiveParametersCodecs) {
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07006976 AddRecvStream();
6977 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08006978 parameters.codecs.push_back(GetEngineCodec("VP8"));
6979 parameters.codecs.push_back(GetEngineCodec("VP9"));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07006980 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
6981
6982 webrtc::RtpParameters rtp_parameters =
6983 channel_->GetRtpReceiveParameters(last_ssrc_);
6984 ASSERT_EQ(2u, rtp_parameters.codecs.size());
magjed509e4fe2016-11-18 01:34:11 -08006985 EXPECT_EQ(GetEngineCodec("VP8").ToCodecParameters(),
6986 rtp_parameters.codecs[0]);
6987 EXPECT_EQ(GetEngineCodec("VP9").ToCodecParameters(),
6988 rtp_parameters.codecs[1]);
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07006989}
6990
johan073ece42016-08-26 02:59:47 -07006991#if defined(WEBRTC_USE_H264)
eladalonf1841382017-06-12 01:16:46 -07006992TEST_F(WebRtcVideoChannelTest, GetRtpReceiveFmtpSprop) {
johan073ece42016-08-26 02:59:47 -07006993#else
eladalonf1841382017-06-12 01:16:46 -07006994TEST_F(WebRtcVideoChannelTest, DISABLED_GetRtpReceiveFmtpSprop) {
johan073ece42016-08-26 02:59:47 -07006995#endif
johan3859c892016-08-05 09:19:25 -07006996 cricket::VideoRecvParameters parameters;
perkj26752742016-10-24 01:21:16 -07006997 cricket::VideoCodec kH264sprop1(101, "H264");
magjed5dfac562016-11-25 03:56:37 -08006998 kH264sprop1.SetParam(kH264FmtpSpropParameterSets, "uvw");
johan3859c892016-08-05 09:19:25 -07006999 parameters.codecs.push_back(kH264sprop1);
perkj26752742016-10-24 01:21:16 -07007000 cricket::VideoCodec kH264sprop2(102, "H264");
magjed5dfac562016-11-25 03:56:37 -08007001 kH264sprop2.SetParam(kH264FmtpSpropParameterSets, "xyz");
johan3859c892016-08-05 09:19:25 -07007002 parameters.codecs.push_back(kH264sprop2);
7003 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
7004
7005 FakeVideoReceiveStream* recv_stream = AddRecvStream();
7006 const webrtc::VideoReceiveStream::Config& cfg = recv_stream->GetConfig();
7007 webrtc::RtpParameters rtp_parameters =
7008 channel_->GetRtpReceiveParameters(last_ssrc_);
7009 ASSERT_EQ(2u, rtp_parameters.codecs.size());
7010 EXPECT_EQ(kH264sprop1.ToCodecParameters(), rtp_parameters.codecs[0]);
7011 ASSERT_EQ(2u, cfg.decoders.size());
7012 EXPECT_EQ(101, cfg.decoders[0].payload_type);
Niels Möllercb7e1d22018-09-11 15:56:04 +02007013 EXPECT_EQ("H264", cfg.decoders[0].video_format.name);
magjed5dfac562016-11-25 03:56:37 -08007014 const auto it0 =
Niels Möllercb7e1d22018-09-11 15:56:04 +02007015 cfg.decoders[0].video_format.parameters.find(kH264FmtpSpropParameterSets);
7016 ASSERT_TRUE(it0 != cfg.decoders[0].video_format.parameters.end());
magjed5dfac562016-11-25 03:56:37 -08007017 EXPECT_EQ("uvw", it0->second);
johan3859c892016-08-05 09:19:25 -07007018
7019 EXPECT_EQ(102, cfg.decoders[1].payload_type);
Niels Möllercb7e1d22018-09-11 15:56:04 +02007020 EXPECT_EQ("H264", cfg.decoders[1].video_format.name);
magjed5dfac562016-11-25 03:56:37 -08007021 const auto it1 =
Niels Möllercb7e1d22018-09-11 15:56:04 +02007022 cfg.decoders[1].video_format.parameters.find(kH264FmtpSpropParameterSets);
7023 ASSERT_TRUE(it1 != cfg.decoders[1].video_format.parameters.end());
magjed5dfac562016-11-25 03:56:37 -08007024 EXPECT_EQ("xyz", it1->second);
johan3859c892016-08-05 09:19:25 -07007025}
7026
sakal1fd95952016-06-22 00:46:15 -07007027// Test that RtpParameters for receive stream has one encoding and it has
7028// the correct SSRC.
eladalonf1841382017-06-12 01:16:46 -07007029TEST_F(WebRtcVideoChannelTest, GetRtpReceiveParametersSsrc) {
sakal1fd95952016-06-22 00:46:15 -07007030 AddRecvStream();
7031
7032 webrtc::RtpParameters rtp_parameters =
7033 channel_->GetRtpReceiveParameters(last_ssrc_);
7034 ASSERT_EQ(1u, rtp_parameters.encodings.size());
Oskar Sundbom78807582017-11-16 11:09:55 +01007035 EXPECT_EQ(last_ssrc_, rtp_parameters.encodings[0].ssrc);
sakal1fd95952016-06-22 00:46:15 -07007036}
7037
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07007038// Test that if we set/get parameters multiple times, we get the same results.
eladalonf1841382017-06-12 01:16:46 -07007039TEST_F(WebRtcVideoChannelTest, SetAndGetRtpReceiveParameters) {
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07007040 AddRecvStream();
7041 cricket::VideoRecvParameters parameters;
magjed509e4fe2016-11-18 01:34:11 -08007042 parameters.codecs.push_back(GetEngineCodec("VP8"));
7043 parameters.codecs.push_back(GetEngineCodec("VP9"));
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -07007044 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
7045
7046 webrtc::RtpParameters initial_params =
7047 channel_->GetRtpReceiveParameters(last_ssrc_);
7048
7049 // We should be able to set the params we just got.
7050 EXPECT_TRUE(channel_->SetRtpReceiveParameters(last_ssrc_, initial_params));
7051
7052 // ... And this shouldn't change the params returned by
7053 // GetRtpReceiveParameters.
7054 EXPECT_EQ(initial_params, channel_->GetRtpReceiveParameters(last_ssrc_));
Taylor Brandstetter0cd086b2016-04-20 16:23:10 -07007055}
7056
deadbeef3bc15102017-04-20 19:25:07 -07007057// Test that GetRtpReceiveParameters returns parameters correctly when SSRCs
7058// aren't signaled. It should always return an empty "RtpEncodingParameters",
7059// even after a packet is received and the unsignaled SSRC is known.
eladalonf1841382017-06-12 01:16:46 -07007060TEST_F(WebRtcVideoChannelTest, GetRtpReceiveParametersWithUnsignaledSsrc) {
deadbeef3bc15102017-04-20 19:25:07 -07007061 // Call necessary methods to configure receiving a default stream as
7062 // soon as it arrives.
7063 cricket::VideoRecvParameters parameters;
7064 parameters.codecs.push_back(GetEngineCodec("VP8"));
7065 parameters.codecs.push_back(GetEngineCodec("VP9"));
7066 EXPECT_TRUE(channel_->SetRecvParameters(parameters));
7067
7068 // Call GetRtpReceiveParameters before configured to receive an unsignaled
7069 // stream. Should return nothing.
7070 EXPECT_EQ(webrtc::RtpParameters(), channel_->GetRtpReceiveParameters(0));
7071
7072 // Set a sink for an unsignaled stream.
7073 cricket::FakeVideoRenderer renderer;
7074 // Value of "0" means "unsignaled stream".
7075 EXPECT_TRUE(channel_->SetSink(0, &renderer));
7076
7077 // Call GetRtpReceiveParameters before the SSRC is known. Value of "0"
7078 // in this method means "unsignaled stream".
7079 webrtc::RtpParameters rtp_parameters = channel_->GetRtpReceiveParameters(0);
7080 ASSERT_EQ(1u, rtp_parameters.encodings.size());
7081 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
7082
7083 // Receive VP8 packet.
7084 uint8_t data[kMinRtpPacketLen];
7085 cricket::RtpHeader rtpHeader;
7086 rtpHeader.payload_type = GetEngineCodec("VP8").id;
7087 rtpHeader.seq_num = rtpHeader.timestamp = 0;
7088 rtpHeader.ssrc = kIncomingUnsignalledSsrc;
7089 cricket::SetRtpHeader(data, sizeof(data), rtpHeader);
7090 rtc::CopyOnWriteBuffer packet(data, sizeof(data));
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07007091 channel_->OnPacketReceived(packet, /* packet_time_us */ -1);
deadbeef3bc15102017-04-20 19:25:07 -07007092
7093 // The |ssrc| member should still be unset.
7094 rtp_parameters = channel_->GetRtpReceiveParameters(0);
7095 ASSERT_EQ(1u, rtp_parameters.encodings.size());
7096 EXPECT_FALSE(rtp_parameters.encodings[0].ssrc);
7097}
7098
eladalonf1841382017-06-12 01:16:46 -07007099void WebRtcVideoChannelTest::TestReceiverLocalSsrcConfiguration(
Peter Boström3548dd22015-05-22 18:48:36 +02007100 bool receiver_first) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02007101 EXPECT_TRUE(channel_->SetSendParameters(send_parameters_));
Peter Boström3548dd22015-05-22 18:48:36 +02007102
7103 const uint32_t kSenderSsrc = 0xC0FFEE;
Peter Boströmdfa28152015-10-21 17:21:10 +02007104 const uint32_t kSecondSenderSsrc = 0xBADCAFE;
Peter Boström3548dd22015-05-22 18:48:36 +02007105 const uint32_t kReceiverSsrc = 0x4711;
Peter Boströmdfa28152015-10-21 17:21:10 +02007106 const uint32_t kExpectedDefaultReceiverSsrc = 1;
Peter Boström3548dd22015-05-22 18:48:36 +02007107
7108 if (receiver_first) {
7109 AddRecvStream(StreamParams::CreateLegacy(kReceiverSsrc));
7110 std::vector<FakeVideoReceiveStream*> receive_streams =
7111 fake_call_->GetVideoReceiveStreams();
7112 ASSERT_EQ(1u, receive_streams.size());
Peter Boströmdfa28152015-10-21 17:21:10 +02007113 // Default local SSRC when we have no sender.
7114 EXPECT_EQ(kExpectedDefaultReceiverSsrc,
7115 receive_streams[0]->GetConfig().rtp.local_ssrc);
Peter Boström3548dd22015-05-22 18:48:36 +02007116 }
7117 AddSendStream(StreamParams::CreateLegacy(kSenderSsrc));
7118 if (!receiver_first)
7119 AddRecvStream(StreamParams::CreateLegacy(kReceiverSsrc));
7120 std::vector<FakeVideoReceiveStream*> receive_streams =
7121 fake_call_->GetVideoReceiveStreams();
7122 ASSERT_EQ(1u, receive_streams.size());
7123 EXPECT_EQ(kSenderSsrc, receive_streams[0]->GetConfig().rtp.local_ssrc);
Peter Boströmdfa28152015-10-21 17:21:10 +02007124
7125 // Removing first sender should fall back to another (in this case the second)
7126 // local send stream's SSRC.
7127 AddSendStream(StreamParams::CreateLegacy(kSecondSenderSsrc));
7128 ASSERT_TRUE(channel_->RemoveSendStream(kSenderSsrc));
Yves Gerey665174f2018-06-19 15:03:05 +02007129 receive_streams = fake_call_->GetVideoReceiveStreams();
Peter Boströmdfa28152015-10-21 17:21:10 +02007130 ASSERT_EQ(1u, receive_streams.size());
7131 EXPECT_EQ(kSecondSenderSsrc, receive_streams[0]->GetConfig().rtp.local_ssrc);
7132
7133 // Removing the last sender should fall back to default local SSRC.
7134 ASSERT_TRUE(channel_->RemoveSendStream(kSecondSenderSsrc));
Yves Gerey665174f2018-06-19 15:03:05 +02007135 receive_streams = fake_call_->GetVideoReceiveStreams();
Peter Boströmdfa28152015-10-21 17:21:10 +02007136 ASSERT_EQ(1u, receive_streams.size());
7137 EXPECT_EQ(kExpectedDefaultReceiverSsrc,
7138 receive_streams[0]->GetConfig().rtp.local_ssrc);
Peter Boström3548dd22015-05-22 18:48:36 +02007139}
7140
eladalonf1841382017-06-12 01:16:46 -07007141TEST_F(WebRtcVideoChannelTest, ConfiguresLocalSsrc) {
Peter Boström3548dd22015-05-22 18:48:36 +02007142 TestReceiverLocalSsrcConfiguration(false);
7143}
7144
eladalonf1841382017-06-12 01:16:46 -07007145TEST_F(WebRtcVideoChannelTest, ConfiguresLocalSsrcOnExistingReceivers) {
Peter Boström3548dd22015-05-22 18:48:36 +02007146 TestReceiverLocalSsrcConfiguration(true);
7147}
7148
Mirko Bonadei6a489f22019-04-09 15:11:12 +02007149class WebRtcVideoChannelSimulcastTest : public ::testing::Test {
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007150 public:
eladalonf1841382017-06-12 01:16:46 -07007151 WebRtcVideoChannelSimulcastTest()
Sebastian Jansson8f83b422018-02-21 13:07:13 +01007152 : fake_call_(),
Magnus Jedvert02e7a192017-09-23 17:21:32 +02007153 encoder_factory_(new cricket::FakeWebRtcVideoEncoderFactory),
7154 decoder_factory_(new cricket::FakeWebRtcVideoDecoderFactory),
Jiawei Ouc2ebe212018-11-08 10:02:56 -08007155 mock_rate_allocator_factory_(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02007156 absl::make_unique<webrtc::MockVideoBitrateAllocatorFactory>()),
Anders Carlsson67537952018-05-03 11:28:29 +02007157 engine_(std::unique_ptr<cricket::FakeWebRtcVideoEncoderFactory>(
Magnus Jedvert02e7a192017-09-23 17:21:32 +02007158 encoder_factory_),
Anders Carlsson67537952018-05-03 11:28:29 +02007159 std::unique_ptr<cricket::FakeWebRtcVideoDecoderFactory>(
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02007160 decoder_factory_)),
magjed2475ae22017-09-12 04:42:15 -07007161 last_ssrc_(0) {}
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007162
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +00007163 void SetUp() override {
Anders Carlsson5f2bb622018-05-14 09:48:06 +02007164 encoder_factory_->AddSupportedVideoCodecType("VP8");
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02007165 channel_.reset(engine_.CreateMediaChannel(
7166 &fake_call_, GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
7167 mock_rate_allocator_factory_.get()));
Sergey Ulanove2b15012016-11-22 16:08:30 -08007168 channel_->OnReadyToSend(true);
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007169 last_ssrc_ = 123;
7170 }
7171
7172 protected:
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007173 void VerifySimulcastSettings(const VideoCodec& codec,
perkj26752742016-10-24 01:21:16 -07007174 int capture_width,
7175 int capture_height,
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007176 size_t num_configured_streams,
sprang429600d2017-01-26 06:12:26 -08007177 size_t expected_num_streams,
7178 bool screenshare,
7179 bool conference_mode) {
Fredrik Solenbergb071a192015-09-17 16:42:56 +02007180 cricket::VideoSendParameters parameters;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02007181 parameters.codecs.push_back(codec);
sprang429600d2017-01-26 06:12:26 -08007182 parameters.conference_mode = conference_mode;
Fredrik Solenbergb071a192015-09-17 16:42:56 +02007183 ASSERT_TRUE(channel_->SetSendParameters(parameters));
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007184
Peter Boström0c4e06b2015-10-07 12:23:21 +02007185 std::vector<uint32_t> ssrcs = MAKE_VECTOR(kSsrcs3);
henrikg91d6ede2015-09-17 00:24:34 -07007186 RTC_DCHECK(num_configured_streams <= ssrcs.size());
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007187 ssrcs.resize(num_configured_streams);
7188
sprangf24a0642017-02-28 13:23:26 -08007189 AddSendStream(CreateSimStreamParams("cname", ssrcs));
pbos@webrtc.org86196c42015-02-16 21:02:00 +00007190 // Send a full-size frame to trigger a stream reconfiguration to use all
7191 // expected simulcast layers.
Niels Möller805a27e2019-01-21 12:21:27 +01007192 webrtc::test::FrameForwarder frame_forwarder;
7193 cricket::FakeFrameSource frame_source(capture_width, capture_height,
7194 rtc::kNumMicrosecsPerSec / 30);
7195
sprangf24a0642017-02-28 13:23:26 -08007196 VideoOptions options;
7197 if (screenshare)
Oskar Sundbom78807582017-11-16 11:09:55 +01007198 options.is_screencast = screenshare;
Niels Möller805a27e2019-01-21 12:21:27 +01007199 EXPECT_TRUE(
7200 channel_->SetVideoSend(ssrcs.front(), &options, &frame_forwarder));
sprangf24a0642017-02-28 13:23:26 -08007201 // Fetch the latest stream since SetVideoSend() may recreate it if the
7202 // screen content setting is changed.
7203 FakeVideoSendStream* stream = fake_call_.GetVideoSendStreams().front();
pbos@webrtc.org86196c42015-02-16 21:02:00 +00007204 channel_->SetSend(true);
Niels Möller805a27e2019-01-21 12:21:27 +01007205 frame_forwarder.IncomingCapturedFrame(frame_source.GetFrame());
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007206
Zach Stein3ca452b2018-01-18 10:01:24 -08007207 auto rtp_parameters = channel_->GetRtpSendParameters(kSsrcs3[0]);
7208 EXPECT_EQ(num_configured_streams, rtp_parameters.encodings.size());
7209
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007210 std::vector<webrtc::VideoStream> video_streams = stream->GetVideoStreams();
7211 ASSERT_EQ(expected_num_streams, video_streams.size());
Ilya Nikolaevskiy33d2a912019-04-02 11:05:03 +02007212 EXPECT_LE(expected_num_streams, stream->GetConfig().rtp.ssrcs.size());
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007213
sprang429600d2017-01-26 06:12:26 -08007214 std::vector<webrtc::VideoStream> expected_streams;
7215 if (conference_mode) {
7216 expected_streams = GetSimulcastConfig(
7217 num_configured_streams, capture_width, capture_height, 0,
Seth Hampson24722b32017-12-22 09:36:42 -08007218 webrtc::kDefaultBitratePriority, kDefaultQpMax,
Sergio Garcia Murillo43800f92018-06-21 16:16:38 +02007219 kDefaultVideoMaxFramerate, screenshare, true);
sprang3ebabf12017-02-16 07:35:22 -08007220 if (screenshare) {
7221 for (const webrtc::VideoStream& stream : expected_streams) {
7222 // Never scale screen content.
Danil Chapovalov350531e2018-06-08 11:04:04 +00007223 EXPECT_EQ(stream.width, rtc::checked_cast<size_t>(capture_width));
7224 EXPECT_EQ(stream.height, rtc::checked_cast<size_t>(capture_height));
sprang3ebabf12017-02-16 07:35:22 -08007225 }
7226 }
sprang429600d2017-01-26 06:12:26 -08007227 } else {
7228 webrtc::VideoStream stream;
7229 stream.width = capture_width;
7230 stream.height = capture_height;
7231 stream.max_framerate = kDefaultVideoMaxFramerate;
Åsa Persson45bbc8a2017-11-13 10:16:47 +01007232 stream.min_bitrate_bps = cricket::kMinVideoBitrateBps;
sprang429600d2017-01-26 06:12:26 -08007233 stream.target_bitrate_bps = stream.max_bitrate_bps =
Åsa Perssonbdee46d2018-06-25 11:28:06 +02007234 GetMaxDefaultBitrateBps(capture_width, capture_height);
sprang429600d2017-01-26 06:12:26 -08007235 stream.max_qp = kDefaultQpMax;
7236 expected_streams.push_back(stream);
7237 }
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007238
7239 ASSERT_EQ(expected_streams.size(), video_streams.size());
7240
7241 size_t num_streams = video_streams.size();
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00007242 int total_max_bitrate_bps = 0;
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007243 for (size_t i = 0; i < num_streams; ++i) {
7244 EXPECT_EQ(expected_streams[i].width, video_streams[i].width);
7245 EXPECT_EQ(expected_streams[i].height, video_streams[i].height);
7246
7247 EXPECT_GT(video_streams[i].max_framerate, 0);
7248 EXPECT_EQ(expected_streams[i].max_framerate,
7249 video_streams[i].max_framerate);
7250
7251 EXPECT_GT(video_streams[i].min_bitrate_bps, 0);
7252 EXPECT_EQ(expected_streams[i].min_bitrate_bps,
7253 video_streams[i].min_bitrate_bps);
7254
7255 EXPECT_GT(video_streams[i].target_bitrate_bps, 0);
7256 EXPECT_EQ(expected_streams[i].target_bitrate_bps,
7257 video_streams[i].target_bitrate_bps);
7258
7259 EXPECT_GT(video_streams[i].max_bitrate_bps, 0);
7260 EXPECT_EQ(expected_streams[i].max_bitrate_bps,
7261 video_streams[i].max_bitrate_bps);
7262
7263 EXPECT_GT(video_streams[i].max_qp, 0);
7264 EXPECT_EQ(expected_streams[i].max_qp, video_streams[i].max_qp);
7265
Sergey Silkina796a7e2018-03-01 15:11:29 +01007266 EXPECT_EQ(conference_mode,
7267 expected_streams[i].num_temporal_layers.has_value());
7268
7269 if (conference_mode) {
7270 EXPECT_EQ(expected_streams[i].num_temporal_layers,
7271 video_streams[i].num_temporal_layers);
7272 }
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00007273
7274 if (i == num_streams - 1) {
7275 total_max_bitrate_bps += video_streams[i].max_bitrate_bps;
7276 } else {
7277 total_max_bitrate_bps += video_streams[i].target_bitrate_bps;
7278 }
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007279 }
pbos@webrtc.org77e11bb2015-02-23 16:39:07 +00007280
Niels Möllerff40b142018-04-09 08:49:14 +02007281 EXPECT_TRUE(channel_->SetVideoSend(ssrcs.front(), nullptr, nullptr));
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007282 }
7283
7284 FakeVideoSendStream* AddSendStream() {
7285 return AddSendStream(StreamParams::CreateLegacy(last_ssrc_++));
7286 }
7287
7288 FakeVideoSendStream* AddSendStream(const StreamParams& sp) {
Yves Gerey665174f2018-06-19 15:03:05 +02007289 size_t num_streams = fake_call_.GetVideoSendStreams().size();
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007290 EXPECT_TRUE(channel_->AddSendStream(sp));
7291 std::vector<FakeVideoSendStream*> streams =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02007292 fake_call_.GetVideoSendStreams();
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007293 EXPECT_EQ(num_streams + 1, streams.size());
7294 return streams[streams.size() - 1];
7295 }
7296
7297 std::vector<FakeVideoSendStream*> GetFakeSendStreams() {
Fredrik Solenberg709ed672015-09-15 12:26:33 +02007298 return fake_call_.GetVideoSendStreams();
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007299 }
7300
7301 FakeVideoReceiveStream* AddRecvStream() {
7302 return AddRecvStream(StreamParams::CreateLegacy(last_ssrc_++));
7303 }
7304
7305 FakeVideoReceiveStream* AddRecvStream(const StreamParams& sp) {
Yves Gerey665174f2018-06-19 15:03:05 +02007306 size_t num_streams = fake_call_.GetVideoReceiveStreams().size();
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007307 EXPECT_TRUE(channel_->AddRecvStream(sp));
7308 std::vector<FakeVideoReceiveStream*> streams =
Fredrik Solenberg709ed672015-09-15 12:26:33 +02007309 fake_call_.GetVideoReceiveStreams();
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007310 EXPECT_EQ(num_streams + 1, streams.size());
7311 return streams[streams.size() - 1];
7312 }
7313
skvlad11a9cbf2016-10-07 11:53:05 -07007314 webrtc::RtcEventLogNullImpl event_log_;
Fredrik Solenberg709ed672015-09-15 12:26:33 +02007315 FakeCall fake_call_;
Magnus Jedvert02e7a192017-09-23 17:21:32 +02007316 cricket::FakeWebRtcVideoEncoderFactory* encoder_factory_;
7317 cricket::FakeWebRtcVideoDecoderFactory* decoder_factory_;
Jonas Orelanda3aa9bd2019-04-17 07:38:40 +02007318 std::unique_ptr<webrtc::MockVideoBitrateAllocatorFactory>
7319 mock_rate_allocator_factory_;
eladalonf1841382017-06-12 01:16:46 -07007320 WebRtcVideoEngine engine_;
kwiberg686a8ef2016-02-26 03:00:35 -08007321 std::unique_ptr<VideoMediaChannel> channel_;
Peter Boström0c4e06b2015-10-07 12:23:21 +02007322 uint32_t last_ssrc_;
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007323};
7324
eladalonf1841382017-06-12 01:16:46 -07007325TEST_F(WebRtcVideoChannelSimulcastTest, SetSendCodecsWith2SimulcastStreams) {
sprang429600d2017-01-26 06:12:26 -08007326 VerifySimulcastSettings(cricket::VideoCodec("VP8"), 640, 360, 2, 2, false,
7327 true);
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007328}
7329
eladalonf1841382017-06-12 01:16:46 -07007330TEST_F(WebRtcVideoChannelSimulcastTest, SetSendCodecsWith3SimulcastStreams) {
sprang429600d2017-01-26 06:12:26 -08007331 VerifySimulcastSettings(cricket::VideoCodec("VP8"), 1280, 720, 3, 3, false,
7332 true);
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007333}
7334
7335// Test that we normalize send codec format size in simulcast.
eladalonf1841382017-06-12 01:16:46 -07007336TEST_F(WebRtcVideoChannelSimulcastTest, SetSendCodecsWithOddSizeInSimulcast) {
sprang429600d2017-01-26 06:12:26 -08007337 VerifySimulcastSettings(cricket::VideoCodec("VP8"), 541, 271, 2, 2, false,
7338 true);
buildbot@webrtc.orga8530772014-12-10 09:01:18 +00007339}
sprang429600d2017-01-26 06:12:26 -08007340
Ilya Nikolaevskiy3df1d5d2018-08-22 09:26:51 +02007341TEST_F(WebRtcVideoChannelSimulcastTest, SetSendCodecsForScreenshare) {
Ilya Nikolaevskiy3df1d5d2018-08-22 09:26:51 +02007342 VerifySimulcastSettings(cricket::VideoCodec("VP8"), 1280, 720, 3, 1, true,
7343 false);
7344}
7345
Ilya Nikolaevskiy3df1d5d2018-08-22 09:26:51 +02007346TEST_F(WebRtcVideoChannelSimulcastTest,
7347 SetSendCodecsForConferenceModeScreenshare) {
Erik Språng72e52ee2018-11-29 11:41:53 +01007348 webrtc::test::ScopedFieldTrials field_trials(
7349 "WebRTC-SimulcastScreenshare/Disabled/");
Ilya Nikolaevskiy3df1d5d2018-08-22 09:26:51 +02007350 VerifySimulcastSettings(cricket::VideoCodec("VP8"), 1280, 720, 3, 1, true,
7351 true);
7352}
7353
eladalonf1841382017-06-12 01:16:46 -07007354TEST_F(WebRtcVideoChannelSimulcastTest, SetSendCodecsForSimulcastScreenshare) {
sprang429600d2017-01-26 06:12:26 -08007355 VerifySimulcastSettings(cricket::VideoCodec("VP8"), 1280, 720, 3, 2, true,
7356 true);
7357}
7358
eladalonf1841382017-06-12 01:16:46 -07007359TEST_F(WebRtcVideoChannelSimulcastTest,
sprangfe627f32017-03-29 08:24:59 -07007360 NoSimulcastScreenshareWithoutConference) {
sprangfe627f32017-03-29 08:24:59 -07007361 VerifySimulcastSettings(cricket::VideoCodec("VP8"), 1280, 720, 3, 1, true,
7362 false);
7363}
7364
Yves Gereyb6a89422018-10-08 10:08:32 +02007365class WebRtcVideoFakeClock {
Jonas Oreland49ac5952018-09-26 16:04:32 +02007366 public:
Yves Gereyb6a89422018-10-08 10:08:32 +02007367 WebRtcVideoFakeClock() {
Jonas Oreland49ac5952018-09-26 16:04:32 +02007368 fake_clock_.AdvanceTime(webrtc::TimeDelta::ms(1)); // avoid time=0
7369 }
7370 rtc::ScopedFakeClock fake_clock_;
7371};
7372
Yves Gereyb6a89422018-10-08 10:08:32 +02007373// The fake clock needs to be initialized before the call, and not
7374// destroyed until after all threads spawned by the test have been stopped.
7375// This mixin ensures that.
7376class WebRtcVideoChannelTestWithClock : public WebRtcVideoFakeClock,
7377 public WebRtcVideoChannelBaseTest {};
7378
Jonas Oreland49ac5952018-09-26 16:04:32 +02007379TEST_F(WebRtcVideoChannelTestWithClock, GetSources) {
7380 uint8_t data1[] = {0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
7381 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
7382
7383 EXPECT_EQ(0u, channel_->GetSources(kSsrc).size());
7384
7385 rtc::CopyOnWriteBuffer packet1(data1, sizeof(data1));
7386 rtc::SetBE32(packet1.data() + 8, kSsrc);
7387 channel_->SetSink(kDefaultReceiveSsrc, NULL);
7388 EXPECT_TRUE(SetDefaultCodec());
7389 EXPECT_TRUE(SetSend(true));
7390 EXPECT_EQ(0, renderer_.num_rendered_frames());
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07007391 channel_->OnPacketReceived(packet1, /*packet_time_us=*/-1);
Jonas Oreland49ac5952018-09-26 16:04:32 +02007392
7393 std::vector<webrtc::RtpSource> sources = channel_->GetSources(kSsrc);
7394 EXPECT_EQ(1u, sources.size());
7395 EXPECT_EQ(webrtc::RtpSourceType::SSRC, sources[0].source_type());
7396 int64_t timestamp1 = sources[0].timestamp_ms();
7397
7398 // a new packet.
7399 int64_t timeDeltaMs = 1;
7400 fake_clock_.AdvanceTime(webrtc::TimeDelta::ms(timeDeltaMs));
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07007401 channel_->OnPacketReceived(packet1, /*packet_time_us=*/-1);
Jonas Oreland49ac5952018-09-26 16:04:32 +02007402 int64_t timestamp2 = channel_->GetSources(kSsrc)[0].timestamp_ms();
7403 EXPECT_EQ(timestamp2, timestamp1 + timeDeltaMs);
7404
7405 // It only keeps 10s of history.
7406 fake_clock_.AdvanceTime(webrtc::TimeDelta::seconds(10));
7407 fake_clock_.AdvanceTime(webrtc::TimeDelta::ms(1));
7408 EXPECT_EQ(0u, channel_->GetSources(kSsrc).size());
7409}
7410
7411TEST_F(WebRtcVideoChannelTestWithClock, GetContributingSources) {
7412 uint8_t data1[] = {0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
7413 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
7414
7415 uint32_t kCsrc = 4321u;
7416 EXPECT_EQ(0u, channel_->GetSources(kSsrc).size());
7417 EXPECT_EQ(0u, channel_->GetSources(kCsrc).size());
7418
7419 rtc::CopyOnWriteBuffer packet1(data1, sizeof(data1));
7420 rtc::SetBE32(packet1.data() + 8, kSsrc);
7421 rtc::SetBE32(packet1.data() + 12, kCsrc);
7422 channel_->SetSink(kDefaultReceiveSsrc, NULL);
7423 EXPECT_TRUE(SetDefaultCodec());
7424 EXPECT_TRUE(SetSend(true));
7425 EXPECT_EQ(0, renderer_.num_rendered_frames());
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07007426 channel_->OnPacketReceived(packet1, /*packet_time_us=*/-1);
Jonas Oreland49ac5952018-09-26 16:04:32 +02007427
7428 {
7429 ASSERT_EQ(2u, channel_->GetSources(kSsrc).size());
7430 EXPECT_EQ(0u, channel_->GetSources(kCsrc).size());
7431 std::vector<webrtc::RtpSource> sources = channel_->GetSources(kSsrc);
7432 EXPECT_EQ(sources[0].timestamp_ms(), sources[1].timestamp_ms());
7433 // 1 SSRC and 1 CSRC.
Steve Anton2c9ebef2019-01-28 17:27:58 -08007434 EXPECT_EQ(1, absl::c_count_if(sources, [](const webrtc::RtpSource& source) {
7435 return source.source_type() == webrtc::RtpSourceType::SSRC;
7436 }));
7437 EXPECT_EQ(1, absl::c_count_if(sources, [](const webrtc::RtpSource& source) {
7438 return source.source_type() == webrtc::RtpSourceType::CSRC;
7439 }));
Jonas Oreland49ac5952018-09-26 16:04:32 +02007440 }
7441 int64_t timestamp1 = channel_->GetSources(kSsrc)[0].timestamp_ms();
7442
7443 // a new packet with only ssrc (i.e no csrc).
7444 uint8_t data2[] = {0x80, 0x00, 0x00, 0x00, 0x00, 0x00,
7445 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
7446 rtc::CopyOnWriteBuffer packet2(data2, sizeof(data2));
7447 rtc::SetBE32(packet2.data() + 8, kSsrc);
7448
7449 int64_t timeDeltaMs = 1;
7450 fake_clock_.AdvanceTime(webrtc::TimeDelta::ms(timeDeltaMs));
Amit Hilbuche7a5f7b2019-03-12 11:10:27 -07007451 channel_->OnPacketReceived(packet2, /*packet_time_us=*/-1);
Jonas Oreland49ac5952018-09-26 16:04:32 +02007452
7453 {
7454 ASSERT_EQ(2u, channel_->GetSources(kSsrc).size());
7455 EXPECT_EQ(0u, channel_->GetSources(kCsrc).size());
7456 std::vector<webrtc::RtpSource> sources = channel_->GetSources(kSsrc);
7457 EXPECT_NE(sources[0].timestamp_ms(), sources[1].timestamp_ms());
7458 // 1 SSRC and 1 CSRC.
Steve Anton2c9ebef2019-01-28 17:27:58 -08007459 EXPECT_EQ(1, absl::c_count_if(sources, [](const webrtc::RtpSource& source) {
7460 return source.source_type() == webrtc::RtpSourceType::SSRC;
7461 }));
7462 EXPECT_EQ(1, absl::c_count_if(sources, [](const webrtc::RtpSource& source) {
7463 return source.source_type() == webrtc::RtpSourceType::CSRC;
7464 }));
7465 auto ssrcSource =
7466 absl::c_find_if(sources, [](const webrtc::RtpSource& source) {
Jonas Oreland49ac5952018-09-26 16:04:32 +02007467 return source.source_type() == webrtc::RtpSourceType::SSRC;
7468 });
Steve Anton2c9ebef2019-01-28 17:27:58 -08007469 auto csrcSource =
7470 absl::c_find_if(sources, [](const webrtc::RtpSource& source) {
Jonas Oreland49ac5952018-09-26 16:04:32 +02007471 return source.source_type() == webrtc::RtpSourceType::CSRC;
7472 });
7473
7474 EXPECT_EQ(ssrcSource->timestamp_ms(), timestamp1 + timeDeltaMs);
7475 EXPECT_EQ(csrcSource->timestamp_ms(), timestamp1);
7476 }
7477
7478 // It only keeps 10s of history.
7479 fake_clock_.AdvanceTime(webrtc::TimeDelta::seconds(10));
7480
7481 {
7482 ASSERT_EQ(1u, channel_->GetSources(kSsrc).size());
7483 EXPECT_EQ(0u, channel_->GetSources(kCsrc).size());
7484 std::vector<webrtc::RtpSource> sources = channel_->GetSources(kSsrc);
Steve Anton2c9ebef2019-01-28 17:27:58 -08007485 EXPECT_EQ(1, absl::c_count_if(sources, [](const webrtc::RtpSource& source) {
7486 return source.source_type() == webrtc::RtpSourceType::SSRC;
7487 }));
7488 EXPECT_EQ(0, absl::c_count_if(sources, [](const webrtc::RtpSource& source) {
7489 return source.source_type() == webrtc::RtpSourceType::CSRC;
7490 }));
Jonas Oreland49ac5952018-09-26 16:04:32 +02007491 }
7492
7493 fake_clock_.AdvanceTime(webrtc::TimeDelta::ms(1));
7494 EXPECT_EQ(0u, channel_->GetSources(kSsrc).size());
7495 EXPECT_EQ(0u, channel_->GetSources(kCsrc).size());
7496}
7497
Amit Hilbuchb000b712019-02-25 10:22:14 -08007498TEST_F(WebRtcVideoChannelTest, SetsRidsOnSendStream) {
7499 StreamParams sp = CreateSimStreamParams("cname", {123, 456, 789});
7500
7501 std::vector<std::string> rids = {"f", "h", "q"};
7502 std::vector<cricket::RidDescription> rid_descriptions;
7503 for (const auto& rid : rids) {
7504 rid_descriptions.emplace_back(rid, cricket::RidDirection::kSend);
7505 }
7506 sp.set_rids(rid_descriptions);
7507
7508 ASSERT_TRUE(channel_->AddSendStream(sp));
7509 const auto& streams = fake_call_->GetVideoSendStreams();
7510 ASSERT_EQ(1u, streams.size());
7511 auto stream = streams[0];
7512 ASSERT_NE(stream, nullptr);
7513 const auto& config = stream->GetConfig();
7514 EXPECT_THAT(config.rtp.rids, ::testing::ElementsAreArray(rids));
7515}
7516
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +00007517} // namespace cricket