1*d9f75844SAndroid Build Coastguard Worker /*
2*d9f75844SAndroid Build Coastguard Worker * Copyright 2012 The WebRTC project authors. All Rights Reserved.
3*d9f75844SAndroid Build Coastguard Worker *
4*d9f75844SAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license
5*d9f75844SAndroid Build Coastguard Worker * that can be found in the LICENSE file in the root of the source
6*d9f75844SAndroid Build Coastguard Worker * tree. An additional intellectual property rights grant can be found
7*d9f75844SAndroid Build Coastguard Worker * in the file PATENTS. All contributing project authors may
8*d9f75844SAndroid Build Coastguard Worker * be found in the AUTHORS file in the root of the source tree.
9*d9f75844SAndroid Build Coastguard Worker */
10*d9f75844SAndroid Build Coastguard Worker
11*d9f75844SAndroid Build Coastguard Worker #include <stddef.h>
12*d9f75844SAndroid Build Coastguard Worker
13*d9f75844SAndroid Build Coastguard Worker #include <cstdint>
14*d9f75844SAndroid Build Coastguard Worker #include <iterator>
15*d9f75844SAndroid Build Coastguard Worker #include <memory>
16*d9f75844SAndroid Build Coastguard Worker #include <string>
17*d9f75844SAndroid Build Coastguard Worker #include <utility>
18*d9f75844SAndroid Build Coastguard Worker #include <vector>
19*d9f75844SAndroid Build Coastguard Worker
20*d9f75844SAndroid Build Coastguard Worker #include "absl/algorithm/container.h"
21*d9f75844SAndroid Build Coastguard Worker #include "absl/memory/memory.h"
22*d9f75844SAndroid Build Coastguard Worker #include "absl/types/optional.h"
23*d9f75844SAndroid Build Coastguard Worker #include "api/audio_options.h"
24*d9f75844SAndroid Build Coastguard Worker #include "api/crypto/crypto_options.h"
25*d9f75844SAndroid Build Coastguard Worker #include "api/crypto/frame_decryptor_interface.h"
26*d9f75844SAndroid Build Coastguard Worker #include "api/crypto/frame_encryptor_interface.h"
27*d9f75844SAndroid Build Coastguard Worker #include "api/dtmf_sender_interface.h"
28*d9f75844SAndroid Build Coastguard Worker #include "api/media_stream_interface.h"
29*d9f75844SAndroid Build Coastguard Worker #include "api/rtc_error.h"
30*d9f75844SAndroid Build Coastguard Worker #include "api/rtc_event_log/rtc_event_log.h"
31*d9f75844SAndroid Build Coastguard Worker #include "api/rtp_parameters.h"
32*d9f75844SAndroid Build Coastguard Worker #include "api/rtp_receiver_interface.h"
33*d9f75844SAndroid Build Coastguard Worker #include "api/scoped_refptr.h"
34*d9f75844SAndroid Build Coastguard Worker #include "api/test/fake_frame_decryptor.h"
35*d9f75844SAndroid Build Coastguard Worker #include "api/test/fake_frame_encryptor.h"
36*d9f75844SAndroid Build Coastguard Worker #include "api/video/builtin_video_bitrate_allocator_factory.h"
37*d9f75844SAndroid Build Coastguard Worker #include "api/video/video_bitrate_allocator_factory.h"
38*d9f75844SAndroid Build Coastguard Worker #include "api/video/video_codec_constants.h"
39*d9f75844SAndroid Build Coastguard Worker #include "media/base/codec.h"
40*d9f75844SAndroid Build Coastguard Worker #include "media/base/delayable.h"
41*d9f75844SAndroid Build Coastguard Worker #include "media/base/fake_media_engine.h"
42*d9f75844SAndroid Build Coastguard Worker #include "media/base/media_channel.h"
43*d9f75844SAndroid Build Coastguard Worker #include "media/base/media_config.h"
44*d9f75844SAndroid Build Coastguard Worker #include "media/base/media_engine.h"
45*d9f75844SAndroid Build Coastguard Worker #include "media/base/rid_description.h"
46*d9f75844SAndroid Build Coastguard Worker #include "media/base/stream_params.h"
47*d9f75844SAndroid Build Coastguard Worker #include "media/base/test_utils.h"
48*d9f75844SAndroid Build Coastguard Worker #include "media/engine/fake_webrtc_call.h"
49*d9f75844SAndroid Build Coastguard Worker #include "p2p/base/dtls_transport_internal.h"
50*d9f75844SAndroid Build Coastguard Worker #include "p2p/base/fake_dtls_transport.h"
51*d9f75844SAndroid Build Coastguard Worker #include "p2p/base/p2p_constants.h"
52*d9f75844SAndroid Build Coastguard Worker #include "pc/audio_rtp_receiver.h"
53*d9f75844SAndroid Build Coastguard Worker #include "pc/audio_track.h"
54*d9f75844SAndroid Build Coastguard Worker #include "pc/channel.h"
55*d9f75844SAndroid Build Coastguard Worker #include "pc/dtls_srtp_transport.h"
56*d9f75844SAndroid Build Coastguard Worker #include "pc/local_audio_source.h"
57*d9f75844SAndroid Build Coastguard Worker #include "pc/media_stream.h"
58*d9f75844SAndroid Build Coastguard Worker #include "pc/rtp_sender.h"
59*d9f75844SAndroid Build Coastguard Worker #include "pc/rtp_transport_internal.h"
60*d9f75844SAndroid Build Coastguard Worker #include "pc/test/fake_video_track_source.h"
61*d9f75844SAndroid Build Coastguard Worker #include "pc/video_rtp_receiver.h"
62*d9f75844SAndroid Build Coastguard Worker #include "pc/video_track.h"
63*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/checks.h"
64*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/gunit.h"
65*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/thread.h"
66*d9f75844SAndroid Build Coastguard Worker #include "test/gmock.h"
67*d9f75844SAndroid Build Coastguard Worker #include "test/gtest.h"
68*d9f75844SAndroid Build Coastguard Worker #include "test/run_loop.h"
69*d9f75844SAndroid Build Coastguard Worker #include "test/scoped_key_value_config.h"
70*d9f75844SAndroid Build Coastguard Worker
71*d9f75844SAndroid Build Coastguard Worker using ::testing::_;
72*d9f75844SAndroid Build Coastguard Worker using ::testing::ContainerEq;
73*d9f75844SAndroid Build Coastguard Worker using ::testing::Exactly;
74*d9f75844SAndroid Build Coastguard Worker using ::testing::InvokeWithoutArgs;
75*d9f75844SAndroid Build Coastguard Worker using ::testing::Return;
76*d9f75844SAndroid Build Coastguard Worker using RidList = std::vector<std::string>;
77*d9f75844SAndroid Build Coastguard Worker
78*d9f75844SAndroid Build Coastguard Worker namespace {
79*d9f75844SAndroid Build Coastguard Worker
80*d9f75844SAndroid Build Coastguard Worker static const char kStreamId1[] = "local_stream_1";
81*d9f75844SAndroid Build Coastguard Worker static const char kVideoTrackId[] = "video_1";
82*d9f75844SAndroid Build Coastguard Worker static const char kAudioTrackId[] = "audio_1";
83*d9f75844SAndroid Build Coastguard Worker static const uint32_t kVideoSsrc = 98;
84*d9f75844SAndroid Build Coastguard Worker static const uint32_t kVideoSsrc2 = 100;
85*d9f75844SAndroid Build Coastguard Worker static const uint32_t kAudioSsrc = 99;
86*d9f75844SAndroid Build Coastguard Worker static const uint32_t kAudioSsrc2 = 101;
87*d9f75844SAndroid Build Coastguard Worker static const uint32_t kVideoSsrcSimulcast = 102;
88*d9f75844SAndroid Build Coastguard Worker static const uint32_t kVideoSimulcastLayerCount = 2;
89*d9f75844SAndroid Build Coastguard Worker static const int kDefaultTimeout = 10000; // 10 seconds.
90*d9f75844SAndroid Build Coastguard Worker
91*d9f75844SAndroid Build Coastguard Worker class MockSetStreamsObserver
92*d9f75844SAndroid Build Coastguard Worker : public webrtc::RtpSenderBase::SetStreamsObserver {
93*d9f75844SAndroid Build Coastguard Worker public:
94*d9f75844SAndroid Build Coastguard Worker MOCK_METHOD(void, OnSetStreams, (), (override));
95*d9f75844SAndroid Build Coastguard Worker };
96*d9f75844SAndroid Build Coastguard Worker
97*d9f75844SAndroid Build Coastguard Worker } // namespace
98*d9f75844SAndroid Build Coastguard Worker
99*d9f75844SAndroid Build Coastguard Worker namespace webrtc {
100*d9f75844SAndroid Build Coastguard Worker
101*d9f75844SAndroid Build Coastguard Worker class RtpSenderReceiverTest
102*d9f75844SAndroid Build Coastguard Worker : public ::testing::Test,
103*d9f75844SAndroid Build Coastguard Worker public ::testing::WithParamInterface<std::pair<RidList, RidList>> {
104*d9f75844SAndroid Build Coastguard Worker public:
RtpSenderReceiverTest()105*d9f75844SAndroid Build Coastguard Worker RtpSenderReceiverTest()
106*d9f75844SAndroid Build Coastguard Worker : network_thread_(rtc::Thread::Current()),
107*d9f75844SAndroid Build Coastguard Worker worker_thread_(rtc::Thread::Current()),
108*d9f75844SAndroid Build Coastguard Worker video_bitrate_allocator_factory_(
109*d9f75844SAndroid Build Coastguard Worker webrtc::CreateBuiltinVideoBitrateAllocatorFactory()),
110*d9f75844SAndroid Build Coastguard Worker // Create fake media engine/etc. so we can create channels to use to
111*d9f75844SAndroid Build Coastguard Worker // test RtpSenders/RtpReceivers.
112*d9f75844SAndroid Build Coastguard Worker media_engine_(std::make_unique<cricket::FakeMediaEngine>()),
113*d9f75844SAndroid Build Coastguard Worker fake_call_(worker_thread_, network_thread_),
114*d9f75844SAndroid Build Coastguard Worker local_stream_(MediaStream::Create(kStreamId1)) {
115*d9f75844SAndroid Build Coastguard Worker rtp_dtls_transport_ = std::make_unique<cricket::FakeDtlsTransport>(
116*d9f75844SAndroid Build Coastguard Worker "fake_dtls_transport", cricket::ICE_CANDIDATE_COMPONENT_RTP);
117*d9f75844SAndroid Build Coastguard Worker rtp_transport_ = CreateDtlsSrtpTransport();
118*d9f75844SAndroid Build Coastguard Worker
119*d9f75844SAndroid Build Coastguard Worker // Create the channels, discard the result; we get them later.
120*d9f75844SAndroid Build Coastguard Worker // Fake media channels are owned by the media engine.
121*d9f75844SAndroid Build Coastguard Worker media_engine_->voice().CreateMediaChannel(
122*d9f75844SAndroid Build Coastguard Worker &fake_call_, cricket::MediaConfig(), cricket::AudioOptions(),
123*d9f75844SAndroid Build Coastguard Worker webrtc::CryptoOptions());
124*d9f75844SAndroid Build Coastguard Worker media_engine_->video().CreateMediaChannel(
125*d9f75844SAndroid Build Coastguard Worker &fake_call_, cricket::MediaConfig(), cricket::VideoOptions(),
126*d9f75844SAndroid Build Coastguard Worker webrtc::CryptoOptions(), video_bitrate_allocator_factory_.get());
127*d9f75844SAndroid Build Coastguard Worker
128*d9f75844SAndroid Build Coastguard Worker voice_media_channel_ = absl::WrapUnique(media_engine_->GetVoiceChannel(0));
129*d9f75844SAndroid Build Coastguard Worker video_media_channel_ = absl::WrapUnique(media_engine_->GetVideoChannel(0));
130*d9f75844SAndroid Build Coastguard Worker
131*d9f75844SAndroid Build Coastguard Worker RTC_CHECK(voice_media_channel());
132*d9f75844SAndroid Build Coastguard Worker RTC_CHECK(video_media_channel());
133*d9f75844SAndroid Build Coastguard Worker
134*d9f75844SAndroid Build Coastguard Worker // Create streams for predefined SSRCs. Streams need to exist in order
135*d9f75844SAndroid Build Coastguard Worker // for the senders and receievers to apply parameters to them.
136*d9f75844SAndroid Build Coastguard Worker // Normally these would be created by SetLocalDescription and
137*d9f75844SAndroid Build Coastguard Worker // SetRemoteDescription.
138*d9f75844SAndroid Build Coastguard Worker voice_media_channel_->AddSendStream(
139*d9f75844SAndroid Build Coastguard Worker cricket::StreamParams::CreateLegacy(kAudioSsrc));
140*d9f75844SAndroid Build Coastguard Worker voice_media_channel_->AddRecvStream(
141*d9f75844SAndroid Build Coastguard Worker cricket::StreamParams::CreateLegacy(kAudioSsrc));
142*d9f75844SAndroid Build Coastguard Worker voice_media_channel_->AddSendStream(
143*d9f75844SAndroid Build Coastguard Worker cricket::StreamParams::CreateLegacy(kAudioSsrc2));
144*d9f75844SAndroid Build Coastguard Worker voice_media_channel_->AddRecvStream(
145*d9f75844SAndroid Build Coastguard Worker cricket::StreamParams::CreateLegacy(kAudioSsrc2));
146*d9f75844SAndroid Build Coastguard Worker video_media_channel_->AddSendStream(
147*d9f75844SAndroid Build Coastguard Worker cricket::StreamParams::CreateLegacy(kVideoSsrc));
148*d9f75844SAndroid Build Coastguard Worker video_media_channel_->AddRecvStream(
149*d9f75844SAndroid Build Coastguard Worker cricket::StreamParams::CreateLegacy(kVideoSsrc));
150*d9f75844SAndroid Build Coastguard Worker video_media_channel_->AddSendStream(
151*d9f75844SAndroid Build Coastguard Worker cricket::StreamParams::CreateLegacy(kVideoSsrc2));
152*d9f75844SAndroid Build Coastguard Worker video_media_channel_->AddRecvStream(
153*d9f75844SAndroid Build Coastguard Worker cricket::StreamParams::CreateLegacy(kVideoSsrc2));
154*d9f75844SAndroid Build Coastguard Worker }
155*d9f75844SAndroid Build Coastguard Worker
~RtpSenderReceiverTest()156*d9f75844SAndroid Build Coastguard Worker ~RtpSenderReceiverTest() {
157*d9f75844SAndroid Build Coastguard Worker audio_rtp_sender_ = nullptr;
158*d9f75844SAndroid Build Coastguard Worker video_rtp_sender_ = nullptr;
159*d9f75844SAndroid Build Coastguard Worker audio_rtp_receiver_ = nullptr;
160*d9f75844SAndroid Build Coastguard Worker video_rtp_receiver_ = nullptr;
161*d9f75844SAndroid Build Coastguard Worker local_stream_ = nullptr;
162*d9f75844SAndroid Build Coastguard Worker video_track_ = nullptr;
163*d9f75844SAndroid Build Coastguard Worker audio_track_ = nullptr;
164*d9f75844SAndroid Build Coastguard Worker }
165*d9f75844SAndroid Build Coastguard Worker
CreateDtlsSrtpTransport()166*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<webrtc::RtpTransportInternal> CreateDtlsSrtpTransport() {
167*d9f75844SAndroid Build Coastguard Worker auto dtls_srtp_transport = std::make_unique<webrtc::DtlsSrtpTransport>(
168*d9f75844SAndroid Build Coastguard Worker /*rtcp_mux_required=*/true, field_trials_);
169*d9f75844SAndroid Build Coastguard Worker dtls_srtp_transport->SetDtlsTransports(rtp_dtls_transport_.get(),
170*d9f75844SAndroid Build Coastguard Worker /*rtcp_dtls_transport=*/nullptr);
171*d9f75844SAndroid Build Coastguard Worker return dtls_srtp_transport;
172*d9f75844SAndroid Build Coastguard Worker }
173*d9f75844SAndroid Build Coastguard Worker
174*d9f75844SAndroid Build Coastguard Worker // Needed to use DTMF sender.
AddDtmfCodec()175*d9f75844SAndroid Build Coastguard Worker void AddDtmfCodec() {
176*d9f75844SAndroid Build Coastguard Worker cricket::AudioSendParameters params;
177*d9f75844SAndroid Build Coastguard Worker const cricket::AudioCodec kTelephoneEventCodec(106, "telephone-event", 8000,
178*d9f75844SAndroid Build Coastguard Worker 0, 1);
179*d9f75844SAndroid Build Coastguard Worker params.codecs.push_back(kTelephoneEventCodec);
180*d9f75844SAndroid Build Coastguard Worker voice_media_channel()->SetSendParameters(params);
181*d9f75844SAndroid Build Coastguard Worker }
182*d9f75844SAndroid Build Coastguard Worker
AddVideoTrack()183*d9f75844SAndroid Build Coastguard Worker void AddVideoTrack() { AddVideoTrack(false); }
184*d9f75844SAndroid Build Coastguard Worker
AddVideoTrack(bool is_screencast)185*d9f75844SAndroid Build Coastguard Worker void AddVideoTrack(bool is_screencast) {
186*d9f75844SAndroid Build Coastguard Worker rtc::scoped_refptr<VideoTrackSourceInterface> source(
187*d9f75844SAndroid Build Coastguard Worker FakeVideoTrackSource::Create(is_screencast));
188*d9f75844SAndroid Build Coastguard Worker video_track_ =
189*d9f75844SAndroid Build Coastguard Worker VideoTrack::Create(kVideoTrackId, source, rtc::Thread::Current());
190*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(local_stream_->AddTrack(video_track_));
191*d9f75844SAndroid Build Coastguard Worker }
192*d9f75844SAndroid Build Coastguard Worker
CreateAudioRtpSender()193*d9f75844SAndroid Build Coastguard Worker void CreateAudioRtpSender() { CreateAudioRtpSender(nullptr); }
194*d9f75844SAndroid Build Coastguard Worker
CreateAudioRtpSender(const rtc::scoped_refptr<LocalAudioSource> & source)195*d9f75844SAndroid Build Coastguard Worker void CreateAudioRtpSender(
196*d9f75844SAndroid Build Coastguard Worker const rtc::scoped_refptr<LocalAudioSource>& source) {
197*d9f75844SAndroid Build Coastguard Worker audio_track_ = AudioTrack::Create(kAudioTrackId, source);
198*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(local_stream_->AddTrack(audio_track_));
199*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<MockSetStreamsObserver> set_streams_observer =
200*d9f75844SAndroid Build Coastguard Worker std::make_unique<MockSetStreamsObserver>();
201*d9f75844SAndroid Build Coastguard Worker audio_rtp_sender_ =
202*d9f75844SAndroid Build Coastguard Worker AudioRtpSender::Create(worker_thread_, audio_track_->id(), nullptr,
203*d9f75844SAndroid Build Coastguard Worker set_streams_observer.get());
204*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(audio_rtp_sender_->SetTrack(audio_track_.get()));
205*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(*set_streams_observer, OnSetStreams());
206*d9f75844SAndroid Build Coastguard Worker audio_rtp_sender_->SetStreams({local_stream_->id()});
207*d9f75844SAndroid Build Coastguard Worker audio_rtp_sender_->SetMediaChannel(voice_media_channel());
208*d9f75844SAndroid Build Coastguard Worker audio_rtp_sender_->SetSsrc(kAudioSsrc);
209*d9f75844SAndroid Build Coastguard Worker VerifyVoiceChannelInput();
210*d9f75844SAndroid Build Coastguard Worker }
211*d9f75844SAndroid Build Coastguard Worker
CreateAudioRtpSenderWithNoTrack()212*d9f75844SAndroid Build Coastguard Worker void CreateAudioRtpSenderWithNoTrack() {
213*d9f75844SAndroid Build Coastguard Worker audio_rtp_sender_ =
214*d9f75844SAndroid Build Coastguard Worker AudioRtpSender::Create(worker_thread_, /*id=*/"", nullptr, nullptr);
215*d9f75844SAndroid Build Coastguard Worker audio_rtp_sender_->SetMediaChannel(voice_media_channel());
216*d9f75844SAndroid Build Coastguard Worker }
217*d9f75844SAndroid Build Coastguard Worker
CreateVideoRtpSender(uint32_t ssrc)218*d9f75844SAndroid Build Coastguard Worker void CreateVideoRtpSender(uint32_t ssrc) {
219*d9f75844SAndroid Build Coastguard Worker CreateVideoRtpSender(false, ssrc);
220*d9f75844SAndroid Build Coastguard Worker }
221*d9f75844SAndroid Build Coastguard Worker
CreateVideoRtpSender()222*d9f75844SAndroid Build Coastguard Worker void CreateVideoRtpSender() { CreateVideoRtpSender(false); }
223*d9f75844SAndroid Build Coastguard Worker
CreateSimulcastStreamParams(int num_layers)224*d9f75844SAndroid Build Coastguard Worker cricket::StreamParams CreateSimulcastStreamParams(int num_layers) {
225*d9f75844SAndroid Build Coastguard Worker std::vector<uint32_t> ssrcs;
226*d9f75844SAndroid Build Coastguard Worker ssrcs.reserve(num_layers);
227*d9f75844SAndroid Build Coastguard Worker for (int i = 0; i < num_layers; ++i) {
228*d9f75844SAndroid Build Coastguard Worker ssrcs.push_back(kVideoSsrcSimulcast + i);
229*d9f75844SAndroid Build Coastguard Worker }
230*d9f75844SAndroid Build Coastguard Worker return cricket::CreateSimStreamParams("cname", ssrcs);
231*d9f75844SAndroid Build Coastguard Worker }
232*d9f75844SAndroid Build Coastguard Worker
CreateVideoRtpSender(const cricket::StreamParams & stream_params)233*d9f75844SAndroid Build Coastguard Worker uint32_t CreateVideoRtpSender(const cricket::StreamParams& stream_params) {
234*d9f75844SAndroid Build Coastguard Worker video_media_channel_->AddSendStream(stream_params);
235*d9f75844SAndroid Build Coastguard Worker uint32_t primary_ssrc = stream_params.first_ssrc();
236*d9f75844SAndroid Build Coastguard Worker CreateVideoRtpSender(primary_ssrc);
237*d9f75844SAndroid Build Coastguard Worker return primary_ssrc;
238*d9f75844SAndroid Build Coastguard Worker }
239*d9f75844SAndroid Build Coastguard Worker
CreateVideoRtpSenderWithSimulcast(int num_layers=kVideoSimulcastLayerCount)240*d9f75844SAndroid Build Coastguard Worker uint32_t CreateVideoRtpSenderWithSimulcast(
241*d9f75844SAndroid Build Coastguard Worker int num_layers = kVideoSimulcastLayerCount) {
242*d9f75844SAndroid Build Coastguard Worker return CreateVideoRtpSender(CreateSimulcastStreamParams(num_layers));
243*d9f75844SAndroid Build Coastguard Worker }
244*d9f75844SAndroid Build Coastguard Worker
CreateVideoRtpSenderWithSimulcast(const std::vector<std::string> & rids)245*d9f75844SAndroid Build Coastguard Worker uint32_t CreateVideoRtpSenderWithSimulcast(
246*d9f75844SAndroid Build Coastguard Worker const std::vector<std::string>& rids) {
247*d9f75844SAndroid Build Coastguard Worker cricket::StreamParams stream_params =
248*d9f75844SAndroid Build Coastguard Worker CreateSimulcastStreamParams(rids.size());
249*d9f75844SAndroid Build Coastguard Worker std::vector<cricket::RidDescription> rid_descriptions;
250*d9f75844SAndroid Build Coastguard Worker absl::c_transform(
251*d9f75844SAndroid Build Coastguard Worker rids, std::back_inserter(rid_descriptions), [](const std::string& rid) {
252*d9f75844SAndroid Build Coastguard Worker return cricket::RidDescription(rid, cricket::RidDirection::kSend);
253*d9f75844SAndroid Build Coastguard Worker });
254*d9f75844SAndroid Build Coastguard Worker stream_params.set_rids(rid_descriptions);
255*d9f75844SAndroid Build Coastguard Worker return CreateVideoRtpSender(stream_params);
256*d9f75844SAndroid Build Coastguard Worker }
257*d9f75844SAndroid Build Coastguard Worker
CreateVideoRtpSender(bool is_screencast,uint32_t ssrc=kVideoSsrc)258*d9f75844SAndroid Build Coastguard Worker void CreateVideoRtpSender(bool is_screencast, uint32_t ssrc = kVideoSsrc) {
259*d9f75844SAndroid Build Coastguard Worker AddVideoTrack(is_screencast);
260*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<MockSetStreamsObserver> set_streams_observer =
261*d9f75844SAndroid Build Coastguard Worker std::make_unique<MockSetStreamsObserver>();
262*d9f75844SAndroid Build Coastguard Worker video_rtp_sender_ = VideoRtpSender::Create(
263*d9f75844SAndroid Build Coastguard Worker worker_thread_, video_track_->id(), set_streams_observer.get());
264*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(video_rtp_sender_->SetTrack(video_track_.get()));
265*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(*set_streams_observer, OnSetStreams());
266*d9f75844SAndroid Build Coastguard Worker video_rtp_sender_->SetStreams({local_stream_->id()});
267*d9f75844SAndroid Build Coastguard Worker video_rtp_sender_->SetMediaChannel(video_media_channel());
268*d9f75844SAndroid Build Coastguard Worker video_rtp_sender_->SetSsrc(ssrc);
269*d9f75844SAndroid Build Coastguard Worker VerifyVideoChannelInput(ssrc);
270*d9f75844SAndroid Build Coastguard Worker }
CreateVideoRtpSenderWithNoTrack()271*d9f75844SAndroid Build Coastguard Worker void CreateVideoRtpSenderWithNoTrack() {
272*d9f75844SAndroid Build Coastguard Worker video_rtp_sender_ =
273*d9f75844SAndroid Build Coastguard Worker VideoRtpSender::Create(worker_thread_, /*id=*/"", nullptr);
274*d9f75844SAndroid Build Coastguard Worker video_rtp_sender_->SetMediaChannel(video_media_channel());
275*d9f75844SAndroid Build Coastguard Worker }
276*d9f75844SAndroid Build Coastguard Worker
DestroyAudioRtpSender()277*d9f75844SAndroid Build Coastguard Worker void DestroyAudioRtpSender() {
278*d9f75844SAndroid Build Coastguard Worker audio_rtp_sender_ = nullptr;
279*d9f75844SAndroid Build Coastguard Worker VerifyVoiceChannelNoInput();
280*d9f75844SAndroid Build Coastguard Worker }
281*d9f75844SAndroid Build Coastguard Worker
DestroyVideoRtpSender()282*d9f75844SAndroid Build Coastguard Worker void DestroyVideoRtpSender() {
283*d9f75844SAndroid Build Coastguard Worker video_rtp_sender_ = nullptr;
284*d9f75844SAndroid Build Coastguard Worker VerifyVideoChannelNoInput();
285*d9f75844SAndroid Build Coastguard Worker }
286*d9f75844SAndroid Build Coastguard Worker
CreateAudioRtpReceiver(std::vector<rtc::scoped_refptr<MediaStreamInterface>> streams={})287*d9f75844SAndroid Build Coastguard Worker void CreateAudioRtpReceiver(
288*d9f75844SAndroid Build Coastguard Worker std::vector<rtc::scoped_refptr<MediaStreamInterface>> streams = {}) {
289*d9f75844SAndroid Build Coastguard Worker audio_rtp_receiver_ = rtc::make_ref_counted<AudioRtpReceiver>(
290*d9f75844SAndroid Build Coastguard Worker rtc::Thread::Current(), kAudioTrackId, streams,
291*d9f75844SAndroid Build Coastguard Worker /*is_unified_plan=*/true);
292*d9f75844SAndroid Build Coastguard Worker audio_rtp_receiver_->SetMediaChannel(voice_media_channel());
293*d9f75844SAndroid Build Coastguard Worker audio_rtp_receiver_->SetupMediaChannel(kAudioSsrc);
294*d9f75844SAndroid Build Coastguard Worker audio_track_ = audio_rtp_receiver_->audio_track();
295*d9f75844SAndroid Build Coastguard Worker VerifyVoiceChannelOutput();
296*d9f75844SAndroid Build Coastguard Worker }
297*d9f75844SAndroid Build Coastguard Worker
CreateVideoRtpReceiver(std::vector<rtc::scoped_refptr<MediaStreamInterface>> streams={})298*d9f75844SAndroid Build Coastguard Worker void CreateVideoRtpReceiver(
299*d9f75844SAndroid Build Coastguard Worker std::vector<rtc::scoped_refptr<MediaStreamInterface>> streams = {}) {
300*d9f75844SAndroid Build Coastguard Worker video_rtp_receiver_ = rtc::make_ref_counted<VideoRtpReceiver>(
301*d9f75844SAndroid Build Coastguard Worker rtc::Thread::Current(), kVideoTrackId, streams);
302*d9f75844SAndroid Build Coastguard Worker video_rtp_receiver_->SetMediaChannel(video_media_channel());
303*d9f75844SAndroid Build Coastguard Worker video_rtp_receiver_->SetupMediaChannel(kVideoSsrc);
304*d9f75844SAndroid Build Coastguard Worker video_track_ = video_rtp_receiver_->video_track();
305*d9f75844SAndroid Build Coastguard Worker VerifyVideoChannelOutput();
306*d9f75844SAndroid Build Coastguard Worker }
307*d9f75844SAndroid Build Coastguard Worker
CreateVideoRtpReceiverWithSimulcast(std::vector<rtc::scoped_refptr<MediaStreamInterface>> streams={},int num_layers=kVideoSimulcastLayerCount)308*d9f75844SAndroid Build Coastguard Worker void CreateVideoRtpReceiverWithSimulcast(
309*d9f75844SAndroid Build Coastguard Worker std::vector<rtc::scoped_refptr<MediaStreamInterface>> streams = {},
310*d9f75844SAndroid Build Coastguard Worker int num_layers = kVideoSimulcastLayerCount) {
311*d9f75844SAndroid Build Coastguard Worker std::vector<uint32_t> ssrcs;
312*d9f75844SAndroid Build Coastguard Worker ssrcs.reserve(num_layers);
313*d9f75844SAndroid Build Coastguard Worker for (int i = 0; i < num_layers; ++i)
314*d9f75844SAndroid Build Coastguard Worker ssrcs.push_back(kVideoSsrcSimulcast + i);
315*d9f75844SAndroid Build Coastguard Worker cricket::StreamParams stream_params =
316*d9f75844SAndroid Build Coastguard Worker cricket::CreateSimStreamParams("cname", ssrcs);
317*d9f75844SAndroid Build Coastguard Worker video_media_channel_->AddRecvStream(stream_params);
318*d9f75844SAndroid Build Coastguard Worker uint32_t primary_ssrc = stream_params.first_ssrc();
319*d9f75844SAndroid Build Coastguard Worker
320*d9f75844SAndroid Build Coastguard Worker video_rtp_receiver_ = rtc::make_ref_counted<VideoRtpReceiver>(
321*d9f75844SAndroid Build Coastguard Worker rtc::Thread::Current(), kVideoTrackId, streams);
322*d9f75844SAndroid Build Coastguard Worker video_rtp_receiver_->SetMediaChannel(video_media_channel());
323*d9f75844SAndroid Build Coastguard Worker video_rtp_receiver_->SetupMediaChannel(primary_ssrc);
324*d9f75844SAndroid Build Coastguard Worker video_track_ = video_rtp_receiver_->video_track();
325*d9f75844SAndroid Build Coastguard Worker }
326*d9f75844SAndroid Build Coastguard Worker
DestroyAudioRtpReceiver()327*d9f75844SAndroid Build Coastguard Worker void DestroyAudioRtpReceiver() {
328*d9f75844SAndroid Build Coastguard Worker if (!audio_rtp_receiver_)
329*d9f75844SAndroid Build Coastguard Worker return;
330*d9f75844SAndroid Build Coastguard Worker audio_rtp_receiver_->SetMediaChannel(nullptr);
331*d9f75844SAndroid Build Coastguard Worker audio_rtp_receiver_ = nullptr;
332*d9f75844SAndroid Build Coastguard Worker VerifyVoiceChannelNoOutput();
333*d9f75844SAndroid Build Coastguard Worker }
334*d9f75844SAndroid Build Coastguard Worker
DestroyVideoRtpReceiver()335*d9f75844SAndroid Build Coastguard Worker void DestroyVideoRtpReceiver() {
336*d9f75844SAndroid Build Coastguard Worker if (!video_rtp_receiver_)
337*d9f75844SAndroid Build Coastguard Worker return;
338*d9f75844SAndroid Build Coastguard Worker video_rtp_receiver_->Stop();
339*d9f75844SAndroid Build Coastguard Worker video_rtp_receiver_->SetMediaChannel(nullptr);
340*d9f75844SAndroid Build Coastguard Worker video_rtp_receiver_ = nullptr;
341*d9f75844SAndroid Build Coastguard Worker VerifyVideoChannelNoOutput();
342*d9f75844SAndroid Build Coastguard Worker }
343*d9f75844SAndroid Build Coastguard Worker
VerifyVoiceChannelInput()344*d9f75844SAndroid Build Coastguard Worker void VerifyVoiceChannelInput() { VerifyVoiceChannelInput(kAudioSsrc); }
345*d9f75844SAndroid Build Coastguard Worker
VerifyVoiceChannelInput(uint32_t ssrc)346*d9f75844SAndroid Build Coastguard Worker void VerifyVoiceChannelInput(uint32_t ssrc) {
347*d9f75844SAndroid Build Coastguard Worker // Verify that the media channel has an audio source, and the stream isn't
348*d9f75844SAndroid Build Coastguard Worker // muted.
349*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(voice_media_channel()->HasSource(ssrc));
350*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(voice_media_channel()->IsStreamMuted(ssrc));
351*d9f75844SAndroid Build Coastguard Worker }
352*d9f75844SAndroid Build Coastguard Worker
VerifyVideoChannelInput()353*d9f75844SAndroid Build Coastguard Worker void VerifyVideoChannelInput() { VerifyVideoChannelInput(kVideoSsrc); }
354*d9f75844SAndroid Build Coastguard Worker
VerifyVideoChannelInput(uint32_t ssrc)355*d9f75844SAndroid Build Coastguard Worker void VerifyVideoChannelInput(uint32_t ssrc) {
356*d9f75844SAndroid Build Coastguard Worker // Verify that the media channel has a video source,
357*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(video_media_channel_->HasSource(ssrc));
358*d9f75844SAndroid Build Coastguard Worker }
359*d9f75844SAndroid Build Coastguard Worker
VerifyVoiceChannelNoInput()360*d9f75844SAndroid Build Coastguard Worker void VerifyVoiceChannelNoInput() { VerifyVoiceChannelNoInput(kAudioSsrc); }
361*d9f75844SAndroid Build Coastguard Worker
VerifyVoiceChannelNoInput(uint32_t ssrc)362*d9f75844SAndroid Build Coastguard Worker void VerifyVoiceChannelNoInput(uint32_t ssrc) {
363*d9f75844SAndroid Build Coastguard Worker // Verify that the media channel's source is reset.
364*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(voice_media_channel()->HasSource(ssrc));
365*d9f75844SAndroid Build Coastguard Worker }
366*d9f75844SAndroid Build Coastguard Worker
VerifyVideoChannelNoInput()367*d9f75844SAndroid Build Coastguard Worker void VerifyVideoChannelNoInput() { VerifyVideoChannelNoInput(kVideoSsrc); }
368*d9f75844SAndroid Build Coastguard Worker
VerifyVideoChannelNoInput(uint32_t ssrc)369*d9f75844SAndroid Build Coastguard Worker void VerifyVideoChannelNoInput(uint32_t ssrc) {
370*d9f75844SAndroid Build Coastguard Worker // Verify that the media channel's source is reset.
371*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(video_media_channel_->HasSource(ssrc));
372*d9f75844SAndroid Build Coastguard Worker }
373*d9f75844SAndroid Build Coastguard Worker
VerifyVoiceChannelOutput()374*d9f75844SAndroid Build Coastguard Worker void VerifyVoiceChannelOutput() {
375*d9f75844SAndroid Build Coastguard Worker // Verify that the volume is initialized to 1.
376*d9f75844SAndroid Build Coastguard Worker double volume;
377*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(voice_media_channel()->GetOutputVolume(kAudioSsrc, &volume));
378*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1, volume);
379*d9f75844SAndroid Build Coastguard Worker }
380*d9f75844SAndroid Build Coastguard Worker
VerifyVideoChannelOutput()381*d9f75844SAndroid Build Coastguard Worker void VerifyVideoChannelOutput() {
382*d9f75844SAndroid Build Coastguard Worker // Verify that the media channel has a sink.
383*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(video_media_channel_->HasSink(kVideoSsrc));
384*d9f75844SAndroid Build Coastguard Worker }
385*d9f75844SAndroid Build Coastguard Worker
VerifyVoiceChannelNoOutput()386*d9f75844SAndroid Build Coastguard Worker void VerifyVoiceChannelNoOutput() {
387*d9f75844SAndroid Build Coastguard Worker // Verify that the volume is reset to 0.
388*d9f75844SAndroid Build Coastguard Worker double volume;
389*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(voice_media_channel()->GetOutputVolume(kAudioSsrc, &volume));
390*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0, volume);
391*d9f75844SAndroid Build Coastguard Worker }
392*d9f75844SAndroid Build Coastguard Worker
VerifyVideoChannelNoOutput()393*d9f75844SAndroid Build Coastguard Worker void VerifyVideoChannelNoOutput() {
394*d9f75844SAndroid Build Coastguard Worker // Verify that the media channel's sink is reset.
395*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(video_media_channel_->HasSink(kVideoSsrc));
396*d9f75844SAndroid Build Coastguard Worker }
397*d9f75844SAndroid Build Coastguard Worker
398*d9f75844SAndroid Build Coastguard Worker // Verifies that the encoding layers contain the specified RIDs.
VerifyEncodingLayers(const VideoRtpSender & sender,const std::vector<std::string> & rids)399*d9f75844SAndroid Build Coastguard Worker bool VerifyEncodingLayers(const VideoRtpSender& sender,
400*d9f75844SAndroid Build Coastguard Worker const std::vector<std::string>& rids) {
401*d9f75844SAndroid Build Coastguard Worker bool has_failure = HasFailure();
402*d9f75844SAndroid Build Coastguard Worker RtpParameters parameters = sender.GetParameters();
403*d9f75844SAndroid Build Coastguard Worker std::vector<std::string> encoding_rids;
404*d9f75844SAndroid Build Coastguard Worker absl::c_transform(
405*d9f75844SAndroid Build Coastguard Worker parameters.encodings, std::back_inserter(encoding_rids),
406*d9f75844SAndroid Build Coastguard Worker [](const RtpEncodingParameters& encoding) { return encoding.rid; });
407*d9f75844SAndroid Build Coastguard Worker EXPECT_THAT(rids, ContainerEq(encoding_rids));
408*d9f75844SAndroid Build Coastguard Worker return has_failure || !HasFailure();
409*d9f75844SAndroid Build Coastguard Worker }
410*d9f75844SAndroid Build Coastguard Worker
411*d9f75844SAndroid Build Coastguard Worker // Runs a test for disabling the encoding layers on the specified sender.
RunDisableEncodingLayersTest(const std::vector<std::string> & all_layers,const std::vector<std::string> & disabled_layers,VideoRtpSender * sender)412*d9f75844SAndroid Build Coastguard Worker void RunDisableEncodingLayersTest(
413*d9f75844SAndroid Build Coastguard Worker const std::vector<std::string>& all_layers,
414*d9f75844SAndroid Build Coastguard Worker const std::vector<std::string>& disabled_layers,
415*d9f75844SAndroid Build Coastguard Worker VideoRtpSender* sender) {
416*d9f75844SAndroid Build Coastguard Worker std::vector<std::string> expected;
417*d9f75844SAndroid Build Coastguard Worker absl::c_copy_if(all_layers, std::back_inserter(expected),
418*d9f75844SAndroid Build Coastguard Worker [&disabled_layers](const std::string& rid) {
419*d9f75844SAndroid Build Coastguard Worker return !absl::c_linear_search(disabled_layers, rid);
420*d9f75844SAndroid Build Coastguard Worker });
421*d9f75844SAndroid Build Coastguard Worker
422*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(VerifyEncodingLayers(*sender, all_layers));
423*d9f75844SAndroid Build Coastguard Worker sender->DisableEncodingLayers(disabled_layers);
424*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(VerifyEncodingLayers(*sender, expected));
425*d9f75844SAndroid Build Coastguard Worker }
426*d9f75844SAndroid Build Coastguard Worker
427*d9f75844SAndroid Build Coastguard Worker // Runs a test for setting an encoding layer as inactive.
428*d9f75844SAndroid Build Coastguard Worker // This test assumes that some layers have already been disabled.
RunSetLastLayerAsInactiveTest(VideoRtpSender * sender)429*d9f75844SAndroid Build Coastguard Worker void RunSetLastLayerAsInactiveTest(VideoRtpSender* sender) {
430*d9f75844SAndroid Build Coastguard Worker auto parameters = sender->GetParameters();
431*d9f75844SAndroid Build Coastguard Worker if (parameters.encodings.size() == 0) {
432*d9f75844SAndroid Build Coastguard Worker return;
433*d9f75844SAndroid Build Coastguard Worker }
434*d9f75844SAndroid Build Coastguard Worker
435*d9f75844SAndroid Build Coastguard Worker RtpEncodingParameters& encoding = parameters.encodings.back();
436*d9f75844SAndroid Build Coastguard Worker auto rid = encoding.rid;
437*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(encoding.active);
438*d9f75844SAndroid Build Coastguard Worker encoding.active = false;
439*d9f75844SAndroid Build Coastguard Worker auto error = sender->SetParameters(parameters);
440*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(error.ok());
441*d9f75844SAndroid Build Coastguard Worker parameters = sender->GetParameters();
442*d9f75844SAndroid Build Coastguard Worker RtpEncodingParameters& result_encoding = parameters.encodings.back();
443*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(rid, result_encoding.rid);
444*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(result_encoding.active);
445*d9f75844SAndroid Build Coastguard Worker }
446*d9f75844SAndroid Build Coastguard Worker
447*d9f75844SAndroid Build Coastguard Worker // Runs a test for disabling the encoding layers on a sender without a media
448*d9f75844SAndroid Build Coastguard Worker // channel.
RunDisableSimulcastLayersWithoutMediaEngineTest(const std::vector<std::string> & all_layers,const std::vector<std::string> & disabled_layers)449*d9f75844SAndroid Build Coastguard Worker void RunDisableSimulcastLayersWithoutMediaEngineTest(
450*d9f75844SAndroid Build Coastguard Worker const std::vector<std::string>& all_layers,
451*d9f75844SAndroid Build Coastguard Worker const std::vector<std::string>& disabled_layers) {
452*d9f75844SAndroid Build Coastguard Worker auto sender = VideoRtpSender::Create(rtc::Thread::Current(), "1", nullptr);
453*d9f75844SAndroid Build Coastguard Worker RtpParameters parameters;
454*d9f75844SAndroid Build Coastguard Worker parameters.encodings.resize(all_layers.size());
455*d9f75844SAndroid Build Coastguard Worker for (size_t i = 0; i < all_layers.size(); ++i) {
456*d9f75844SAndroid Build Coastguard Worker parameters.encodings[i].rid = all_layers[i];
457*d9f75844SAndroid Build Coastguard Worker }
458*d9f75844SAndroid Build Coastguard Worker sender->set_init_send_encodings(parameters.encodings);
459*d9f75844SAndroid Build Coastguard Worker RunDisableEncodingLayersTest(all_layers, disabled_layers, sender.get());
460*d9f75844SAndroid Build Coastguard Worker RunSetLastLayerAsInactiveTest(sender.get());
461*d9f75844SAndroid Build Coastguard Worker }
462*d9f75844SAndroid Build Coastguard Worker
463*d9f75844SAndroid Build Coastguard Worker // Runs a test for disabling the encoding layers on a sender with a media
464*d9f75844SAndroid Build Coastguard Worker // channel.
RunDisableSimulcastLayersWithMediaEngineTest(const std::vector<std::string> & all_layers,const std::vector<std::string> & disabled_layers)465*d9f75844SAndroid Build Coastguard Worker void RunDisableSimulcastLayersWithMediaEngineTest(
466*d9f75844SAndroid Build Coastguard Worker const std::vector<std::string>& all_layers,
467*d9f75844SAndroid Build Coastguard Worker const std::vector<std::string>& disabled_layers) {
468*d9f75844SAndroid Build Coastguard Worker uint32_t ssrc = CreateVideoRtpSenderWithSimulcast(all_layers);
469*d9f75844SAndroid Build Coastguard Worker RunDisableEncodingLayersTest(all_layers, disabled_layers,
470*d9f75844SAndroid Build Coastguard Worker video_rtp_sender_.get());
471*d9f75844SAndroid Build Coastguard Worker
472*d9f75844SAndroid Build Coastguard Worker auto channel_parameters = video_media_channel_->GetRtpSendParameters(ssrc);
473*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ(channel_parameters.encodings.size(), all_layers.size());
474*d9f75844SAndroid Build Coastguard Worker for (size_t i = 0; i < all_layers.size(); ++i) {
475*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(all_layers[i], channel_parameters.encodings[i].rid);
476*d9f75844SAndroid Build Coastguard Worker bool is_active = !absl::c_linear_search(disabled_layers, all_layers[i]);
477*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(is_active, channel_parameters.encodings[i].active);
478*d9f75844SAndroid Build Coastguard Worker }
479*d9f75844SAndroid Build Coastguard Worker
480*d9f75844SAndroid Build Coastguard Worker RunSetLastLayerAsInactiveTest(video_rtp_sender_.get());
481*d9f75844SAndroid Build Coastguard Worker }
482*d9f75844SAndroid Build Coastguard Worker
483*d9f75844SAndroid Build Coastguard Worker // Check that minimum Jitter Buffer delay is propagated to the underlying
484*d9f75844SAndroid Build Coastguard Worker // `media_channel`.
VerifyRtpReceiverDelayBehaviour(cricket::Delayable * media_channel,RtpReceiverInterface * receiver,uint32_t ssrc)485*d9f75844SAndroid Build Coastguard Worker void VerifyRtpReceiverDelayBehaviour(cricket::Delayable* media_channel,
486*d9f75844SAndroid Build Coastguard Worker RtpReceiverInterface* receiver,
487*d9f75844SAndroid Build Coastguard Worker uint32_t ssrc) {
488*d9f75844SAndroid Build Coastguard Worker receiver->SetJitterBufferMinimumDelay(/*delay_seconds=*/0.5);
489*d9f75844SAndroid Build Coastguard Worker absl::optional<int> delay_ms =
490*d9f75844SAndroid Build Coastguard Worker media_channel->GetBaseMinimumPlayoutDelayMs(ssrc); // In milliseconds.
491*d9f75844SAndroid Build Coastguard Worker EXPECT_DOUBLE_EQ(0.5, delay_ms.value_or(0) / 1000.0);
492*d9f75844SAndroid Build Coastguard Worker }
493*d9f75844SAndroid Build Coastguard Worker
494*d9f75844SAndroid Build Coastguard Worker protected:
video_media_channel()495*d9f75844SAndroid Build Coastguard Worker cricket::FakeVideoMediaChannel* video_media_channel() {
496*d9f75844SAndroid Build Coastguard Worker return video_media_channel_.get();
497*d9f75844SAndroid Build Coastguard Worker }
voice_media_channel()498*d9f75844SAndroid Build Coastguard Worker cricket::FakeVoiceMediaChannel* voice_media_channel() {
499*d9f75844SAndroid Build Coastguard Worker return voice_media_channel_.get();
500*d9f75844SAndroid Build Coastguard Worker }
501*d9f75844SAndroid Build Coastguard Worker
502*d9f75844SAndroid Build Coastguard Worker test::RunLoop run_loop_;
503*d9f75844SAndroid Build Coastguard Worker rtc::Thread* const network_thread_;
504*d9f75844SAndroid Build Coastguard Worker rtc::Thread* const worker_thread_;
505*d9f75844SAndroid Build Coastguard Worker webrtc::RtcEventLogNull event_log_;
506*d9f75844SAndroid Build Coastguard Worker // The `rtp_dtls_transport_` and `rtp_transport_` should be destroyed after
507*d9f75844SAndroid Build Coastguard Worker // the `channel_manager`.
508*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<cricket::DtlsTransportInternal> rtp_dtls_transport_;
509*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<webrtc::RtpTransportInternal> rtp_transport_;
510*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<webrtc::VideoBitrateAllocatorFactory>
511*d9f75844SAndroid Build Coastguard Worker video_bitrate_allocator_factory_;
512*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<cricket::FakeMediaEngine> media_engine_;
513*d9f75844SAndroid Build Coastguard Worker rtc::UniqueRandomIdGenerator ssrc_generator_;
514*d9f75844SAndroid Build Coastguard Worker cricket::FakeCall fake_call_;
515*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<cricket::FakeVoiceMediaChannel> voice_media_channel_;
516*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<cricket::FakeVideoMediaChannel> video_media_channel_;
517*d9f75844SAndroid Build Coastguard Worker rtc::scoped_refptr<AudioRtpSender> audio_rtp_sender_;
518*d9f75844SAndroid Build Coastguard Worker rtc::scoped_refptr<VideoRtpSender> video_rtp_sender_;
519*d9f75844SAndroid Build Coastguard Worker rtc::scoped_refptr<AudioRtpReceiver> audio_rtp_receiver_;
520*d9f75844SAndroid Build Coastguard Worker rtc::scoped_refptr<VideoRtpReceiver> video_rtp_receiver_;
521*d9f75844SAndroid Build Coastguard Worker rtc::scoped_refptr<MediaStreamInterface> local_stream_;
522*d9f75844SAndroid Build Coastguard Worker rtc::scoped_refptr<VideoTrackInterface> video_track_;
523*d9f75844SAndroid Build Coastguard Worker rtc::scoped_refptr<AudioTrackInterface> audio_track_;
524*d9f75844SAndroid Build Coastguard Worker webrtc::test::ScopedKeyValueConfig field_trials_;
525*d9f75844SAndroid Build Coastguard Worker };
526*d9f75844SAndroid Build Coastguard Worker
527*d9f75844SAndroid Build Coastguard Worker // Test that `voice_channel_` is updated when an audio track is associated
528*d9f75844SAndroid Build Coastguard Worker // and disassociated with an AudioRtpSender.
TEST_F(RtpSenderReceiverTest,AddAndDestroyAudioRtpSender)529*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, AddAndDestroyAudioRtpSender) {
530*d9f75844SAndroid Build Coastguard Worker CreateAudioRtpSender();
531*d9f75844SAndroid Build Coastguard Worker DestroyAudioRtpSender();
532*d9f75844SAndroid Build Coastguard Worker }
533*d9f75844SAndroid Build Coastguard Worker
534*d9f75844SAndroid Build Coastguard Worker // Test that `video_channel_` is updated when a video track is associated and
535*d9f75844SAndroid Build Coastguard Worker // disassociated with a VideoRtpSender.
TEST_F(RtpSenderReceiverTest,AddAndDestroyVideoRtpSender)536*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, AddAndDestroyVideoRtpSender) {
537*d9f75844SAndroid Build Coastguard Worker CreateVideoRtpSender();
538*d9f75844SAndroid Build Coastguard Worker DestroyVideoRtpSender();
539*d9f75844SAndroid Build Coastguard Worker }
540*d9f75844SAndroid Build Coastguard Worker
541*d9f75844SAndroid Build Coastguard Worker // Test that `voice_channel_` is updated when a remote audio track is
542*d9f75844SAndroid Build Coastguard Worker // associated and disassociated with an AudioRtpReceiver.
TEST_F(RtpSenderReceiverTest,AddAndDestroyAudioRtpReceiver)543*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, AddAndDestroyAudioRtpReceiver) {
544*d9f75844SAndroid Build Coastguard Worker CreateAudioRtpReceiver();
545*d9f75844SAndroid Build Coastguard Worker DestroyAudioRtpReceiver();
546*d9f75844SAndroid Build Coastguard Worker }
547*d9f75844SAndroid Build Coastguard Worker
548*d9f75844SAndroid Build Coastguard Worker // Test that `video_channel_` is updated when a remote video track is
549*d9f75844SAndroid Build Coastguard Worker // associated and disassociated with a VideoRtpReceiver.
TEST_F(RtpSenderReceiverTest,AddAndDestroyVideoRtpReceiver)550*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, AddAndDestroyVideoRtpReceiver) {
551*d9f75844SAndroid Build Coastguard Worker CreateVideoRtpReceiver();
552*d9f75844SAndroid Build Coastguard Worker DestroyVideoRtpReceiver();
553*d9f75844SAndroid Build Coastguard Worker }
554*d9f75844SAndroid Build Coastguard Worker
TEST_F(RtpSenderReceiverTest,AddAndDestroyAudioRtpReceiverWithStreams)555*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, AddAndDestroyAudioRtpReceiverWithStreams) {
556*d9f75844SAndroid Build Coastguard Worker CreateAudioRtpReceiver({local_stream_});
557*d9f75844SAndroid Build Coastguard Worker DestroyAudioRtpReceiver();
558*d9f75844SAndroid Build Coastguard Worker }
559*d9f75844SAndroid Build Coastguard Worker
TEST_F(RtpSenderReceiverTest,AddAndDestroyVideoRtpReceiverWithStreams)560*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, AddAndDestroyVideoRtpReceiverWithStreams) {
561*d9f75844SAndroid Build Coastguard Worker CreateVideoRtpReceiver({local_stream_});
562*d9f75844SAndroid Build Coastguard Worker DestroyVideoRtpReceiver();
563*d9f75844SAndroid Build Coastguard Worker }
564*d9f75844SAndroid Build Coastguard Worker
565*d9f75844SAndroid Build Coastguard Worker // Test that the AudioRtpSender applies options from the local audio source.
TEST_F(RtpSenderReceiverTest,LocalAudioSourceOptionsApplied)566*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, LocalAudioSourceOptionsApplied) {
567*d9f75844SAndroid Build Coastguard Worker cricket::AudioOptions options;
568*d9f75844SAndroid Build Coastguard Worker options.echo_cancellation = true;
569*d9f75844SAndroid Build Coastguard Worker auto source = LocalAudioSource::Create(&options);
570*d9f75844SAndroid Build Coastguard Worker CreateAudioRtpSender(source);
571*d9f75844SAndroid Build Coastguard Worker
572*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(true, voice_media_channel()->options().echo_cancellation);
573*d9f75844SAndroid Build Coastguard Worker
574*d9f75844SAndroid Build Coastguard Worker DestroyAudioRtpSender();
575*d9f75844SAndroid Build Coastguard Worker }
576*d9f75844SAndroid Build Coastguard Worker
577*d9f75844SAndroid Build Coastguard Worker // Test that the stream is muted when the track is disabled, and unmuted when
578*d9f75844SAndroid Build Coastguard Worker // the track is enabled.
TEST_F(RtpSenderReceiverTest,LocalAudioTrackDisable)579*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, LocalAudioTrackDisable) {
580*d9f75844SAndroid Build Coastguard Worker CreateAudioRtpSender();
581*d9f75844SAndroid Build Coastguard Worker
582*d9f75844SAndroid Build Coastguard Worker audio_track_->set_enabled(false);
583*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(voice_media_channel()->IsStreamMuted(kAudioSsrc));
584*d9f75844SAndroid Build Coastguard Worker
585*d9f75844SAndroid Build Coastguard Worker audio_track_->set_enabled(true);
586*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(voice_media_channel()->IsStreamMuted(kAudioSsrc));
587*d9f75844SAndroid Build Coastguard Worker
588*d9f75844SAndroid Build Coastguard Worker DestroyAudioRtpSender();
589*d9f75844SAndroid Build Coastguard Worker }
590*d9f75844SAndroid Build Coastguard Worker
591*d9f75844SAndroid Build Coastguard Worker // Test that the volume is set to 0 when the track is disabled, and back to
592*d9f75844SAndroid Build Coastguard Worker // 1 when the track is enabled.
TEST_F(RtpSenderReceiverTest,RemoteAudioTrackDisable)593*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, RemoteAudioTrackDisable) {
594*d9f75844SAndroid Build Coastguard Worker CreateAudioRtpReceiver();
595*d9f75844SAndroid Build Coastguard Worker
596*d9f75844SAndroid Build Coastguard Worker double volume;
597*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(voice_media_channel()->GetOutputVolume(kAudioSsrc, &volume));
598*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1, volume);
599*d9f75844SAndroid Build Coastguard Worker
600*d9f75844SAndroid Build Coastguard Worker // Handling of enable/disable is applied asynchronously.
601*d9f75844SAndroid Build Coastguard Worker audio_track_->set_enabled(false);
602*d9f75844SAndroid Build Coastguard Worker run_loop_.Flush();
603*d9f75844SAndroid Build Coastguard Worker
604*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(voice_media_channel()->GetOutputVolume(kAudioSsrc, &volume));
605*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0, volume);
606*d9f75844SAndroid Build Coastguard Worker
607*d9f75844SAndroid Build Coastguard Worker audio_track_->set_enabled(true);
608*d9f75844SAndroid Build Coastguard Worker run_loop_.Flush();
609*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(voice_media_channel()->GetOutputVolume(kAudioSsrc, &volume));
610*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1, volume);
611*d9f75844SAndroid Build Coastguard Worker
612*d9f75844SAndroid Build Coastguard Worker DestroyAudioRtpReceiver();
613*d9f75844SAndroid Build Coastguard Worker }
614*d9f75844SAndroid Build Coastguard Worker
615*d9f75844SAndroid Build Coastguard Worker // Currently no action is taken when a remote video track is disabled or
616*d9f75844SAndroid Build Coastguard Worker // enabled, so there's nothing to test here, other than what is normally
617*d9f75844SAndroid Build Coastguard Worker // verified in DestroyVideoRtpSender.
TEST_F(RtpSenderReceiverTest,LocalVideoTrackDisable)618*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, LocalVideoTrackDisable) {
619*d9f75844SAndroid Build Coastguard Worker CreateVideoRtpSender();
620*d9f75844SAndroid Build Coastguard Worker
621*d9f75844SAndroid Build Coastguard Worker video_track_->set_enabled(false);
622*d9f75844SAndroid Build Coastguard Worker video_track_->set_enabled(true);
623*d9f75844SAndroid Build Coastguard Worker
624*d9f75844SAndroid Build Coastguard Worker DestroyVideoRtpSender();
625*d9f75844SAndroid Build Coastguard Worker }
626*d9f75844SAndroid Build Coastguard Worker
627*d9f75844SAndroid Build Coastguard Worker // Test that the state of the video track created by the VideoRtpReceiver is
628*d9f75844SAndroid Build Coastguard Worker // updated when the receiver is destroyed.
TEST_F(RtpSenderReceiverTest,RemoteVideoTrackState)629*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, RemoteVideoTrackState) {
630*d9f75844SAndroid Build Coastguard Worker CreateVideoRtpReceiver();
631*d9f75844SAndroid Build Coastguard Worker
632*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(webrtc::MediaStreamTrackInterface::kLive, video_track_->state());
633*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(webrtc::MediaSourceInterface::kLive,
634*d9f75844SAndroid Build Coastguard Worker video_track_->GetSource()->state());
635*d9f75844SAndroid Build Coastguard Worker
636*d9f75844SAndroid Build Coastguard Worker DestroyVideoRtpReceiver();
637*d9f75844SAndroid Build Coastguard Worker
638*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(webrtc::MediaStreamTrackInterface::kEnded, video_track_->state());
639*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(webrtc::MediaSourceInterface::kEnded,
640*d9f75844SAndroid Build Coastguard Worker video_track_->GetSource()->state());
641*d9f75844SAndroid Build Coastguard Worker DestroyVideoRtpReceiver();
642*d9f75844SAndroid Build Coastguard Worker }
643*d9f75844SAndroid Build Coastguard Worker
644*d9f75844SAndroid Build Coastguard Worker // Currently no action is taken when a remote video track is disabled or
645*d9f75844SAndroid Build Coastguard Worker // enabled, so there's nothing to test here, other than what is normally
646*d9f75844SAndroid Build Coastguard Worker // verified in DestroyVideoRtpReceiver.
TEST_F(RtpSenderReceiverTest,RemoteVideoTrackDisable)647*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, RemoteVideoTrackDisable) {
648*d9f75844SAndroid Build Coastguard Worker CreateVideoRtpReceiver();
649*d9f75844SAndroid Build Coastguard Worker
650*d9f75844SAndroid Build Coastguard Worker video_track_->set_enabled(false);
651*d9f75844SAndroid Build Coastguard Worker video_track_->set_enabled(true);
652*d9f75844SAndroid Build Coastguard Worker
653*d9f75844SAndroid Build Coastguard Worker DestroyVideoRtpReceiver();
654*d9f75844SAndroid Build Coastguard Worker }
655*d9f75844SAndroid Build Coastguard Worker
656*d9f75844SAndroid Build Coastguard Worker // Test that the AudioRtpReceiver applies volume changes from the track source
657*d9f75844SAndroid Build Coastguard Worker // to the media channel.
TEST_F(RtpSenderReceiverTest,RemoteAudioTrackSetVolume)658*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, RemoteAudioTrackSetVolume) {
659*d9f75844SAndroid Build Coastguard Worker CreateAudioRtpReceiver();
660*d9f75844SAndroid Build Coastguard Worker
661*d9f75844SAndroid Build Coastguard Worker double volume;
662*d9f75844SAndroid Build Coastguard Worker audio_track_->GetSource()->SetVolume(0.5);
663*d9f75844SAndroid Build Coastguard Worker run_loop_.Flush();
664*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(voice_media_channel()->GetOutputVolume(kAudioSsrc, &volume));
665*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0.5, volume);
666*d9f75844SAndroid Build Coastguard Worker
667*d9f75844SAndroid Build Coastguard Worker // Disable the audio track, this should prevent setting the volume.
668*d9f75844SAndroid Build Coastguard Worker audio_track_->set_enabled(false);
669*d9f75844SAndroid Build Coastguard Worker RTC_DCHECK_EQ(worker_thread_, run_loop_.task_queue());
670*d9f75844SAndroid Build Coastguard Worker run_loop_.Flush();
671*d9f75844SAndroid Build Coastguard Worker audio_track_->GetSource()->SetVolume(0.8);
672*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(voice_media_channel()->GetOutputVolume(kAudioSsrc, &volume));
673*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0, volume);
674*d9f75844SAndroid Build Coastguard Worker
675*d9f75844SAndroid Build Coastguard Worker // When the track is enabled, the previously set volume should take effect.
676*d9f75844SAndroid Build Coastguard Worker audio_track_->set_enabled(true);
677*d9f75844SAndroid Build Coastguard Worker run_loop_.Flush();
678*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(voice_media_channel()->GetOutputVolume(kAudioSsrc, &volume));
679*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0.8, volume);
680*d9f75844SAndroid Build Coastguard Worker
681*d9f75844SAndroid Build Coastguard Worker // Try changing volume one more time.
682*d9f75844SAndroid Build Coastguard Worker audio_track_->GetSource()->SetVolume(0.9);
683*d9f75844SAndroid Build Coastguard Worker run_loop_.Flush();
684*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(voice_media_channel()->GetOutputVolume(kAudioSsrc, &volume));
685*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0.9, volume);
686*d9f75844SAndroid Build Coastguard Worker
687*d9f75844SAndroid Build Coastguard Worker DestroyAudioRtpReceiver();
688*d9f75844SAndroid Build Coastguard Worker }
689*d9f75844SAndroid Build Coastguard Worker
TEST_F(RtpSenderReceiverTest,AudioRtpReceiverDelay)690*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, AudioRtpReceiverDelay) {
691*d9f75844SAndroid Build Coastguard Worker CreateAudioRtpReceiver();
692*d9f75844SAndroid Build Coastguard Worker VerifyRtpReceiverDelayBehaviour(voice_media_channel(),
693*d9f75844SAndroid Build Coastguard Worker audio_rtp_receiver_.get(), kAudioSsrc);
694*d9f75844SAndroid Build Coastguard Worker DestroyAudioRtpReceiver();
695*d9f75844SAndroid Build Coastguard Worker }
696*d9f75844SAndroid Build Coastguard Worker
TEST_F(RtpSenderReceiverTest,VideoRtpReceiverDelay)697*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, VideoRtpReceiverDelay) {
698*d9f75844SAndroid Build Coastguard Worker CreateVideoRtpReceiver();
699*d9f75844SAndroid Build Coastguard Worker VerifyRtpReceiverDelayBehaviour(video_media_channel(),
700*d9f75844SAndroid Build Coastguard Worker video_rtp_receiver_.get(), kVideoSsrc);
701*d9f75844SAndroid Build Coastguard Worker DestroyVideoRtpReceiver();
702*d9f75844SAndroid Build Coastguard Worker }
703*d9f75844SAndroid Build Coastguard Worker
704*d9f75844SAndroid Build Coastguard Worker // Test that the media channel isn't enabled for sending if the audio sender
705*d9f75844SAndroid Build Coastguard Worker // doesn't have both a track and SSRC.
TEST_F(RtpSenderReceiverTest,AudioSenderWithoutTrackAndSsrc)706*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, AudioSenderWithoutTrackAndSsrc) {
707*d9f75844SAndroid Build Coastguard Worker CreateAudioRtpSenderWithNoTrack();
708*d9f75844SAndroid Build Coastguard Worker rtc::scoped_refptr<AudioTrackInterface> track =
709*d9f75844SAndroid Build Coastguard Worker AudioTrack::Create(kAudioTrackId, nullptr);
710*d9f75844SAndroid Build Coastguard Worker
711*d9f75844SAndroid Build Coastguard Worker // Track but no SSRC.
712*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(audio_rtp_sender_->SetTrack(track.get()));
713*d9f75844SAndroid Build Coastguard Worker VerifyVoiceChannelNoInput();
714*d9f75844SAndroid Build Coastguard Worker
715*d9f75844SAndroid Build Coastguard Worker // SSRC but no track.
716*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(audio_rtp_sender_->SetTrack(nullptr));
717*d9f75844SAndroid Build Coastguard Worker audio_rtp_sender_->SetSsrc(kAudioSsrc);
718*d9f75844SAndroid Build Coastguard Worker VerifyVoiceChannelNoInput();
719*d9f75844SAndroid Build Coastguard Worker }
720*d9f75844SAndroid Build Coastguard Worker
721*d9f75844SAndroid Build Coastguard Worker // Test that the media channel isn't enabled for sending if the video sender
722*d9f75844SAndroid Build Coastguard Worker // doesn't have both a track and SSRC.
TEST_F(RtpSenderReceiverTest,VideoSenderWithoutTrackAndSsrc)723*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, VideoSenderWithoutTrackAndSsrc) {
724*d9f75844SAndroid Build Coastguard Worker CreateVideoRtpSenderWithNoTrack();
725*d9f75844SAndroid Build Coastguard Worker
726*d9f75844SAndroid Build Coastguard Worker // Track but no SSRC.
727*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(video_rtp_sender_->SetTrack(video_track_.get()));
728*d9f75844SAndroid Build Coastguard Worker VerifyVideoChannelNoInput();
729*d9f75844SAndroid Build Coastguard Worker
730*d9f75844SAndroid Build Coastguard Worker // SSRC but no track.
731*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(video_rtp_sender_->SetTrack(nullptr));
732*d9f75844SAndroid Build Coastguard Worker video_rtp_sender_->SetSsrc(kVideoSsrc);
733*d9f75844SAndroid Build Coastguard Worker VerifyVideoChannelNoInput();
734*d9f75844SAndroid Build Coastguard Worker }
735*d9f75844SAndroid Build Coastguard Worker
736*d9f75844SAndroid Build Coastguard Worker // Test that the media channel is enabled for sending when the audio sender
737*d9f75844SAndroid Build Coastguard Worker // has a track and SSRC, when the SSRC is set first.
TEST_F(RtpSenderReceiverTest,AudioSenderEarlyWarmupSsrcThenTrack)738*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, AudioSenderEarlyWarmupSsrcThenTrack) {
739*d9f75844SAndroid Build Coastguard Worker CreateAudioRtpSenderWithNoTrack();
740*d9f75844SAndroid Build Coastguard Worker rtc::scoped_refptr<AudioTrackInterface> track =
741*d9f75844SAndroid Build Coastguard Worker AudioTrack::Create(kAudioTrackId, nullptr);
742*d9f75844SAndroid Build Coastguard Worker audio_rtp_sender_->SetSsrc(kAudioSsrc);
743*d9f75844SAndroid Build Coastguard Worker audio_rtp_sender_->SetTrack(track.get());
744*d9f75844SAndroid Build Coastguard Worker VerifyVoiceChannelInput();
745*d9f75844SAndroid Build Coastguard Worker
746*d9f75844SAndroid Build Coastguard Worker DestroyAudioRtpSender();
747*d9f75844SAndroid Build Coastguard Worker }
748*d9f75844SAndroid Build Coastguard Worker
749*d9f75844SAndroid Build Coastguard Worker // Test that the media channel is enabled for sending when the audio sender
750*d9f75844SAndroid Build Coastguard Worker // has a track and SSRC, when the SSRC is set last.
TEST_F(RtpSenderReceiverTest,AudioSenderEarlyWarmupTrackThenSsrc)751*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, AudioSenderEarlyWarmupTrackThenSsrc) {
752*d9f75844SAndroid Build Coastguard Worker CreateAudioRtpSenderWithNoTrack();
753*d9f75844SAndroid Build Coastguard Worker rtc::scoped_refptr<AudioTrackInterface> track =
754*d9f75844SAndroid Build Coastguard Worker AudioTrack::Create(kAudioTrackId, nullptr);
755*d9f75844SAndroid Build Coastguard Worker audio_rtp_sender_->SetTrack(track.get());
756*d9f75844SAndroid Build Coastguard Worker audio_rtp_sender_->SetSsrc(kAudioSsrc);
757*d9f75844SAndroid Build Coastguard Worker VerifyVoiceChannelInput();
758*d9f75844SAndroid Build Coastguard Worker
759*d9f75844SAndroid Build Coastguard Worker DestroyAudioRtpSender();
760*d9f75844SAndroid Build Coastguard Worker }
761*d9f75844SAndroid Build Coastguard Worker
762*d9f75844SAndroid Build Coastguard Worker // Test that the media channel is enabled for sending when the video sender
763*d9f75844SAndroid Build Coastguard Worker // has a track and SSRC, when the SSRC is set first.
TEST_F(RtpSenderReceiverTest,VideoSenderEarlyWarmupSsrcThenTrack)764*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, VideoSenderEarlyWarmupSsrcThenTrack) {
765*d9f75844SAndroid Build Coastguard Worker AddVideoTrack();
766*d9f75844SAndroid Build Coastguard Worker CreateVideoRtpSenderWithNoTrack();
767*d9f75844SAndroid Build Coastguard Worker video_rtp_sender_->SetSsrc(kVideoSsrc);
768*d9f75844SAndroid Build Coastguard Worker video_rtp_sender_->SetTrack(video_track_.get());
769*d9f75844SAndroid Build Coastguard Worker VerifyVideoChannelInput();
770*d9f75844SAndroid Build Coastguard Worker
771*d9f75844SAndroid Build Coastguard Worker DestroyVideoRtpSender();
772*d9f75844SAndroid Build Coastguard Worker }
773*d9f75844SAndroid Build Coastguard Worker
774*d9f75844SAndroid Build Coastguard Worker // Test that the media channel is enabled for sending when the video sender
775*d9f75844SAndroid Build Coastguard Worker // has a track and SSRC, when the SSRC is set last.
TEST_F(RtpSenderReceiverTest,VideoSenderEarlyWarmupTrackThenSsrc)776*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, VideoSenderEarlyWarmupTrackThenSsrc) {
777*d9f75844SAndroid Build Coastguard Worker AddVideoTrack();
778*d9f75844SAndroid Build Coastguard Worker CreateVideoRtpSenderWithNoTrack();
779*d9f75844SAndroid Build Coastguard Worker video_rtp_sender_->SetTrack(video_track_.get());
780*d9f75844SAndroid Build Coastguard Worker video_rtp_sender_->SetSsrc(kVideoSsrc);
781*d9f75844SAndroid Build Coastguard Worker VerifyVideoChannelInput();
782*d9f75844SAndroid Build Coastguard Worker
783*d9f75844SAndroid Build Coastguard Worker DestroyVideoRtpSender();
784*d9f75844SAndroid Build Coastguard Worker }
785*d9f75844SAndroid Build Coastguard Worker
786*d9f75844SAndroid Build Coastguard Worker // Test that the media channel stops sending when the audio sender's SSRC is set
787*d9f75844SAndroid Build Coastguard Worker // to 0.
TEST_F(RtpSenderReceiverTest,AudioSenderSsrcSetToZero)788*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, AudioSenderSsrcSetToZero) {
789*d9f75844SAndroid Build Coastguard Worker CreateAudioRtpSender();
790*d9f75844SAndroid Build Coastguard Worker
791*d9f75844SAndroid Build Coastguard Worker audio_rtp_sender_->SetSsrc(0);
792*d9f75844SAndroid Build Coastguard Worker VerifyVoiceChannelNoInput();
793*d9f75844SAndroid Build Coastguard Worker }
794*d9f75844SAndroid Build Coastguard Worker
795*d9f75844SAndroid Build Coastguard Worker // Test that the media channel stops sending when the video sender's SSRC is set
796*d9f75844SAndroid Build Coastguard Worker // to 0.
TEST_F(RtpSenderReceiverTest,VideoSenderSsrcSetToZero)797*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, VideoSenderSsrcSetToZero) {
798*d9f75844SAndroid Build Coastguard Worker CreateAudioRtpSender();
799*d9f75844SAndroid Build Coastguard Worker
800*d9f75844SAndroid Build Coastguard Worker audio_rtp_sender_->SetSsrc(0);
801*d9f75844SAndroid Build Coastguard Worker VerifyVideoChannelNoInput();
802*d9f75844SAndroid Build Coastguard Worker }
803*d9f75844SAndroid Build Coastguard Worker
804*d9f75844SAndroid Build Coastguard Worker // Test that the media channel stops sending when the audio sender's track is
805*d9f75844SAndroid Build Coastguard Worker // set to null.
TEST_F(RtpSenderReceiverTest,AudioSenderTrackSetToNull)806*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, AudioSenderTrackSetToNull) {
807*d9f75844SAndroid Build Coastguard Worker CreateAudioRtpSender();
808*d9f75844SAndroid Build Coastguard Worker
809*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(audio_rtp_sender_->SetTrack(nullptr));
810*d9f75844SAndroid Build Coastguard Worker VerifyVoiceChannelNoInput();
811*d9f75844SAndroid Build Coastguard Worker }
812*d9f75844SAndroid Build Coastguard Worker
813*d9f75844SAndroid Build Coastguard Worker // Test that the media channel stops sending when the video sender's track is
814*d9f75844SAndroid Build Coastguard Worker // set to null.
TEST_F(RtpSenderReceiverTest,VideoSenderTrackSetToNull)815*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, VideoSenderTrackSetToNull) {
816*d9f75844SAndroid Build Coastguard Worker CreateVideoRtpSender();
817*d9f75844SAndroid Build Coastguard Worker
818*d9f75844SAndroid Build Coastguard Worker video_rtp_sender_->SetSsrc(0);
819*d9f75844SAndroid Build Coastguard Worker VerifyVideoChannelNoInput();
820*d9f75844SAndroid Build Coastguard Worker }
821*d9f75844SAndroid Build Coastguard Worker
822*d9f75844SAndroid Build Coastguard Worker // Test that when the audio sender's SSRC is changed, the media channel stops
823*d9f75844SAndroid Build Coastguard Worker // sending with the old SSRC and starts sending with the new one.
TEST_F(RtpSenderReceiverTest,AudioSenderSsrcChanged)824*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, AudioSenderSsrcChanged) {
825*d9f75844SAndroid Build Coastguard Worker CreateAudioRtpSender();
826*d9f75844SAndroid Build Coastguard Worker
827*d9f75844SAndroid Build Coastguard Worker audio_rtp_sender_->SetSsrc(kAudioSsrc2);
828*d9f75844SAndroid Build Coastguard Worker VerifyVoiceChannelNoInput(kAudioSsrc);
829*d9f75844SAndroid Build Coastguard Worker VerifyVoiceChannelInput(kAudioSsrc2);
830*d9f75844SAndroid Build Coastguard Worker
831*d9f75844SAndroid Build Coastguard Worker audio_rtp_sender_ = nullptr;
832*d9f75844SAndroid Build Coastguard Worker VerifyVoiceChannelNoInput(kAudioSsrc2);
833*d9f75844SAndroid Build Coastguard Worker }
834*d9f75844SAndroid Build Coastguard Worker
835*d9f75844SAndroid Build Coastguard Worker // Test that when the audio sender's SSRC is changed, the media channel stops
836*d9f75844SAndroid Build Coastguard Worker // sending with the old SSRC and starts sending with the new one.
TEST_F(RtpSenderReceiverTest,VideoSenderSsrcChanged)837*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, VideoSenderSsrcChanged) {
838*d9f75844SAndroid Build Coastguard Worker CreateVideoRtpSender();
839*d9f75844SAndroid Build Coastguard Worker
840*d9f75844SAndroid Build Coastguard Worker video_rtp_sender_->SetSsrc(kVideoSsrc2);
841*d9f75844SAndroid Build Coastguard Worker VerifyVideoChannelNoInput(kVideoSsrc);
842*d9f75844SAndroid Build Coastguard Worker VerifyVideoChannelInput(kVideoSsrc2);
843*d9f75844SAndroid Build Coastguard Worker
844*d9f75844SAndroid Build Coastguard Worker video_rtp_sender_ = nullptr;
845*d9f75844SAndroid Build Coastguard Worker VerifyVideoChannelNoInput(kVideoSsrc2);
846*d9f75844SAndroid Build Coastguard Worker }
847*d9f75844SAndroid Build Coastguard Worker
TEST_F(RtpSenderReceiverTest,AudioSenderCanSetParameters)848*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, AudioSenderCanSetParameters) {
849*d9f75844SAndroid Build Coastguard Worker CreateAudioRtpSender();
850*d9f75844SAndroid Build Coastguard Worker
851*d9f75844SAndroid Build Coastguard Worker RtpParameters params = audio_rtp_sender_->GetParameters();
852*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1u, params.encodings.size());
853*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(audio_rtp_sender_->SetParameters(params).ok());
854*d9f75844SAndroid Build Coastguard Worker
855*d9f75844SAndroid Build Coastguard Worker DestroyAudioRtpSender();
856*d9f75844SAndroid Build Coastguard Worker }
857*d9f75844SAndroid Build Coastguard Worker
TEST_F(RtpSenderReceiverTest,AudioSenderCanSetParametersAsync)858*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, AudioSenderCanSetParametersAsync) {
859*d9f75844SAndroid Build Coastguard Worker CreateAudioRtpSender();
860*d9f75844SAndroid Build Coastguard Worker
861*d9f75844SAndroid Build Coastguard Worker RtpParameters params = audio_rtp_sender_->GetParameters();
862*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1u, params.encodings.size());
863*d9f75844SAndroid Build Coastguard Worker absl::optional<webrtc::RTCError> result;
864*d9f75844SAndroid Build Coastguard Worker audio_rtp_sender_->SetParametersAsync(
865*d9f75844SAndroid Build Coastguard Worker params, [&result](webrtc::RTCError error) { result = error; });
866*d9f75844SAndroid Build Coastguard Worker run_loop_.Flush();
867*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(result->ok());
868*d9f75844SAndroid Build Coastguard Worker
869*d9f75844SAndroid Build Coastguard Worker DestroyAudioRtpSender();
870*d9f75844SAndroid Build Coastguard Worker }
871*d9f75844SAndroid Build Coastguard Worker
TEST_F(RtpSenderReceiverTest,AudioSenderCanSetParametersBeforeNegotiation)872*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, AudioSenderCanSetParametersBeforeNegotiation) {
873*d9f75844SAndroid Build Coastguard Worker audio_rtp_sender_ =
874*d9f75844SAndroid Build Coastguard Worker AudioRtpSender::Create(worker_thread_, /*id=*/"", nullptr, nullptr);
875*d9f75844SAndroid Build Coastguard Worker
876*d9f75844SAndroid Build Coastguard Worker RtpParameters params = audio_rtp_sender_->GetParameters();
877*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ(1u, params.encodings.size());
878*d9f75844SAndroid Build Coastguard Worker params.encodings[0].max_bitrate_bps = 90000;
879*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(audio_rtp_sender_->SetParameters(params).ok());
880*d9f75844SAndroid Build Coastguard Worker
881*d9f75844SAndroid Build Coastguard Worker params = audio_rtp_sender_->GetParameters();
882*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(params.encodings[0].max_bitrate_bps, 90000);
883*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(audio_rtp_sender_->SetParameters(params).ok());
884*d9f75844SAndroid Build Coastguard Worker
885*d9f75844SAndroid Build Coastguard Worker DestroyAudioRtpSender();
886*d9f75844SAndroid Build Coastguard Worker }
887*d9f75844SAndroid Build Coastguard Worker
TEST_F(RtpSenderReceiverTest,AudioSenderCanSetParametersAsyncBeforeNegotiation)888*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest,
889*d9f75844SAndroid Build Coastguard Worker AudioSenderCanSetParametersAsyncBeforeNegotiation) {
890*d9f75844SAndroid Build Coastguard Worker audio_rtp_sender_ =
891*d9f75844SAndroid Build Coastguard Worker AudioRtpSender::Create(worker_thread_, /*id=*/"", nullptr, nullptr);
892*d9f75844SAndroid Build Coastguard Worker
893*d9f75844SAndroid Build Coastguard Worker absl::optional<webrtc::RTCError> result;
894*d9f75844SAndroid Build Coastguard Worker RtpParameters params = audio_rtp_sender_->GetParameters();
895*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ(1u, params.encodings.size());
896*d9f75844SAndroid Build Coastguard Worker params.encodings[0].max_bitrate_bps = 90000;
897*d9f75844SAndroid Build Coastguard Worker
898*d9f75844SAndroid Build Coastguard Worker audio_rtp_sender_->SetParametersAsync(
899*d9f75844SAndroid Build Coastguard Worker params, [&result](webrtc::RTCError error) { result = error; });
900*d9f75844SAndroid Build Coastguard Worker run_loop_.Flush();
901*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(result->ok());
902*d9f75844SAndroid Build Coastguard Worker
903*d9f75844SAndroid Build Coastguard Worker params = audio_rtp_sender_->GetParameters();
904*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(params.encodings[0].max_bitrate_bps, 90000);
905*d9f75844SAndroid Build Coastguard Worker
906*d9f75844SAndroid Build Coastguard Worker audio_rtp_sender_->SetParametersAsync(
907*d9f75844SAndroid Build Coastguard Worker params, [&result](webrtc::RTCError error) { result = error; });
908*d9f75844SAndroid Build Coastguard Worker run_loop_.Flush();
909*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(result->ok());
910*d9f75844SAndroid Build Coastguard Worker
911*d9f75844SAndroid Build Coastguard Worker DestroyAudioRtpSender();
912*d9f75844SAndroid Build Coastguard Worker }
913*d9f75844SAndroid Build Coastguard Worker
TEST_F(RtpSenderReceiverTest,AudioSenderInitParametersMovedAfterNegotiation)914*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, AudioSenderInitParametersMovedAfterNegotiation) {
915*d9f75844SAndroid Build Coastguard Worker audio_track_ = AudioTrack::Create(kAudioTrackId, nullptr);
916*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(local_stream_->AddTrack(audio_track_));
917*d9f75844SAndroid Build Coastguard Worker
918*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<MockSetStreamsObserver> set_streams_observer =
919*d9f75844SAndroid Build Coastguard Worker std::make_unique<MockSetStreamsObserver>();
920*d9f75844SAndroid Build Coastguard Worker audio_rtp_sender_ = AudioRtpSender::Create(
921*d9f75844SAndroid Build Coastguard Worker worker_thread_, audio_track_->id(), nullptr, set_streams_observer.get());
922*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(audio_rtp_sender_->SetTrack(audio_track_.get()));
923*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(*set_streams_observer, OnSetStreams());
924*d9f75844SAndroid Build Coastguard Worker audio_rtp_sender_->SetStreams({local_stream_->id()});
925*d9f75844SAndroid Build Coastguard Worker
926*d9f75844SAndroid Build Coastguard Worker std::vector<RtpEncodingParameters> init_encodings(1);
927*d9f75844SAndroid Build Coastguard Worker init_encodings[0].max_bitrate_bps = 60000;
928*d9f75844SAndroid Build Coastguard Worker audio_rtp_sender_->set_init_send_encodings(init_encodings);
929*d9f75844SAndroid Build Coastguard Worker
930*d9f75844SAndroid Build Coastguard Worker RtpParameters params = audio_rtp_sender_->GetParameters();
931*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ(1u, params.encodings.size());
932*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(params.encodings[0].max_bitrate_bps, 60000);
933*d9f75844SAndroid Build Coastguard Worker
934*d9f75844SAndroid Build Coastguard Worker // Simulate the setLocalDescription call
935*d9f75844SAndroid Build Coastguard Worker std::vector<uint32_t> ssrcs(1, 1);
936*d9f75844SAndroid Build Coastguard Worker cricket::StreamParams stream_params =
937*d9f75844SAndroid Build Coastguard Worker cricket::CreateSimStreamParams("cname", ssrcs);
938*d9f75844SAndroid Build Coastguard Worker voice_media_channel()->AddSendStream(stream_params);
939*d9f75844SAndroid Build Coastguard Worker audio_rtp_sender_->SetMediaChannel(voice_media_channel());
940*d9f75844SAndroid Build Coastguard Worker audio_rtp_sender_->SetSsrc(1);
941*d9f75844SAndroid Build Coastguard Worker
942*d9f75844SAndroid Build Coastguard Worker params = audio_rtp_sender_->GetParameters();
943*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ(1u, params.encodings.size());
944*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(params.encodings[0].max_bitrate_bps, 60000);
945*d9f75844SAndroid Build Coastguard Worker
946*d9f75844SAndroid Build Coastguard Worker DestroyAudioRtpSender();
947*d9f75844SAndroid Build Coastguard Worker }
948*d9f75844SAndroid Build Coastguard Worker
TEST_F(RtpSenderReceiverTest,AudioSenderMustCallGetParametersBeforeSetParametersBeforeNegotiation)949*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest,
950*d9f75844SAndroid Build Coastguard Worker AudioSenderMustCallGetParametersBeforeSetParametersBeforeNegotiation) {
951*d9f75844SAndroid Build Coastguard Worker audio_rtp_sender_ =
952*d9f75844SAndroid Build Coastguard Worker AudioRtpSender::Create(worker_thread_, /*id=*/"", nullptr, nullptr);
953*d9f75844SAndroid Build Coastguard Worker
954*d9f75844SAndroid Build Coastguard Worker RtpParameters params;
955*d9f75844SAndroid Build Coastguard Worker RTCError result = audio_rtp_sender_->SetParameters(params);
956*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(RTCErrorType::INVALID_STATE, result.type());
957*d9f75844SAndroid Build Coastguard Worker DestroyAudioRtpSender();
958*d9f75844SAndroid Build Coastguard Worker }
959*d9f75844SAndroid Build Coastguard Worker
TEST_F(RtpSenderReceiverTest,AudioSenderMustCallGetParametersBeforeSetParameters)960*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest,
961*d9f75844SAndroid Build Coastguard Worker AudioSenderMustCallGetParametersBeforeSetParameters) {
962*d9f75844SAndroid Build Coastguard Worker CreateAudioRtpSender();
963*d9f75844SAndroid Build Coastguard Worker
964*d9f75844SAndroid Build Coastguard Worker RtpParameters params;
965*d9f75844SAndroid Build Coastguard Worker RTCError result = audio_rtp_sender_->SetParameters(params);
966*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(RTCErrorType::INVALID_STATE, result.type());
967*d9f75844SAndroid Build Coastguard Worker
968*d9f75844SAndroid Build Coastguard Worker DestroyAudioRtpSender();
969*d9f75844SAndroid Build Coastguard Worker }
970*d9f75844SAndroid Build Coastguard Worker
TEST_F(RtpSenderReceiverTest,AudioSenderSetParametersInvalidatesTransactionId)971*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest,
972*d9f75844SAndroid Build Coastguard Worker AudioSenderSetParametersInvalidatesTransactionId) {
973*d9f75844SAndroid Build Coastguard Worker CreateAudioRtpSender();
974*d9f75844SAndroid Build Coastguard Worker
975*d9f75844SAndroid Build Coastguard Worker RtpParameters params = audio_rtp_sender_->GetParameters();
976*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1u, params.encodings.size());
977*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(audio_rtp_sender_->SetParameters(params).ok());
978*d9f75844SAndroid Build Coastguard Worker RTCError result = audio_rtp_sender_->SetParameters(params);
979*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(RTCErrorType::INVALID_STATE, result.type());
980*d9f75844SAndroid Build Coastguard Worker
981*d9f75844SAndroid Build Coastguard Worker DestroyAudioRtpSender();
982*d9f75844SAndroid Build Coastguard Worker }
983*d9f75844SAndroid Build Coastguard Worker
TEST_F(RtpSenderReceiverTest,AudioSenderSetParametersAsyncInvalidatesTransactionId)984*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest,
985*d9f75844SAndroid Build Coastguard Worker AudioSenderSetParametersAsyncInvalidatesTransactionId) {
986*d9f75844SAndroid Build Coastguard Worker CreateAudioRtpSender();
987*d9f75844SAndroid Build Coastguard Worker
988*d9f75844SAndroid Build Coastguard Worker RtpParameters params = audio_rtp_sender_->GetParameters();
989*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1u, params.encodings.size());
990*d9f75844SAndroid Build Coastguard Worker absl::optional<webrtc::RTCError> result;
991*d9f75844SAndroid Build Coastguard Worker audio_rtp_sender_->SetParametersAsync(
992*d9f75844SAndroid Build Coastguard Worker params, [&result](webrtc::RTCError error) { result = error; });
993*d9f75844SAndroid Build Coastguard Worker run_loop_.Flush();
994*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(result->ok());
995*d9f75844SAndroid Build Coastguard Worker audio_rtp_sender_->SetParametersAsync(
996*d9f75844SAndroid Build Coastguard Worker params, [&result](webrtc::RTCError error) { result = error; });
997*d9f75844SAndroid Build Coastguard Worker run_loop_.Flush();
998*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(RTCErrorType::INVALID_STATE, result->type());
999*d9f75844SAndroid Build Coastguard Worker
1000*d9f75844SAndroid Build Coastguard Worker DestroyAudioRtpSender();
1001*d9f75844SAndroid Build Coastguard Worker }
1002*d9f75844SAndroid Build Coastguard Worker
TEST_F(RtpSenderReceiverTest,AudioSenderDetectTransactionIdModification)1003*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, AudioSenderDetectTransactionIdModification) {
1004*d9f75844SAndroid Build Coastguard Worker CreateAudioRtpSender();
1005*d9f75844SAndroid Build Coastguard Worker
1006*d9f75844SAndroid Build Coastguard Worker RtpParameters params = audio_rtp_sender_->GetParameters();
1007*d9f75844SAndroid Build Coastguard Worker params.transaction_id = "";
1008*d9f75844SAndroid Build Coastguard Worker RTCError result = audio_rtp_sender_->SetParameters(params);
1009*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(RTCErrorType::INVALID_MODIFICATION, result.type());
1010*d9f75844SAndroid Build Coastguard Worker
1011*d9f75844SAndroid Build Coastguard Worker DestroyAudioRtpSender();
1012*d9f75844SAndroid Build Coastguard Worker }
1013*d9f75844SAndroid Build Coastguard Worker
TEST_F(RtpSenderReceiverTest,AudioSenderCheckTransactionIdRefresh)1014*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, AudioSenderCheckTransactionIdRefresh) {
1015*d9f75844SAndroid Build Coastguard Worker CreateAudioRtpSender();
1016*d9f75844SAndroid Build Coastguard Worker
1017*d9f75844SAndroid Build Coastguard Worker RtpParameters params = audio_rtp_sender_->GetParameters();
1018*d9f75844SAndroid Build Coastguard Worker EXPECT_NE(params.transaction_id.size(), 0U);
1019*d9f75844SAndroid Build Coastguard Worker auto saved_transaction_id = params.transaction_id;
1020*d9f75844SAndroid Build Coastguard Worker params = audio_rtp_sender_->GetParameters();
1021*d9f75844SAndroid Build Coastguard Worker EXPECT_NE(saved_transaction_id, params.transaction_id);
1022*d9f75844SAndroid Build Coastguard Worker
1023*d9f75844SAndroid Build Coastguard Worker DestroyAudioRtpSender();
1024*d9f75844SAndroid Build Coastguard Worker }
1025*d9f75844SAndroid Build Coastguard Worker
TEST_F(RtpSenderReceiverTest,AudioSenderSetParametersOldValueFail)1026*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, AudioSenderSetParametersOldValueFail) {
1027*d9f75844SAndroid Build Coastguard Worker CreateAudioRtpSender();
1028*d9f75844SAndroid Build Coastguard Worker
1029*d9f75844SAndroid Build Coastguard Worker RtpParameters params = audio_rtp_sender_->GetParameters();
1030*d9f75844SAndroid Build Coastguard Worker RtpParameters second_params = audio_rtp_sender_->GetParameters();
1031*d9f75844SAndroid Build Coastguard Worker
1032*d9f75844SAndroid Build Coastguard Worker RTCError result = audio_rtp_sender_->SetParameters(params);
1033*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(RTCErrorType::INVALID_MODIFICATION, result.type());
1034*d9f75844SAndroid Build Coastguard Worker DestroyAudioRtpSender();
1035*d9f75844SAndroid Build Coastguard Worker }
1036*d9f75844SAndroid Build Coastguard Worker
TEST_F(RtpSenderReceiverTest,AudioSenderCantSetUnimplementedRtpParameters)1037*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, AudioSenderCantSetUnimplementedRtpParameters) {
1038*d9f75844SAndroid Build Coastguard Worker CreateAudioRtpSender();
1039*d9f75844SAndroid Build Coastguard Worker RtpParameters params = audio_rtp_sender_->GetParameters();
1040*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1u, params.encodings.size());
1041*d9f75844SAndroid Build Coastguard Worker
1042*d9f75844SAndroid Build Coastguard Worker // Unimplemented RtpParameters: mid
1043*d9f75844SAndroid Build Coastguard Worker params.mid = "dummy_mid";
1044*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(RTCErrorType::UNSUPPORTED_PARAMETER,
1045*d9f75844SAndroid Build Coastguard Worker audio_rtp_sender_->SetParameters(params).type());
1046*d9f75844SAndroid Build Coastguard Worker params = audio_rtp_sender_->GetParameters();
1047*d9f75844SAndroid Build Coastguard Worker
1048*d9f75844SAndroid Build Coastguard Worker DestroyAudioRtpSender();
1049*d9f75844SAndroid Build Coastguard Worker }
1050*d9f75844SAndroid Build Coastguard Worker
TEST_F(RtpSenderReceiverTest,SetAudioMaxSendBitrate)1051*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, SetAudioMaxSendBitrate) {
1052*d9f75844SAndroid Build Coastguard Worker CreateAudioRtpSender();
1053*d9f75844SAndroid Build Coastguard Worker
1054*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(-1, voice_media_channel()->max_bps());
1055*d9f75844SAndroid Build Coastguard Worker webrtc::RtpParameters params = audio_rtp_sender_->GetParameters();
1056*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1U, params.encodings.size());
1057*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(params.encodings[0].max_bitrate_bps);
1058*d9f75844SAndroid Build Coastguard Worker params.encodings[0].max_bitrate_bps = 1000;
1059*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(audio_rtp_sender_->SetParameters(params).ok());
1060*d9f75844SAndroid Build Coastguard Worker
1061*d9f75844SAndroid Build Coastguard Worker // Read back the parameters and verify they have been changed.
1062*d9f75844SAndroid Build Coastguard Worker params = audio_rtp_sender_->GetParameters();
1063*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1U, params.encodings.size());
1064*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1000, params.encodings[0].max_bitrate_bps);
1065*d9f75844SAndroid Build Coastguard Worker
1066*d9f75844SAndroid Build Coastguard Worker // Verify that the audio channel received the new parameters.
1067*d9f75844SAndroid Build Coastguard Worker params = voice_media_channel()->GetRtpSendParameters(kAudioSsrc);
1068*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1U, params.encodings.size());
1069*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1000, params.encodings[0].max_bitrate_bps);
1070*d9f75844SAndroid Build Coastguard Worker
1071*d9f75844SAndroid Build Coastguard Worker // Verify that the global bitrate limit has not been changed.
1072*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(-1, voice_media_channel()->max_bps());
1073*d9f75844SAndroid Build Coastguard Worker
1074*d9f75844SAndroid Build Coastguard Worker DestroyAudioRtpSender();
1075*d9f75844SAndroid Build Coastguard Worker }
1076*d9f75844SAndroid Build Coastguard Worker
TEST_F(RtpSenderReceiverTest,SetAudioBitratePriority)1077*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, SetAudioBitratePriority) {
1078*d9f75844SAndroid Build Coastguard Worker CreateAudioRtpSender();
1079*d9f75844SAndroid Build Coastguard Worker
1080*d9f75844SAndroid Build Coastguard Worker webrtc::RtpParameters params = audio_rtp_sender_->GetParameters();
1081*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1U, params.encodings.size());
1082*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(webrtc::kDefaultBitratePriority,
1083*d9f75844SAndroid Build Coastguard Worker params.encodings[0].bitrate_priority);
1084*d9f75844SAndroid Build Coastguard Worker double new_bitrate_priority = 2.0;
1085*d9f75844SAndroid Build Coastguard Worker params.encodings[0].bitrate_priority = new_bitrate_priority;
1086*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(audio_rtp_sender_->SetParameters(params).ok());
1087*d9f75844SAndroid Build Coastguard Worker
1088*d9f75844SAndroid Build Coastguard Worker params = audio_rtp_sender_->GetParameters();
1089*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1U, params.encodings.size());
1090*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(new_bitrate_priority, params.encodings[0].bitrate_priority);
1091*d9f75844SAndroid Build Coastguard Worker
1092*d9f75844SAndroid Build Coastguard Worker params = voice_media_channel()->GetRtpSendParameters(kAudioSsrc);
1093*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1U, params.encodings.size());
1094*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(new_bitrate_priority, params.encodings[0].bitrate_priority);
1095*d9f75844SAndroid Build Coastguard Worker
1096*d9f75844SAndroid Build Coastguard Worker DestroyAudioRtpSender();
1097*d9f75844SAndroid Build Coastguard Worker }
1098*d9f75844SAndroid Build Coastguard Worker
TEST_F(RtpSenderReceiverTest,VideoSenderCanSetParameters)1099*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, VideoSenderCanSetParameters) {
1100*d9f75844SAndroid Build Coastguard Worker CreateVideoRtpSender();
1101*d9f75844SAndroid Build Coastguard Worker
1102*d9f75844SAndroid Build Coastguard Worker RtpParameters params = video_rtp_sender_->GetParameters();
1103*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1u, params.encodings.size());
1104*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(video_rtp_sender_->SetParameters(params).ok());
1105*d9f75844SAndroid Build Coastguard Worker
1106*d9f75844SAndroid Build Coastguard Worker DestroyVideoRtpSender();
1107*d9f75844SAndroid Build Coastguard Worker }
1108*d9f75844SAndroid Build Coastguard Worker
TEST_F(RtpSenderReceiverTest,VideoSenderCanSetParametersAsync)1109*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, VideoSenderCanSetParametersAsync) {
1110*d9f75844SAndroid Build Coastguard Worker CreateVideoRtpSender();
1111*d9f75844SAndroid Build Coastguard Worker
1112*d9f75844SAndroid Build Coastguard Worker RtpParameters params = video_rtp_sender_->GetParameters();
1113*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1u, params.encodings.size());
1114*d9f75844SAndroid Build Coastguard Worker absl::optional<webrtc::RTCError> result;
1115*d9f75844SAndroid Build Coastguard Worker video_rtp_sender_->SetParametersAsync(
1116*d9f75844SAndroid Build Coastguard Worker params, [&result](webrtc::RTCError error) { result = error; });
1117*d9f75844SAndroid Build Coastguard Worker run_loop_.Flush();
1118*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(result->ok());
1119*d9f75844SAndroid Build Coastguard Worker
1120*d9f75844SAndroid Build Coastguard Worker DestroyVideoRtpSender();
1121*d9f75844SAndroid Build Coastguard Worker }
1122*d9f75844SAndroid Build Coastguard Worker
TEST_F(RtpSenderReceiverTest,VideoSenderCanSetParametersBeforeNegotiation)1123*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, VideoSenderCanSetParametersBeforeNegotiation) {
1124*d9f75844SAndroid Build Coastguard Worker video_rtp_sender_ =
1125*d9f75844SAndroid Build Coastguard Worker VideoRtpSender::Create(worker_thread_, /*id=*/"", nullptr);
1126*d9f75844SAndroid Build Coastguard Worker
1127*d9f75844SAndroid Build Coastguard Worker RtpParameters params = video_rtp_sender_->GetParameters();
1128*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ(1u, params.encodings.size());
1129*d9f75844SAndroid Build Coastguard Worker params.encodings[0].max_bitrate_bps = 90000;
1130*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(video_rtp_sender_->SetParameters(params).ok());
1131*d9f75844SAndroid Build Coastguard Worker
1132*d9f75844SAndroid Build Coastguard Worker params = video_rtp_sender_->GetParameters();
1133*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(video_rtp_sender_->SetParameters(params).ok());
1134*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(params.encodings[0].max_bitrate_bps, 90000);
1135*d9f75844SAndroid Build Coastguard Worker
1136*d9f75844SAndroid Build Coastguard Worker DestroyVideoRtpSender();
1137*d9f75844SAndroid Build Coastguard Worker }
1138*d9f75844SAndroid Build Coastguard Worker
TEST_F(RtpSenderReceiverTest,VideoSenderCanSetParametersAsyncBeforeNegotiation)1139*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest,
1140*d9f75844SAndroid Build Coastguard Worker VideoSenderCanSetParametersAsyncBeforeNegotiation) {
1141*d9f75844SAndroid Build Coastguard Worker video_rtp_sender_ =
1142*d9f75844SAndroid Build Coastguard Worker VideoRtpSender::Create(worker_thread_, /*id=*/"", nullptr);
1143*d9f75844SAndroid Build Coastguard Worker
1144*d9f75844SAndroid Build Coastguard Worker absl::optional<webrtc::RTCError> result;
1145*d9f75844SAndroid Build Coastguard Worker RtpParameters params = video_rtp_sender_->GetParameters();
1146*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ(1u, params.encodings.size());
1147*d9f75844SAndroid Build Coastguard Worker params.encodings[0].max_bitrate_bps = 90000;
1148*d9f75844SAndroid Build Coastguard Worker video_rtp_sender_->SetParametersAsync(
1149*d9f75844SAndroid Build Coastguard Worker params, [&result](webrtc::RTCError error) { result = error; });
1150*d9f75844SAndroid Build Coastguard Worker run_loop_.Flush();
1151*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(result->ok());
1152*d9f75844SAndroid Build Coastguard Worker
1153*d9f75844SAndroid Build Coastguard Worker params = video_rtp_sender_->GetParameters();
1154*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(params.encodings[0].max_bitrate_bps, 90000);
1155*d9f75844SAndroid Build Coastguard Worker video_rtp_sender_->SetParametersAsync(
1156*d9f75844SAndroid Build Coastguard Worker params, [&result](webrtc::RTCError error) { result = error; });
1157*d9f75844SAndroid Build Coastguard Worker run_loop_.Flush();
1158*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(result->ok());
1159*d9f75844SAndroid Build Coastguard Worker
1160*d9f75844SAndroid Build Coastguard Worker DestroyVideoRtpSender();
1161*d9f75844SAndroid Build Coastguard Worker }
1162*d9f75844SAndroid Build Coastguard Worker
TEST_F(RtpSenderReceiverTest,VideoSenderInitParametersMovedAfterNegotiation)1163*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, VideoSenderInitParametersMovedAfterNegotiation) {
1164*d9f75844SAndroid Build Coastguard Worker AddVideoTrack(false);
1165*d9f75844SAndroid Build Coastguard Worker
1166*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<MockSetStreamsObserver> set_streams_observer =
1167*d9f75844SAndroid Build Coastguard Worker std::make_unique<MockSetStreamsObserver>();
1168*d9f75844SAndroid Build Coastguard Worker video_rtp_sender_ = VideoRtpSender::Create(worker_thread_, video_track_->id(),
1169*d9f75844SAndroid Build Coastguard Worker set_streams_observer.get());
1170*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(video_rtp_sender_->SetTrack(video_track_.get()));
1171*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(*set_streams_observer, OnSetStreams());
1172*d9f75844SAndroid Build Coastguard Worker video_rtp_sender_->SetStreams({local_stream_->id()});
1173*d9f75844SAndroid Build Coastguard Worker
1174*d9f75844SAndroid Build Coastguard Worker std::vector<RtpEncodingParameters> init_encodings(2);
1175*d9f75844SAndroid Build Coastguard Worker init_encodings[0].max_bitrate_bps = 60000;
1176*d9f75844SAndroid Build Coastguard Worker init_encodings[1].max_bitrate_bps = 900000;
1177*d9f75844SAndroid Build Coastguard Worker video_rtp_sender_->set_init_send_encodings(init_encodings);
1178*d9f75844SAndroid Build Coastguard Worker
1179*d9f75844SAndroid Build Coastguard Worker RtpParameters params = video_rtp_sender_->GetParameters();
1180*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ(2u, params.encodings.size());
1181*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(params.encodings[0].max_bitrate_bps, 60000);
1182*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(params.encodings[1].max_bitrate_bps, 900000);
1183*d9f75844SAndroid Build Coastguard Worker
1184*d9f75844SAndroid Build Coastguard Worker // Simulate the setLocalDescription call
1185*d9f75844SAndroid Build Coastguard Worker std::vector<uint32_t> ssrcs;
1186*d9f75844SAndroid Build Coastguard Worker ssrcs.reserve(2);
1187*d9f75844SAndroid Build Coastguard Worker for (int i = 0; i < 2; ++i)
1188*d9f75844SAndroid Build Coastguard Worker ssrcs.push_back(kVideoSsrcSimulcast + i);
1189*d9f75844SAndroid Build Coastguard Worker cricket::StreamParams stream_params =
1190*d9f75844SAndroid Build Coastguard Worker cricket::CreateSimStreamParams("cname", ssrcs);
1191*d9f75844SAndroid Build Coastguard Worker video_media_channel()->AddSendStream(stream_params);
1192*d9f75844SAndroid Build Coastguard Worker video_rtp_sender_->SetMediaChannel(video_media_channel());
1193*d9f75844SAndroid Build Coastguard Worker video_rtp_sender_->SetSsrc(kVideoSsrcSimulcast);
1194*d9f75844SAndroid Build Coastguard Worker
1195*d9f75844SAndroid Build Coastguard Worker params = video_rtp_sender_->GetParameters();
1196*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ(2u, params.encodings.size());
1197*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(params.encodings[0].max_bitrate_bps, 60000);
1198*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(params.encodings[1].max_bitrate_bps, 900000);
1199*d9f75844SAndroid Build Coastguard Worker
1200*d9f75844SAndroid Build Coastguard Worker DestroyVideoRtpSender();
1201*d9f75844SAndroid Build Coastguard Worker }
1202*d9f75844SAndroid Build Coastguard Worker
TEST_F(RtpSenderReceiverTest,VideoSenderInitParametersMovedAfterManualSimulcastAndNegotiation)1203*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest,
1204*d9f75844SAndroid Build Coastguard Worker VideoSenderInitParametersMovedAfterManualSimulcastAndNegotiation) {
1205*d9f75844SAndroid Build Coastguard Worker AddVideoTrack(false);
1206*d9f75844SAndroid Build Coastguard Worker
1207*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<MockSetStreamsObserver> set_streams_observer =
1208*d9f75844SAndroid Build Coastguard Worker std::make_unique<MockSetStreamsObserver>();
1209*d9f75844SAndroid Build Coastguard Worker video_rtp_sender_ = VideoRtpSender::Create(worker_thread_, video_track_->id(),
1210*d9f75844SAndroid Build Coastguard Worker set_streams_observer.get());
1211*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(video_rtp_sender_->SetTrack(video_track_.get()));
1212*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(*set_streams_observer, OnSetStreams());
1213*d9f75844SAndroid Build Coastguard Worker video_rtp_sender_->SetStreams({local_stream_->id()});
1214*d9f75844SAndroid Build Coastguard Worker
1215*d9f75844SAndroid Build Coastguard Worker std::vector<RtpEncodingParameters> init_encodings(1);
1216*d9f75844SAndroid Build Coastguard Worker init_encodings[0].max_bitrate_bps = 60000;
1217*d9f75844SAndroid Build Coastguard Worker video_rtp_sender_->set_init_send_encodings(init_encodings);
1218*d9f75844SAndroid Build Coastguard Worker
1219*d9f75844SAndroid Build Coastguard Worker RtpParameters params = video_rtp_sender_->GetParameters();
1220*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ(1u, params.encodings.size());
1221*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(params.encodings[0].max_bitrate_bps, 60000);
1222*d9f75844SAndroid Build Coastguard Worker
1223*d9f75844SAndroid Build Coastguard Worker // Simulate the setLocalDescription call as if the user used SDP munging
1224*d9f75844SAndroid Build Coastguard Worker // to enable simulcast
1225*d9f75844SAndroid Build Coastguard Worker std::vector<uint32_t> ssrcs;
1226*d9f75844SAndroid Build Coastguard Worker ssrcs.reserve(2);
1227*d9f75844SAndroid Build Coastguard Worker for (int i = 0; i < 2; ++i)
1228*d9f75844SAndroid Build Coastguard Worker ssrcs.push_back(kVideoSsrcSimulcast + i);
1229*d9f75844SAndroid Build Coastguard Worker cricket::StreamParams stream_params =
1230*d9f75844SAndroid Build Coastguard Worker cricket::CreateSimStreamParams("cname", ssrcs);
1231*d9f75844SAndroid Build Coastguard Worker video_media_channel()->AddSendStream(stream_params);
1232*d9f75844SAndroid Build Coastguard Worker video_rtp_sender_->SetMediaChannel(video_media_channel());
1233*d9f75844SAndroid Build Coastguard Worker video_rtp_sender_->SetSsrc(kVideoSsrcSimulcast);
1234*d9f75844SAndroid Build Coastguard Worker
1235*d9f75844SAndroid Build Coastguard Worker params = video_rtp_sender_->GetParameters();
1236*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ(2u, params.encodings.size());
1237*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(params.encodings[0].max_bitrate_bps, 60000);
1238*d9f75844SAndroid Build Coastguard Worker
1239*d9f75844SAndroid Build Coastguard Worker DestroyVideoRtpSender();
1240*d9f75844SAndroid Build Coastguard Worker }
1241*d9f75844SAndroid Build Coastguard Worker
1242*d9f75844SAndroid Build Coastguard Worker #if GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
1243*d9f75844SAndroid Build Coastguard Worker using RtpSenderReceiverDeathTest = RtpSenderReceiverTest;
1244*d9f75844SAndroid Build Coastguard Worker
TEST_F(RtpSenderReceiverDeathTest,VideoSenderManualRemoveSimulcastFailsDeathTest)1245*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverDeathTest,
1246*d9f75844SAndroid Build Coastguard Worker VideoSenderManualRemoveSimulcastFailsDeathTest) {
1247*d9f75844SAndroid Build Coastguard Worker AddVideoTrack(false);
1248*d9f75844SAndroid Build Coastguard Worker
1249*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<MockSetStreamsObserver> set_streams_observer =
1250*d9f75844SAndroid Build Coastguard Worker std::make_unique<MockSetStreamsObserver>();
1251*d9f75844SAndroid Build Coastguard Worker video_rtp_sender_ = VideoRtpSender::Create(worker_thread_, video_track_->id(),
1252*d9f75844SAndroid Build Coastguard Worker set_streams_observer.get());
1253*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(video_rtp_sender_->SetTrack(video_track_.get()));
1254*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(*set_streams_observer, OnSetStreams());
1255*d9f75844SAndroid Build Coastguard Worker video_rtp_sender_->SetStreams({local_stream_->id()});
1256*d9f75844SAndroid Build Coastguard Worker
1257*d9f75844SAndroid Build Coastguard Worker std::vector<RtpEncodingParameters> init_encodings(2);
1258*d9f75844SAndroid Build Coastguard Worker init_encodings[0].max_bitrate_bps = 60000;
1259*d9f75844SAndroid Build Coastguard Worker init_encodings[1].max_bitrate_bps = 120000;
1260*d9f75844SAndroid Build Coastguard Worker video_rtp_sender_->set_init_send_encodings(init_encodings);
1261*d9f75844SAndroid Build Coastguard Worker
1262*d9f75844SAndroid Build Coastguard Worker RtpParameters params = video_rtp_sender_->GetParameters();
1263*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ(2u, params.encodings.size());
1264*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(params.encodings[0].max_bitrate_bps, 60000);
1265*d9f75844SAndroid Build Coastguard Worker
1266*d9f75844SAndroid Build Coastguard Worker // Simulate the setLocalDescription call as if the user used SDP munging
1267*d9f75844SAndroid Build Coastguard Worker // to disable simulcast.
1268*d9f75844SAndroid Build Coastguard Worker std::vector<uint32_t> ssrcs;
1269*d9f75844SAndroid Build Coastguard Worker ssrcs.reserve(2);
1270*d9f75844SAndroid Build Coastguard Worker for (int i = 0; i < 2; ++i)
1271*d9f75844SAndroid Build Coastguard Worker ssrcs.push_back(kVideoSsrcSimulcast + i);
1272*d9f75844SAndroid Build Coastguard Worker cricket::StreamParams stream_params =
1273*d9f75844SAndroid Build Coastguard Worker cricket::StreamParams::CreateLegacy(kVideoSsrc);
1274*d9f75844SAndroid Build Coastguard Worker video_media_channel()->AddSendStream(stream_params);
1275*d9f75844SAndroid Build Coastguard Worker video_rtp_sender_->SetMediaChannel(video_media_channel());
1276*d9f75844SAndroid Build Coastguard Worker EXPECT_DEATH(video_rtp_sender_->SetSsrc(kVideoSsrcSimulcast), "");
1277*d9f75844SAndroid Build Coastguard Worker }
1278*d9f75844SAndroid Build Coastguard Worker #endif
1279*d9f75844SAndroid Build Coastguard Worker
TEST_F(RtpSenderReceiverTest,VideoSenderMustCallGetParametersBeforeSetParametersBeforeNegotiation)1280*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest,
1281*d9f75844SAndroid Build Coastguard Worker VideoSenderMustCallGetParametersBeforeSetParametersBeforeNegotiation) {
1282*d9f75844SAndroid Build Coastguard Worker video_rtp_sender_ =
1283*d9f75844SAndroid Build Coastguard Worker VideoRtpSender::Create(worker_thread_, /*id=*/"", nullptr);
1284*d9f75844SAndroid Build Coastguard Worker
1285*d9f75844SAndroid Build Coastguard Worker RtpParameters params;
1286*d9f75844SAndroid Build Coastguard Worker RTCError result = video_rtp_sender_->SetParameters(params);
1287*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(RTCErrorType::INVALID_STATE, result.type());
1288*d9f75844SAndroid Build Coastguard Worker DestroyVideoRtpSender();
1289*d9f75844SAndroid Build Coastguard Worker }
1290*d9f75844SAndroid Build Coastguard Worker
TEST_F(RtpSenderReceiverTest,VideoSenderMustCallGetParametersBeforeSetParameters)1291*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest,
1292*d9f75844SAndroid Build Coastguard Worker VideoSenderMustCallGetParametersBeforeSetParameters) {
1293*d9f75844SAndroid Build Coastguard Worker CreateVideoRtpSender();
1294*d9f75844SAndroid Build Coastguard Worker
1295*d9f75844SAndroid Build Coastguard Worker RtpParameters params;
1296*d9f75844SAndroid Build Coastguard Worker RTCError result = video_rtp_sender_->SetParameters(params);
1297*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(RTCErrorType::INVALID_STATE, result.type());
1298*d9f75844SAndroid Build Coastguard Worker
1299*d9f75844SAndroid Build Coastguard Worker DestroyVideoRtpSender();
1300*d9f75844SAndroid Build Coastguard Worker }
1301*d9f75844SAndroid Build Coastguard Worker
TEST_F(RtpSenderReceiverTest,VideoSenderSetParametersInvalidatesTransactionId)1302*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest,
1303*d9f75844SAndroid Build Coastguard Worker VideoSenderSetParametersInvalidatesTransactionId) {
1304*d9f75844SAndroid Build Coastguard Worker CreateVideoRtpSender();
1305*d9f75844SAndroid Build Coastguard Worker
1306*d9f75844SAndroid Build Coastguard Worker RtpParameters params = video_rtp_sender_->GetParameters();
1307*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1u, params.encodings.size());
1308*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(video_rtp_sender_->SetParameters(params).ok());
1309*d9f75844SAndroid Build Coastguard Worker RTCError result = video_rtp_sender_->SetParameters(params);
1310*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(RTCErrorType::INVALID_STATE, result.type());
1311*d9f75844SAndroid Build Coastguard Worker
1312*d9f75844SAndroid Build Coastguard Worker DestroyVideoRtpSender();
1313*d9f75844SAndroid Build Coastguard Worker }
1314*d9f75844SAndroid Build Coastguard Worker
TEST_F(RtpSenderReceiverTest,VideoSenderSetParametersAsyncInvalidatesTransactionId)1315*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest,
1316*d9f75844SAndroid Build Coastguard Worker VideoSenderSetParametersAsyncInvalidatesTransactionId) {
1317*d9f75844SAndroid Build Coastguard Worker CreateVideoRtpSender();
1318*d9f75844SAndroid Build Coastguard Worker
1319*d9f75844SAndroid Build Coastguard Worker RtpParameters params = video_rtp_sender_->GetParameters();
1320*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1u, params.encodings.size());
1321*d9f75844SAndroid Build Coastguard Worker absl::optional<webrtc::RTCError> result;
1322*d9f75844SAndroid Build Coastguard Worker video_rtp_sender_->SetParametersAsync(
1323*d9f75844SAndroid Build Coastguard Worker params, [&result](webrtc::RTCError error) { result = error; });
1324*d9f75844SAndroid Build Coastguard Worker run_loop_.Flush();
1325*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(result->ok());
1326*d9f75844SAndroid Build Coastguard Worker video_rtp_sender_->SetParametersAsync(
1327*d9f75844SAndroid Build Coastguard Worker params, [&result](webrtc::RTCError error) { result = error; });
1328*d9f75844SAndroid Build Coastguard Worker run_loop_.Flush();
1329*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(RTCErrorType::INVALID_STATE, result->type());
1330*d9f75844SAndroid Build Coastguard Worker
1331*d9f75844SAndroid Build Coastguard Worker DestroyVideoRtpSender();
1332*d9f75844SAndroid Build Coastguard Worker }
1333*d9f75844SAndroid Build Coastguard Worker
TEST_F(RtpSenderReceiverTest,VideoSenderDetectTransactionIdModification)1334*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, VideoSenderDetectTransactionIdModification) {
1335*d9f75844SAndroid Build Coastguard Worker CreateVideoRtpSender();
1336*d9f75844SAndroid Build Coastguard Worker
1337*d9f75844SAndroid Build Coastguard Worker RtpParameters params = video_rtp_sender_->GetParameters();
1338*d9f75844SAndroid Build Coastguard Worker params.transaction_id = "";
1339*d9f75844SAndroid Build Coastguard Worker RTCError result = video_rtp_sender_->SetParameters(params);
1340*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(RTCErrorType::INVALID_MODIFICATION, result.type());
1341*d9f75844SAndroid Build Coastguard Worker
1342*d9f75844SAndroid Build Coastguard Worker DestroyVideoRtpSender();
1343*d9f75844SAndroid Build Coastguard Worker }
1344*d9f75844SAndroid Build Coastguard Worker
TEST_F(RtpSenderReceiverTest,VideoSenderCheckTransactionIdRefresh)1345*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, VideoSenderCheckTransactionIdRefresh) {
1346*d9f75844SAndroid Build Coastguard Worker CreateVideoRtpSender();
1347*d9f75844SAndroid Build Coastguard Worker
1348*d9f75844SAndroid Build Coastguard Worker RtpParameters params = video_rtp_sender_->GetParameters();
1349*d9f75844SAndroid Build Coastguard Worker EXPECT_NE(params.transaction_id.size(), 0U);
1350*d9f75844SAndroid Build Coastguard Worker auto saved_transaction_id = params.transaction_id;
1351*d9f75844SAndroid Build Coastguard Worker params = video_rtp_sender_->GetParameters();
1352*d9f75844SAndroid Build Coastguard Worker EXPECT_NE(saved_transaction_id, params.transaction_id);
1353*d9f75844SAndroid Build Coastguard Worker
1354*d9f75844SAndroid Build Coastguard Worker DestroyVideoRtpSender();
1355*d9f75844SAndroid Build Coastguard Worker }
1356*d9f75844SAndroid Build Coastguard Worker
TEST_F(RtpSenderReceiverTest,VideoSenderSetParametersOldValueFail)1357*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, VideoSenderSetParametersOldValueFail) {
1358*d9f75844SAndroid Build Coastguard Worker CreateVideoRtpSender();
1359*d9f75844SAndroid Build Coastguard Worker
1360*d9f75844SAndroid Build Coastguard Worker RtpParameters params = video_rtp_sender_->GetParameters();
1361*d9f75844SAndroid Build Coastguard Worker RtpParameters second_params = video_rtp_sender_->GetParameters();
1362*d9f75844SAndroid Build Coastguard Worker
1363*d9f75844SAndroid Build Coastguard Worker RTCError result = video_rtp_sender_->SetParameters(params);
1364*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(RTCErrorType::INVALID_MODIFICATION, result.type());
1365*d9f75844SAndroid Build Coastguard Worker
1366*d9f75844SAndroid Build Coastguard Worker DestroyVideoRtpSender();
1367*d9f75844SAndroid Build Coastguard Worker }
1368*d9f75844SAndroid Build Coastguard Worker
TEST_F(RtpSenderReceiverTest,VideoSenderCantSetUnimplementedRtpParameters)1369*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, VideoSenderCantSetUnimplementedRtpParameters) {
1370*d9f75844SAndroid Build Coastguard Worker CreateVideoRtpSender();
1371*d9f75844SAndroid Build Coastguard Worker RtpParameters params = video_rtp_sender_->GetParameters();
1372*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1u, params.encodings.size());
1373*d9f75844SAndroid Build Coastguard Worker
1374*d9f75844SAndroid Build Coastguard Worker // Unimplemented RtpParameters: mid
1375*d9f75844SAndroid Build Coastguard Worker params.mid = "dummy_mid";
1376*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(RTCErrorType::UNSUPPORTED_PARAMETER,
1377*d9f75844SAndroid Build Coastguard Worker video_rtp_sender_->SetParameters(params).type());
1378*d9f75844SAndroid Build Coastguard Worker params = video_rtp_sender_->GetParameters();
1379*d9f75844SAndroid Build Coastguard Worker
1380*d9f75844SAndroid Build Coastguard Worker DestroyVideoRtpSender();
1381*d9f75844SAndroid Build Coastguard Worker }
1382*d9f75844SAndroid Build Coastguard Worker
TEST_F(RtpSenderReceiverTest,VideoSenderCanSetScaleResolutionDownBy)1383*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, VideoSenderCanSetScaleResolutionDownBy) {
1384*d9f75844SAndroid Build Coastguard Worker CreateVideoRtpSender();
1385*d9f75844SAndroid Build Coastguard Worker
1386*d9f75844SAndroid Build Coastguard Worker RtpParameters params = video_rtp_sender_->GetParameters();
1387*d9f75844SAndroid Build Coastguard Worker params.encodings[0].scale_resolution_down_by = 2;
1388*d9f75844SAndroid Build Coastguard Worker
1389*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(video_rtp_sender_->SetParameters(params).ok());
1390*d9f75844SAndroid Build Coastguard Worker params = video_rtp_sender_->GetParameters();
1391*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(2, params.encodings[0].scale_resolution_down_by);
1392*d9f75844SAndroid Build Coastguard Worker
1393*d9f75844SAndroid Build Coastguard Worker DestroyVideoRtpSender();
1394*d9f75844SAndroid Build Coastguard Worker }
1395*d9f75844SAndroid Build Coastguard Worker
TEST_F(RtpSenderReceiverTest,VideoSenderDetectInvalidScaleResolutionDownBy)1396*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, VideoSenderDetectInvalidScaleResolutionDownBy) {
1397*d9f75844SAndroid Build Coastguard Worker CreateVideoRtpSender();
1398*d9f75844SAndroid Build Coastguard Worker
1399*d9f75844SAndroid Build Coastguard Worker RtpParameters params = video_rtp_sender_->GetParameters();
1400*d9f75844SAndroid Build Coastguard Worker params.encodings[0].scale_resolution_down_by = 0.5;
1401*d9f75844SAndroid Build Coastguard Worker RTCError result = video_rtp_sender_->SetParameters(params);
1402*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(RTCErrorType::INVALID_RANGE, result.type());
1403*d9f75844SAndroid Build Coastguard Worker
1404*d9f75844SAndroid Build Coastguard Worker DestroyVideoRtpSender();
1405*d9f75844SAndroid Build Coastguard Worker }
1406*d9f75844SAndroid Build Coastguard Worker
TEST_F(RtpSenderReceiverTest,VideoSenderCanSetNumTemporalLayers)1407*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, VideoSenderCanSetNumTemporalLayers) {
1408*d9f75844SAndroid Build Coastguard Worker CreateVideoRtpSender();
1409*d9f75844SAndroid Build Coastguard Worker
1410*d9f75844SAndroid Build Coastguard Worker RtpParameters params = video_rtp_sender_->GetParameters();
1411*d9f75844SAndroid Build Coastguard Worker params.encodings[0].num_temporal_layers = 2;
1412*d9f75844SAndroid Build Coastguard Worker
1413*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(video_rtp_sender_->SetParameters(params).ok());
1414*d9f75844SAndroid Build Coastguard Worker params = video_rtp_sender_->GetParameters();
1415*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(2, params.encodings[0].num_temporal_layers);
1416*d9f75844SAndroid Build Coastguard Worker
1417*d9f75844SAndroid Build Coastguard Worker DestroyVideoRtpSender();
1418*d9f75844SAndroid Build Coastguard Worker }
1419*d9f75844SAndroid Build Coastguard Worker
TEST_F(RtpSenderReceiverTest,VideoSenderDetectInvalidNumTemporalLayers)1420*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, VideoSenderDetectInvalidNumTemporalLayers) {
1421*d9f75844SAndroid Build Coastguard Worker CreateVideoRtpSender();
1422*d9f75844SAndroid Build Coastguard Worker
1423*d9f75844SAndroid Build Coastguard Worker RtpParameters params = video_rtp_sender_->GetParameters();
1424*d9f75844SAndroid Build Coastguard Worker params.encodings[0].num_temporal_layers = webrtc::kMaxTemporalStreams + 1;
1425*d9f75844SAndroid Build Coastguard Worker RTCError result = video_rtp_sender_->SetParameters(params);
1426*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(RTCErrorType::INVALID_RANGE, result.type());
1427*d9f75844SAndroid Build Coastguard Worker
1428*d9f75844SAndroid Build Coastguard Worker DestroyVideoRtpSender();
1429*d9f75844SAndroid Build Coastguard Worker }
1430*d9f75844SAndroid Build Coastguard Worker
TEST_F(RtpSenderReceiverTest,VideoSenderCanSetMaxFramerate)1431*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, VideoSenderCanSetMaxFramerate) {
1432*d9f75844SAndroid Build Coastguard Worker CreateVideoRtpSender();
1433*d9f75844SAndroid Build Coastguard Worker
1434*d9f75844SAndroid Build Coastguard Worker RtpParameters params = video_rtp_sender_->GetParameters();
1435*d9f75844SAndroid Build Coastguard Worker params.encodings[0].max_framerate = 20;
1436*d9f75844SAndroid Build Coastguard Worker
1437*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(video_rtp_sender_->SetParameters(params).ok());
1438*d9f75844SAndroid Build Coastguard Worker params = video_rtp_sender_->GetParameters();
1439*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(20., params.encodings[0].max_framerate);
1440*d9f75844SAndroid Build Coastguard Worker
1441*d9f75844SAndroid Build Coastguard Worker DestroyVideoRtpSender();
1442*d9f75844SAndroid Build Coastguard Worker }
1443*d9f75844SAndroid Build Coastguard Worker
TEST_F(RtpSenderReceiverTest,VideoSenderCanSetMaxFramerateZero)1444*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, VideoSenderCanSetMaxFramerateZero) {
1445*d9f75844SAndroid Build Coastguard Worker CreateVideoRtpSender();
1446*d9f75844SAndroid Build Coastguard Worker
1447*d9f75844SAndroid Build Coastguard Worker RtpParameters params = video_rtp_sender_->GetParameters();
1448*d9f75844SAndroid Build Coastguard Worker params.encodings[0].max_framerate = 0.;
1449*d9f75844SAndroid Build Coastguard Worker
1450*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(video_rtp_sender_->SetParameters(params).ok());
1451*d9f75844SAndroid Build Coastguard Worker params = video_rtp_sender_->GetParameters();
1452*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0., params.encodings[0].max_framerate);
1453*d9f75844SAndroid Build Coastguard Worker
1454*d9f75844SAndroid Build Coastguard Worker DestroyVideoRtpSender();
1455*d9f75844SAndroid Build Coastguard Worker }
1456*d9f75844SAndroid Build Coastguard Worker
TEST_F(RtpSenderReceiverTest,VideoSenderDetectInvalidMaxFramerate)1457*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, VideoSenderDetectInvalidMaxFramerate) {
1458*d9f75844SAndroid Build Coastguard Worker CreateVideoRtpSender();
1459*d9f75844SAndroid Build Coastguard Worker
1460*d9f75844SAndroid Build Coastguard Worker RtpParameters params = video_rtp_sender_->GetParameters();
1461*d9f75844SAndroid Build Coastguard Worker params.encodings[0].max_framerate = -5.;
1462*d9f75844SAndroid Build Coastguard Worker RTCError result = video_rtp_sender_->SetParameters(params);
1463*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(RTCErrorType::INVALID_RANGE, result.type());
1464*d9f75844SAndroid Build Coastguard Worker
1465*d9f75844SAndroid Build Coastguard Worker DestroyVideoRtpSender();
1466*d9f75844SAndroid Build Coastguard Worker }
1467*d9f75844SAndroid Build Coastguard Worker
1468*d9f75844SAndroid Build Coastguard Worker // A video sender can have multiple simulcast layers, in which case it will
1469*d9f75844SAndroid Build Coastguard Worker // contain multiple RtpEncodingParameters. This tests that if this is the case
1470*d9f75844SAndroid Build Coastguard Worker // (simulcast), then we can't set the bitrate_priority, or max_bitrate_bps
1471*d9f75844SAndroid Build Coastguard Worker // for any encodings besides at index 0, because these are both implemented
1472*d9f75844SAndroid Build Coastguard Worker // "per-sender."
TEST_F(RtpSenderReceiverTest,VideoSenderCantSetPerSenderEncodingParameters)1473*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, VideoSenderCantSetPerSenderEncodingParameters) {
1474*d9f75844SAndroid Build Coastguard Worker // Add a simulcast specific send stream that contains 2 encoding parameters.
1475*d9f75844SAndroid Build Coastguard Worker CreateVideoRtpSenderWithSimulcast();
1476*d9f75844SAndroid Build Coastguard Worker RtpParameters params = video_rtp_sender_->GetParameters();
1477*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(kVideoSimulcastLayerCount, params.encodings.size());
1478*d9f75844SAndroid Build Coastguard Worker
1479*d9f75844SAndroid Build Coastguard Worker params.encodings[1].bitrate_priority = 2.0;
1480*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(RTCErrorType::UNSUPPORTED_PARAMETER,
1481*d9f75844SAndroid Build Coastguard Worker video_rtp_sender_->SetParameters(params).type());
1482*d9f75844SAndroid Build Coastguard Worker params = video_rtp_sender_->GetParameters();
1483*d9f75844SAndroid Build Coastguard Worker
1484*d9f75844SAndroid Build Coastguard Worker DestroyVideoRtpSender();
1485*d9f75844SAndroid Build Coastguard Worker }
1486*d9f75844SAndroid Build Coastguard Worker
TEST_F(RtpSenderReceiverTest,VideoSenderCantSetReadOnlyEncodingParameters)1487*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, VideoSenderCantSetReadOnlyEncodingParameters) {
1488*d9f75844SAndroid Build Coastguard Worker // Add a simulcast specific send stream that contains 2 encoding parameters.
1489*d9f75844SAndroid Build Coastguard Worker CreateVideoRtpSenderWithSimulcast();
1490*d9f75844SAndroid Build Coastguard Worker RtpParameters params = video_rtp_sender_->GetParameters();
1491*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(kVideoSimulcastLayerCount, params.encodings.size());
1492*d9f75844SAndroid Build Coastguard Worker
1493*d9f75844SAndroid Build Coastguard Worker for (size_t i = 0; i < params.encodings.size(); i++) {
1494*d9f75844SAndroid Build Coastguard Worker params.encodings[i].ssrc = 1337;
1495*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(RTCErrorType::INVALID_MODIFICATION,
1496*d9f75844SAndroid Build Coastguard Worker video_rtp_sender_->SetParameters(params).type());
1497*d9f75844SAndroid Build Coastguard Worker params = video_rtp_sender_->GetParameters();
1498*d9f75844SAndroid Build Coastguard Worker }
1499*d9f75844SAndroid Build Coastguard Worker
1500*d9f75844SAndroid Build Coastguard Worker DestroyVideoRtpSender();
1501*d9f75844SAndroid Build Coastguard Worker }
1502*d9f75844SAndroid Build Coastguard Worker
TEST_F(RtpSenderReceiverTest,SetVideoMinMaxSendBitrate)1503*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, SetVideoMinMaxSendBitrate) {
1504*d9f75844SAndroid Build Coastguard Worker CreateVideoRtpSender();
1505*d9f75844SAndroid Build Coastguard Worker
1506*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(-1, video_media_channel()->max_bps());
1507*d9f75844SAndroid Build Coastguard Worker webrtc::RtpParameters params = video_rtp_sender_->GetParameters();
1508*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1U, params.encodings.size());
1509*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(params.encodings[0].min_bitrate_bps);
1510*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(params.encodings[0].max_bitrate_bps);
1511*d9f75844SAndroid Build Coastguard Worker params.encodings[0].min_bitrate_bps = 100;
1512*d9f75844SAndroid Build Coastguard Worker params.encodings[0].max_bitrate_bps = 1000;
1513*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(video_rtp_sender_->SetParameters(params).ok());
1514*d9f75844SAndroid Build Coastguard Worker
1515*d9f75844SAndroid Build Coastguard Worker // Read back the parameters and verify they have been changed.
1516*d9f75844SAndroid Build Coastguard Worker params = video_rtp_sender_->GetParameters();
1517*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1U, params.encodings.size());
1518*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(100, params.encodings[0].min_bitrate_bps);
1519*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1000, params.encodings[0].max_bitrate_bps);
1520*d9f75844SAndroid Build Coastguard Worker
1521*d9f75844SAndroid Build Coastguard Worker // Verify that the video channel received the new parameters.
1522*d9f75844SAndroid Build Coastguard Worker params = video_media_channel()->GetRtpSendParameters(kVideoSsrc);
1523*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1U, params.encodings.size());
1524*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(100, params.encodings[0].min_bitrate_bps);
1525*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1000, params.encodings[0].max_bitrate_bps);
1526*d9f75844SAndroid Build Coastguard Worker
1527*d9f75844SAndroid Build Coastguard Worker // Verify that the global bitrate limit has not been changed.
1528*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(-1, video_media_channel()->max_bps());
1529*d9f75844SAndroid Build Coastguard Worker
1530*d9f75844SAndroid Build Coastguard Worker DestroyVideoRtpSender();
1531*d9f75844SAndroid Build Coastguard Worker }
1532*d9f75844SAndroid Build Coastguard Worker
TEST_F(RtpSenderReceiverTest,SetVideoMinMaxSendBitrateSimulcast)1533*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, SetVideoMinMaxSendBitrateSimulcast) {
1534*d9f75844SAndroid Build Coastguard Worker // Add a simulcast specific send stream that contains 2 encoding parameters.
1535*d9f75844SAndroid Build Coastguard Worker CreateVideoRtpSenderWithSimulcast();
1536*d9f75844SAndroid Build Coastguard Worker
1537*d9f75844SAndroid Build Coastguard Worker RtpParameters params = video_rtp_sender_->GetParameters();
1538*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(kVideoSimulcastLayerCount, params.encodings.size());
1539*d9f75844SAndroid Build Coastguard Worker params.encodings[0].min_bitrate_bps = 100;
1540*d9f75844SAndroid Build Coastguard Worker params.encodings[0].max_bitrate_bps = 1000;
1541*d9f75844SAndroid Build Coastguard Worker params.encodings[1].min_bitrate_bps = 200;
1542*d9f75844SAndroid Build Coastguard Worker params.encodings[1].max_bitrate_bps = 2000;
1543*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(video_rtp_sender_->SetParameters(params).ok());
1544*d9f75844SAndroid Build Coastguard Worker
1545*d9f75844SAndroid Build Coastguard Worker // Verify that the video channel received the new parameters.
1546*d9f75844SAndroid Build Coastguard Worker params = video_media_channel()->GetRtpSendParameters(kVideoSsrcSimulcast);
1547*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(kVideoSimulcastLayerCount, params.encodings.size());
1548*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(100, params.encodings[0].min_bitrate_bps);
1549*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1000, params.encodings[0].max_bitrate_bps);
1550*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(200, params.encodings[1].min_bitrate_bps);
1551*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(2000, params.encodings[1].max_bitrate_bps);
1552*d9f75844SAndroid Build Coastguard Worker
1553*d9f75844SAndroid Build Coastguard Worker DestroyVideoRtpSender();
1554*d9f75844SAndroid Build Coastguard Worker }
1555*d9f75844SAndroid Build Coastguard Worker
TEST_F(RtpSenderReceiverTest,SetVideoBitratePriority)1556*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, SetVideoBitratePriority) {
1557*d9f75844SAndroid Build Coastguard Worker CreateVideoRtpSender();
1558*d9f75844SAndroid Build Coastguard Worker
1559*d9f75844SAndroid Build Coastguard Worker webrtc::RtpParameters params = video_rtp_sender_->GetParameters();
1560*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1U, params.encodings.size());
1561*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(webrtc::kDefaultBitratePriority,
1562*d9f75844SAndroid Build Coastguard Worker params.encodings[0].bitrate_priority);
1563*d9f75844SAndroid Build Coastguard Worker double new_bitrate_priority = 2.0;
1564*d9f75844SAndroid Build Coastguard Worker params.encodings[0].bitrate_priority = new_bitrate_priority;
1565*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(video_rtp_sender_->SetParameters(params).ok());
1566*d9f75844SAndroid Build Coastguard Worker
1567*d9f75844SAndroid Build Coastguard Worker params = video_rtp_sender_->GetParameters();
1568*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1U, params.encodings.size());
1569*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(new_bitrate_priority, params.encodings[0].bitrate_priority);
1570*d9f75844SAndroid Build Coastguard Worker
1571*d9f75844SAndroid Build Coastguard Worker params = video_media_channel()->GetRtpSendParameters(kVideoSsrc);
1572*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(1U, params.encodings.size());
1573*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(new_bitrate_priority, params.encodings[0].bitrate_priority);
1574*d9f75844SAndroid Build Coastguard Worker
1575*d9f75844SAndroid Build Coastguard Worker DestroyVideoRtpSender();
1576*d9f75844SAndroid Build Coastguard Worker }
1577*d9f75844SAndroid Build Coastguard Worker
TEST_F(RtpSenderReceiverTest,VideoReceiverCanGetParametersWithSimulcast)1578*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, VideoReceiverCanGetParametersWithSimulcast) {
1579*d9f75844SAndroid Build Coastguard Worker CreateVideoRtpReceiverWithSimulcast({}, 2);
1580*d9f75844SAndroid Build Coastguard Worker
1581*d9f75844SAndroid Build Coastguard Worker RtpParameters params = video_rtp_receiver_->GetParameters();
1582*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(2u, params.encodings.size());
1583*d9f75844SAndroid Build Coastguard Worker
1584*d9f75844SAndroid Build Coastguard Worker DestroyVideoRtpReceiver();
1585*d9f75844SAndroid Build Coastguard Worker }
1586*d9f75844SAndroid Build Coastguard Worker
TEST_F(RtpSenderReceiverTest,GenerateKeyFrameWithAudio)1587*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, GenerateKeyFrameWithAudio) {
1588*d9f75844SAndroid Build Coastguard Worker CreateAudioRtpSender();
1589*d9f75844SAndroid Build Coastguard Worker
1590*d9f75844SAndroid Build Coastguard Worker auto error = audio_rtp_sender_->GenerateKeyFrame({});
1591*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(error.ok());
1592*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(error.type(), RTCErrorType::UNSUPPORTED_OPERATION);
1593*d9f75844SAndroid Build Coastguard Worker
1594*d9f75844SAndroid Build Coastguard Worker DestroyAudioRtpSender();
1595*d9f75844SAndroid Build Coastguard Worker }
1596*d9f75844SAndroid Build Coastguard Worker
TEST_F(RtpSenderReceiverTest,GenerateKeyFrameWithVideo)1597*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, GenerateKeyFrameWithVideo) {
1598*d9f75844SAndroid Build Coastguard Worker CreateVideoRtpSenderWithSimulcast({"1", "2", "3"});
1599*d9f75844SAndroid Build Coastguard Worker
1600*d9f75844SAndroid Build Coastguard Worker auto error = video_rtp_sender_->GenerateKeyFrame({});
1601*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(error.ok());
1602*d9f75844SAndroid Build Coastguard Worker
1603*d9f75844SAndroid Build Coastguard Worker error = video_rtp_sender_->GenerateKeyFrame({"1"});
1604*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(error.ok());
1605*d9f75844SAndroid Build Coastguard Worker
1606*d9f75844SAndroid Build Coastguard Worker error = video_rtp_sender_->GenerateKeyFrame({""});
1607*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(error.ok());
1608*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(error.type(), RTCErrorType::INVALID_PARAMETER);
1609*d9f75844SAndroid Build Coastguard Worker
1610*d9f75844SAndroid Build Coastguard Worker error = video_rtp_sender_->GenerateKeyFrame({"no-such-rid"});
1611*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(error.ok());
1612*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(error.type(), RTCErrorType::INVALID_PARAMETER);
1613*d9f75844SAndroid Build Coastguard Worker
1614*d9f75844SAndroid Build Coastguard Worker DestroyVideoRtpSender();
1615*d9f75844SAndroid Build Coastguard Worker }
1616*d9f75844SAndroid Build Coastguard Worker
1617*d9f75844SAndroid Build Coastguard Worker // Test that makes sure that a video track content hint translates to the proper
1618*d9f75844SAndroid Build Coastguard Worker // value for sources that are not screencast.
TEST_F(RtpSenderReceiverTest,PropagatesVideoTrackContentHint)1619*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, PropagatesVideoTrackContentHint) {
1620*d9f75844SAndroid Build Coastguard Worker CreateVideoRtpSender();
1621*d9f75844SAndroid Build Coastguard Worker
1622*d9f75844SAndroid Build Coastguard Worker video_track_->set_enabled(true);
1623*d9f75844SAndroid Build Coastguard Worker
1624*d9f75844SAndroid Build Coastguard Worker // `video_track_` is not screencast by default.
1625*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(false, video_media_channel()->options().is_screencast);
1626*d9f75844SAndroid Build Coastguard Worker // No content hint should be set by default.
1627*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(VideoTrackInterface::ContentHint::kNone,
1628*d9f75844SAndroid Build Coastguard Worker video_track_->content_hint());
1629*d9f75844SAndroid Build Coastguard Worker // Setting detailed should turn a non-screencast source into screencast mode.
1630*d9f75844SAndroid Build Coastguard Worker video_track_->set_content_hint(VideoTrackInterface::ContentHint::kDetailed);
1631*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(true, video_media_channel()->options().is_screencast);
1632*d9f75844SAndroid Build Coastguard Worker // Removing the content hint should turn the track back into non-screencast
1633*d9f75844SAndroid Build Coastguard Worker // mode.
1634*d9f75844SAndroid Build Coastguard Worker video_track_->set_content_hint(VideoTrackInterface::ContentHint::kNone);
1635*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(false, video_media_channel()->options().is_screencast);
1636*d9f75844SAndroid Build Coastguard Worker // Setting fluid should remain in non-screencast mode (its default).
1637*d9f75844SAndroid Build Coastguard Worker video_track_->set_content_hint(VideoTrackInterface::ContentHint::kFluid);
1638*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(false, video_media_channel()->options().is_screencast);
1639*d9f75844SAndroid Build Coastguard Worker // Setting text should have the same effect as Detailed
1640*d9f75844SAndroid Build Coastguard Worker video_track_->set_content_hint(VideoTrackInterface::ContentHint::kText);
1641*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(true, video_media_channel()->options().is_screencast);
1642*d9f75844SAndroid Build Coastguard Worker
1643*d9f75844SAndroid Build Coastguard Worker DestroyVideoRtpSender();
1644*d9f75844SAndroid Build Coastguard Worker }
1645*d9f75844SAndroid Build Coastguard Worker
1646*d9f75844SAndroid Build Coastguard Worker // Test that makes sure that a video track content hint translates to the proper
1647*d9f75844SAndroid Build Coastguard Worker // value for screencast sources.
TEST_F(RtpSenderReceiverTest,PropagatesVideoTrackContentHintForScreencastSource)1648*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest,
1649*d9f75844SAndroid Build Coastguard Worker PropagatesVideoTrackContentHintForScreencastSource) {
1650*d9f75844SAndroid Build Coastguard Worker CreateVideoRtpSender(true);
1651*d9f75844SAndroid Build Coastguard Worker
1652*d9f75844SAndroid Build Coastguard Worker video_track_->set_enabled(true);
1653*d9f75844SAndroid Build Coastguard Worker
1654*d9f75844SAndroid Build Coastguard Worker // `video_track_` with a screencast source should be screencast by default.
1655*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(true, video_media_channel()->options().is_screencast);
1656*d9f75844SAndroid Build Coastguard Worker // No content hint should be set by default.
1657*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(VideoTrackInterface::ContentHint::kNone,
1658*d9f75844SAndroid Build Coastguard Worker video_track_->content_hint());
1659*d9f75844SAndroid Build Coastguard Worker // Setting fluid should turn a screencast source into non-screencast mode.
1660*d9f75844SAndroid Build Coastguard Worker video_track_->set_content_hint(VideoTrackInterface::ContentHint::kFluid);
1661*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(false, video_media_channel()->options().is_screencast);
1662*d9f75844SAndroid Build Coastguard Worker // Removing the content hint should turn the track back into screencast mode.
1663*d9f75844SAndroid Build Coastguard Worker video_track_->set_content_hint(VideoTrackInterface::ContentHint::kNone);
1664*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(true, video_media_channel()->options().is_screencast);
1665*d9f75844SAndroid Build Coastguard Worker // Setting detailed should still remain in screencast mode (its default).
1666*d9f75844SAndroid Build Coastguard Worker video_track_->set_content_hint(VideoTrackInterface::ContentHint::kDetailed);
1667*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(true, video_media_channel()->options().is_screencast);
1668*d9f75844SAndroid Build Coastguard Worker // Setting text should have the same effect as Detailed
1669*d9f75844SAndroid Build Coastguard Worker video_track_->set_content_hint(VideoTrackInterface::ContentHint::kText);
1670*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(true, video_media_channel()->options().is_screencast);
1671*d9f75844SAndroid Build Coastguard Worker
1672*d9f75844SAndroid Build Coastguard Worker DestroyVideoRtpSender();
1673*d9f75844SAndroid Build Coastguard Worker }
1674*d9f75844SAndroid Build Coastguard Worker
1675*d9f75844SAndroid Build Coastguard Worker // Test that makes sure any content hints that are set on a track before
1676*d9f75844SAndroid Build Coastguard Worker // VideoRtpSender is ready to send are still applied when it gets ready to send.
TEST_F(RtpSenderReceiverTest,PropagatesVideoTrackContentHintSetBeforeEnabling)1677*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest,
1678*d9f75844SAndroid Build Coastguard Worker PropagatesVideoTrackContentHintSetBeforeEnabling) {
1679*d9f75844SAndroid Build Coastguard Worker AddVideoTrack();
1680*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<MockSetStreamsObserver> set_streams_observer =
1681*d9f75844SAndroid Build Coastguard Worker std::make_unique<MockSetStreamsObserver>();
1682*d9f75844SAndroid Build Coastguard Worker // Setting detailed overrides the default non-screencast mode. This should be
1683*d9f75844SAndroid Build Coastguard Worker // applied even if the track is set on construction.
1684*d9f75844SAndroid Build Coastguard Worker video_track_->set_content_hint(VideoTrackInterface::ContentHint::kDetailed);
1685*d9f75844SAndroid Build Coastguard Worker video_rtp_sender_ = VideoRtpSender::Create(worker_thread_, video_track_->id(),
1686*d9f75844SAndroid Build Coastguard Worker set_streams_observer.get());
1687*d9f75844SAndroid Build Coastguard Worker ASSERT_TRUE(video_rtp_sender_->SetTrack(video_track_.get()));
1688*d9f75844SAndroid Build Coastguard Worker EXPECT_CALL(*set_streams_observer, OnSetStreams());
1689*d9f75844SAndroid Build Coastguard Worker video_rtp_sender_->SetStreams({local_stream_->id()});
1690*d9f75844SAndroid Build Coastguard Worker video_rtp_sender_->SetMediaChannel(video_media_channel());
1691*d9f75844SAndroid Build Coastguard Worker video_track_->set_enabled(true);
1692*d9f75844SAndroid Build Coastguard Worker
1693*d9f75844SAndroid Build Coastguard Worker // Sender is not ready to send (no SSRC) so no option should have been set.
1694*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(absl::nullopt, video_media_channel()->options().is_screencast);
1695*d9f75844SAndroid Build Coastguard Worker
1696*d9f75844SAndroid Build Coastguard Worker // Verify that the content hint is accounted for when video_rtp_sender_ does
1697*d9f75844SAndroid Build Coastguard Worker // get enabled.
1698*d9f75844SAndroid Build Coastguard Worker video_rtp_sender_->SetSsrc(kVideoSsrc);
1699*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(true, video_media_channel()->options().is_screencast);
1700*d9f75844SAndroid Build Coastguard Worker
1701*d9f75844SAndroid Build Coastguard Worker // And removing the hint should go back to false (to verify that false was
1702*d9f75844SAndroid Build Coastguard Worker // default correctly).
1703*d9f75844SAndroid Build Coastguard Worker video_track_->set_content_hint(VideoTrackInterface::ContentHint::kNone);
1704*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(false, video_media_channel()->options().is_screencast);
1705*d9f75844SAndroid Build Coastguard Worker
1706*d9f75844SAndroid Build Coastguard Worker DestroyVideoRtpSender();
1707*d9f75844SAndroid Build Coastguard Worker }
1708*d9f75844SAndroid Build Coastguard Worker
TEST_F(RtpSenderReceiverTest,AudioSenderHasDtmfSender)1709*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, AudioSenderHasDtmfSender) {
1710*d9f75844SAndroid Build Coastguard Worker CreateAudioRtpSender();
1711*d9f75844SAndroid Build Coastguard Worker EXPECT_NE(nullptr, audio_rtp_sender_->GetDtmfSender());
1712*d9f75844SAndroid Build Coastguard Worker }
1713*d9f75844SAndroid Build Coastguard Worker
TEST_F(RtpSenderReceiverTest,VideoSenderDoesNotHaveDtmfSender)1714*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, VideoSenderDoesNotHaveDtmfSender) {
1715*d9f75844SAndroid Build Coastguard Worker CreateVideoRtpSender();
1716*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(nullptr, video_rtp_sender_->GetDtmfSender());
1717*d9f75844SAndroid Build Coastguard Worker }
1718*d9f75844SAndroid Build Coastguard Worker
1719*d9f75844SAndroid Build Coastguard Worker // Test that the DTMF sender is really using `voice_channel_`, and thus returns
1720*d9f75844SAndroid Build Coastguard Worker // true/false from CanSendDtmf based on what `voice_channel_` returns.
TEST_F(RtpSenderReceiverTest,CanInsertDtmf)1721*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, CanInsertDtmf) {
1722*d9f75844SAndroid Build Coastguard Worker AddDtmfCodec();
1723*d9f75844SAndroid Build Coastguard Worker CreateAudioRtpSender();
1724*d9f75844SAndroid Build Coastguard Worker auto dtmf_sender = audio_rtp_sender_->GetDtmfSender();
1725*d9f75844SAndroid Build Coastguard Worker ASSERT_NE(nullptr, dtmf_sender);
1726*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(dtmf_sender->CanInsertDtmf());
1727*d9f75844SAndroid Build Coastguard Worker }
1728*d9f75844SAndroid Build Coastguard Worker
TEST_F(RtpSenderReceiverTest,CanNotInsertDtmf)1729*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, CanNotInsertDtmf) {
1730*d9f75844SAndroid Build Coastguard Worker CreateAudioRtpSender();
1731*d9f75844SAndroid Build Coastguard Worker auto dtmf_sender = audio_rtp_sender_->GetDtmfSender();
1732*d9f75844SAndroid Build Coastguard Worker ASSERT_NE(nullptr, dtmf_sender);
1733*d9f75844SAndroid Build Coastguard Worker // DTMF codec has not been added, as it was in the above test.
1734*d9f75844SAndroid Build Coastguard Worker EXPECT_FALSE(dtmf_sender->CanInsertDtmf());
1735*d9f75844SAndroid Build Coastguard Worker }
1736*d9f75844SAndroid Build Coastguard Worker
TEST_F(RtpSenderReceiverTest,InsertDtmf)1737*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, InsertDtmf) {
1738*d9f75844SAndroid Build Coastguard Worker AddDtmfCodec();
1739*d9f75844SAndroid Build Coastguard Worker CreateAudioRtpSender();
1740*d9f75844SAndroid Build Coastguard Worker auto dtmf_sender = audio_rtp_sender_->GetDtmfSender();
1741*d9f75844SAndroid Build Coastguard Worker ASSERT_NE(nullptr, dtmf_sender);
1742*d9f75844SAndroid Build Coastguard Worker
1743*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(0U, voice_media_channel()->dtmf_info_queue().size());
1744*d9f75844SAndroid Build Coastguard Worker
1745*d9f75844SAndroid Build Coastguard Worker // Insert DTMF
1746*d9f75844SAndroid Build Coastguard Worker const int expected_duration = 90;
1747*d9f75844SAndroid Build Coastguard Worker dtmf_sender->InsertDtmf("012", expected_duration, 100);
1748*d9f75844SAndroid Build Coastguard Worker
1749*d9f75844SAndroid Build Coastguard Worker // Verify
1750*d9f75844SAndroid Build Coastguard Worker ASSERT_EQ_WAIT(3U, voice_media_channel()->dtmf_info_queue().size(),
1751*d9f75844SAndroid Build Coastguard Worker kDefaultTimeout);
1752*d9f75844SAndroid Build Coastguard Worker const uint32_t send_ssrc =
1753*d9f75844SAndroid Build Coastguard Worker voice_media_channel()->send_streams()[0].first_ssrc();
1754*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(CompareDtmfInfo(voice_media_channel()->dtmf_info_queue()[0],
1755*d9f75844SAndroid Build Coastguard Worker send_ssrc, 0, expected_duration));
1756*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(CompareDtmfInfo(voice_media_channel()->dtmf_info_queue()[1],
1757*d9f75844SAndroid Build Coastguard Worker send_ssrc, 1, expected_duration));
1758*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(CompareDtmfInfo(voice_media_channel()->dtmf_info_queue()[2],
1759*d9f75844SAndroid Build Coastguard Worker send_ssrc, 2, expected_duration));
1760*d9f75844SAndroid Build Coastguard Worker }
1761*d9f75844SAndroid Build Coastguard Worker
1762*d9f75844SAndroid Build Coastguard Worker // Validate that the default FrameEncryptor setting is nullptr.
TEST_F(RtpSenderReceiverTest,AudioSenderCanSetFrameEncryptor)1763*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, AudioSenderCanSetFrameEncryptor) {
1764*d9f75844SAndroid Build Coastguard Worker CreateAudioRtpSender();
1765*d9f75844SAndroid Build Coastguard Worker rtc::scoped_refptr<FrameEncryptorInterface> fake_frame_encryptor(
1766*d9f75844SAndroid Build Coastguard Worker new FakeFrameEncryptor());
1767*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(nullptr, audio_rtp_sender_->GetFrameEncryptor());
1768*d9f75844SAndroid Build Coastguard Worker audio_rtp_sender_->SetFrameEncryptor(fake_frame_encryptor);
1769*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(fake_frame_encryptor.get(),
1770*d9f75844SAndroid Build Coastguard Worker audio_rtp_sender_->GetFrameEncryptor().get());
1771*d9f75844SAndroid Build Coastguard Worker }
1772*d9f75844SAndroid Build Coastguard Worker
1773*d9f75844SAndroid Build Coastguard Worker // Validate that setting a FrameEncryptor after the send stream is stopped does
1774*d9f75844SAndroid Build Coastguard Worker // nothing.
TEST_F(RtpSenderReceiverTest,AudioSenderCannotSetFrameEncryptorAfterStop)1775*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, AudioSenderCannotSetFrameEncryptorAfterStop) {
1776*d9f75844SAndroid Build Coastguard Worker CreateAudioRtpSender();
1777*d9f75844SAndroid Build Coastguard Worker rtc::scoped_refptr<FrameEncryptorInterface> fake_frame_encryptor(
1778*d9f75844SAndroid Build Coastguard Worker new FakeFrameEncryptor());
1779*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(nullptr, audio_rtp_sender_->GetFrameEncryptor());
1780*d9f75844SAndroid Build Coastguard Worker audio_rtp_sender_->Stop();
1781*d9f75844SAndroid Build Coastguard Worker audio_rtp_sender_->SetFrameEncryptor(fake_frame_encryptor);
1782*d9f75844SAndroid Build Coastguard Worker // TODO(webrtc:9926) - Validate media channel not set once fakes updated.
1783*d9f75844SAndroid Build Coastguard Worker }
1784*d9f75844SAndroid Build Coastguard Worker
1785*d9f75844SAndroid Build Coastguard Worker // Validate that the default FrameEncryptor setting is nullptr.
TEST_F(RtpSenderReceiverTest,AudioReceiverCanSetFrameDecryptor)1786*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, AudioReceiverCanSetFrameDecryptor) {
1787*d9f75844SAndroid Build Coastguard Worker CreateAudioRtpReceiver();
1788*d9f75844SAndroid Build Coastguard Worker rtc::scoped_refptr<FrameDecryptorInterface> fake_frame_decryptor(
1789*d9f75844SAndroid Build Coastguard Worker rtc::make_ref_counted<FakeFrameDecryptor>());
1790*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(nullptr, audio_rtp_receiver_->GetFrameDecryptor());
1791*d9f75844SAndroid Build Coastguard Worker audio_rtp_receiver_->SetFrameDecryptor(fake_frame_decryptor);
1792*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(fake_frame_decryptor.get(),
1793*d9f75844SAndroid Build Coastguard Worker audio_rtp_receiver_->GetFrameDecryptor().get());
1794*d9f75844SAndroid Build Coastguard Worker DestroyAudioRtpReceiver();
1795*d9f75844SAndroid Build Coastguard Worker }
1796*d9f75844SAndroid Build Coastguard Worker
1797*d9f75844SAndroid Build Coastguard Worker // Validate that the default FrameEncryptor setting is nullptr.
TEST_F(RtpSenderReceiverTest,AudioReceiverCannotSetFrameDecryptorAfterStop)1798*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, AudioReceiverCannotSetFrameDecryptorAfterStop) {
1799*d9f75844SAndroid Build Coastguard Worker CreateAudioRtpReceiver();
1800*d9f75844SAndroid Build Coastguard Worker rtc::scoped_refptr<FrameDecryptorInterface> fake_frame_decryptor(
1801*d9f75844SAndroid Build Coastguard Worker rtc::make_ref_counted<FakeFrameDecryptor>());
1802*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(nullptr, audio_rtp_receiver_->GetFrameDecryptor());
1803*d9f75844SAndroid Build Coastguard Worker audio_rtp_receiver_->SetMediaChannel(nullptr);
1804*d9f75844SAndroid Build Coastguard Worker audio_rtp_receiver_->SetFrameDecryptor(fake_frame_decryptor);
1805*d9f75844SAndroid Build Coastguard Worker // TODO(webrtc:9926) - Validate media channel not set once fakes updated.
1806*d9f75844SAndroid Build Coastguard Worker DestroyAudioRtpReceiver();
1807*d9f75844SAndroid Build Coastguard Worker }
1808*d9f75844SAndroid Build Coastguard Worker
1809*d9f75844SAndroid Build Coastguard Worker // Validate that the default FrameEncryptor setting is nullptr.
TEST_F(RtpSenderReceiverTest,VideoSenderCanSetFrameEncryptor)1810*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, VideoSenderCanSetFrameEncryptor) {
1811*d9f75844SAndroid Build Coastguard Worker CreateVideoRtpSender();
1812*d9f75844SAndroid Build Coastguard Worker rtc::scoped_refptr<FrameEncryptorInterface> fake_frame_encryptor(
1813*d9f75844SAndroid Build Coastguard Worker new FakeFrameEncryptor());
1814*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(nullptr, video_rtp_sender_->GetFrameEncryptor());
1815*d9f75844SAndroid Build Coastguard Worker video_rtp_sender_->SetFrameEncryptor(fake_frame_encryptor);
1816*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(fake_frame_encryptor.get(),
1817*d9f75844SAndroid Build Coastguard Worker video_rtp_sender_->GetFrameEncryptor().get());
1818*d9f75844SAndroid Build Coastguard Worker }
1819*d9f75844SAndroid Build Coastguard Worker
1820*d9f75844SAndroid Build Coastguard Worker // Validate that setting a FrameEncryptor after the send stream is stopped does
1821*d9f75844SAndroid Build Coastguard Worker // nothing.
TEST_F(RtpSenderReceiverTest,VideoSenderCannotSetFrameEncryptorAfterStop)1822*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, VideoSenderCannotSetFrameEncryptorAfterStop) {
1823*d9f75844SAndroid Build Coastguard Worker CreateVideoRtpSender();
1824*d9f75844SAndroid Build Coastguard Worker rtc::scoped_refptr<FrameEncryptorInterface> fake_frame_encryptor(
1825*d9f75844SAndroid Build Coastguard Worker new FakeFrameEncryptor());
1826*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(nullptr, video_rtp_sender_->GetFrameEncryptor());
1827*d9f75844SAndroid Build Coastguard Worker video_rtp_sender_->Stop();
1828*d9f75844SAndroid Build Coastguard Worker video_rtp_sender_->SetFrameEncryptor(fake_frame_encryptor);
1829*d9f75844SAndroid Build Coastguard Worker // TODO(webrtc:9926) - Validate media channel not set once fakes updated.
1830*d9f75844SAndroid Build Coastguard Worker }
1831*d9f75844SAndroid Build Coastguard Worker
1832*d9f75844SAndroid Build Coastguard Worker // Validate that the default FrameEncryptor setting is nullptr.
TEST_F(RtpSenderReceiverTest,VideoReceiverCanSetFrameDecryptor)1833*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, VideoReceiverCanSetFrameDecryptor) {
1834*d9f75844SAndroid Build Coastguard Worker CreateVideoRtpReceiver();
1835*d9f75844SAndroid Build Coastguard Worker rtc::scoped_refptr<FrameDecryptorInterface> fake_frame_decryptor(
1836*d9f75844SAndroid Build Coastguard Worker rtc::make_ref_counted<FakeFrameDecryptor>());
1837*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(nullptr, video_rtp_receiver_->GetFrameDecryptor());
1838*d9f75844SAndroid Build Coastguard Worker video_rtp_receiver_->SetFrameDecryptor(fake_frame_decryptor);
1839*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(fake_frame_decryptor.get(),
1840*d9f75844SAndroid Build Coastguard Worker video_rtp_receiver_->GetFrameDecryptor().get());
1841*d9f75844SAndroid Build Coastguard Worker DestroyVideoRtpReceiver();
1842*d9f75844SAndroid Build Coastguard Worker }
1843*d9f75844SAndroid Build Coastguard Worker
1844*d9f75844SAndroid Build Coastguard Worker // Validate that the default FrameEncryptor setting is nullptr.
TEST_F(RtpSenderReceiverTest,VideoReceiverCannotSetFrameDecryptorAfterStop)1845*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest, VideoReceiverCannotSetFrameDecryptorAfterStop) {
1846*d9f75844SAndroid Build Coastguard Worker CreateVideoRtpReceiver();
1847*d9f75844SAndroid Build Coastguard Worker rtc::scoped_refptr<FrameDecryptorInterface> fake_frame_decryptor(
1848*d9f75844SAndroid Build Coastguard Worker rtc::make_ref_counted<FakeFrameDecryptor>());
1849*d9f75844SAndroid Build Coastguard Worker EXPECT_EQ(nullptr, video_rtp_receiver_->GetFrameDecryptor());
1850*d9f75844SAndroid Build Coastguard Worker video_rtp_receiver_->SetMediaChannel(nullptr);
1851*d9f75844SAndroid Build Coastguard Worker video_rtp_receiver_->SetFrameDecryptor(fake_frame_decryptor);
1852*d9f75844SAndroid Build Coastguard Worker // TODO(webrtc:9926) - Validate media channel not set once fakes updated.
1853*d9f75844SAndroid Build Coastguard Worker DestroyVideoRtpReceiver();
1854*d9f75844SAndroid Build Coastguard Worker }
1855*d9f75844SAndroid Build Coastguard Worker
1856*d9f75844SAndroid Build Coastguard Worker // Checks that calling the internal methods for get/set parameters do not
1857*d9f75844SAndroid Build Coastguard Worker // invalidate any parameters retreived by clients.
TEST_F(RtpSenderReceiverTest,InternalParameterMethodsDoNotInvalidateTransaction)1858*d9f75844SAndroid Build Coastguard Worker TEST_F(RtpSenderReceiverTest,
1859*d9f75844SAndroid Build Coastguard Worker InternalParameterMethodsDoNotInvalidateTransaction) {
1860*d9f75844SAndroid Build Coastguard Worker CreateVideoRtpSender();
1861*d9f75844SAndroid Build Coastguard Worker RtpParameters parameters = video_rtp_sender_->GetParameters();
1862*d9f75844SAndroid Build Coastguard Worker RtpParameters new_parameters = video_rtp_sender_->GetParametersInternal();
1863*d9f75844SAndroid Build Coastguard Worker new_parameters.encodings[0].active = false;
1864*d9f75844SAndroid Build Coastguard Worker video_rtp_sender_->SetParametersInternal(new_parameters, nullptr, true);
1865*d9f75844SAndroid Build Coastguard Worker new_parameters.encodings[0].active = true;
1866*d9f75844SAndroid Build Coastguard Worker video_rtp_sender_->SetParametersInternal(new_parameters, nullptr, true);
1867*d9f75844SAndroid Build Coastguard Worker parameters.encodings[0].active = false;
1868*d9f75844SAndroid Build Coastguard Worker EXPECT_TRUE(video_rtp_sender_->SetParameters(parameters).ok());
1869*d9f75844SAndroid Build Coastguard Worker }
1870*d9f75844SAndroid Build Coastguard Worker
1871*d9f75844SAndroid Build Coastguard Worker // Helper method for syntactic sugar for accepting a vector with '{}' notation.
CreatePairOfRidVectors(const std::vector<std::string> & first,const std::vector<std::string> & second)1872*d9f75844SAndroid Build Coastguard Worker std::pair<RidList, RidList> CreatePairOfRidVectors(
1873*d9f75844SAndroid Build Coastguard Worker const std::vector<std::string>& first,
1874*d9f75844SAndroid Build Coastguard Worker const std::vector<std::string>& second) {
1875*d9f75844SAndroid Build Coastguard Worker return std::make_pair(first, second);
1876*d9f75844SAndroid Build Coastguard Worker }
1877*d9f75844SAndroid Build Coastguard Worker
1878*d9f75844SAndroid Build Coastguard Worker // These parameters are used to test disabling simulcast layers.
1879*d9f75844SAndroid Build Coastguard Worker const std::pair<RidList, RidList> kDisableSimulcastLayersParameters[] = {
1880*d9f75844SAndroid Build Coastguard Worker // Tests removing the first layer. This is a special case because
1881*d9f75844SAndroid Build Coastguard Worker // the first layer's SSRC is also the 'primary' SSRC used to associate the
1882*d9f75844SAndroid Build Coastguard Worker // parameters to the media channel.
1883*d9f75844SAndroid Build Coastguard Worker CreatePairOfRidVectors({"1", "2", "3", "4"}, {"1"}),
1884*d9f75844SAndroid Build Coastguard Worker // Tests removing some layers.
1885*d9f75844SAndroid Build Coastguard Worker CreatePairOfRidVectors({"1", "2", "3", "4"}, {"2", "4"}),
1886*d9f75844SAndroid Build Coastguard Worker // Tests simulcast rejected scenario all layers except first are rejected.
1887*d9f75844SAndroid Build Coastguard Worker CreatePairOfRidVectors({"1", "2", "3", "4"}, {"2", "3", "4"}),
1888*d9f75844SAndroid Build Coastguard Worker // Tests removing all layers.
1889*d9f75844SAndroid Build Coastguard Worker CreatePairOfRidVectors({"1", "2", "3", "4"}, {"1", "2", "3", "4"}),
1890*d9f75844SAndroid Build Coastguard Worker };
1891*d9f75844SAndroid Build Coastguard Worker
1892*d9f75844SAndroid Build Coastguard Worker // Runs test for disabling layers on a sender without a media engine set.
TEST_P(RtpSenderReceiverTest,DisableSimulcastLayersWithoutMediaEngine)1893*d9f75844SAndroid Build Coastguard Worker TEST_P(RtpSenderReceiverTest, DisableSimulcastLayersWithoutMediaEngine) {
1894*d9f75844SAndroid Build Coastguard Worker auto parameter = GetParam();
1895*d9f75844SAndroid Build Coastguard Worker RunDisableSimulcastLayersWithoutMediaEngineTest(parameter.first,
1896*d9f75844SAndroid Build Coastguard Worker parameter.second);
1897*d9f75844SAndroid Build Coastguard Worker }
1898*d9f75844SAndroid Build Coastguard Worker
1899*d9f75844SAndroid Build Coastguard Worker // Runs test for disabling layers on a sender with a media engine set.
TEST_P(RtpSenderReceiverTest,DisableSimulcastLayersWithMediaEngine)1900*d9f75844SAndroid Build Coastguard Worker TEST_P(RtpSenderReceiverTest, DisableSimulcastLayersWithMediaEngine) {
1901*d9f75844SAndroid Build Coastguard Worker auto parameter = GetParam();
1902*d9f75844SAndroid Build Coastguard Worker RunDisableSimulcastLayersWithMediaEngineTest(parameter.first,
1903*d9f75844SAndroid Build Coastguard Worker parameter.second);
1904*d9f75844SAndroid Build Coastguard Worker }
1905*d9f75844SAndroid Build Coastguard Worker
1906*d9f75844SAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(
1907*d9f75844SAndroid Build Coastguard Worker DisableSimulcastLayersInSender,
1908*d9f75844SAndroid Build Coastguard Worker RtpSenderReceiverTest,
1909*d9f75844SAndroid Build Coastguard Worker ::testing::ValuesIn(kDisableSimulcastLayersParameters));
1910*d9f75844SAndroid Build Coastguard Worker
1911*d9f75844SAndroid Build Coastguard Worker } // namespace webrtc
1912