Thanks to visit codestin.com
Credit goes to webrtc.googlesource.com

blob: e277fece3f4a3b36ef0d11fca70c044b5e7636ba [file] [log] [blame]
[email protected]5f93d0a2015-01-20 21:36:131/*
kjellander65c7f672016-02-12 08:05:012 * Copyright 2009 The WebRTC project authors. All Rights Reserved.
[email protected]5f93d0a2015-01-20 21:36:133 *
kjellander65c7f672016-02-12 08:05:014 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
[email protected]5f93d0a2015-01-20 21:36:139 */
[email protected]28e20752013-07-10 00:45:3610
Anton Sukhanov4f08faa2019-05-21 18:12:5711#include "pc/channel.h"
12
Philipp Hanckeb2ea9362025-07-18 17:47:3913#include <cstddef>
Yves Gerey3e707812018-11-28 15:47:4914#include <cstdint>
Philipp Hancke740d7262024-12-09 05:26:3415#include <memory>
16#include <optional>
Harald Alvestrandc24a2182022-02-23 13:44:5917#include <string>
Philipp Hancke740d7262024-12-09 05:26:3418#include <utility>
19#include <vector>
kwiberg31022942016-03-11 22:18:2120
Danil Chapovalova30439b2022-07-07 08:08:4921#include "absl/functional/any_invocable.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3122#include "api/array_view.h"
Yves Gerey3e707812018-11-28 15:47:4923#include "api/audio_options.h"
Philipp Hancke740d7262024-12-09 05:26:3424#include "api/crypto/crypto_options.h"
Danil Chapovalov6e65ae32025-06-10 11:06:0325#include "api/field_trials.h"
Philipp Hancke740d7262024-12-09 05:26:3426#include "api/jsep.h"
Tomas Lundqvistb40c5592024-11-22 13:45:2727#include "api/rtp_headers.h"
Steve Anton10542f22019-01-11 17:11:0028#include "api/rtp_parameters.h"
Philipp Hancke740d7262024-12-09 05:26:3429#include "api/rtp_transceiver_direction.h"
30#include "api/scoped_refptr.h"
31#include "api/sequence_checker.h"
Artem Titovc374d112022-06-16 19:27:4532#include "api/task_queue/pending_task_safety_flag.h"
Yves Gerey3e707812018-11-28 15:47:4933#include "media/base/codec.h"
Steve Anton10542f22019-01-11 17:11:0034#include "media/base/fake_media_engine.h"
35#include "media/base/fake_rtp.h"
36#include "media/base/media_channel.h"
Harald Alvestrandc24a2182022-02-23 13:44:5937#include "media/base/media_constants.h"
38#include "media/base/rid_description.h"
Philipp Hancke740d7262024-12-09 05:26:3439#include "media/base/stream_params.h"
Steve Anton10542f22019-01-11 17:11:0040#include "p2p/base/candidate_pair_interface.h"
Steve Anton10542f22019-01-11 17:11:0041#include "p2p/base/ice_transport_internal.h"
42#include "p2p/base/p2p_constants.h"
Harald Alvestrandc24a2182022-02-23 13:44:5943#include "p2p/base/packet_transport_internal.h"
Philipp Hancke740d7262024-12-09 05:26:3444#include "p2p/dtls/dtls_transport_internal.h"
45#include "p2p/dtls/fake_dtls_transport.h"
Jonas Orelandb85686c2025-02-27 09:52:3546#include "p2p/test/fake_packet_transport.h"
Steve Anton10542f22019-01-11 17:11:0047#include "pc/dtls_srtp_transport.h"
Steve Anton10542f22019-01-11 17:11:0048#include "pc/rtp_transport.h"
Philipp Hancke740d7262024-12-09 05:26:3449#include "pc/rtp_transport_internal.h"
50#include "pc/session_description.h"
Harald Alvestrand3d092402025-05-05 13:32:5351#include "rtc_base/async_packet_socket.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3152#include "rtc_base/buffer.h"
Steve Anton10542f22019-01-11 17:11:0053#include "rtc_base/byte_order.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3154#include "rtc_base/checks.h"
Philipp Hancke740d7262024-12-09 05:26:3455#include "rtc_base/network_route.h"
Steve Anton10542f22019-01-11 17:11:0056#include "rtc_base/rtc_certificate.h"
Philipp Hancke740d7262024-12-09 05:26:3457#include "rtc_base/socket.h"
Steve Anton10542f22019-01-11 17:11:0058#include "rtc_base/ssl_identity.h"
Danil Chapovalov2aaef452022-08-12 13:55:1159#include "rtc_base/task_queue_for_test.h"
Philipp Hancke740d7262024-12-09 05:26:3460#include "rtc_base/thread.h"
61#include "rtc_base/unique_id_generator.h"
Danil Chapovalov6e65ae32025-06-10 11:06:0362#include "test/create_test_field_trials.h"
Mirta Dvornicic479a3c02019-06-04 13:38:5063#include "test/gmock.h"
Yves Gerey3e707812018-11-28 15:47:4964#include "test/gtest.h"
[email protected]28e20752013-07-10 00:45:3665
Danil Chapovalov33b01f22016-05-11 17:55:2766namespace {
Emil Lundmark17304c32023-09-15 14:33:0367
Emil Lundmark17304c32023-09-15 14:33:0368using ::testing::AllOf;
69using ::testing::ElementsAre;
70using ::testing::Field;
Danil Chapovalov52c16dc2025-06-02 07:57:1571using ::webrtc::ArrayView;
Danil Chapovalov6e65ae32025-06-10 11:06:0372using ::webrtc::CreateTestFieldTrials;
Evan Shrubsolee6a1f702025-04-15 14:55:4273using ::webrtc::DtlsTransportInternal;
Evan Shrubsole945e5172025-04-08 14:11:4574using ::webrtc::FakeVoiceMediaReceiveChannel;
75using ::webrtc::FakeVoiceMediaSendChannel;
Danil Chapovalov6e65ae32025-06-10 11:06:0376using ::webrtc::FieldTrials;
Evan Shrubsole945e5172025-04-08 14:11:4577using ::webrtc::RidDescription;
78using ::webrtc::RidDirection;
Per K38bb3312025-08-19 13:46:2479using ::webrtc::RtpExtension;
Emil Lundmark17304c32023-09-15 14:33:0380using ::webrtc::RtpTransceiverDirection;
81using ::webrtc::SdpType;
Evan Shrubsole945e5172025-04-08 14:11:4582using ::webrtc::StreamParams;
Emil Lundmark17304c32023-09-15 14:33:0383
Evan Shrubsole0b212e32025-04-07 13:43:0184const webrtc::Codec kPcmuCodec = webrtc::CreateAudioCodec(0, "PCMU", 64000, 1);
85const webrtc::Codec kPcmaCodec = webrtc::CreateAudioCodec(8, "PCMA", 64000, 1);
86const webrtc::Codec kIsacCodec =
87 webrtc::CreateAudioCodec(103, "ISAC", 40000, 1);
88const webrtc::Codec kH264Codec = webrtc::CreateVideoCodec(97, "H264");
89const webrtc::Codec kH264SvcCodec = webrtc::CreateVideoCodec(99, "H264-SVC");
Philipp Hancke81f4e782025-07-07 18:57:0990constexpr uint32_t kSsrc1 = 0x1111;
91constexpr uint32_t kSsrc2 = 0x2222;
92constexpr uint32_t kSsrc3 = 0x3333;
93constexpr uint32_t kSsrc4 = 0x4444;
94constexpr int kAudioPts[] = {0, 8};
95constexpr int kVideoPts[] = {97, 99};
96constexpr char kAudioMid[] = "0";
97constexpr char kVideoMid[] = "1";
Danil Chapovalov33b01f22016-05-11 17:55:2798enum class NetworkIsWorker { Yes, No };
Niels Möller02284852018-01-17 09:22:4799
deadbeefcbecd352015-09-23 18:50:27100template <class ChannelT,
Harald Alvestrand50454ef2022-12-15 16:49:13101 class MediaSendChannelT,
102 class MediaReceiveChannelT,
Florent Castelli1f31c202023-06-26 00:26:07103 class MediaSendChannelInterfaceT,
104 class MediaReceiveChannelInterfaceT,
deadbeefcbecd352015-09-23 18:50:27105 class ContentT,
deadbeefcbecd352015-09-23 18:50:27106 class MediaInfoT,
107 class OptionsT>
[email protected]28e20752013-07-10 00:45:36108class Traits {
109 public:
Harald Alvestrand3d092402025-05-05 13:32:53110 using Channel = ChannelT;
111 using MediaSendChannel = MediaSendChannelT;
112 using MediaReceiveChannel = MediaReceiveChannelT;
113 using MediaSendChannelInterface = MediaSendChannelInterfaceT;
114 using MediaReceiveChannelInterface = MediaReceiveChannelInterfaceT;
115 using Content = ContentT;
116 using MediaInfo = MediaInfoT;
117 using Options = OptionsT;
[email protected]28e20752013-07-10 00:45:36118};
119
Evan Shrubsole3c825f12025-04-04 14:07:27120class VoiceTraits : public Traits<webrtc::VoiceChannel,
Evan Shrubsole945e5172025-04-08 14:11:45121 webrtc::FakeVoiceMediaSendChannel,
122 webrtc::FakeVoiceMediaReceiveChannel,
123 webrtc::VoiceMediaSendChannelInterface,
124 webrtc::VoiceMediaReceiveChannelInterface,
Evan Shrubsole080cdac2025-03-20 09:34:48125 webrtc::AudioContentDescription,
Evan Shrubsole945e5172025-04-08 14:11:45126 webrtc::VoiceMediaInfo,
127 webrtc::AudioOptions> {};
[email protected]28e20752013-07-10 00:45:36128
Evan Shrubsole3c825f12025-04-04 14:07:27129class VideoTraits : public Traits<webrtc::VideoChannel,
Evan Shrubsole945e5172025-04-08 14:11:45130 webrtc::FakeVideoMediaSendChannel,
131 webrtc::FakeVideoMediaReceiveChannel,
132 webrtc::VideoMediaSendChannelInterface,
133 webrtc::VideoMediaReceiveChannelInterface,
Evan Shrubsole080cdac2025-03-20 09:34:48134 webrtc::VideoContentDescription,
Evan Shrubsole945e5172025-04-08 14:11:45135 webrtc::VideoMediaInfo,
136 webrtc::VideoOptions> {};
[email protected]28e20752013-07-10 00:45:36137
Harald Alvestrand48171ec2021-04-20 15:06:03138// Base class for Voice/Video tests
Yves Gerey665174f2018-06-19 13:03:05139template <class T>
Philipp Hancked22c6e62025-08-04 23:15:30140class ChannelTest : public ::testing::Test {
[email protected]28e20752013-07-10 00:45:36141 public:
deadbeefac22f702017-01-13 05:59:29142 enum Flags {
143 RTCP_MUX = 0x1,
deadbeefac22f702017-01-13 05:59:29144 SSRC_MUX = 0x8,
145 DTLS = 0x10,
deadbeef5bd5ca32017-02-10 19:31:50146 // Use BaseChannel with PacketTransportInternal rather than
deadbeeff5346592017-01-25 05:51:21147 // DtlsTransportInternal.
deadbeef7914b8c2017-04-21 10:23:33148 RAW_PACKET_TRANSPORT = 0x20,
deadbeefac22f702017-01-13 05:59:29149 };
[email protected]28e20752013-07-10 00:45:36150
Peter Boström34fbfff2015-09-24 17:20:30151 ChannelTest(bool verify_playout,
Evan Shrubsolee6a1f702025-04-15 14:55:42152 webrtc::ArrayView<const uint8_t> rtp_data,
153 webrtc::ArrayView<const uint8_t> rtcp_data,
Danil Chapovalov33b01f22016-05-11 17:55:27154 NetworkIsWorker network_is_worker)
Peter Boström34fbfff2015-09-24 17:20:30155 : verify_playout_(verify_playout),
Danil Chapovalov33b01f22016-05-11 17:55:27156 rtp_packet_(rtp_data.data(), rtp_data.size()),
deadbeeff5346592017-01-25 05:51:21157 rtcp_packet_(rtcp_data.data(), rtcp_data.size()) {
Danil Chapovalov33b01f22016-05-11 17:55:27158 if (network_is_worker == NetworkIsWorker::Yes) {
Evan Shrubsole6a9a1ae2025-03-21 12:54:15159 network_thread_ = webrtc::Thread::Current();
Danil Chapovalov33b01f22016-05-11 17:55:27160 } else {
Evan Shrubsole6a9a1ae2025-03-21 12:54:15161 network_thread_keeper_ = webrtc::Thread::Create();
Danil Chapovalov33b01f22016-05-11 17:55:27162 network_thread_keeper_->SetName("Network", nullptr);
Danil Chapovalov33b01f22016-05-11 17:55:27163 network_thread_ = network_thread_keeper_.get();
164 }
Tommic9625f02021-05-06 20:03:19165 RTC_DCHECK(network_thread_);
166 }
167
Philipp Hanckec6d7e6c2025-06-13 17:28:17168 ~ChannelTest() override {
Tommic9625f02021-05-06 20:03:19169 if (network_thread_) {
Danil Chapovalov2aaef452022-08-12 13:55:11170 SendTask(network_thread_, [this]() {
Tomas Gunnarsson1933d3b2022-01-17 10:25:21171 network_thread_safety_->SetNotAlive();
172 DeinitChannels();
Per Kf4aadf32024-02-27 08:01:15173
174 // Transports must be created and destroyed on the network thread.
175 fake_rtp_dtls_transport1_ = nullptr;
176 fake_rtcp_dtls_transport1_ = nullptr;
177 fake_rtp_dtls_transport2_ = nullptr;
178 fake_rtcp_dtls_transport2_ = nullptr;
179 fake_rtp_packet_transport1_ = nullptr;
180 fake_rtcp_packet_transport1_ = nullptr;
181 fake_rtp_packet_transport2_ = nullptr;
182 fake_rtcp_packet_transport2_ = nullptr;
183 rtp_transport1_ = nullptr;
184 rtp_transport2_ = nullptr;
185 new_rtp_transport_ = nullptr;
Tomas Gunnarsson1933d3b2022-01-17 10:25:21186 });
Tommic9625f02021-05-06 20:03:19187 }
Danil Chapovalov33b01f22016-05-11 17:55:27188 }
[email protected]28e20752013-07-10 00:45:36189
[email protected]28e20752013-07-10 00:45:36190 void CreateChannels(int flags1, int flags2) {
Florent Castelli1f31c202023-06-26 00:26:07191 CreateChannels(std::make_unique<typename T::MediaSendChannel>(
Harald Alvestrand16579cc2023-02-09 13:01:24192 typename T::Options(), network_thread_),
Florent Castelli1f31c202023-06-26 00:26:07193 std::make_unique<typename T::MediaReceiveChannel>(
Harald Alvestrand2f553702023-03-07 10:10:03194 typename T::Options(), network_thread_),
Florent Castelli1f31c202023-06-26 00:26:07195 std::make_unique<typename T::MediaSendChannel>(
Harald Alvestrand2f553702023-03-07 10:10:03196 typename T::Options(), network_thread_),
Florent Castelli1f31c202023-06-26 00:26:07197 std::make_unique<typename T::MediaReceiveChannel>(
Harald Alvestrand16579cc2023-02-09 13:01:24198 typename T::Options(), network_thread_),
Danil Chapovalov33b01f22016-05-11 17:55:27199 flags1, flags2);
[email protected]28e20752013-07-10 00:45:36200 }
Florent Castelli1f31c202023-06-26 00:26:07201 void CreateChannels(std::unique_ptr<typename T::MediaSendChannel> ch1s,
202 std::unique_ptr<typename T::MediaReceiveChannel> ch1r,
203 std::unique_ptr<typename T::MediaSendChannel> ch2s,
204 std::unique_ptr<typename T::MediaReceiveChannel> ch2r,
Danil Chapovalov33b01f22016-05-11 17:55:27205 int flags1,
206 int flags2) {
Tommic9625f02021-05-06 20:03:19207 RTC_DCHECK(!channel1_);
208 RTC_DCHECK(!channel2_);
209
deadbeeff5346592017-01-25 05:51:21210 // Network thread is started in CreateChannels, to allow the test to
211 // configure a fake clock before any threads are spawned and attempt to
212 // access the time.
213 if (network_thread_keeper_) {
214 network_thread_keeper_->Start();
215 }
Zhi Huange830e682018-03-30 17:48:35216
deadbeeff5346592017-01-25 05:51:21217 // Make sure if using raw packet transports, they're used for both
218 // channels.
219 RTC_DCHECK_EQ(flags1 & RAW_PACKET_TRANSPORT, flags2 & RAW_PACKET_TRANSPORT);
Evan Shrubsole6a9a1ae2025-03-21 12:54:15220 webrtc::Thread* worker_thread = webrtc::Thread::Current();
Per Kf4aadf32024-02-27 08:01:15221
222 network_thread_->BlockingCall([&] {
223 // Based on flags, create fake DTLS or raw packet transports.
224
225 if (flags1 & RAW_PACKET_TRANSPORT) {
226 fake_rtp_packet_transport1_.reset(
Evan Shrubsolec13956e2025-03-13 12:45:54227 new webrtc::FakePacketTransport("channel1_rtp"));
Per Kf4aadf32024-02-27 08:01:15228 if (!(flags1 & RTCP_MUX)) {
229 fake_rtcp_packet_transport1_.reset(
Evan Shrubsolec13956e2025-03-13 12:45:54230 new webrtc::FakePacketTransport("channel1_rtcp"));
Per Kf4aadf32024-02-27 08:01:15231 }
232 } else {
233 // Confirmed to work with KT_RSA and KT_ECDSA.
Evan Shrubsolee4b09d72025-03-17 13:25:49234 fake_rtp_dtls_transport1_.reset(new webrtc::FakeDtlsTransport(
Evan Shrubsole945e5172025-04-08 14:11:45235 "channel1", webrtc::ICE_CANDIDATE_COMPONENT_RTP, network_thread_));
Per Kf4aadf32024-02-27 08:01:15236 if (!(flags1 & RTCP_MUX)) {
Evan Shrubsolee4b09d72025-03-17 13:25:49237 fake_rtcp_dtls_transport1_.reset(new webrtc::FakeDtlsTransport(
Evan Shrubsole945e5172025-04-08 14:11:45238 "channel1", webrtc::ICE_CANDIDATE_COMPONENT_RTCP,
Per Kf4aadf32024-02-27 08:01:15239 network_thread_));
240 }
241 if (flags1 & DTLS) {
Evan Shrubsole8990f2a2025-03-13 10:01:12242 auto cert1 = webrtc::RTCCertificate::Create(
Evan Shrubsole8f7678f2025-04-01 14:23:55243 webrtc::SSLIdentity::Create("session1", webrtc::KT_DEFAULT));
Per Kf4aadf32024-02-27 08:01:15244 fake_rtp_dtls_transport1_->SetLocalCertificate(cert1);
245 if (fake_rtcp_dtls_transport1_) {
246 fake_rtcp_dtls_transport1_->SetLocalCertificate(cert1);
247 }
deadbeeff5346592017-01-25 05:51:21248 }
249 }
Per Kf4aadf32024-02-27 08:01:15250 // Based on flags, create fake DTLS or raw packet transports.
251 if (flags2 & RAW_PACKET_TRANSPORT) {
252 fake_rtp_packet_transport2_.reset(
Evan Shrubsolec13956e2025-03-13 12:45:54253 new webrtc::FakePacketTransport("channel2_rtp"));
Per Kf4aadf32024-02-27 08:01:15254 if (!(flags2 & RTCP_MUX)) {
255 fake_rtcp_packet_transport2_.reset(
Evan Shrubsolec13956e2025-03-13 12:45:54256 new webrtc::FakePacketTransport("channel2_rtcp"));
Per Kf4aadf32024-02-27 08:01:15257 }
258 } else {
259 // Confirmed to work with KT_RSA and KT_ECDSA.
Evan Shrubsolee4b09d72025-03-17 13:25:49260 fake_rtp_dtls_transport2_.reset(new webrtc::FakeDtlsTransport(
Evan Shrubsole945e5172025-04-08 14:11:45261 "channel2", webrtc::ICE_CANDIDATE_COMPONENT_RTP, network_thread_));
Per Kf4aadf32024-02-27 08:01:15262 if (!(flags2 & RTCP_MUX)) {
Evan Shrubsolee4b09d72025-03-17 13:25:49263 fake_rtcp_dtls_transport2_.reset(new webrtc::FakeDtlsTransport(
Evan Shrubsole945e5172025-04-08 14:11:45264 "channel2", webrtc::ICE_CANDIDATE_COMPONENT_RTCP,
Per Kf4aadf32024-02-27 08:01:15265 network_thread_));
266 }
267 if (flags2 & DTLS) {
Evan Shrubsole8990f2a2025-03-13 10:01:12268 auto cert2 = webrtc::RTCCertificate::Create(
Evan Shrubsole8f7678f2025-04-01 14:23:55269 webrtc::SSLIdentity::Create("session2", webrtc::KT_DEFAULT));
Per Kf4aadf32024-02-27 08:01:15270 fake_rtp_dtls_transport2_->SetLocalCertificate(cert2);
271 if (fake_rtcp_dtls_transport2_) {
272 fake_rtcp_dtls_transport2_->SetLocalCertificate(cert2);
273 }
deadbeeff5346592017-01-25 05:51:21274 }
275 }
Per Kf4aadf32024-02-27 08:01:15276 rtp_transport1_ = CreateRtpTransportBasedOnFlags(
277 fake_rtp_packet_transport1_.get(), fake_rtcp_packet_transport1_.get(),
278 fake_rtp_dtls_transport1_.get(), fake_rtcp_dtls_transport1_.get(),
279 flags1);
280 rtp_transport2_ = CreateRtpTransportBasedOnFlags(
281 fake_rtp_packet_transport2_.get(), fake_rtcp_packet_transport2_.get(),
282 fake_rtp_dtls_transport2_.get(), fake_rtcp_dtls_transport2_.get(),
283 flags2);
284 });
Zhi Huange830e682018-03-30 17:48:35285
Harald Alvestrand2f553702023-03-07 10:10:03286 channel1_ = CreateChannel(worker_thread, network_thread_, std::move(ch1s),
287 std::move(ch1r), rtp_transport1_.get(), flags1);
288 channel2_ = CreateChannel(worker_thread, network_thread_, std::move(ch2s),
289 std::move(ch2r), rtp_transport2_.get(), flags2);
Yves Gerey665174f2018-06-19 13:03:05290 CreateContent(flags1, kPcmuCodec, kH264Codec, &local_media_content1_);
291 CreateContent(flags2, kPcmuCodec, kH264Codec, &local_media_content2_);
[email protected]28e20752013-07-10 00:45:36292 CopyContent(local_media_content1_, &remote_media_content1_);
293 CopyContent(local_media_content2_, &remote_media_content2_);
294
[email protected]28e20752013-07-10 00:45:36295 // Add stream information (SSRC) to the local content but not to the remote
296 // content. This means that we per default know the SSRC of what we send but
297 // not what we receive.
298 AddLegacyStreamInContent(kSsrc1, flags1, &local_media_content1_);
299 AddLegacyStreamInContent(kSsrc2, flags2, &local_media_content2_);
300
301 // If SSRC_MUX is used we also need to know the SSRC of the incoming stream.
302 if (flags1 & SSRC_MUX) {
303 AddLegacyStreamInContent(kSsrc1, flags1, &remote_media_content1_);
304 }
305 if (flags2 & SSRC_MUX) {
306 AddLegacyStreamInContent(kSsrc2, flags2, &remote_media_content2_);
307 }
308 }
Steve Anton8699a322017-11-06 23:53:33309 std::unique_ptr<typename T::Channel> CreateChannel(
Evan Shrubsole6a9a1ae2025-03-21 12:54:15310 webrtc::Thread* worker_thread,
311 webrtc::Thread* network_thread,
Florent Castelli1f31c202023-06-26 00:26:07312 std::unique_ptr<typename T::MediaSendChannel> ch_send,
313 std::unique_ptr<typename T::MediaReceiveChannel> ch_receive,
Zhi Huange830e682018-03-30 17:48:35314 webrtc::RtpTransportInternal* rtp_transport,
Sebastian Jansson1b83a9e2019-09-18 16:22:12315 int flags);
[email protected]28e20752013-07-10 00:45:36316
Zhi Huange830e682018-03-30 17:48:35317 std::unique_ptr<webrtc::RtpTransportInternal> CreateRtpTransportBasedOnFlags(
Evan Shrubsole8f7678f2025-04-01 14:23:55318 webrtc::PacketTransportInternal* rtp_packet_transport,
319 webrtc::PacketTransportInternal* rtcp_packet_transport,
Zhi Huange830e682018-03-30 17:48:35320 DtlsTransportInternal* rtp_dtls_transport,
321 DtlsTransportInternal* rtcp_dtls_transport,
322 int flags) {
323 if (flags & RTCP_MUX) {
324 rtcp_packet_transport = nullptr;
325 rtcp_dtls_transport = nullptr;
326 }
327
328 if (flags & DTLS) {
329 return CreateDtlsSrtpTransport(rtp_dtls_transport, rtcp_dtls_transport);
330 } else {
331 if (flags & RAW_PACKET_TRANSPORT) {
332 return CreateUnencryptedTransport(rtp_packet_transport,
333 rtcp_packet_transport);
334 } else {
335 return CreateUnencryptedTransport(rtp_dtls_transport,
336 rtcp_dtls_transport);
337 }
338 }
339 }
340
Tomas Gunnarsson1933d3b2022-01-17 10:25:21341 // Unininitializes the channels on the network thread.
342 void DeinitChannels() {
343 if (!channel1_ && !channel2_)
344 return;
Danil Chapovalov2aaef452022-08-12 13:55:11345 SendTask(network_thread_, [this]() {
Tomas Gunnarsson1933d3b2022-01-17 10:25:21346 if (channel1_) {
347 RTC_DCHECK_RUN_ON(channel1_->network_thread());
Tomas Gunnarsson4f8a58c2022-01-19 10:36:23348 channel1_->SetRtpTransport(nullptr);
Tomas Gunnarsson1933d3b2022-01-17 10:25:21349 }
350 if (channel2_) {
351 RTC_DCHECK_RUN_ON(channel2_->network_thread());
Tomas Gunnarsson4f8a58c2022-01-19 10:36:23352 channel2_->SetRtpTransport(nullptr);
Tomas Gunnarsson1933d3b2022-01-17 10:25:21353 }
354 });
355 }
356
Zhi Huange830e682018-03-30 17:48:35357 std::unique_ptr<webrtc::RtpTransport> CreateUnencryptedTransport(
Evan Shrubsole8f7678f2025-04-01 14:23:55358 webrtc::PacketTransportInternal* rtp_packet_transport,
359 webrtc::PacketTransportInternal* rtcp_packet_transport) {
Mirko Bonadei317a1f02019-09-17 15:06:18360 auto rtp_transport = std::make_unique<webrtc::RtpTransport>(
Per Kb60f0ff2024-08-22 08:54:32361 rtcp_packet_transport == nullptr, field_trials_);
Zhi Huange830e682018-03-30 17:48:35362
Danil Chapovalov2aaef452022-08-12 13:55:11363 SendTask(network_thread_,
364 [&rtp_transport, rtp_packet_transport, rtcp_packet_transport] {
365 rtp_transport->SetRtpPacketTransport(rtp_packet_transport);
366 if (rtcp_packet_transport) {
367 rtp_transport->SetRtcpPacketTransport(rtcp_packet_transport);
368 }
369 });
Zhi Huange830e682018-03-30 17:48:35370 return rtp_transport;
371 }
372
373 std::unique_ptr<webrtc::DtlsSrtpTransport> CreateDtlsSrtpTransport(
Evan Shrubsole945e5172025-04-08 14:11:45374 webrtc::DtlsTransportInternal* rtp_dtls_transport,
375 webrtc::DtlsTransportInternal* rtcp_dtls_transport) {
Mirko Bonadei317a1f02019-09-17 15:06:18376 auto dtls_srtp_transport = std::make_unique<webrtc::DtlsSrtpTransport>(
Jonas Orelanded99dae2022-03-09 08:28:10377 rtcp_dtls_transport == nullptr, field_trials_);
Zhi Huange830e682018-03-30 17:48:35378
Danil Chapovalov2aaef452022-08-12 13:55:11379 SendTask(network_thread_,
380 [&dtls_srtp_transport, rtp_dtls_transport, rtcp_dtls_transport] {
381 dtls_srtp_transport->SetDtlsTransports(rtp_dtls_transport,
382 rtcp_dtls_transport);
383 });
Zhi Huange830e682018-03-30 17:48:35384 return dtls_srtp_transport;
385 }
386
deadbeeff5346592017-01-25 05:51:21387 void ConnectFakeTransports() {
Danil Chapovalov2aaef452022-08-12 13:55:11388 SendTask(network_thread_, [this] {
deadbeeff5346592017-01-25 05:51:21389 bool asymmetric = false;
390 // Depending on test flags, could be using DTLS or raw packet transport.
391 if (fake_rtp_dtls_transport1_ && fake_rtp_dtls_transport2_) {
392 fake_rtp_dtls_transport1_->SetDestination(
393 fake_rtp_dtls_transport2_.get(), asymmetric);
394 }
395 if (fake_rtcp_dtls_transport1_ && fake_rtcp_dtls_transport2_) {
396 fake_rtcp_dtls_transport1_->SetDestination(
397 fake_rtcp_dtls_transport2_.get(), asymmetric);
398 }
399 if (fake_rtp_packet_transport1_ && fake_rtp_packet_transport2_) {
400 fake_rtp_packet_transport1_->SetDestination(
401 fake_rtp_packet_transport2_.get(), asymmetric);
402 }
403 if (fake_rtcp_packet_transport1_ && fake_rtcp_packet_transport2_) {
404 fake_rtcp_packet_transport1_->SetDestination(
405 fake_rtcp_packet_transport2_.get(), asymmetric);
406 }
407 });
Taylor Brandstetter2ab9b282021-02-01 22:39:07408 // The transport becoming writable will asynchronously update the send state
409 // on the worker thread; since this test uses the main thread as the worker
410 // thread, we must process the message queue for this to occur.
411 WaitForThreads();
deadbeeff5346592017-01-25 05:51:21412 }
413
[email protected]28e20752013-07-10 00:45:36414 bool SendInitiate() {
Tomas Gunnarssond908d742022-01-05 10:44:26415 std::string err;
[email protected]4b26e2e2014-01-15 23:15:54416 bool result = channel1_->SetLocalContent(&local_media_content1_,
Tomas Gunnarssond908d742022-01-05 10:44:26417 SdpType::kOffer, err);
[email protected]28e20752013-07-10 00:45:36418 if (result) {
419 channel1_->Enable(true);
Tommi1959f8f2021-04-26 08:20:19420 FlushCurrentThread();
[email protected]4b26e2e2014-01-15 23:15:54421 result = channel2_->SetRemoteContent(&remote_media_content1_,
Tomas Gunnarssond908d742022-01-05 10:44:26422 SdpType::kOffer, err);
[email protected]28e20752013-07-10 00:45:36423 if (result) {
deadbeeff5346592017-01-25 05:51:21424 ConnectFakeTransports();
[email protected]4b26e2e2014-01-15 23:15:54425 result = channel2_->SetLocalContent(&local_media_content2_,
Tomas Gunnarssond908d742022-01-05 10:44:26426 SdpType::kAnswer, err);
[email protected]28e20752013-07-10 00:45:36427 }
428 }
429 return result;
430 }
431
432 bool SendAccept() {
433 channel2_->Enable(true);
Tommi1959f8f2021-04-26 08:20:19434 FlushCurrentThread();
Tomas Gunnarssond908d742022-01-05 10:44:26435 std::string err;
[email protected]4b26e2e2014-01-15 23:15:54436 return channel1_->SetRemoteContent(&remote_media_content2_,
Tomas Gunnarssond908d742022-01-05 10:44:26437 SdpType::kAnswer, err);
[email protected]28e20752013-07-10 00:45:36438 }
439
440 bool SendOffer() {
Tomas Gunnarssond908d742022-01-05 10:44:26441 std::string err;
[email protected]4b26e2e2014-01-15 23:15:54442 bool result = channel1_->SetLocalContent(&local_media_content1_,
Tomas Gunnarssond908d742022-01-05 10:44:26443 SdpType::kOffer, err);
[email protected]28e20752013-07-10 00:45:36444 if (result) {
445 channel1_->Enable(true);
[email protected]4b26e2e2014-01-15 23:15:54446 result = channel2_->SetRemoteContent(&remote_media_content1_,
Tomas Gunnarssond908d742022-01-05 10:44:26447 SdpType::kOffer, err);
[email protected]28e20752013-07-10 00:45:36448 }
449 return result;
450 }
451
452 bool SendProvisionalAnswer() {
Tomas Gunnarssond908d742022-01-05 10:44:26453 std::string err;
[email protected]28e20752013-07-10 00:45:36454 bool result = channel2_->SetLocalContent(&local_media_content2_,
Tomas Gunnarssond908d742022-01-05 10:44:26455 SdpType::kPrAnswer, err);
[email protected]28e20752013-07-10 00:45:36456 if (result) {
457 channel2_->Enable(true);
458 result = channel1_->SetRemoteContent(&remote_media_content2_,
Tomas Gunnarssond908d742022-01-05 10:44:26459 SdpType::kPrAnswer, err);
deadbeeff5346592017-01-25 05:51:21460 ConnectFakeTransports();
[email protected]28e20752013-07-10 00:45:36461 }
462 return result;
463 }
464
465 bool SendFinalAnswer() {
Tomas Gunnarssond908d742022-01-05 10:44:26466 std::string err;
[email protected]4b26e2e2014-01-15 23:15:54467 bool result = channel2_->SetLocalContent(&local_media_content2_,
Tomas Gunnarssond908d742022-01-05 10:44:26468 SdpType::kAnswer, err);
469 if (result) {
[email protected]4b26e2e2014-01-15 23:15:54470 result = channel1_->SetRemoteContent(&remote_media_content2_,
Tomas Gunnarssond908d742022-01-05 10:44:26471 SdpType::kAnswer, err);
472 }
[email protected]28e20752013-07-10 00:45:36473 return result;
474 }
475
Evan Shrubsolee6a1f702025-04-15 14:55:42476 void SendRtp(typename T::MediaSendChannel* media_channel,
477 webrtc::Buffer data) {
Danil Chapovalova30439b2022-07-07 08:08:49478 network_thread_->PostTask(webrtc::SafeTask(
Tommic9625f02021-05-06 20:03:19479 network_thread_safety_, [media_channel, data = std::move(data)]() {
Florent Castelli1f31c202023-06-26 00:26:07480 media_channel->SendPacket(data.data(), data.size(),
Evan Shrubsolee6a1f702025-04-15 14:55:42481 webrtc::AsyncSocketPacketOptions());
Tommic9625f02021-05-06 20:03:19482 }));
483 }
484
Danil Chapovalov33b01f22016-05-11 17:55:27485 void SendRtp1() {
Evan Shrubsolee6a1f702025-04-15 14:55:42486 SendRtp1(webrtc::Buffer(rtp_packet_.data(), rtp_packet_.size()));
[email protected]28e20752013-07-10 00:45:36487 }
Tommic9625f02021-05-06 20:03:19488
Evan Shrubsolee6a1f702025-04-15 14:55:42489 void SendRtp1(webrtc::Buffer data) {
Harald Alvestrand2f553702023-03-07 10:10:03490 SendRtp(media_send_channel1_impl(), std::move(data));
Tommic9625f02021-05-06 20:03:19491 }
492
Danil Chapovalov33b01f22016-05-11 17:55:27493 void SendRtp2() {
Evan Shrubsolee6a1f702025-04-15 14:55:42494 SendRtp2(webrtc::Buffer(rtp_packet_.data(), rtp_packet_.size()));
[email protected]28e20752013-07-10 00:45:36495 }
Tommic9625f02021-05-06 20:03:19496
Evan Shrubsolee6a1f702025-04-15 14:55:42497 void SendRtp2(webrtc::Buffer data) {
Harald Alvestrand2f553702023-03-07 10:10:03498 SendRtp(media_send_channel2_impl(), std::move(data));
Tommic9625f02021-05-06 20:03:19499 }
500
[email protected]28e20752013-07-10 00:45:36501 // Methods to send custom data.
Danil Chapovalov33b01f22016-05-11 17:55:27502 void SendCustomRtp1(uint32_t ssrc, int sequence_number, int pl_type = -1) {
Tommic9625f02021-05-06 20:03:19503 SendRtp1(CreateRtpData(ssrc, sequence_number, pl_type));
[email protected]28e20752013-07-10 00:45:36504 }
Danil Chapovalov33b01f22016-05-11 17:55:27505 void SendCustomRtp2(uint32_t ssrc, int sequence_number, int pl_type = -1) {
Tommic9625f02021-05-06 20:03:19506 SendRtp2(CreateRtpData(ssrc, sequence_number, pl_type));
[email protected]28e20752013-07-10 00:45:36507 }
Danil Chapovalov33b01f22016-05-11 17:55:27508
[email protected]28e20752013-07-10 00:45:36509 bool CheckRtp1() {
Harald Alvestrand2f553702023-03-07 10:10:03510 return media_receive_channel1_impl()->CheckRtp(rtp_packet_.data(),
511 rtp_packet_.size());
[email protected]28e20752013-07-10 00:45:36512 }
513 bool CheckRtp2() {
Harald Alvestrand2f553702023-03-07 10:10:03514 return media_receive_channel2_impl()->CheckRtp(rtp_packet_.data(),
515 rtp_packet_.size());
[email protected]28e20752013-07-10 00:45:36516 }
[email protected]28e20752013-07-10 00:45:36517 // Methods to check custom data.
Peter Boström0c4e06b2015-10-07 10:23:21518 bool CheckCustomRtp1(uint32_t ssrc, int sequence_number, int pl_type = -1) {
Evan Shrubsolee6a1f702025-04-15 14:55:42519 webrtc::Buffer data = CreateRtpData(ssrc, sequence_number, pl_type);
Harald Alvestrand2f553702023-03-07 10:10:03520 return media_receive_channel1_impl()->CheckRtp(data.data(), data.size());
[email protected]28e20752013-07-10 00:45:36521 }
Peter Boström0c4e06b2015-10-07 10:23:21522 bool CheckCustomRtp2(uint32_t ssrc, int sequence_number, int pl_type = -1) {
Evan Shrubsolee6a1f702025-04-15 14:55:42523 webrtc::Buffer data = CreateRtpData(ssrc, sequence_number, pl_type);
Harald Alvestrand2f553702023-03-07 10:10:03524 return media_receive_channel2_impl()->CheckRtp(data.data(), data.size());
[email protected]28e20752013-07-10 00:45:36525 }
Evan Shrubsolee6a1f702025-04-15 14:55:42526 webrtc::Buffer CreateRtpData(uint32_t ssrc,
527 int sequence_number,
528 int pl_type) {
529 webrtc::Buffer data(rtp_packet_.data(), rtp_packet_.size());
[email protected]28e20752013-07-10 00:45:36530 // Set SSRC in the rtp packet copy.
Evan Shrubsole49ba3e22025-03-07 12:54:07531 webrtc::SetBE32(data.data() + 8, ssrc);
532 webrtc::SetBE16(data.data() + 2, sequence_number);
[email protected]5ee0f052014-05-05 20:18:08533 if (pl_type >= 0) {
Evan Shrubsole49ba3e22025-03-07 12:54:07534 webrtc::Set8(data.data(), 1, static_cast<uint8_t>(pl_type));
[email protected]5ee0f052014-05-05 20:18:08535 }
[email protected]28e20752013-07-10 00:45:36536 return data;
537 }
[email protected]28e20752013-07-10 00:45:36538
Harald Alvestrand2f553702023-03-07 10:10:03539 bool CheckNoRtp1() { return media_send_channel1_impl()->CheckNoRtp(); }
540 bool CheckNoRtp2() { return media_send_channel2_impl()->CheckNoRtp(); }
[email protected]28e20752013-07-10 00:45:36541
542 void CreateContent(int flags,
Evan Shrubsole0b212e32025-04-07 13:43:01543 const webrtc::Codec& audio_codec,
544 const webrtc::Codec& video_codec,
[email protected]28e20752013-07-10 00:45:36545 typename T::Content* content) {
546 // overridden in specialized classes
547 }
548 void CopyContent(const typename T::Content& source,
549 typename T::Content* content) {
550 // overridden in specialized classes
551 }
552
Steve Anton18ee1d52017-09-11 18:32:35553 // Creates a MediaContent with one stream.
[email protected]28e20752013-07-10 00:45:36554 // kPcmuCodec is used as audio codec and kH264Codec is used as video codec.
Steve Anton18ee1d52017-09-11 18:32:35555 typename T::Content* CreateMediaContentWithStream(uint32_t ssrc) {
556 typename T::Content* content = new typename T::Content();
Zhi Huange830e682018-03-30 17:48:35557 CreateContent(0, kPcmuCodec, kH264Codec, content);
Steve Anton18ee1d52017-09-11 18:32:35558 AddLegacyStreamInContent(ssrc, 0, content);
559 return content;
[email protected]28e20752013-07-10 00:45:36560 }
561
ossu292d6582016-03-17 09:31:13562 // Will manage the lifetime of a CallThread, making sure it's
563 // destroyed before this object goes out of scope.
564 class ScopedCallThread {
565 public:
Danil Chapovalova30439b2022-07-07 08:08:49566 explicit ScopedCallThread(absl::AnyInvocable<void() &&> functor)
Evan Shrubsole6a9a1ae2025-03-21 12:54:15567 : thread_(webrtc::Thread::Create()) {
ossu292d6582016-03-17 09:31:13568 thread_->Start();
Danil Chapovalova30439b2022-07-07 08:08:49569 thread_->PostTask(std::move(functor));
ossu292d6582016-03-17 09:31:13570 }
571
Danil Chapovalov33b01f22016-05-11 17:55:27572 ~ScopedCallThread() { thread_->Stop(); }
ossu292d6582016-03-17 09:31:13573
Evan Shrubsole6a9a1ae2025-03-21 12:54:15574 webrtc::Thread* thread() { return thread_.get(); }
ossu292d6582016-03-17 09:31:13575
576 private:
Evan Shrubsole6a9a1ae2025-03-21 12:54:15577 std::unique_ptr<webrtc::Thread> thread_;
ossu292d6582016-03-17 09:31:13578 };
[email protected]28e20752013-07-10 00:45:36579
Evan Shrubsole945e5172025-04-08 14:11:45580 webrtc::CandidatePairInterface* last_selected_candidate_pair() {
Honghai Zhangcc411c02016-03-30 00:27:21581 return last_selected_candidate_pair_;
582 }
583
Peter Boström0c4e06b2015-10-07 10:23:21584 void AddLegacyStreamInContent(uint32_t ssrc,
585 int flags,
586 typename T::Content* content) {
[email protected]28e20752013-07-10 00:45:36587 // Base implementation.
588 }
589
Tomas Gunnarsson6cd50812021-04-06 09:26:47590 // Utility method that calls BaseChannel::srtp_active() on the network thread
Artem Titov880fa812021-07-30 20:30:23591 // and returns the result. The `srtp_active()` state is maintained on the
Tomas Gunnarsson6cd50812021-04-06 09:26:47592 // network thread, which callers need to factor in.
593 bool IsSrtpActive(std::unique_ptr<typename T::Channel>& channel) {
594 RTC_DCHECK(channel.get());
Danil Chapovalov2aaef452022-08-12 13:55:11595 bool result;
596 SendTask(network_thread_, [&] { result = channel->srtp_active(); });
597 return result;
Tomas Gunnarsson6cd50812021-04-06 09:26:47598 }
599
600 // Returns true iff the transport is set for a channel and rtcp_mux_enabled()
601 // returns true.
602 bool IsRtcpMuxEnabled(std::unique_ptr<typename T::Channel>& channel) {
603 RTC_DCHECK(channel.get());
Danil Chapovalov2aaef452022-08-12 13:55:11604 bool result;
605 SendTask(network_thread_, [&] {
606 result = channel->rtp_transport() &&
607 channel->rtp_transport()->rtcp_mux_enabled();
Tomas Gunnarsson6cd50812021-04-06 09:26:47608 });
Danil Chapovalov2aaef452022-08-12 13:55:11609 return result;
Tomas Gunnarsson6cd50812021-04-06 09:26:47610 }
611
[email protected]28e20752013-07-10 00:45:36612 // Tests that can be used by derived classes.
613
614 // Basic sanity check.
615 void TestInit() {
616 CreateChannels(0, 0);
Tomas Gunnarsson6cd50812021-04-06 09:26:47617 EXPECT_FALSE(IsSrtpActive(channel1_));
Harald Alvestrand2f553702023-03-07 10:10:03618 EXPECT_FALSE(media_send_channel1_impl()->sending());
Peter Boström34fbfff2015-09-24 17:20:30619 if (verify_playout_) {
Harald Alvestrand2f553702023-03-07 10:10:03620 EXPECT_FALSE(media_receive_channel1_impl()->playout());
Peter Boström34fbfff2015-09-24 17:20:30621 }
Florent Castelli1f31c202023-06-26 00:26:07622 EXPECT_TRUE(media_send_channel1_impl()->send_codecs().empty());
Harald Alvestrand2f553702023-03-07 10:10:03623 EXPECT_TRUE(media_receive_channel1_impl()->recv_streams().empty());
624 EXPECT_TRUE(media_send_channel1_impl()->rtp_packets().empty());
Harald Alvestrand50454ef2022-12-15 16:49:13625 // Basic sanity test for send and receive channel objects
626 EXPECT_EQ(channel1_->media_send_channel()->media_type(),
Harald Alvestrand2f553702023-03-07 10:10:03627 media_send_channel1_impl()->media_type());
Harald Alvestrand50454ef2022-12-15 16:49:13628 EXPECT_EQ(channel1_->media_receive_channel()->media_type(),
Harald Alvestrand2f553702023-03-07 10:10:03629 media_receive_channel1_impl()->media_type());
630 EXPECT_EQ(channel1_->media_send_channel()->media_type(),
631 channel1_->media_receive_channel()->media_type());
[email protected]28e20752013-07-10 00:45:36632 }
633
634 // Test that SetLocalContent and SetRemoteContent properly configure
635 // the codecs.
636 void TestSetContents() {
637 CreateChannels(0, 0);
638 typename T::Content content;
639 CreateContent(0, kPcmuCodec, kH264Codec, &content);
Tomas Gunnarssond908d742022-01-05 10:44:26640 std::string err;
641 EXPECT_TRUE(channel1_->SetLocalContent(&content, SdpType::kOffer, err));
Florent Castelli1f31c202023-06-26 00:26:07642 EXPECT_EQ(0U, media_send_channel1_impl()->send_codecs().size());
Tomas Gunnarssond908d742022-01-05 10:44:26643 EXPECT_TRUE(channel1_->SetRemoteContent(&content, SdpType::kAnswer, err));
Florent Castelli1f31c202023-06-26 00:26:07644 ASSERT_EQ(1U, media_send_channel1_impl()->send_codecs().size());
Philipp Hanckeb5276992023-10-18 07:23:55645 EXPECT_EQ(content.codecs()[0],
646 media_send_channel1_impl()->send_codecs()[0]);
[email protected]28e20752013-07-10 00:45:36647 }
648
Per K38bb3312025-08-19 13:46:24649 void TestRemovesExtensionNotPresentInRemoteAnswer() {
650 typename T::Content local;
651 typename T::Content remote;
652 CreateContent(/*flags=*/0, kPcmuCodec, kH264Codec, &local);
653 CreateContent(/*flags=*/0, kPcmuCodec, kH264Codec, &remote);
654 local.set_rtp_header_extensions({
655 RtpExtension(RtpExtension::kTransportSequenceNumberUri, 0),
656 RtpExtension(RtpExtension::kVideoRotationUri, 1),
657 });
658 remote.set_rtp_header_extensions({
659 RtpExtension(RtpExtension::kVideoRotationUri, 1),
660 });
661
662 CreateChannels(0, 0);
663 std::string err;
664 ASSERT_TRUE(channel1_->SetLocalContent(&local, SdpType::kOffer, err))
665 << err;
666 ASSERT_TRUE(channel1_->SetRemoteContent(&remote, SdpType::kAnswer, err))
667 << err;
668
669 EXPECT_THAT(media_receive_channel1_impl()->recv_extensions(),
670 ElementsAre(AllOf(Field("id", &RtpExtension::id, 1),
671 Field("uri", &RtpExtension::uri,
672 RtpExtension::kVideoRotationUri))));
673 EXPECT_THAT(media_send_channel1_impl()->send_extensions(),
674 ElementsAre(AllOf(Field("id", &RtpExtension::id, 1),
675 Field("uri", &RtpExtension::uri,
676 RtpExtension::kVideoRotationUri))));
677 }
678 void TestRemovesExtensionNotPresentInLocalAnswer() {
679 typename T::Content local;
680 typename T::Content remote;
681 CreateContent(/*flags=*/0, kPcmuCodec, kH264Codec, &local);
682 CreateContent(/*flags=*/0, kPcmuCodec, kH264Codec, &remote);
683 local.set_rtp_header_extensions({
684 RtpExtension(RtpExtension::kVideoRotationUri, 1),
685 });
686 remote.set_rtp_header_extensions({
687 RtpExtension(RtpExtension::kTransportSequenceNumberUri, 0),
688 RtpExtension(RtpExtension::kVideoRotationUri, 1),
689 });
690
691 CreateChannels(0, 0);
692 std::string err;
693 ASSERT_TRUE(channel1_->SetRemoteContent(&remote, SdpType::kOffer, err))
694 << err;
695 ASSERT_TRUE(channel1_->SetLocalContent(&local, SdpType::kAnswer, err))
696 << err;
697
698 EXPECT_THAT(media_receive_channel1_impl()->recv_extensions(),
699 ElementsAre(AllOf(Field("id", &RtpExtension::id, 1),
700 Field("uri", &RtpExtension::uri,
701 RtpExtension::kVideoRotationUri))));
702 EXPECT_THAT(media_send_channel1_impl()->send_extensions(),
703 ElementsAre(AllOf(Field("id", &RtpExtension::id, 1),
704 Field("uri", &RtpExtension::uri,
705 RtpExtension::kVideoRotationUri))));
706 }
707
Johannes Kron9190b822018-10-29 10:22:05708 // Test that SetLocalContent and SetRemoteContent properly configure
709 // extmap-allow-mixed.
710 void TestSetContentsExtmapAllowMixedCaller(bool offer, bool answer) {
711 // For a caller, SetLocalContent() is called first with an offer and next
712 // SetRemoteContent() is called with the answer.
713 CreateChannels(0, 0);
714 typename T::Content content;
715 CreateContent(0, kPcmuCodec, kH264Codec, &content);
716 auto offer_enum = offer ? (T::Content::kSession) : (T::Content::kNo);
717 auto answer_enum = answer ? (T::Content::kSession) : (T::Content::kNo);
718 content.set_extmap_allow_mixed_enum(offer_enum);
Tomas Gunnarssond908d742022-01-05 10:44:26719 std::string err;
720 EXPECT_TRUE(channel1_->SetLocalContent(&content, SdpType::kOffer, err));
Johannes Kron9190b822018-10-29 10:22:05721 content.set_extmap_allow_mixed_enum(answer_enum);
Tomas Gunnarssond908d742022-01-05 10:44:26722 EXPECT_TRUE(channel1_->SetRemoteContent(&content, SdpType::kAnswer, err));
Harald Alvestrand2f553702023-03-07 10:10:03723 EXPECT_EQ(answer, media_send_channel1_impl()->ExtmapAllowMixed());
Johannes Kron9190b822018-10-29 10:22:05724 }
725 void TestSetContentsExtmapAllowMixedCallee(bool offer, bool answer) {
726 // For a callee, SetRemoteContent() is called first with an offer and next
727 // SetLocalContent() is called with the answer.
728 CreateChannels(0, 0);
729 typename T::Content content;
730 CreateContent(0, kPcmuCodec, kH264Codec, &content);
731 auto offer_enum = offer ? (T::Content::kSession) : (T::Content::kNo);
732 auto answer_enum = answer ? (T::Content::kSession) : (T::Content::kNo);
733 content.set_extmap_allow_mixed_enum(offer_enum);
Tomas Gunnarssond908d742022-01-05 10:44:26734 std::string err;
735 EXPECT_TRUE(channel1_->SetRemoteContent(&content, SdpType::kOffer, err));
Johannes Kron9190b822018-10-29 10:22:05736 content.set_extmap_allow_mixed_enum(answer_enum);
Tomas Gunnarssond908d742022-01-05 10:44:26737 EXPECT_TRUE(channel1_->SetLocalContent(&content, SdpType::kAnswer, err));
Harald Alvestrand36fafc82022-12-08 08:47:42738 EXPECT_EQ(answer, media_send_channel1()->ExtmapAllowMixed());
Johannes Kron9190b822018-10-29 10:22:05739 }
740
[email protected]28e20752013-07-10 00:45:36741 // Test that SetLocalContent and SetRemoteContent properly deals
742 // with an empty offer.
743 void TestSetContentsNullOffer() {
744 CreateChannels(0, 0);
745 typename T::Content content;
Tomas Gunnarssond908d742022-01-05 10:44:26746 std::string err;
747 EXPECT_TRUE(channel1_->SetLocalContent(&content, SdpType::kOffer, err));
[email protected]28e20752013-07-10 00:45:36748 CreateContent(0, kPcmuCodec, kH264Codec, &content);
Florent Castelli1f31c202023-06-26 00:26:07749 EXPECT_EQ(0U, media_send_channel1_impl()->send_codecs().size());
Tomas Gunnarssond908d742022-01-05 10:44:26750 EXPECT_TRUE(channel1_->SetRemoteContent(&content, SdpType::kAnswer, err));
Florent Castelli1f31c202023-06-26 00:26:07751 ASSERT_EQ(1U, media_send_channel1_impl()->send_codecs().size());
Philipp Hanckeb5276992023-10-18 07:23:55752 EXPECT_EQ(content.codecs()[0],
753 media_send_channel1_impl()->send_codecs()[0]);
[email protected]28e20752013-07-10 00:45:36754 }
755
756 // Test that SetLocalContent and SetRemoteContent properly set RTCP
757 // mux.
758 void TestSetContentsRtcpMux() {
deadbeefac22f702017-01-13 05:59:29759 CreateChannels(0, 0);
[email protected]28e20752013-07-10 00:45:36760 typename T::Content content;
761 CreateContent(0, kPcmuCodec, kH264Codec, &content);
762 // Both sides agree on mux. Should no longer be a separate RTCP channel.
763 content.set_rtcp_mux(true);
Tomas Gunnarssond908d742022-01-05 10:44:26764 std::string err;
765 EXPECT_TRUE(channel1_->SetLocalContent(&content, SdpType::kOffer, err));
766 EXPECT_TRUE(channel1_->SetRemoteContent(&content, SdpType::kAnswer, err));
[email protected]28e20752013-07-10 00:45:36767 // Only initiator supports mux. Should still have a separate RTCP channel.
Tomas Gunnarssond908d742022-01-05 10:44:26768 EXPECT_TRUE(channel2_->SetLocalContent(&content, SdpType::kOffer, err));
[email protected]28e20752013-07-10 00:45:36769 content.set_rtcp_mux(false);
Tomas Gunnarssond908d742022-01-05 10:44:26770 EXPECT_TRUE(channel2_->SetRemoteContent(&content, SdpType::kAnswer, err));
[email protected]28e20752013-07-10 00:45:36771 }
772
Tomas Lundqvistb40c5592024-11-22 13:45:27773 // Test that SetLocalContent and SetRemoteContent properly set RTCP
774 // reduced_size.
775 void TestSetContentsRtcpReducedSize() {
776 CreateChannels(0, 0);
777 typename T::Content content;
778 CreateContent(0, kPcmuCodec, kH264Codec, &content);
779 // Both sides agree on reduced size.
780 content.set_rtcp_reduced_size(true);
781 std::string err;
782 // The RTCP mode is a send property and should be configured based on
783 // the remote content and not the local content.
784 EXPECT_TRUE(channel1_->SetLocalContent(&content, SdpType::kOffer, err));
785 EXPECT_EQ(media_receive_channel1_impl()->RtcpMode(),
786 webrtc::RtcpMode::kCompound);
787 EXPECT_TRUE(channel1_->SetRemoteContent(&content, SdpType::kAnswer, err));
788 EXPECT_EQ(media_receive_channel1_impl()->RtcpMode(),
789 webrtc::RtcpMode::kReducedSize);
790 // Only initiator supports reduced size.
791 EXPECT_TRUE(channel2_->SetLocalContent(&content, SdpType::kOffer, err));
792 EXPECT_EQ(media_receive_channel2_impl()->RtcpMode(),
793 webrtc::RtcpMode::kCompound);
794 content.set_rtcp_reduced_size(false);
795 EXPECT_TRUE(channel2_->SetRemoteContent(&content, SdpType::kAnswer, err));
796 EXPECT_EQ(media_receive_channel2_impl()->RtcpMode(),
797 webrtc::RtcpMode::kCompound);
798 // Peer renegotiates without reduced size.
799 EXPECT_TRUE(channel1_->SetRemoteContent(&content, SdpType::kAnswer, err));
800 EXPECT_EQ(media_receive_channel1_impl()->RtcpMode(),
801 webrtc::RtcpMode::kCompound);
802 }
803
[email protected]28e20752013-07-10 00:45:36804 // Test that SetLocalContent and SetRemoteContent properly
805 // handles adding and removing StreamParams when the action is a full
Steve Anton3828c062017-12-06 18:34:51806 // SdpType::kOffer / SdpType::kAnswer.
[email protected]28e20752013-07-10 00:45:36807 void TestChangeStreamParamsInContent() {
Evan Shrubsole945e5172025-04-08 14:11:45808 webrtc::StreamParams stream1;
[email protected]28e20752013-07-10 00:45:36809 stream1.id = "stream1";
810 stream1.ssrcs.push_back(kSsrc1);
811 stream1.cname = "stream1_cname";
812
Evan Shrubsole945e5172025-04-08 14:11:45813 webrtc::StreamParams stream2;
[email protected]28e20752013-07-10 00:45:36814 stream2.id = "stream2";
815 stream2.ssrcs.push_back(kSsrc2);
816 stream2.cname = "stream2_cname";
817
Artem Titov880fa812021-07-30 20:30:23818 // Setup a call where channel 1 send `stream1` to channel 2.
[email protected]28e20752013-07-10 00:45:36819 CreateChannels(0, 0);
820 typename T::Content content1;
821 CreateContent(0, kPcmuCodec, kH264Codec, &content1);
822 content1.AddStream(stream1);
Tomas Gunnarssond908d742022-01-05 10:44:26823 std::string err;
824 EXPECT_TRUE(channel1_->SetLocalContent(&content1, SdpType::kOffer, err));
Tommi1959f8f2021-04-26 08:20:19825 channel1_->Enable(true);
Harald Alvestrand2f553702023-03-07 10:10:03826 EXPECT_EQ(1u, media_send_channel1_impl()->send_streams().size());
[email protected]28e20752013-07-10 00:45:36827
Tomas Gunnarssond908d742022-01-05 10:44:26828 EXPECT_TRUE(channel2_->SetRemoteContent(&content1, SdpType::kOffer, err));
Harald Alvestrand2f553702023-03-07 10:10:03829 EXPECT_EQ(1u, media_receive_channel2_impl()->recv_streams().size());
deadbeeff5346592017-01-25 05:51:21830 ConnectFakeTransports();
[email protected]28e20752013-07-10 00:45:36831
832 // Channel 2 do not send anything.
833 typename T::Content content2;
834 CreateContent(0, kPcmuCodec, kH264Codec, &content2);
Tomas Gunnarssond908d742022-01-05 10:44:26835 EXPECT_TRUE(channel1_->SetRemoteContent(&content2, SdpType::kAnswer, err));
Harald Alvestrand2f553702023-03-07 10:10:03836 EXPECT_EQ(0u, media_receive_channel1_impl()->recv_streams().size());
Tomas Gunnarssond908d742022-01-05 10:44:26837 EXPECT_TRUE(channel2_->SetLocalContent(&content2, SdpType::kAnswer, err));
Tommi1959f8f2021-04-26 08:20:19838 channel2_->Enable(true);
Harald Alvestrand2f553702023-03-07 10:10:03839 EXPECT_EQ(0u, media_send_channel2_impl()->send_streams().size());
[email protected]28e20752013-07-10 00:45:36840
Danil Chapovalov33b01f22016-05-11 17:55:27841 SendCustomRtp1(kSsrc1, 0);
842 WaitForThreads();
[email protected]28e20752013-07-10 00:45:36843 EXPECT_TRUE(CheckCustomRtp2(kSsrc1, 0));
844
Artem Titov880fa812021-07-30 20:30:23845 // Let channel 2 update the content by sending `stream2` and enable SRTP.
[email protected]28e20752013-07-10 00:45:36846 typename T::Content content3;
Zhi Huange830e682018-03-30 17:48:35847 CreateContent(0, kPcmuCodec, kH264Codec, &content3);
[email protected]28e20752013-07-10 00:45:36848 content3.AddStream(stream2);
Tomas Gunnarssond908d742022-01-05 10:44:26849 EXPECT_TRUE(channel2_->SetLocalContent(&content3, SdpType::kOffer, err));
Harald Alvestrand2f553702023-03-07 10:10:03850 ASSERT_EQ(1u, media_send_channel2_impl()->send_streams().size());
851 EXPECT_EQ(stream2, media_send_channel2_impl()->send_streams()[0]);
[email protected]28e20752013-07-10 00:45:36852
Tomas Gunnarssond908d742022-01-05 10:44:26853 EXPECT_TRUE(channel1_->SetRemoteContent(&content3, SdpType::kOffer, err));
Harald Alvestrand2f553702023-03-07 10:10:03854 ASSERT_EQ(1u, media_receive_channel1_impl()->recv_streams().size());
855 EXPECT_EQ(stream2, media_receive_channel1_impl()->recv_streams()[0]);
[email protected]28e20752013-07-10 00:45:36856
857 // Channel 1 replies but stop sending stream1.
858 typename T::Content content4;
Zhi Huange830e682018-03-30 17:48:35859 CreateContent(0, kPcmuCodec, kH264Codec, &content4);
Tomas Gunnarssond908d742022-01-05 10:44:26860 EXPECT_TRUE(channel1_->SetLocalContent(&content4, SdpType::kAnswer, err));
Harald Alvestrand2f553702023-03-07 10:10:03861 EXPECT_EQ(0u, media_send_channel1_impl()->send_streams().size());
[email protected]28e20752013-07-10 00:45:36862
Tomas Gunnarssond908d742022-01-05 10:44:26863 EXPECT_TRUE(channel2_->SetRemoteContent(&content4, SdpType::kAnswer, err));
Harald Alvestrand2f553702023-03-07 10:10:03864 EXPECT_EQ(0u, media_receive_channel2_impl()->recv_streams().size());
[email protected]28e20752013-07-10 00:45:36865
Danil Chapovalov33b01f22016-05-11 17:55:27866 SendCustomRtp2(kSsrc2, 0);
867 WaitForThreads();
[email protected]28e20752013-07-10 00:45:36868 EXPECT_TRUE(CheckCustomRtp1(kSsrc2, 0));
869 }
870
871 // Test that we only start playout and sending at the right times.
872 void TestPlayoutAndSendingStates() {
873 CreateChannels(0, 0);
Peter Boström34fbfff2015-09-24 17:20:30874 if (verify_playout_) {
Harald Alvestrand2f553702023-03-07 10:10:03875 EXPECT_FALSE(media_receive_channel1_impl()->playout());
Peter Boström34fbfff2015-09-24 17:20:30876 }
Harald Alvestrand2f553702023-03-07 10:10:03877 EXPECT_FALSE(media_send_channel1_impl()->sending());
Peter Boström34fbfff2015-09-24 17:20:30878 if (verify_playout_) {
Harald Alvestrand2f553702023-03-07 10:10:03879 EXPECT_FALSE(media_receive_channel2_impl()->playout());
Peter Boström34fbfff2015-09-24 17:20:30880 }
Harald Alvestrand2f553702023-03-07 10:10:03881 EXPECT_FALSE(media_send_channel2_impl()->sending());
Tommi1959f8f2021-04-26 08:20:19882 channel1_->Enable(true);
883 FlushCurrentThread();
Peter Boström34fbfff2015-09-24 17:20:30884 if (verify_playout_) {
Harald Alvestrand2f553702023-03-07 10:10:03885 EXPECT_FALSE(media_receive_channel1_impl()->playout());
Peter Boström34fbfff2015-09-24 17:20:30886 }
Harald Alvestrand2f553702023-03-07 10:10:03887 EXPECT_FALSE(media_send_channel1_impl()->sending());
Tomas Gunnarssond908d742022-01-05 10:44:26888 std::string err;
[email protected]4b26e2e2014-01-15 23:15:54889 EXPECT_TRUE(channel1_->SetLocalContent(&local_media_content1_,
Tomas Gunnarssond908d742022-01-05 10:44:26890 SdpType::kOffer, err));
Peter Boström34fbfff2015-09-24 17:20:30891 if (verify_playout_) {
Harald Alvestrand2f553702023-03-07 10:10:03892 EXPECT_TRUE(media_receive_channel1_impl()->playout());
Peter Boström34fbfff2015-09-24 17:20:30893 }
Harald Alvestrand2f553702023-03-07 10:10:03894 EXPECT_FALSE(media_send_channel1_impl()->sending());
[email protected]4b26e2e2014-01-15 23:15:54895 EXPECT_TRUE(channel2_->SetRemoteContent(&local_media_content1_,
Tomas Gunnarssond908d742022-01-05 10:44:26896 SdpType::kOffer, err));
Peter Boström34fbfff2015-09-24 17:20:30897 if (verify_playout_) {
Harald Alvestrand2f553702023-03-07 10:10:03898 EXPECT_FALSE(media_receive_channel2_impl()->playout());
Peter Boström34fbfff2015-09-24 17:20:30899 }
Harald Alvestrand2f553702023-03-07 10:10:03900 EXPECT_FALSE(media_send_channel2_impl()->sending());
[email protected]4b26e2e2014-01-15 23:15:54901 EXPECT_TRUE(channel2_->SetLocalContent(&local_media_content2_,
Tomas Gunnarssond908d742022-01-05 10:44:26902 SdpType::kAnswer, err));
Peter Boström34fbfff2015-09-24 17:20:30903 if (verify_playout_) {
Harald Alvestrand2f553702023-03-07 10:10:03904 EXPECT_FALSE(media_receive_channel2_impl()->playout());
Peter Boström34fbfff2015-09-24 17:20:30905 }
Harald Alvestrand2f553702023-03-07 10:10:03906 EXPECT_FALSE(media_send_channel2_impl()->sending());
deadbeeff5346592017-01-25 05:51:21907 ConnectFakeTransports();
Peter Boström34fbfff2015-09-24 17:20:30908 if (verify_playout_) {
Harald Alvestrand2f553702023-03-07 10:10:03909 EXPECT_TRUE(media_receive_channel1_impl()->playout());
Peter Boström34fbfff2015-09-24 17:20:30910 }
Harald Alvestrand2f553702023-03-07 10:10:03911 EXPECT_FALSE(media_send_channel1_impl()->sending());
Peter Boström34fbfff2015-09-24 17:20:30912 if (verify_playout_) {
Harald Alvestrand2f553702023-03-07 10:10:03913 EXPECT_FALSE(media_receive_channel2_impl()->playout());
Peter Boström34fbfff2015-09-24 17:20:30914 }
Harald Alvestrand2f553702023-03-07 10:10:03915 EXPECT_FALSE(media_send_channel2_impl()->sending());
Tommi1959f8f2021-04-26 08:20:19916 channel2_->Enable(true);
917 FlushCurrentThread();
Peter Boström34fbfff2015-09-24 17:20:30918 if (verify_playout_) {
Harald Alvestrand2f553702023-03-07 10:10:03919 EXPECT_TRUE(media_receive_channel2_impl()->playout());
Peter Boström34fbfff2015-09-24 17:20:30920 }
Harald Alvestrand2f553702023-03-07 10:10:03921 EXPECT_TRUE(media_send_channel2_impl()->sending());
[email protected]4b26e2e2014-01-15 23:15:54922 EXPECT_TRUE(channel1_->SetRemoteContent(&local_media_content2_,
Tomas Gunnarssond908d742022-01-05 10:44:26923 SdpType::kAnswer, err));
Peter Boström34fbfff2015-09-24 17:20:30924 if (verify_playout_) {
Harald Alvestrand2f553702023-03-07 10:10:03925 EXPECT_TRUE(media_receive_channel1_impl()->playout());
Peter Boström34fbfff2015-09-24 17:20:30926 }
Harald Alvestrand2f553702023-03-07 10:10:03927 EXPECT_TRUE(media_send_channel1_impl()->sending());
[email protected]28e20752013-07-10 00:45:36928 }
929
[email protected]28e20752013-07-10 00:45:36930 // Test that changing the MediaContentDirection in the local and remote
931 // session description start playout and sending at the right time.
932 void TestMediaContentDirection() {
933 CreateChannels(0, 0);
934 typename T::Content content1;
935 CreateContent(0, kPcmuCodec, kH264Codec, &content1);
936 typename T::Content content2;
937 CreateContent(0, kPcmuCodec, kH264Codec, &content2);
Artem Titov880fa812021-07-30 20:30:23938 // Set `content2` to be InActive.
Steve Anton4e70a722017-11-28 22:57:10939 content2.set_direction(RtpTransceiverDirection::kInactive);
[email protected]28e20752013-07-10 00:45:36940
Tommi1959f8f2021-04-26 08:20:19941 channel1_->Enable(true);
942 channel2_->Enable(true);
943 FlushCurrentThread();
Peter Boström34fbfff2015-09-24 17:20:30944 if (verify_playout_) {
Harald Alvestrand2f553702023-03-07 10:10:03945 EXPECT_FALSE(media_receive_channel1_impl()->playout());
Peter Boström34fbfff2015-09-24 17:20:30946 }
Harald Alvestrand2f553702023-03-07 10:10:03947 EXPECT_FALSE(media_send_channel1_impl()->sending());
Peter Boström34fbfff2015-09-24 17:20:30948 if (verify_playout_) {
Harald Alvestrand2f553702023-03-07 10:10:03949 EXPECT_FALSE(media_receive_channel2_impl()->playout());
Peter Boström34fbfff2015-09-24 17:20:30950 }
Harald Alvestrand2f553702023-03-07 10:10:03951 EXPECT_FALSE(media_send_channel2_impl()->sending());
[email protected]28e20752013-07-10 00:45:36952
Tomas Gunnarssond908d742022-01-05 10:44:26953 std::string err;
954 EXPECT_TRUE(channel1_->SetLocalContent(&content1, SdpType::kOffer, err));
955 EXPECT_TRUE(channel2_->SetRemoteContent(&content1, SdpType::kOffer, err));
956 EXPECT_TRUE(channel2_->SetLocalContent(&content2, SdpType::kPrAnswer, err));
Steve Anton3828c062017-12-06 18:34:51957 EXPECT_TRUE(
Tomas Gunnarssond908d742022-01-05 10:44:26958 channel1_->SetRemoteContent(&content2, SdpType::kPrAnswer, err));
deadbeeff5346592017-01-25 05:51:21959 ConnectFakeTransports();
[email protected]28e20752013-07-10 00:45:36960
Peter Boström34fbfff2015-09-24 17:20:30961 if (verify_playout_) {
Harald Alvestrand2f553702023-03-07 10:10:03962 EXPECT_TRUE(media_receive_channel1_impl()->playout());
Peter Boström34fbfff2015-09-24 17:20:30963 }
Harald Alvestrand2f553702023-03-07 10:10:03964 EXPECT_FALSE(media_send_channel1_impl()->sending()); // remote InActive
Peter Boström34fbfff2015-09-24 17:20:30965 if (verify_playout_) {
Harald Alvestrand2f553702023-03-07 10:10:03966 EXPECT_FALSE(media_receive_channel2_impl()->playout()); // local InActive
Peter Boström34fbfff2015-09-24 17:20:30967 }
Harald Alvestrand2f553702023-03-07 10:10:03968 EXPECT_FALSE(media_send_channel2_impl()->sending()); // local InActive
[email protected]28e20752013-07-10 00:45:36969
Artem Titov880fa812021-07-30 20:30:23970 // Update `content2` to be RecvOnly.
Steve Anton4e70a722017-11-28 22:57:10971 content2.set_direction(RtpTransceiverDirection::kRecvOnly);
Tomas Gunnarssond908d742022-01-05 10:44:26972 EXPECT_TRUE(channel2_->SetLocalContent(&content2, SdpType::kPrAnswer, err));
Steve Anton3828c062017-12-06 18:34:51973 EXPECT_TRUE(
Tomas Gunnarssond908d742022-01-05 10:44:26974 channel1_->SetRemoteContent(&content2, SdpType::kPrAnswer, err));
[email protected]28e20752013-07-10 00:45:36975
Peter Boström34fbfff2015-09-24 17:20:30976 if (verify_playout_) {
Harald Alvestrand2f553702023-03-07 10:10:03977 EXPECT_TRUE(media_receive_channel1_impl()->playout());
Peter Boström34fbfff2015-09-24 17:20:30978 }
Harald Alvestrand2f553702023-03-07 10:10:03979 EXPECT_TRUE(media_send_channel1_impl()->sending());
Peter Boström34fbfff2015-09-24 17:20:30980 if (verify_playout_) {
Harald Alvestrand2f553702023-03-07 10:10:03981 EXPECT_TRUE(media_receive_channel2_impl()->playout()); // local RecvOnly
Peter Boström34fbfff2015-09-24 17:20:30982 }
Harald Alvestrand2f553702023-03-07 10:10:03983 EXPECT_FALSE(media_send_channel2_impl()->sending()); // local RecvOnly
[email protected]28e20752013-07-10 00:45:36984
Artem Titov880fa812021-07-30 20:30:23985 // Update `content2` to be SendRecv.
Steve Anton4e70a722017-11-28 22:57:10986 content2.set_direction(RtpTransceiverDirection::kSendRecv);
Tomas Gunnarssond908d742022-01-05 10:44:26987 EXPECT_TRUE(channel2_->SetLocalContent(&content2, SdpType::kAnswer, err));
988 EXPECT_TRUE(channel1_->SetRemoteContent(&content2, SdpType::kAnswer, err));
[email protected]28e20752013-07-10 00:45:36989
Peter Boström34fbfff2015-09-24 17:20:30990 if (verify_playout_) {
Harald Alvestrand2f553702023-03-07 10:10:03991 EXPECT_TRUE(media_receive_channel1_impl()->playout());
Peter Boström34fbfff2015-09-24 17:20:30992 }
Harald Alvestrand2f553702023-03-07 10:10:03993 EXPECT_TRUE(media_send_channel1_impl()->sending());
Peter Boström34fbfff2015-09-24 17:20:30994 if (verify_playout_) {
Harald Alvestrand2f553702023-03-07 10:10:03995 EXPECT_TRUE(media_receive_channel2_impl()->playout());
Peter Boström34fbfff2015-09-24 17:20:30996 }
Harald Alvestrand2f553702023-03-07 10:10:03997 EXPECT_TRUE(media_send_channel2_impl()->sending());
Philipp Hancke79249152023-05-11 16:13:34998
999 // Update `content2` to be inactive on the receiver while sending at the
1000 // sender.
1001 content2.set_direction(RtpTransceiverDirection::kInactive);
1002 EXPECT_TRUE(channel1_->SetLocalContent(&content1, SdpType::kOffer, err));
1003 EXPECT_TRUE(channel2_->SetRemoteContent(&content1, SdpType::kOffer, err));
1004 EXPECT_TRUE(channel2_->SetLocalContent(&content2, SdpType::kAnswer, err));
1005 content2.set_direction(RtpTransceiverDirection::kRecvOnly);
1006 EXPECT_TRUE(channel1_->SetRemoteContent(&content2, SdpType::kAnswer, err));
1007 if (verify_playout_) {
1008 EXPECT_FALSE(media_receive_channel2_impl()->playout());
1009 }
1010 EXPECT_TRUE(media_send_channel1_impl()->sending());
1011
1012 // Re-enable `content2`.
1013 content2.set_direction(RtpTransceiverDirection::kSendRecv);
1014 EXPECT_TRUE(channel1_->SetLocalContent(&content1, SdpType::kOffer, err));
1015 EXPECT_TRUE(channel2_->SetRemoteContent(&content1, SdpType::kOffer, err));
1016 EXPECT_TRUE(channel2_->SetLocalContent(&content2, SdpType::kAnswer, err));
1017 EXPECT_TRUE(channel1_->SetRemoteContent(&content2, SdpType::kAnswer, err));
1018 if (verify_playout_) {
1019 EXPECT_TRUE(media_receive_channel2_impl()->playout());
1020 }
1021 EXPECT_TRUE(media_send_channel1_impl()->sending());
[email protected]28e20752013-07-10 00:45:361022 }
1023
Honghai Zhangcc411c02016-03-30 00:27:211024 // Tests that when the transport channel signals a candidate pair change
1025 // event, the media channel will receive a call on the network route change.
1026 void TestNetworkRouteChanges() {
eladalon05b07bb2017-08-24 14:40:161027 static constexpr uint16_t kLocalNetId = 1;
1028 static constexpr uint16_t kRemoteNetId = 2;
1029 static constexpr int kLastPacketId = 100;
Zhi Huang942bc2e2017-11-13 21:26:071030 // Ipv4(20) + UDP(8).
1031 static constexpr int kTransportOverheadPerPacket = 28;
Zhi Huangcf6e24a2018-02-21 18:40:071032 static constexpr int kSrtpOverheadPerPacket = 10;
Danil Chapovalov33b01f22016-05-11 17:55:271033
Zhi Huangcf6e24a2018-02-21 18:40:071034 CreateChannels(DTLS, DTLS);
1035 SendInitiate();
Honghai Zhangcc411c02016-03-30 00:27:211036
Florent Castelli1f31c202023-06-26 00:26:071037 typename T::MediaSendChannel* media_send_channel1_impl =
Harald Alvestrand2f553702023-03-07 10:10:031038 this->media_send_channel1_impl();
1039 ASSERT_TRUE(media_send_channel1_impl);
Honghai Zhangcc411c02016-03-30 00:27:211040
Zhi Huang942bc2e2017-11-13 21:26:071041 // Need to wait for the threads before calling
Artem Titov880fa812021-07-30 20:30:231042 // `set_num_network_route_changes` because the network route would be set
Zhi Huang942bc2e2017-11-13 21:26:071043 // when creating the channel.
1044 WaitForThreads();
Harald Alvestrand2f553702023-03-07 10:10:031045 media_send_channel1_impl->set_num_network_route_changes(0);
Danil Chapovalov2aaef452022-08-12 13:55:111046 SendTask(network_thread_, [this] {
Evan Shrubsoledaf96cf2025-03-31 12:34:021047 webrtc::NetworkRoute network_route;
Danil Chapovalov33b01f22016-05-11 17:55:271048 // The transport channel becomes disconnected.
Lena Kaplan83b0eaa2025-09-15 16:53:391049 fake_rtp_dtls_transport1_->ice_transport()->NotifyNetworkRouteChanged(
Evan Shrubsoledaf96cf2025-03-31 12:34:021050 std::optional<webrtc::NetworkRoute>(network_route));
Danil Chapovalov33b01f22016-05-11 17:55:271051 });
1052 WaitForThreads();
Harald Alvestrand2f553702023-03-07 10:10:031053 EXPECT_EQ(1, media_send_channel1_impl->num_network_route_changes());
1054 EXPECT_FALSE(media_send_channel1_impl->last_network_route().connected);
1055 media_send_channel1_impl->set_num_network_route_changes(0);
Honghai Zhangcc411c02016-03-30 00:27:211056
Danil Chapovalov2aaef452022-08-12 13:55:111057 SendTask(network_thread_, [this] {
Evan Shrubsoledaf96cf2025-03-31 12:34:021058 webrtc::NetworkRoute network_route;
Zhi Huang942bc2e2017-11-13 21:26:071059 network_route.connected = true;
Jonas Oreland71fda362020-03-20 15:11:561060 network_route.local =
Evan Shrubsoledaf96cf2025-03-31 12:34:021061 webrtc::RouteEndpoint::CreateWithNetworkId(kLocalNetId);
Jonas Oreland71fda362020-03-20 15:11:561062 network_route.remote =
Evan Shrubsoledaf96cf2025-03-31 12:34:021063 webrtc::RouteEndpoint::CreateWithNetworkId(kRemoteNetId);
Zhi Huang942bc2e2017-11-13 21:26:071064 network_route.last_sent_packet_id = kLastPacketId;
1065 network_route.packet_overhead = kTransportOverheadPerPacket;
Danil Chapovalov33b01f22016-05-11 17:55:271066 // The transport channel becomes connected.
Lena Kaplan83b0eaa2025-09-15 16:53:391067 fake_rtp_dtls_transport1_->ice_transport()->NotifyNetworkRouteChanged(
Zhi Huang942bc2e2017-11-13 21:26:071068
Evan Shrubsoledaf96cf2025-03-31 12:34:021069 std::optional<webrtc::NetworkRoute>(network_route));
Danil Chapovalov33b01f22016-05-11 17:55:271070 });
1071 WaitForThreads();
Harald Alvestrand2f553702023-03-07 10:10:031072 EXPECT_EQ(1, media_send_channel1_impl->num_network_route_changes());
1073 EXPECT_TRUE(media_send_channel1_impl->last_network_route().connected);
1074 EXPECT_EQ(
1075 kLocalNetId,
1076 media_send_channel1_impl->last_network_route().local.network_id());
1077 EXPECT_EQ(
1078 kRemoteNetId,
1079 media_send_channel1_impl->last_network_route().remote.network_id());
1080 EXPECT_EQ(
1081 kLastPacketId,
1082 media_send_channel1_impl->last_network_route().last_sent_packet_id);
Zhi Huangcf6e24a2018-02-21 18:40:071083 EXPECT_EQ(kTransportOverheadPerPacket + kSrtpOverheadPerPacket,
Harald Alvestrand2f553702023-03-07 10:10:031084 media_send_channel1_impl->transport_overhead_per_packet());
Honghai Zhangcc411c02016-03-30 00:27:211085 }
1086
[email protected]28e20752013-07-10 00:45:361087 // Test setting up a call.
1088 void TestCallSetup() {
1089 CreateChannels(0, 0);
Tomas Gunnarsson6cd50812021-04-06 09:26:471090 EXPECT_FALSE(IsSrtpActive(channel1_));
[email protected]28e20752013-07-10 00:45:361091 EXPECT_TRUE(SendInitiate());
Peter Boström34fbfff2015-09-24 17:20:301092 if (verify_playout_) {
Harald Alvestrand2f553702023-03-07 10:10:031093 EXPECT_TRUE(media_receive_channel1_impl()->playout());
Peter Boström34fbfff2015-09-24 17:20:301094 }
Harald Alvestrand2f553702023-03-07 10:10:031095 EXPECT_FALSE(media_send_channel1_impl()->sending());
[email protected]28e20752013-07-10 00:45:361096 EXPECT_TRUE(SendAccept());
Tomas Gunnarsson6cd50812021-04-06 09:26:471097 EXPECT_FALSE(IsSrtpActive(channel1_));
Harald Alvestrand2f553702023-03-07 10:10:031098 EXPECT_TRUE(media_send_channel1_impl()->sending());
Florent Castelli1f31c202023-06-26 00:26:071099 EXPECT_EQ(1U, media_send_channel1_impl()->send_codecs().size());
Peter Boström34fbfff2015-09-24 17:20:301100 if (verify_playout_) {
Harald Alvestrand2f553702023-03-07 10:10:031101 EXPECT_TRUE(media_receive_channel2_impl()->playout());
Peter Boström34fbfff2015-09-24 17:20:301102 }
Harald Alvestrand2f553702023-03-07 10:10:031103 EXPECT_TRUE(media_send_channel2_impl()->sending());
Florent Castelli1f31c202023-06-26 00:26:071104 EXPECT_EQ(1U, media_send_channel2_impl()->send_codecs().size());
[email protected]28e20752013-07-10 00:45:361105 }
1106
[email protected]28e20752013-07-10 00:45:361107 // Send voice RTP data to the other side and ensure it gets there.
1108 void SendRtpToRtp() {
Zhi Huange830e682018-03-30 17:48:351109 CreateChannels(RTCP_MUX, RTCP_MUX);
[email protected]28e20752013-07-10 00:45:361110 EXPECT_TRUE(SendInitiate());
1111 EXPECT_TRUE(SendAccept());
Tomas Gunnarsson6cd50812021-04-06 09:26:471112 EXPECT_TRUE(IsRtcpMuxEnabled(channel1_));
1113 EXPECT_TRUE(IsRtcpMuxEnabled(channel2_));
Danil Chapovalov33b01f22016-05-11 17:55:271114 SendRtp1();
1115 SendRtp2();
1116 WaitForThreads();
[email protected]28e20752013-07-10 00:45:361117 EXPECT_TRUE(CheckRtp1());
1118 EXPECT_TRUE(CheckRtp2());
1119 EXPECT_TRUE(CheckNoRtp1());
1120 EXPECT_TRUE(CheckNoRtp2());
1121 }
1122
Danil Chapovalovdae07ba2016-05-13 23:43:501123 void TestDeinit() {
deadbeefac22f702017-01-13 05:59:291124 CreateChannels(0, 0);
Danil Chapovalovdae07ba2016-05-13 23:43:501125 EXPECT_TRUE(SendInitiate());
1126 EXPECT_TRUE(SendAccept());
1127 SendRtp1();
1128 SendRtp2();
Tomas Gunnarsson1933d3b2022-01-17 10:25:211129
1130 DeinitChannels();
1131
Danil Chapovalovdae07ba2016-05-13 23:43:501132 // Do not wait, destroy channels.
1133 channel1_.reset(nullptr);
1134 channel2_.reset(nullptr);
1135 }
1136
Zhi Huange830e682018-03-30 17:48:351137 void SendDtlsSrtpToDtlsSrtp(int flags1, int flags2) {
1138 CreateChannels(flags1 | DTLS, flags2 | DTLS);
Tomas Gunnarsson6cd50812021-04-06 09:26:471139 EXPECT_FALSE(IsSrtpActive(channel1_));
1140 EXPECT_FALSE(IsSrtpActive(channel2_));
[email protected]28e20752013-07-10 00:45:361141 EXPECT_TRUE(SendInitiate());
Danil Chapovalov33b01f22016-05-11 17:55:271142 WaitForThreads();
[email protected]28e20752013-07-10 00:45:361143 EXPECT_TRUE(SendAccept());
Tomas Gunnarsson6cd50812021-04-06 09:26:471144 EXPECT_TRUE(IsSrtpActive(channel1_));
1145 EXPECT_TRUE(IsSrtpActive(channel2_));
Danil Chapovalov33b01f22016-05-11 17:55:271146 SendRtp1();
1147 SendRtp2();
Danil Chapovalov33b01f22016-05-11 17:55:271148 WaitForThreads();
[email protected]28e20752013-07-10 00:45:361149 EXPECT_TRUE(CheckRtp1());
1150 EXPECT_TRUE(CheckRtp2());
1151 EXPECT_TRUE(CheckNoRtp1());
1152 EXPECT_TRUE(CheckNoRtp2());
[email protected]28e20752013-07-10 00:45:361153 }
1154
1155 // Test that we can send and receive early media when a provisional answer is
1156 // sent and received. The test uses SRTP, RTCP mux and SSRC mux.
1157 void SendEarlyMediaUsingRtcpMuxSrtp() {
Yves Gerey665174f2018-06-19 13:03:051158 int sequence_number1_1 = 0, sequence_number2_2 = 0;
[email protected]28e20752013-07-10 00:45:361159
Yves Gerey665174f2018-06-19 13:03:051160 CreateChannels(SSRC_MUX | RTCP_MUX | DTLS, SSRC_MUX | RTCP_MUX | DTLS);
1161 EXPECT_TRUE(SendOffer());
1162 EXPECT_TRUE(SendProvisionalAnswer());
Tomas Gunnarsson6cd50812021-04-06 09:26:471163 EXPECT_TRUE(IsSrtpActive(channel1_));
1164 EXPECT_TRUE(IsSrtpActive(channel2_));
1165 EXPECT_TRUE(IsRtcpMuxEnabled(channel1_));
1166 EXPECT_TRUE(IsRtcpMuxEnabled(channel2_));
Yves Gerey665174f2018-06-19 13:03:051167 WaitForThreads(); // Wait for 'sending' flag go through network thread.
Yves Gerey665174f2018-06-19 13:03:051168 SendCustomRtp1(kSsrc1, ++sequence_number1_1);
1169 WaitForThreads();
Yves Gerey665174f2018-06-19 13:03:051170 EXPECT_TRUE(CheckCustomRtp2(kSsrc1, sequence_number1_1));
[email protected]28e20752013-07-10 00:45:361171
Yves Gerey665174f2018-06-19 13:03:051172 // Send packets from callee and verify that it is received.
Yves Gerey665174f2018-06-19 13:03:051173 SendCustomRtp2(kSsrc2, ++sequence_number2_2);
1174 WaitForThreads();
Yves Gerey665174f2018-06-19 13:03:051175 EXPECT_TRUE(CheckCustomRtp1(kSsrc2, sequence_number2_2));
[email protected]28e20752013-07-10 00:45:361176
Yves Gerey665174f2018-06-19 13:03:051177 // Complete call setup and ensure everything is still OK.
1178 EXPECT_TRUE(SendFinalAnswer());
Tomas Gunnarsson6cd50812021-04-06 09:26:471179 EXPECT_TRUE(IsSrtpActive(channel1_));
1180 EXPECT_TRUE(IsSrtpActive(channel2_));
Yves Gerey665174f2018-06-19 13:03:051181 SendCustomRtp1(kSsrc1, ++sequence_number1_1);
Yves Gerey665174f2018-06-19 13:03:051182 SendCustomRtp2(kSsrc2, ++sequence_number2_2);
1183 WaitForThreads();
Yves Gerey665174f2018-06-19 13:03:051184 EXPECT_TRUE(CheckCustomRtp2(kSsrc1, sequence_number1_1));
Yves Gerey665174f2018-06-19 13:03:051185 EXPECT_TRUE(CheckCustomRtp1(kSsrc2, sequence_number2_2));
[email protected]28e20752013-07-10 00:45:361186 }
1187
1188 // Test that we properly send RTP without SRTP from a thread.
1189 void SendRtpToRtpOnThread() {
deadbeefac22f702017-01-13 05:59:291190 CreateChannels(0, 0);
[email protected]28e20752013-07-10 00:45:361191 EXPECT_TRUE(SendInitiate());
1192 EXPECT_TRUE(SendAccept());
Danil Chapovalov33b01f22016-05-11 17:55:271193 ScopedCallThread send_rtp1([this] { SendRtp1(); });
1194 ScopedCallThread send_rtp2([this] { SendRtp2(); });
Evan Shrubsole6a9a1ae2025-03-21 12:54:151195 webrtc::Thread* involved_threads[] = {send_rtp1.thread(),
1196 send_rtp2.thread()};
Danil Chapovalov33b01f22016-05-11 17:55:271197 WaitForThreads(involved_threads);
1198 EXPECT_TRUE(CheckRtp1());
1199 EXPECT_TRUE(CheckRtp2());
[email protected]28e20752013-07-10 00:45:361200 EXPECT_TRUE(CheckNoRtp1());
1201 EXPECT_TRUE(CheckNoRtp2());
[email protected]28e20752013-07-10 00:45:361202 }
1203
[email protected]28e20752013-07-10 00:45:361204 // Test that the mediachannel retains its sending state after the transport
1205 // becomes non-writable.
1206 void SendWithWritabilityLoss() {
Zhi Huange830e682018-03-30 17:48:351207 CreateChannels(RTCP_MUX, RTCP_MUX);
[email protected]28e20752013-07-10 00:45:361208 EXPECT_TRUE(SendInitiate());
1209 EXPECT_TRUE(SendAccept());
Tomas Gunnarsson6cd50812021-04-06 09:26:471210 EXPECT_TRUE(IsRtcpMuxEnabled(channel1_));
1211 EXPECT_TRUE(IsRtcpMuxEnabled(channel2_));
Danil Chapovalov33b01f22016-05-11 17:55:271212 SendRtp1();
1213 SendRtp2();
1214 WaitForThreads();
[email protected]28e20752013-07-10 00:45:361215 EXPECT_TRUE(CheckRtp1());
1216 EXPECT_TRUE(CheckRtp2());
1217 EXPECT_TRUE(CheckNoRtp1());
1218 EXPECT_TRUE(CheckNoRtp2());
1219
[email protected]97077a32013-10-25 21:18:331220 // Lose writability, which should fail.
Danil Chapovalov2aaef452022-08-12 13:55:111221 SendTask(network_thread_,
1222 [this] { fake_rtp_dtls_transport1_->SetWritable(false); });
Danil Chapovalov33b01f22016-05-11 17:55:271223 SendRtp1();
1224 SendRtp2();
1225 WaitForThreads();
[email protected]28e20752013-07-10 00:45:361226 EXPECT_TRUE(CheckRtp1());
1227 EXPECT_TRUE(CheckNoRtp2());
1228
1229 // Regain writability
Danil Chapovalov2aaef452022-08-12 13:55:111230 SendTask(network_thread_,
1231 [this] { fake_rtp_dtls_transport1_->SetWritable(true); });
Harald Alvestrand2f553702023-03-07 10:10:031232 EXPECT_TRUE(media_send_channel1_impl()->sending());
Danil Chapovalov33b01f22016-05-11 17:55:271233 SendRtp1();
1234 SendRtp2();
1235 WaitForThreads();
[email protected]28e20752013-07-10 00:45:361236 EXPECT_TRUE(CheckRtp1());
1237 EXPECT_TRUE(CheckRtp2());
1238 EXPECT_TRUE(CheckNoRtp1());
1239 EXPECT_TRUE(CheckNoRtp2());
1240
1241 // Lose writability completely
Danil Chapovalov2aaef452022-08-12 13:55:111242 SendTask(network_thread_, [this] {
deadbeeff5346592017-01-25 05:51:211243 bool asymmetric = true;
1244 fake_rtp_dtls_transport1_->SetDestination(nullptr, asymmetric);
1245 });
Harald Alvestrand2f553702023-03-07 10:10:031246 EXPECT_TRUE(media_send_channel1_impl()->sending());
[email protected]28e20752013-07-10 00:45:361247
[email protected]97077a32013-10-25 21:18:331248 // Should fail also.
Danil Chapovalov33b01f22016-05-11 17:55:271249 SendRtp1();
1250 SendRtp2();
1251 WaitForThreads();
[email protected]28e20752013-07-10 00:45:361252 EXPECT_TRUE(CheckRtp1());
1253 EXPECT_TRUE(CheckNoRtp2());
zhihuangb2cdd932017-01-20 00:54:251254 EXPECT_TRUE(CheckNoRtp1());
[email protected]28e20752013-07-10 00:45:361255
1256 // Gain writability back
Danil Chapovalov2aaef452022-08-12 13:55:111257 SendTask(network_thread_, [this] {
deadbeeff5346592017-01-25 05:51:211258 bool asymmetric = true;
1259 fake_rtp_dtls_transport1_->SetDestination(fake_rtp_dtls_transport2_.get(),
1260 asymmetric);
Taylor Brandstetter5d97a9a2016-06-10 21:17:271261 });
Harald Alvestrand2f553702023-03-07 10:10:031262 EXPECT_TRUE(media_send_channel1_impl()->sending());
Danil Chapovalov33b01f22016-05-11 17:55:271263 SendRtp1();
1264 SendRtp2();
1265 WaitForThreads();
[email protected]28e20752013-07-10 00:45:361266 EXPECT_TRUE(CheckRtp1());
1267 EXPECT_TRUE(CheckRtp2());
1268 EXPECT_TRUE(CheckNoRtp1());
1269 EXPECT_TRUE(CheckNoRtp2());
1270 }
1271
Danil Chapovalov52c16dc2025-06-02 07:57:151272 void SendBundleToBundle(ArrayView<const int, 2> pl_types,
Yves Gerey665174f2018-06-19 13:03:051273 bool rtcp_mux,
1274 bool secure) {
[email protected]28e20752013-07-10 00:45:361275 int sequence_number1_1 = 0, sequence_number2_2 = 0;
Artem Titov880fa812021-07-30 20:30:231276 // Only pl_type1 was added to the bundle filter for both `channel1_`
1277 // and `channel2_`.
[email protected]5ee0f052014-05-05 20:18:081278 int pl_type1 = pl_types[0];
1279 int pl_type2 = pl_types[1];
deadbeefac22f702017-01-13 05:59:291280 int flags = SSRC_MUX;
Zhi Huange830e682018-03-30 17:48:351281 if (secure)
1282 flags |= DTLS;
[email protected]5ee0f052014-05-05 20:18:081283 if (rtcp_mux) {
1284 flags |= RTCP_MUX;
[email protected]5ee0f052014-05-05 20:18:081285 }
1286 CreateChannels(flags, flags);
[email protected]28e20752013-07-10 00:45:361287 EXPECT_TRUE(SendInitiate());
[email protected]28e20752013-07-10 00:45:361288 EXPECT_TRUE(SendAccept());
[email protected]5ee0f052014-05-05 20:18:081289
1290 // Both channels can receive pl_type1 only.
Danil Chapovalov33b01f22016-05-11 17:55:271291 SendCustomRtp1(kSsrc1, ++sequence_number1_1, pl_type1);
1292 SendCustomRtp2(kSsrc2, ++sequence_number2_2, pl_type1);
1293 WaitForThreads();
[email protected]5ee0f052014-05-05 20:18:081294 EXPECT_TRUE(CheckCustomRtp2(kSsrc1, sequence_number1_1, pl_type1));
[email protected]5ee0f052014-05-05 20:18:081295 EXPECT_TRUE(CheckCustomRtp1(kSsrc2, sequence_number2_2, pl_type1));
1296 EXPECT_TRUE(CheckNoRtp1());
1297 EXPECT_TRUE(CheckNoRtp2());
1298
Zhi Huang365381f2018-04-13 23:44:341299 SendCustomRtp1(kSsrc3, ++sequence_number1_1, pl_type2);
1300 SendCustomRtp2(kSsrc4, ++sequence_number2_2, pl_type2);
Danil Chapovalov33b01f22016-05-11 17:55:271301 WaitForThreads();
Zhi Huang365381f2018-04-13 23:44:341302 EXPECT_FALSE(CheckCustomRtp2(kSsrc3, sequence_number1_1, pl_type2));
1303 EXPECT_FALSE(CheckCustomRtp1(kSsrc4, sequence_number2_2, pl_type2));
[email protected]28e20752013-07-10 00:45:361304 }
1305
[email protected]28e20752013-07-10 00:45:361306 void TestSetContentFailure() {
1307 CreateChannels(0, 0);
[email protected]28e20752013-07-10 00:45:361308
Peter Thatchera6d24442015-07-10 04:26:361309 std::string err;
Steve Anton18ee1d52017-09-11 18:32:351310 std::unique_ptr<typename T::Content> content(
1311 CreateMediaContentWithStream(1));
1312
Harald Alvestrand2f553702023-03-07 10:10:031313 media_receive_channel1_impl()->set_fail_set_recv_codecs(true);
Steve Anton18ee1d52017-09-11 18:32:351314 EXPECT_FALSE(
Tomas Gunnarssond908d742022-01-05 10:44:261315 channel1_->SetLocalContent(content.get(), SdpType::kOffer, err));
Steve Anton18ee1d52017-09-11 18:32:351316 EXPECT_FALSE(
Tomas Gunnarssond908d742022-01-05 10:44:261317 channel1_->SetLocalContent(content.get(), SdpType::kAnswer, err));
[email protected]28e20752013-07-10 00:45:361318
Harald Alvestrand2f553702023-03-07 10:10:031319 media_send_channel1_impl()->set_fail_set_send_codecs(true);
Steve Anton18ee1d52017-09-11 18:32:351320 EXPECT_FALSE(
Tomas Gunnarssond908d742022-01-05 10:44:261321 channel1_->SetRemoteContent(content.get(), SdpType::kOffer, err));
Steve Anton18ee1d52017-09-11 18:32:351322
Harald Alvestrand2f553702023-03-07 10:10:031323 media_send_channel1_impl()->set_fail_set_send_codecs(true);
Steve Anton18ee1d52017-09-11 18:32:351324 EXPECT_FALSE(
Tomas Gunnarssond908d742022-01-05 10:44:261325 channel1_->SetRemoteContent(content.get(), SdpType::kAnswer, err));
[email protected]28e20752013-07-10 00:45:361326 }
1327
1328 void TestSendTwoOffers() {
1329 CreateChannels(0, 0);
1330
Peter Thatchera6d24442015-07-10 04:26:361331 std::string err;
Steve Anton18ee1d52017-09-11 18:32:351332 std::unique_ptr<typename T::Content> content1(
1333 CreateMediaContentWithStream(1));
1334 EXPECT_TRUE(
Tomas Gunnarssond908d742022-01-05 10:44:261335 channel1_->SetLocalContent(content1.get(), SdpType::kOffer, err));
Harald Alvestrand2f553702023-03-07 10:10:031336 EXPECT_TRUE(media_send_channel1_impl()->HasSendStream(1));
[email protected]28e20752013-07-10 00:45:361337
Steve Anton18ee1d52017-09-11 18:32:351338 std::unique_ptr<typename T::Content> content2(
1339 CreateMediaContentWithStream(2));
1340 EXPECT_TRUE(
Tomas Gunnarssond908d742022-01-05 10:44:261341 channel1_->SetLocalContent(content2.get(), SdpType::kOffer, err));
Harald Alvestrand2f553702023-03-07 10:10:031342 EXPECT_FALSE(media_send_channel1_impl()->HasSendStream(1));
1343 EXPECT_TRUE(media_send_channel1_impl()->HasSendStream(2));
[email protected]28e20752013-07-10 00:45:361344 }
1345
1346 void TestReceiveTwoOffers() {
1347 CreateChannels(0, 0);
1348
Peter Thatchera6d24442015-07-10 04:26:361349 std::string err;
Steve Anton18ee1d52017-09-11 18:32:351350 std::unique_ptr<typename T::Content> content1(
1351 CreateMediaContentWithStream(1));
1352 EXPECT_TRUE(
Tomas Gunnarssond908d742022-01-05 10:44:261353 channel1_->SetRemoteContent(content1.get(), SdpType::kOffer, err));
Harald Alvestrand2f553702023-03-07 10:10:031354 EXPECT_TRUE(media_receive_channel1_impl()->HasRecvStream(1));
[email protected]28e20752013-07-10 00:45:361355
Steve Anton18ee1d52017-09-11 18:32:351356 std::unique_ptr<typename T::Content> content2(
1357 CreateMediaContentWithStream(2));
1358 EXPECT_TRUE(
Tomas Gunnarssond908d742022-01-05 10:44:261359 channel1_->SetRemoteContent(content2.get(), SdpType::kOffer, err));
Harald Alvestrand2f553702023-03-07 10:10:031360 EXPECT_FALSE(media_receive_channel1_impl()->HasRecvStream(1));
1361 EXPECT_TRUE(media_receive_channel1_impl()->HasRecvStream(2));
[email protected]28e20752013-07-10 00:45:361362 }
1363
1364 void TestSendPrAnswer() {
1365 CreateChannels(0, 0);
1366
Peter Thatchera6d24442015-07-10 04:26:361367 std::string err;
1368 // Receive offer
Steve Anton18ee1d52017-09-11 18:32:351369 std::unique_ptr<typename T::Content> content1(
1370 CreateMediaContentWithStream(1));
1371 EXPECT_TRUE(
Tomas Gunnarssond908d742022-01-05 10:44:261372 channel1_->SetRemoteContent(content1.get(), SdpType::kOffer, err));
Harald Alvestrand2f553702023-03-07 10:10:031373 EXPECT_TRUE(media_receive_channel1_impl()->HasRecvStream(1));
[email protected]28e20752013-07-10 00:45:361374
Peter Thatchera6d24442015-07-10 04:26:361375 // Send PR answer
Steve Anton18ee1d52017-09-11 18:32:351376 std::unique_ptr<typename T::Content> content2(
1377 CreateMediaContentWithStream(2));
1378 EXPECT_TRUE(
Tomas Gunnarssond908d742022-01-05 10:44:261379 channel1_->SetLocalContent(content2.get(), SdpType::kPrAnswer, err));
Harald Alvestrand2f553702023-03-07 10:10:031380 EXPECT_TRUE(media_receive_channel1_impl()->HasRecvStream(1));
1381 EXPECT_TRUE(media_send_channel1_impl()->HasSendStream(2));
[email protected]28e20752013-07-10 00:45:361382
Peter Thatchera6d24442015-07-10 04:26:361383 // Send answer
Steve Anton18ee1d52017-09-11 18:32:351384 std::unique_ptr<typename T::Content> content3(
1385 CreateMediaContentWithStream(3));
1386 EXPECT_TRUE(
Tomas Gunnarssond908d742022-01-05 10:44:261387 channel1_->SetLocalContent(content3.get(), SdpType::kAnswer, err));
Harald Alvestrand2f553702023-03-07 10:10:031388 EXPECT_TRUE(media_receive_channel1_impl()->HasRecvStream(1));
1389 EXPECT_FALSE(media_send_channel1_impl()->HasSendStream(2));
1390 EXPECT_TRUE(media_send_channel1_impl()->HasSendStream(3));
[email protected]28e20752013-07-10 00:45:361391 }
1392
1393 void TestReceivePrAnswer() {
1394 CreateChannels(0, 0);
1395
Peter Thatchera6d24442015-07-10 04:26:361396 std::string err;
1397 // Send offer
Steve Anton18ee1d52017-09-11 18:32:351398 std::unique_ptr<typename T::Content> content1(
1399 CreateMediaContentWithStream(1));
1400 EXPECT_TRUE(
Tomas Gunnarssond908d742022-01-05 10:44:261401 channel1_->SetLocalContent(content1.get(), SdpType::kOffer, err));
Harald Alvestrand2f553702023-03-07 10:10:031402 EXPECT_TRUE(media_send_channel1_impl()->HasSendStream(1));
[email protected]28e20752013-07-10 00:45:361403
Peter Thatchera6d24442015-07-10 04:26:361404 // Receive PR answer
Steve Anton18ee1d52017-09-11 18:32:351405 std::unique_ptr<typename T::Content> content2(
1406 CreateMediaContentWithStream(2));
Steve Anton3828c062017-12-06 18:34:511407 EXPECT_TRUE(
Tomas Gunnarssond908d742022-01-05 10:44:261408 channel1_->SetRemoteContent(content2.get(), SdpType::kPrAnswer, err));
Harald Alvestrand2f553702023-03-07 10:10:031409 EXPECT_TRUE(media_send_channel1_impl()->HasSendStream(1));
1410 EXPECT_TRUE(media_receive_channel1_impl()->HasRecvStream(2));
[email protected]28e20752013-07-10 00:45:361411
Peter Thatchera6d24442015-07-10 04:26:361412 // Receive answer
Steve Anton18ee1d52017-09-11 18:32:351413 std::unique_ptr<typename T::Content> content3(
1414 CreateMediaContentWithStream(3));
1415 EXPECT_TRUE(
Tomas Gunnarssond908d742022-01-05 10:44:261416 channel1_->SetRemoteContent(content3.get(), SdpType::kAnswer, err));
Harald Alvestrand2f553702023-03-07 10:10:031417 EXPECT_TRUE(media_send_channel1_impl()->HasSendStream(1));
1418 EXPECT_FALSE(media_receive_channel1_impl()->HasRecvStream(2));
1419 EXPECT_TRUE(media_receive_channel1_impl()->HasRecvStream(3));
[email protected]28e20752013-07-10 00:45:361420 }
1421
zstein56162b92017-04-24 23:54:351422 void TestOnTransportReadyToSend() {
deadbeefac22f702017-01-13 05:59:291423 CreateChannels(0, 0);
Harald Alvestrand2f553702023-03-07 10:10:031424 EXPECT_FALSE(media_send_channel1_impl()->ready_to_send());
Danil Chapovalov33b01f22016-05-11 17:55:271425
Tomas Gunnarssonad325862021-02-03 15:23:401426 network_thread_->PostTask(
Henrik Boström2deee4b2022-01-20 10:58:051427 [this] { channel1_->OnTransportReadyToSend(true); });
Danil Chapovalov33b01f22016-05-11 17:55:271428 WaitForThreads();
Harald Alvestrand2f553702023-03-07 10:10:031429 EXPECT_TRUE(media_send_channel1_impl()->ready_to_send());
[email protected]28e20752013-07-10 00:45:361430
Tomas Gunnarssonad325862021-02-03 15:23:401431 network_thread_->PostTask(
Henrik Boström2deee4b2022-01-20 10:58:051432 [this] { channel1_->OnTransportReadyToSend(false); });
Danil Chapovalov33b01f22016-05-11 17:55:271433 WaitForThreads();
Harald Alvestrand2f553702023-03-07 10:10:031434 EXPECT_FALSE(media_send_channel1_impl()->ready_to_send());
[email protected]28e20752013-07-10 00:45:361435 }
1436
skvladdc1c62c2016-03-17 02:07:431437 bool SetRemoteContentWithBitrateLimit(int remote_limit) {
1438 typename T::Content content;
1439 CreateContent(0, kPcmuCodec, kH264Codec, &content);
1440 content.set_bandwidth(remote_limit);
Steve Anton3828c062017-12-06 18:34:511441 return channel1_->SetRemoteContent(&content, SdpType::kOffer, NULL);
skvladdc1c62c2016-03-17 02:07:431442 }
1443
Florent Castelli8037fc62024-08-29 13:00:401444 webrtc::RtpParameters BitrateLimitedParameters(std::optional<int> limit) {
skvladdc1c62c2016-03-17 02:07:431445 webrtc::RtpParameters parameters;
1446 webrtc::RtpEncodingParameters encoding;
Mirko Bonadei05cf6be2019-01-31 20:38:121447 encoding.max_bitrate_bps = limit;
skvladdc1c62c2016-03-17 02:07:431448 parameters.encodings.push_back(encoding);
1449 return parameters;
1450 }
1451
1452 void VerifyMaxBitrate(const webrtc::RtpParameters& parameters,
Florent Castelli8037fc62024-08-29 13:00:401453 std::optional<int> expected_bitrate) {
skvladdc1c62c2016-03-17 02:07:431454 EXPECT_EQ(1UL, parameters.encodings.size());
1455 EXPECT_EQ(expected_bitrate, parameters.encodings[0].max_bitrate_bps);
1456 }
1457
1458 void DefaultMaxBitrateIsUnlimited() {
1459 CreateChannels(0, 0);
Tomas Gunnarssond908d742022-01-05 10:44:261460 std::string err;
Steve Anton3828c062017-12-06 18:34:511461 EXPECT_TRUE(channel1_->SetLocalContent(&local_media_content1_,
Tomas Gunnarssond908d742022-01-05 10:44:261462 SdpType::kOffer, err));
Harald Alvestrand2f553702023-03-07 10:10:031463 EXPECT_EQ(media_send_channel1_impl()->max_bps(), -1);
Harald Alvestrand36fafc82022-12-08 08:47:421464 VerifyMaxBitrate(media_send_channel1()->GetRtpSendParameters(kSsrc1),
Florent Castelli8037fc62024-08-29 13:00:401465 std::nullopt);
skvladdc1c62c2016-03-17 02:07:431466 }
1467
Zhi Huange830e682018-03-30 17:48:351468 // Test that when a channel gets new RtpTransport with a call to
Artem Titov880fa812021-07-30 20:30:231469 // `SetRtpTransport`, the socket options from the old RtpTransport is merged
Zhi Huange830e682018-03-30 17:48:351470 // with the options on the new one.
1471
Steve Anton8a63f782017-10-23 20:08:531472 // For example, audio and video may use separate socket options, but initially
1473 // be unbundled, then later become bundled. When this happens, their preferred
1474 // socket options should be merged to the underlying transport they share.
1475 void SocketOptionsMergedOnSetTransport() {
1476 constexpr int kSndBufSize = 4000;
1477 constexpr int kRcvBufSize = 8000;
1478
Zhi Huange830e682018-03-30 17:48:351479 CreateChannels(DTLS, DTLS);
Steve Anton8a63f782017-10-23 20:08:531480
Niels Möller92430882021-03-18 09:03:191481 bool rcv_success, send_success;
1482 int rcv_buf, send_buf;
Danil Chapovalov2aaef452022-08-12 13:55:111483 SendTask(network_thread_, [&] {
Per Kf4aadf32024-02-27 08:01:151484 new_rtp_transport_ = CreateDtlsSrtpTransport(
1485 fake_rtp_dtls_transport2_.get(), fake_rtcp_dtls_transport2_.get());
Evan Shrubsole3c825f12025-04-04 14:07:271486 channel1_->SetOption(webrtc::BaseChannel::ST_RTP,
Evan Shrubsole03b68802025-03-18 12:23:051487 webrtc::Socket::Option::OPT_SNDBUF, kSndBufSize);
Evan Shrubsole3c825f12025-04-04 14:07:271488 channel2_->SetOption(webrtc::BaseChannel::ST_RTP,
Evan Shrubsole03b68802025-03-18 12:23:051489 webrtc::Socket::Option::OPT_RCVBUF, kRcvBufSize);
Tomas Gunnarssond9a51b02021-04-02 15:42:021490 channel1_->SetRtpTransport(new_rtp_transport_.get());
Niels Möller92430882021-03-18 09:03:191491 send_success = fake_rtp_dtls_transport2_->GetOption(
Evan Shrubsole03b68802025-03-18 12:23:051492 webrtc::Socket::Option::OPT_SNDBUF, &send_buf);
Niels Möller92430882021-03-18 09:03:191493 rcv_success = fake_rtp_dtls_transport2_->GetOption(
Evan Shrubsole03b68802025-03-18 12:23:051494 webrtc::Socket::Option::OPT_RCVBUF, &rcv_buf);
Niels Möller92430882021-03-18 09:03:191495 });
1496
1497 ASSERT_TRUE(send_success);
1498 EXPECT_EQ(kSndBufSize, send_buf);
1499 ASSERT_TRUE(rcv_success);
1500 EXPECT_EQ(kRcvBufSize, rcv_buf);
Steve Anton8a63f782017-10-23 20:08:531501 }
1502
Amit Hilbuchbcd39d42019-01-26 01:13:561503 void CreateSimulcastContent(const std::vector<std::string>& rids,
1504 typename T::Content* content) {
1505 std::vector<RidDescription> rid_descriptions;
Courtney Edwards134c6992020-03-03 10:36:351506 for (const std::string& name : rids) {
Amit Hilbuchbcd39d42019-01-26 01:13:561507 rid_descriptions.push_back(RidDescription(name, RidDirection::kSend));
1508 }
1509
1510 StreamParams stream;
1511 stream.set_rids(rid_descriptions);
1512 CreateContent(0, kPcmuCodec, kH264Codec, content);
1513 // This is for unified plan, so there can be only one StreamParams.
1514 content->mutable_streams().clear();
1515 content->AddStream(stream);
1516 }
1517
1518 void VerifySimulcastStreamParams(const StreamParams& expected,
1519 const typename T::Channel* channel) {
1520 const std::vector<StreamParams>& streams = channel->local_streams();
1521 ASSERT_EQ(1u, streams.size());
1522 const StreamParams& result = streams[0];
1523 EXPECT_EQ(expected.rids(), result.rids());
1524 EXPECT_TRUE(result.has_ssrcs());
1525 EXPECT_EQ(expected.rids().size() * 2, result.ssrcs.size());
1526 std::vector<uint32_t> primary_ssrcs;
1527 result.GetPrimarySsrcs(&primary_ssrcs);
1528 EXPECT_EQ(expected.rids().size(), primary_ssrcs.size());
1529 }
1530
1531 void TestUpdateLocalStreamsWithSimulcast() {
1532 CreateChannels(0, 0);
1533 typename T::Content content1, content2, content3;
1534 CreateSimulcastContent({"f", "h", "q"}, &content1);
Tomas Gunnarssond908d742022-01-05 10:44:261535 std::string err;
1536 EXPECT_TRUE(channel1_->SetLocalContent(&content1, SdpType::kOffer, err));
Amit Hilbuchbcd39d42019-01-26 01:13:561537 VerifySimulcastStreamParams(content1.streams()[0], channel1_.get());
1538 StreamParams stream1 = channel1_->local_streams()[0];
1539
1540 // Create a similar offer. SetLocalContent should not remove and add.
1541 CreateSimulcastContent({"f", "h", "q"}, &content2);
Tomas Gunnarssond908d742022-01-05 10:44:261542 EXPECT_TRUE(channel1_->SetLocalContent(&content2, SdpType::kOffer, err));
Amit Hilbuchbcd39d42019-01-26 01:13:561543 VerifySimulcastStreamParams(content2.streams()[0], channel1_.get());
1544 StreamParams stream2 = channel1_->local_streams()[0];
1545 // Check that the streams are identical (SSRCs didn't change).
1546 EXPECT_EQ(stream1, stream2);
1547
1548 // Create third offer that has same RIDs in different order.
1549 CreateSimulcastContent({"f", "q", "h"}, &content3);
Tomas Gunnarssond908d742022-01-05 10:44:261550 EXPECT_TRUE(channel1_->SetLocalContent(&content3, SdpType::kOffer, err));
Amit Hilbuchbcd39d42019-01-26 01:13:561551 VerifySimulcastStreamParams(content3.streams()[0], channel1_.get());
1552 }
1553
[email protected]28e20752013-07-10 00:45:361554 protected:
Evan Shrubsolee6a1f702025-04-15 14:55:421555 void WaitForThreads() {
1556 WaitForThreads(webrtc::ArrayView<webrtc::Thread*>());
1557 }
Evan Shrubsole6a9a1ae2025-03-21 12:54:151558 static void ProcessThreadQueue(webrtc::Thread* thread) {
Danil Chapovalov33b01f22016-05-11 17:55:271559 RTC_DCHECK(thread->IsCurrent());
1560 while (!thread->empty()) {
1561 thread->ProcessMessages(0);
1562 }
1563 }
Tommi1959f8f2021-04-26 08:20:191564 static void FlushCurrentThread() {
Evan Shrubsole6a9a1ae2025-03-21 12:54:151565 webrtc::Thread::Current()->ProcessMessages(0);
Tommi1959f8f2021-04-26 08:20:191566 }
Evan Shrubsolee6a1f702025-04-15 14:55:421567 void WaitForThreads(webrtc::ArrayView<webrtc::Thread*> threads) {
Artem Titov880fa812021-07-30 20:30:231568 // `threads` and current thread post packets to network thread.
Evan Shrubsolee6a1f702025-04-15 14:55:421569 for (webrtc::Thread* thread : threads) {
Danil Chapovalov2aaef452022-08-12 13:55:111570 SendTask(thread, [thread] { ProcessThreadQueue(thread); });
Danil Chapovalov33b01f22016-05-11 17:55:271571 }
Evan Shrubsole6a9a1ae2025-03-21 12:54:151572 ProcessThreadQueue(webrtc::Thread::Current());
Danil Chapovalov33b01f22016-05-11 17:55:271573 // Network thread move them around and post back to worker = current thread.
1574 if (!network_thread_->IsCurrent()) {
Danil Chapovalov2aaef452022-08-12 13:55:111575 SendTask(network_thread_,
1576 [this] { ProcessThreadQueue(network_thread_); });
Danil Chapovalov33b01f22016-05-11 17:55:271577 }
1578 // Worker thread = current Thread process received messages.
Evan Shrubsole6a9a1ae2025-03-21 12:54:151579 ProcessThreadQueue(webrtc::Thread::Current());
Danil Chapovalov33b01f22016-05-11 17:55:271580 }
Tommic9625f02021-05-06 20:03:191581
Harald Alvestrand2f553702023-03-07 10:10:031582 // Accessors that return the standard VideoMedia{Send|Receive}ChannelInterface
Florent Castelli1f31c202023-06-26 00:26:071583 typename T::MediaSendChannelInterface* media_send_channel1() {
Harald Alvestrand2f553702023-03-07 10:10:031584 return channel1_->media_send_channel();
1585 }
Florent Castelli1f31c202023-06-26 00:26:071586 typename T::MediaSendChannelInterface* media_send_channel2() {
Harald Alvestrand2f553702023-03-07 10:10:031587 return channel2_->media_send_channel();
1588 }
Florent Castelli1f31c202023-06-26 00:26:071589 typename T::MediaReceiveChannelInterface* media_receive_channel1() {
Harald Alvestrand2f553702023-03-07 10:10:031590 return channel1_->media_receive_channel();
1591 }
Florent Castelli1f31c202023-06-26 00:26:071592 typename T::MediaReceiveChannelInterface* media_receive_channel2() {
Harald Alvestrand2f553702023-03-07 10:10:031593 return channel2_->media_receive_channel();
1594 }
1595
Florent Castelli1f31c202023-06-26 00:26:071596 // Accessors that return the FakeMedia<type>SendChannel object.
Harald Alvestrand50454ef2022-12-15 16:49:131597 // Note that these depend on getting the object back that was
1598 // passed to the channel constructor.
Florent Castelli1f31c202023-06-26 00:26:071599 // T::MediaSendChannel is either FakeVoiceMediaSendChannel or
1600 // FakeVideoMediaSendChannel.
1601 typename T::MediaSendChannel* media_send_channel1_impl() {
Harald Alvestrand50454ef2022-12-15 16:49:131602 RTC_DCHECK(channel1_);
Florent Castelli1f31c202023-06-26 00:26:071603 return static_cast<typename T::MediaSendChannel*>(
Harald Alvestrand847208e2023-06-06 09:45:451604 channel1_->media_send_channel());
Harald Alvestrand50454ef2022-12-15 16:49:131605 }
1606
Florent Castelli1f31c202023-06-26 00:26:071607 typename T::MediaSendChannel* media_send_channel2_impl() {
Harald Alvestrand50454ef2022-12-15 16:49:131608 RTC_DCHECK(channel2_);
Harald Alvestrand36fafc82022-12-08 08:47:421609 RTC_DCHECK(channel2_->media_send_channel());
Florent Castelli1f31c202023-06-26 00:26:071610 return static_cast<typename T::MediaSendChannel*>(
Harald Alvestrand847208e2023-06-06 09:45:451611 channel2_->media_send_channel());
Harald Alvestrand2f553702023-03-07 10:10:031612 }
Florent Castelli1f31c202023-06-26 00:26:071613 typename T::MediaReceiveChannel* media_receive_channel1_impl() {
Harald Alvestrand2f553702023-03-07 10:10:031614 RTC_DCHECK(channel1_);
1615 RTC_DCHECK(channel1_->media_receive_channel());
Florent Castelli1f31c202023-06-26 00:26:071616 return static_cast<typename T::MediaReceiveChannel*>(
Harald Alvestrand847208e2023-06-06 09:45:451617 channel1_->media_receive_channel());
Harald Alvestrand2f553702023-03-07 10:10:031618 }
1619
Florent Castelli1f31c202023-06-26 00:26:071620 typename T::MediaReceiveChannel* media_receive_channel2_impl() {
Harald Alvestrand2f553702023-03-07 10:10:031621 RTC_DCHECK(channel2_);
1622 RTC_DCHECK(channel2_->media_receive_channel());
Florent Castelli1f31c202023-06-26 00:26:071623 return static_cast<typename T::MediaReceiveChannel*>(
Harald Alvestrand847208e2023-06-06 09:45:451624 channel2_->media_receive_channel());
Tommic9625f02021-05-06 20:03:191625 }
1626
Evan Shrubsole6a9a1ae2025-03-21 12:54:151627 webrtc::AutoThread main_thread_;
Peter Boström34fbfff2015-09-24 17:20:301628 // TODO(pbos): Remove playout from all media channels and let renderers mute
1629 // themselves.
1630 const bool verify_playout_;
Evan Shrubsolee6a1f702025-04-15 14:55:421631 webrtc::scoped_refptr<webrtc::PendingTaskSafetyFlag> network_thread_safety_ =
Tommic9625f02021-05-06 20:03:191632 webrtc::PendingTaskSafetyFlag::CreateDetached();
Evan Shrubsole6a9a1ae2025-03-21 12:54:151633 std::unique_ptr<webrtc::Thread> network_thread_keeper_;
1634 webrtc::Thread* network_thread_;
Evan Shrubsolee4b09d72025-03-17 13:25:491635 std::unique_ptr<webrtc::FakeDtlsTransport> fake_rtp_dtls_transport1_;
1636 std::unique_ptr<webrtc::FakeDtlsTransport> fake_rtcp_dtls_transport1_;
1637 std::unique_ptr<webrtc::FakeDtlsTransport> fake_rtp_dtls_transport2_;
1638 std::unique_ptr<webrtc::FakeDtlsTransport> fake_rtcp_dtls_transport2_;
Evan Shrubsolec13956e2025-03-13 12:45:541639 std::unique_ptr<webrtc::FakePacketTransport> fake_rtp_packet_transport1_;
1640 std::unique_ptr<webrtc::FakePacketTransport> fake_rtcp_packet_transport1_;
1641 std::unique_ptr<webrtc::FakePacketTransport> fake_rtp_packet_transport2_;
1642 std::unique_ptr<webrtc::FakePacketTransport> fake_rtcp_packet_transport2_;
Zhi Huange830e682018-03-30 17:48:351643 std::unique_ptr<webrtc::RtpTransportInternal> rtp_transport1_;
1644 std::unique_ptr<webrtc::RtpTransportInternal> rtp_transport2_;
1645 std::unique_ptr<webrtc::RtpTransportInternal> new_rtp_transport_;
Evan Shrubsole945e5172025-04-08 14:11:451646 webrtc::FakeMediaEngine media_engine_;
kwiberg31022942016-03-11 22:18:211647 std::unique_ptr<typename T::Channel> channel1_;
1648 std::unique_ptr<typename T::Channel> channel2_;
[email protected]28e20752013-07-10 00:45:361649 typename T::Content local_media_content1_;
1650 typename T::Content local_media_content2_;
1651 typename T::Content remote_media_content1_;
1652 typename T::Content remote_media_content2_;
[email protected]28e20752013-07-10 00:45:361653 // The RTP and RTCP packets to send in the tests.
Evan Shrubsolee6a1f702025-04-15 14:55:421654 webrtc::Buffer rtp_packet_;
1655 webrtc::Buffer rtcp_packet_;
Evan Shrubsole945e5172025-04-08 14:11:451656 webrtc::CandidatePairInterface* last_selected_candidate_pair_;
Evan Shrubsole5f8bcf92025-02-25 12:10:051657 webrtc::UniqueRandomIdGenerator ssrc_generator_;
Danil Chapovalov6e65ae32025-06-10 11:06:031658 FieldTrials field_trials_ = CreateTestFieldTrials();
[email protected]28e20752013-07-10 00:45:361659};
1660
Yves Gerey665174f2018-06-19 13:03:051661template <>
Evan Shrubsole3c825f12025-04-04 14:07:271662std::unique_ptr<webrtc::VoiceChannel> ChannelTest<VoiceTraits>::CreateChannel(
Evan Shrubsole6a9a1ae2025-03-21 12:54:151663 webrtc::Thread* worker_thread,
1664 webrtc::Thread* network_thread,
Evan Shrubsole945e5172025-04-08 14:11:451665 std::unique_ptr<webrtc::FakeVoiceMediaSendChannel> send_ch,
1666 std::unique_ptr<webrtc::FakeVoiceMediaReceiveChannel> receive_ch,
Sebastian Jansson1b83a9e2019-09-18 16:22:121667 webrtc::RtpTransportInternal* rtp_transport,
1668 int flags) {
Evan Shrubsole6a9a1ae2025-03-21 12:54:151669 webrtc::Thread* signaling_thread = webrtc::Thread::Current();
Evan Shrubsole3c825f12025-04-04 14:07:271670 auto channel = std::make_unique<webrtc::VoiceChannel>(
Harald Alvestrand2f553702023-03-07 10:10:031671 worker_thread, network_thread, signaling_thread, std::move(send_ch),
Philipp Hancke643e2162025-07-01 17:27:161672 std::move(receive_ch), kAudioMid, (flags & DTLS) != 0,
Harald Alvestrand2f553702023-03-07 10:10:031673 webrtc::CryptoOptions(), &ssrc_generator_);
Danil Chapovalov2aaef452022-08-12 13:55:111674 SendTask(network_thread, [&]() {
Tomas Gunnarsson1933d3b2022-01-17 10:25:211675 RTC_DCHECK_RUN_ON(channel->network_thread());
Tomas Gunnarsson4f8a58c2022-01-19 10:36:231676 channel->SetRtpTransport(rtp_transport);
Tomas Gunnarsson1933d3b2022-01-17 10:25:211677 });
Sebastian Jansson1b83a9e2019-09-18 16:22:121678 return channel;
1679}
1680
1681template <>
[email protected]28e20752013-07-10 00:45:361682void ChannelTest<VoiceTraits>::CreateContent(
1683 int flags,
Evan Shrubsole0b212e32025-04-07 13:43:011684 const webrtc::Codec& audio_codec,
1685 const webrtc::Codec& video_codec,
Evan Shrubsole080cdac2025-03-20 09:34:481686 webrtc::AudioContentDescription* audio) {
[email protected]28e20752013-07-10 00:45:361687 audio->AddCodec(audio_codec);
1688 audio->set_rtcp_mux((flags & RTCP_MUX) != 0);
[email protected]28e20752013-07-10 00:45:361689}
1690
Yves Gerey665174f2018-06-19 13:03:051691template <>
[email protected]28e20752013-07-10 00:45:361692void ChannelTest<VoiceTraits>::CopyContent(
Evan Shrubsole080cdac2025-03-20 09:34:481693 const webrtc::AudioContentDescription& source,
1694 webrtc::AudioContentDescription* audio) {
[email protected]28e20752013-07-10 00:45:361695 *audio = source;
1696}
1697
Yves Gerey665174f2018-06-19 13:03:051698template <>
[email protected]28e20752013-07-10 00:45:361699void ChannelTest<VoiceTraits>::AddLegacyStreamInContent(
Peter Boström0c4e06b2015-10-07 10:23:211700 uint32_t ssrc,
1701 int flags,
Evan Shrubsole080cdac2025-03-20 09:34:481702 webrtc::AudioContentDescription* audio) {
[email protected]28e20752013-07-10 00:45:361703 audio->AddLegacyStream(ssrc);
1704}
1705
Danil Chapovalov33b01f22016-05-11 17:55:271706class VoiceChannelSingleThreadTest : public ChannelTest<VoiceTraits> {
[email protected]28e20752013-07-10 00:45:361707 public:
Harald Alvestrand3d092402025-05-05 13:32:531708 using Base = ChannelTest<VoiceTraits>;
Danil Chapovalov33b01f22016-05-11 17:55:271709 VoiceChannelSingleThreadTest()
1710 : Base(true, kPcmuFrame, kRtcpReport, NetworkIsWorker::Yes) {}
1711};
1712
1713class VoiceChannelDoubleThreadTest : public ChannelTest<VoiceTraits> {
1714 public:
Harald Alvestrand3d092402025-05-05 13:32:531715 using Base = ChannelTest<VoiceTraits>;
Danil Chapovalov33b01f22016-05-11 17:55:271716 VoiceChannelDoubleThreadTest()
1717 : Base(true, kPcmuFrame, kRtcpReport, NetworkIsWorker::No) {}
[email protected]28e20752013-07-10 00:45:361718};
1719
jbauch5869f502017-06-29 19:31:361720class VoiceChannelWithEncryptedRtpHeaderExtensionsSingleThreadTest
Yves Gerey665174f2018-06-19 13:03:051721 : public ChannelTest<VoiceTraits> {
jbauch5869f502017-06-29 19:31:361722 public:
Harald Alvestrand3d092402025-05-05 13:32:531723 using Base = ChannelTest<VoiceTraits>;
jbauch5869f502017-06-29 19:31:361724 VoiceChannelWithEncryptedRtpHeaderExtensionsSingleThreadTest()
Yves Gerey665174f2018-06-19 13:03:051725 : Base(true,
1726 kPcmuFrameWithExtensions,
1727 kRtcpReport,
1728 NetworkIsWorker::Yes) {}
jbauch5869f502017-06-29 19:31:361729};
1730
1731class VoiceChannelWithEncryptedRtpHeaderExtensionsDoubleThreadTest
Yves Gerey665174f2018-06-19 13:03:051732 : public ChannelTest<VoiceTraits> {
jbauch5869f502017-06-29 19:31:361733 public:
Harald Alvestrand3d092402025-05-05 13:32:531734 using Base = ChannelTest<VoiceTraits>;
jbauch5869f502017-06-29 19:31:361735 VoiceChannelWithEncryptedRtpHeaderExtensionsDoubleThreadTest()
Yves Gerey665174f2018-06-19 13:03:051736 : Base(true, kPcmuFrameWithExtensions, kRtcpReport, NetworkIsWorker::No) {
1737 }
jbauch5869f502017-06-29 19:31:361738};
1739
[email protected]28e20752013-07-10 00:45:361740// override to add NULL parameter
deadbeefcbecd352015-09-23 18:50:271741template <>
Evan Shrubsole3c825f12025-04-04 14:07:271742std::unique_ptr<webrtc::VideoChannel> ChannelTest<VideoTraits>::CreateChannel(
Evan Shrubsole6a9a1ae2025-03-21 12:54:151743 webrtc::Thread* worker_thread,
1744 webrtc::Thread* network_thread,
Evan Shrubsole945e5172025-04-08 14:11:451745 std::unique_ptr<webrtc::FakeVideoMediaSendChannel> send_ch,
1746 std::unique_ptr<webrtc::FakeVideoMediaReceiveChannel> receive_ch,
Zhi Huange830e682018-03-30 17:48:351747 webrtc::RtpTransportInternal* rtp_transport,
jbauchcb560652016-08-04 12:20:321748 int flags) {
Evan Shrubsole6a9a1ae2025-03-21 12:54:151749 webrtc::Thread* signaling_thread = webrtc::Thread::Current();
Evan Shrubsole3c825f12025-04-04 14:07:271750 auto channel = std::make_unique<webrtc::VideoChannel>(
Harald Alvestrand2f553702023-03-07 10:10:031751 worker_thread, network_thread, signaling_thread, std::move(send_ch),
Philipp Hancke643e2162025-07-01 17:27:161752 std::move(receive_ch), kVideoMid, (flags & DTLS) != 0,
Harald Alvestrand2f553702023-03-07 10:10:031753 webrtc::CryptoOptions(), &ssrc_generator_);
Danil Chapovalov2aaef452022-08-12 13:55:111754 SendTask(network_thread, [&]() {
Tomas Gunnarsson1933d3b2022-01-17 10:25:211755 RTC_DCHECK_RUN_ON(channel->network_thread());
Tomas Gunnarsson4f8a58c2022-01-19 10:36:231756 channel->SetRtpTransport(rtp_transport);
Tomas Gunnarsson1933d3b2022-01-17 10:25:211757 });
[email protected]28e20752013-07-10 00:45:361758 return channel;
1759}
1760
Yves Gerey665174f2018-06-19 13:03:051761template <>
[email protected]28e20752013-07-10 00:45:361762void ChannelTest<VideoTraits>::CreateContent(
1763 int flags,
Evan Shrubsole0b212e32025-04-07 13:43:011764 const webrtc::Codec& audio_codec,
1765 const webrtc::Codec& video_codec,
Evan Shrubsole080cdac2025-03-20 09:34:481766 webrtc::VideoContentDescription* video) {
[email protected]28e20752013-07-10 00:45:361767 video->AddCodec(video_codec);
1768 video->set_rtcp_mux((flags & RTCP_MUX) != 0);
[email protected]28e20752013-07-10 00:45:361769}
1770
Yves Gerey665174f2018-06-19 13:03:051771template <>
[email protected]28e20752013-07-10 00:45:361772void ChannelTest<VideoTraits>::CopyContent(
Evan Shrubsole080cdac2025-03-20 09:34:481773 const webrtc::VideoContentDescription& source,
1774 webrtc::VideoContentDescription* video) {
[email protected]28e20752013-07-10 00:45:361775 *video = source;
1776}
1777
Yves Gerey665174f2018-06-19 13:03:051778template <>
[email protected]28e20752013-07-10 00:45:361779void ChannelTest<VideoTraits>::AddLegacyStreamInContent(
Peter Boström0c4e06b2015-10-07 10:23:211780 uint32_t ssrc,
1781 int flags,
Evan Shrubsole080cdac2025-03-20 09:34:481782 webrtc::VideoContentDescription* video) {
[email protected]28e20752013-07-10 00:45:361783 video->AddLegacyStream(ssrc);
1784}
1785
Danil Chapovalov33b01f22016-05-11 17:55:271786class VideoChannelSingleThreadTest : public ChannelTest<VideoTraits> {
[email protected]28e20752013-07-10 00:45:361787 public:
Harald Alvestrand3d092402025-05-05 13:32:531788 using Base = ChannelTest<VideoTraits>;
Danil Chapovalov33b01f22016-05-11 17:55:271789 VideoChannelSingleThreadTest()
1790 : Base(false, kH264Packet, kRtcpReport, NetworkIsWorker::Yes) {}
[email protected]28e20752013-07-10 00:45:361791};
1792
Danil Chapovalov33b01f22016-05-11 17:55:271793class VideoChannelDoubleThreadTest : public ChannelTest<VideoTraits> {
1794 public:
Harald Alvestrand3d092402025-05-05 13:32:531795 using Base = ChannelTest<VideoTraits>;
Danil Chapovalov33b01f22016-05-11 17:55:271796 VideoChannelDoubleThreadTest()
1797 : Base(false, kH264Packet, kRtcpReport, NetworkIsWorker::No) {}
1798};
[email protected]28e20752013-07-10 00:45:361799
Kári Tristan Helgason8b35df72017-09-25 12:46:431800TEST_F(VoiceChannelSingleThreadTest, TestInit) {
[email protected]28e20752013-07-10 00:45:361801 Base::TestInit();
Harald Alvestrand2f553702023-03-07 10:10:031802 EXPECT_FALSE(media_send_channel1_impl()->IsStreamMuted(0));
1803 EXPECT_TRUE(media_send_channel1_impl()->dtmf_info_queue().empty());
[email protected]28e20752013-07-10 00:45:361804}
1805
Danil Chapovalovdae07ba2016-05-13 23:43:501806TEST_F(VoiceChannelSingleThreadTest, TestDeinit) {
1807 Base::TestDeinit();
1808}
1809
Danil Chapovalov33b01f22016-05-11 17:55:271810TEST_F(VoiceChannelSingleThreadTest, TestSetContents) {
[email protected]28e20752013-07-10 00:45:361811 Base::TestSetContents();
1812}
1813
Johannes Kron9190b822018-10-29 10:22:051814TEST_F(VoiceChannelSingleThreadTest, TestSetContentsExtmapAllowMixedAsCaller) {
1815 Base::TestSetContentsExtmapAllowMixedCaller(/*offer=*/true, /*answer=*/true);
1816}
1817
1818TEST_F(VoiceChannelSingleThreadTest,
1819 TestSetContentsExtmapAllowMixedNotSupportedAsCaller) {
1820 Base::TestSetContentsExtmapAllowMixedCaller(/*offer=*/true, /*answer=*/false);
1821}
1822
1823TEST_F(VoiceChannelSingleThreadTest, TestSetContentsExtmapAllowMixedAsCallee) {
1824 Base::TestSetContentsExtmapAllowMixedCallee(/*offer=*/true, /*answer=*/true);
1825}
1826
1827TEST_F(VoiceChannelSingleThreadTest,
1828 TestSetContentsExtmapAllowMixedNotSupportedAsCallee) {
1829 Base::TestSetContentsExtmapAllowMixedCallee(/*offer=*/true, /*answer=*/false);
1830}
1831
Danil Chapovalov33b01f22016-05-11 17:55:271832TEST_F(VoiceChannelSingleThreadTest, TestSetContentsNullOffer) {
[email protected]28e20752013-07-10 00:45:361833 Base::TestSetContentsNullOffer();
1834}
1835
Danil Chapovalov33b01f22016-05-11 17:55:271836TEST_F(VoiceChannelSingleThreadTest, TestSetContentsRtcpMux) {
[email protected]28e20752013-07-10 00:45:361837 Base::TestSetContentsRtcpMux();
1838}
1839
Danil Chapovalov33b01f22016-05-11 17:55:271840TEST_F(VoiceChannelSingleThreadTest, TestSetContentsRtcpMuxWithPrAnswer) {
[email protected]28e20752013-07-10 00:45:361841 Base::TestSetContentsRtcpMux();
1842}
1843
Tomas Lundqvistb40c5592024-11-22 13:45:271844TEST_F(VoiceChannelSingleThreadTest, TestSetContentsRtcpReducedSize) {
1845 Base::TestSetContentsRtcpReducedSize();
1846}
1847
Danil Chapovalov33b01f22016-05-11 17:55:271848TEST_F(VoiceChannelSingleThreadTest, TestChangeStreamParamsInContent) {
[email protected]28e20752013-07-10 00:45:361849 Base::TestChangeStreamParamsInContent();
1850}
1851
Danil Chapovalov33b01f22016-05-11 17:55:271852TEST_F(VoiceChannelSingleThreadTest, TestPlayoutAndSendingStates) {
[email protected]28e20752013-07-10 00:45:361853 Base::TestPlayoutAndSendingStates();
1854}
1855
Danil Chapovalov33b01f22016-05-11 17:55:271856TEST_F(VoiceChannelSingleThreadTest, TestMediaContentDirection) {
[email protected]28e20752013-07-10 00:45:361857 Base::TestMediaContentDirection();
1858}
1859
Danil Chapovalov33b01f22016-05-11 17:55:271860TEST_F(VoiceChannelSingleThreadTest, TestNetworkRouteChanges) {
Honghai Zhangcc411c02016-03-30 00:27:211861 Base::TestNetworkRouteChanges();
1862}
1863
Danil Chapovalov33b01f22016-05-11 17:55:271864TEST_F(VoiceChannelSingleThreadTest, TestCallSetup) {
[email protected]28e20752013-07-10 00:45:361865 Base::TestCallSetup();
1866}
1867
Danil Chapovalov33b01f22016-05-11 17:55:271868TEST_F(VoiceChannelSingleThreadTest, SendRtpToRtp) {
[email protected]28e20752013-07-10 00:45:361869 Base::SendRtpToRtp();
1870}
1871
Danil Chapovalov33b01f22016-05-11 17:55:271872TEST_F(VoiceChannelSingleThreadTest, SendDtlsSrtpToDtlsSrtp) {
Zhi Huange830e682018-03-30 17:48:351873 Base::SendDtlsSrtpToDtlsSrtp(0, 0);
[email protected]28e20752013-07-10 00:45:361874}
1875
Danil Chapovalov33b01f22016-05-11 17:55:271876TEST_F(VoiceChannelSingleThreadTest, SendDtlsSrtpToDtlsSrtpRtcpMux) {
Zhi Huange830e682018-03-30 17:48:351877 Base::SendDtlsSrtpToDtlsSrtp(RTCP_MUX, RTCP_MUX);
deadbeeff5346592017-01-25 05:51:211878}
1879
Danil Chapovalov33b01f22016-05-11 17:55:271880TEST_F(VoiceChannelSingleThreadTest, SendEarlyMediaUsingRtcpMuxSrtp) {
[email protected]28e20752013-07-10 00:45:361881 Base::SendEarlyMediaUsingRtcpMuxSrtp();
1882}
1883
Danil Chapovalov33b01f22016-05-11 17:55:271884TEST_F(VoiceChannelSingleThreadTest, SendRtpToRtpOnThread) {
[email protected]28e20752013-07-10 00:45:361885 Base::SendRtpToRtpOnThread();
1886}
1887
Danil Chapovalov33b01f22016-05-11 17:55:271888TEST_F(VoiceChannelSingleThreadTest, SendWithWritabilityLoss) {
[email protected]28e20752013-07-10 00:45:361889 Base::SendWithWritabilityLoss();
1890}
1891
Danil Chapovalov33b01f22016-05-11 17:55:271892TEST_F(VoiceChannelSingleThreadTest, TestSetContentFailure) {
[email protected]28e20752013-07-10 00:45:361893 Base::TestSetContentFailure();
1894}
1895
Danil Chapovalov33b01f22016-05-11 17:55:271896TEST_F(VoiceChannelSingleThreadTest, TestSendTwoOffers) {
[email protected]28e20752013-07-10 00:45:361897 Base::TestSendTwoOffers();
1898}
1899
Danil Chapovalov33b01f22016-05-11 17:55:271900TEST_F(VoiceChannelSingleThreadTest, TestReceiveTwoOffers) {
[email protected]28e20752013-07-10 00:45:361901 Base::TestReceiveTwoOffers();
1902}
1903
Danil Chapovalov33b01f22016-05-11 17:55:271904TEST_F(VoiceChannelSingleThreadTest, TestSendPrAnswer) {
[email protected]28e20752013-07-10 00:45:361905 Base::TestSendPrAnswer();
1906}
1907
Danil Chapovalov33b01f22016-05-11 17:55:271908TEST_F(VoiceChannelSingleThreadTest, TestReceivePrAnswer) {
[email protected]28e20752013-07-10 00:45:361909 Base::TestReceivePrAnswer();
1910}
1911
zstein56162b92017-04-24 23:54:351912TEST_F(VoiceChannelSingleThreadTest, TestOnTransportReadyToSend) {
1913 Base::TestOnTransportReadyToSend();
[email protected]28e20752013-07-10 00:45:361914}
1915
Danil Chapovalov33b01f22016-05-11 17:55:271916TEST_F(VoiceChannelSingleThreadTest, SendBundleToBundle) {
Danil Chapovalov52c16dc2025-06-02 07:57:151917 Base::SendBundleToBundle(kAudioPts, false, false);
[email protected]28e20752013-07-10 00:45:361918}
1919
Danil Chapovalov33b01f22016-05-11 17:55:271920TEST_F(VoiceChannelSingleThreadTest, SendBundleToBundleSecure) {
Danil Chapovalov52c16dc2025-06-02 07:57:151921 Base::SendBundleToBundle(kAudioPts, false, true);
[email protected]5ee0f052014-05-05 20:18:081922}
1923
Danil Chapovalov33b01f22016-05-11 17:55:271924TEST_F(VoiceChannelSingleThreadTest, SendBundleToBundleWithRtcpMux) {
Danil Chapovalov52c16dc2025-06-02 07:57:151925 Base::SendBundleToBundle(kAudioPts, true, false);
[email protected]5ee0f052014-05-05 20:18:081926}
1927
Danil Chapovalov33b01f22016-05-11 17:55:271928TEST_F(VoiceChannelSingleThreadTest, SendBundleToBundleWithRtcpMuxSecure) {
Danil Chapovalov52c16dc2025-06-02 07:57:151929 Base::SendBundleToBundle(kAudioPts, true, true);
[email protected]28e20752013-07-10 00:45:361930}
1931
Danil Chapovalov33b01f22016-05-11 17:55:271932TEST_F(VoiceChannelSingleThreadTest, DefaultMaxBitrateIsUnlimited) {
skvlade0d46372016-04-08 05:59:221933 Base::DefaultMaxBitrateIsUnlimited();
skvladdc1c62c2016-03-17 02:07:431934}
1935
Steve Anton8a63f782017-10-23 20:08:531936TEST_F(VoiceChannelSingleThreadTest, SocketOptionsMergedOnSetTransport) {
1937 Base::SocketOptionsMergedOnSetTransport();
1938}
1939
Per K38bb3312025-08-19 13:46:241940TEST_F(VoiceChannelSingleThreadTest, RemovesExtensionNotPresentInRemoteAnswer) {
1941 Base::TestRemovesExtensionNotPresentInRemoteAnswer();
1942}
1943
1944TEST_F(VoiceChannelSingleThreadTest, RemovesExtensionNotPresentInLocalAnswer) {
1945 Base::TestRemovesExtensionNotPresentInLocalAnswer();
1946}
1947
Danil Chapovalov33b01f22016-05-11 17:55:271948// VoiceChannelDoubleThreadTest
1949TEST_F(VoiceChannelDoubleThreadTest, TestInit) {
[email protected]28e20752013-07-10 00:45:361950 Base::TestInit();
Harald Alvestrand2f553702023-03-07 10:10:031951 EXPECT_FALSE(media_send_channel1_impl()->IsStreamMuted(0));
1952 EXPECT_TRUE(media_send_channel1_impl()->dtmf_info_queue().empty());
[email protected]28e20752013-07-10 00:45:361953}
1954
Danil Chapovalovdae07ba2016-05-13 23:43:501955TEST_F(VoiceChannelDoubleThreadTest, TestDeinit) {
1956 Base::TestDeinit();
1957}
1958
Danil Chapovalov33b01f22016-05-11 17:55:271959TEST_F(VoiceChannelDoubleThreadTest, TestSetContents) {
[email protected]28e20752013-07-10 00:45:361960 Base::TestSetContents();
1961}
1962
Johannes Kron9190b822018-10-29 10:22:051963TEST_F(VoiceChannelDoubleThreadTest, TestSetContentsExtmapAllowMixedAsCaller) {
1964 Base::TestSetContentsExtmapAllowMixedCaller(/*offer=*/true, /*answer=*/true);
1965}
1966
1967TEST_F(VoiceChannelDoubleThreadTest,
1968 TestSetContentsExtmapAllowMixedNotSupportedAsCaller) {
1969 Base::TestSetContentsExtmapAllowMixedCaller(/*offer=*/true, /*answer=*/false);
1970}
1971
1972TEST_F(VoiceChannelDoubleThreadTest, TestSetContentsExtmapAllowMixedAsCallee) {
1973 Base::TestSetContentsExtmapAllowMixedCallee(/*offer=*/true, /*answer=*/true);
1974}
1975
1976TEST_F(VoiceChannelDoubleThreadTest,
1977 TestSetContentsExtmapAllowMixedNotSupportedAsCallee) {
1978 Base::TestSetContentsExtmapAllowMixedCallee(/*offer=*/true, /*answer=*/false);
1979}
1980
Danil Chapovalov33b01f22016-05-11 17:55:271981TEST_F(VoiceChannelDoubleThreadTest, TestSetContentsNullOffer) {
[email protected]28e20752013-07-10 00:45:361982 Base::TestSetContentsNullOffer();
1983}
1984
Danil Chapovalov33b01f22016-05-11 17:55:271985TEST_F(VoiceChannelDoubleThreadTest, TestSetContentsRtcpMux) {
[email protected]28e20752013-07-10 00:45:361986 Base::TestSetContentsRtcpMux();
1987}
1988
Danil Chapovalov33b01f22016-05-11 17:55:271989TEST_F(VoiceChannelDoubleThreadTest, TestSetContentsRtcpMuxWithPrAnswer) {
[email protected]28e20752013-07-10 00:45:361990 Base::TestSetContentsRtcpMux();
1991}
1992
Tomas Lundqvistb40c5592024-11-22 13:45:271993TEST_F(VoiceChannelDoubleThreadTest, TestSetContentsRtcpReducedSize) {
1994 Base::TestSetContentsRtcpReducedSize();
1995}
1996
Danil Chapovalov33b01f22016-05-11 17:55:271997TEST_F(VoiceChannelDoubleThreadTest, TestChangeStreamParamsInContent) {
[email protected]28e20752013-07-10 00:45:361998 Base::TestChangeStreamParamsInContent();
1999}
2000
Danil Chapovalov33b01f22016-05-11 17:55:272001TEST_F(VoiceChannelDoubleThreadTest, TestPlayoutAndSendingStates) {
[email protected]28e20752013-07-10 00:45:362002 Base::TestPlayoutAndSendingStates();
2003}
2004
Danil Chapovalov33b01f22016-05-11 17:55:272005TEST_F(VoiceChannelDoubleThreadTest, TestMediaContentDirection) {
2006 Base::TestMediaContentDirection();
2007}
2008
2009TEST_F(VoiceChannelDoubleThreadTest, TestNetworkRouteChanges) {
2010 Base::TestNetworkRouteChanges();
2011}
2012
2013TEST_F(VoiceChannelDoubleThreadTest, TestCallSetup) {
2014 Base::TestCallSetup();
2015}
2016
Danil Chapovalov33b01f22016-05-11 17:55:272017TEST_F(VoiceChannelDoubleThreadTest, SendRtpToRtp) {
2018 Base::SendRtpToRtp();
2019}
2020
Danil Chapovalov33b01f22016-05-11 17:55:272021TEST_F(VoiceChannelDoubleThreadTest, SendDtlsSrtpToDtlsSrtp) {
Zhi Huange830e682018-03-30 17:48:352022 Base::SendDtlsSrtpToDtlsSrtp(0, 0);
Danil Chapovalov33b01f22016-05-11 17:55:272023}
2024
2025TEST_F(VoiceChannelDoubleThreadTest, SendDtlsSrtpToDtlsSrtpRtcpMux) {
Zhi Huange830e682018-03-30 17:48:352026 Base::SendDtlsSrtpToDtlsSrtp(RTCP_MUX, RTCP_MUX);
deadbeeff5346592017-01-25 05:51:212027}
2028
Danil Chapovalov33b01f22016-05-11 17:55:272029TEST_F(VoiceChannelDoubleThreadTest, SendEarlyMediaUsingRtcpMuxSrtp) {
2030 Base::SendEarlyMediaUsingRtcpMuxSrtp();
2031}
2032
2033TEST_F(VoiceChannelDoubleThreadTest, SendRtpToRtpOnThread) {
2034 Base::SendRtpToRtpOnThread();
2035}
2036
Danil Chapovalov33b01f22016-05-11 17:55:272037TEST_F(VoiceChannelDoubleThreadTest, SendWithWritabilityLoss) {
2038 Base::SendWithWritabilityLoss();
2039}
2040
Danil Chapovalov33b01f22016-05-11 17:55:272041TEST_F(VoiceChannelDoubleThreadTest, TestSetContentFailure) {
2042 Base::TestSetContentFailure();
2043}
2044
2045TEST_F(VoiceChannelDoubleThreadTest, TestSendTwoOffers) {
2046 Base::TestSendTwoOffers();
2047}
2048
2049TEST_F(VoiceChannelDoubleThreadTest, TestReceiveTwoOffers) {
2050 Base::TestReceiveTwoOffers();
2051}
2052
2053TEST_F(VoiceChannelDoubleThreadTest, TestSendPrAnswer) {
2054 Base::TestSendPrAnswer();
2055}
2056
2057TEST_F(VoiceChannelDoubleThreadTest, TestReceivePrAnswer) {
2058 Base::TestReceivePrAnswer();
2059}
2060
zstein56162b92017-04-24 23:54:352061TEST_F(VoiceChannelDoubleThreadTest, TestOnTransportReadyToSend) {
2062 Base::TestOnTransportReadyToSend();
Danil Chapovalov33b01f22016-05-11 17:55:272063}
2064
Danil Chapovalov33b01f22016-05-11 17:55:272065TEST_F(VoiceChannelDoubleThreadTest, SendBundleToBundle) {
Danil Chapovalov52c16dc2025-06-02 07:57:152066 Base::SendBundleToBundle(kAudioPts, false, false);
Danil Chapovalov33b01f22016-05-11 17:55:272067}
2068
2069TEST_F(VoiceChannelDoubleThreadTest, SendBundleToBundleSecure) {
Danil Chapovalov52c16dc2025-06-02 07:57:152070 Base::SendBundleToBundle(kAudioPts, false, true);
Danil Chapovalov33b01f22016-05-11 17:55:272071}
2072
2073TEST_F(VoiceChannelDoubleThreadTest, SendBundleToBundleWithRtcpMux) {
Danil Chapovalov52c16dc2025-06-02 07:57:152074 Base::SendBundleToBundle(kAudioPts, true, false);
Danil Chapovalov33b01f22016-05-11 17:55:272075}
2076
2077TEST_F(VoiceChannelDoubleThreadTest, SendBundleToBundleWithRtcpMuxSecure) {
Danil Chapovalov52c16dc2025-06-02 07:57:152078 Base::SendBundleToBundle(kAudioPts, true, true);
Danil Chapovalov33b01f22016-05-11 17:55:272079}
2080
2081TEST_F(VoiceChannelDoubleThreadTest, DefaultMaxBitrateIsUnlimited) {
2082 Base::DefaultMaxBitrateIsUnlimited();
2083}
2084
Steve Anton8a63f782017-10-23 20:08:532085TEST_F(VoiceChannelDoubleThreadTest, SocketOptionsMergedOnSetTransport) {
2086 Base::SocketOptionsMergedOnSetTransport();
2087}
2088
Danil Chapovalov33b01f22016-05-11 17:55:272089// VideoChannelSingleThreadTest
2090TEST_F(VideoChannelSingleThreadTest, TestInit) {
2091 Base::TestInit();
2092}
2093
Danil Chapovalovdae07ba2016-05-13 23:43:502094TEST_F(VideoChannelSingleThreadTest, TestDeinit) {
2095 Base::TestDeinit();
2096}
2097
Danil Chapovalov33b01f22016-05-11 17:55:272098TEST_F(VideoChannelSingleThreadTest, TestSetContents) {
2099 Base::TestSetContents();
2100}
2101
Johannes Kron9190b822018-10-29 10:22:052102TEST_F(VideoChannelSingleThreadTest, TestSetContentsExtmapAllowMixedAsCaller) {
2103 Base::TestSetContentsExtmapAllowMixedCaller(/*offer=*/true, /*answer=*/true);
2104}
2105
2106TEST_F(VideoChannelSingleThreadTest,
2107 TestSetContentsExtmapAllowMixedNotSupportedAsCaller) {
2108 Base::TestSetContentsExtmapAllowMixedCaller(/*offer=*/true, /*answer=*/false);
2109}
2110
2111TEST_F(VideoChannelSingleThreadTest, TestSetContentsExtmapAllowMixedAsCallee) {
2112 Base::TestSetContentsExtmapAllowMixedCallee(/*offer=*/true, /*answer=*/true);
2113}
2114
2115TEST_F(VideoChannelSingleThreadTest,
2116 TestSetContentsExtmapAllowMixedNotSupportedAsCallee) {
2117 Base::TestSetContentsExtmapAllowMixedCallee(/*offer=*/true, /*answer=*/false);
2118}
2119
Danil Chapovalov33b01f22016-05-11 17:55:272120TEST_F(VideoChannelSingleThreadTest, TestSetContentsNullOffer) {
2121 Base::TestSetContentsNullOffer();
2122}
2123
2124TEST_F(VideoChannelSingleThreadTest, TestSetContentsRtcpMux) {
2125 Base::TestSetContentsRtcpMux();
2126}
2127
2128TEST_F(VideoChannelSingleThreadTest, TestSetContentsRtcpMuxWithPrAnswer) {
2129 Base::TestSetContentsRtcpMux();
2130}
2131
Danil Chapovalov33b01f22016-05-11 17:55:272132TEST_F(VideoChannelSingleThreadTest, TestChangeStreamParamsInContent) {
2133 Base::TestChangeStreamParamsInContent();
2134}
2135
2136TEST_F(VideoChannelSingleThreadTest, TestPlayoutAndSendingStates) {
2137 Base::TestPlayoutAndSendingStates();
2138}
2139
Danil Chapovalov33b01f22016-05-11 17:55:272140TEST_F(VideoChannelSingleThreadTest, TestMediaContentDirection) {
[email protected]28e20752013-07-10 00:45:362141 Base::TestMediaContentDirection();
2142}
2143
Danil Chapovalov33b01f22016-05-11 17:55:272144TEST_F(VideoChannelSingleThreadTest, TestNetworkRouteChanges) {
Honghai Zhangcc411c02016-03-30 00:27:212145 Base::TestNetworkRouteChanges();
2146}
2147
Danil Chapovalov33b01f22016-05-11 17:55:272148TEST_F(VideoChannelSingleThreadTest, TestCallSetup) {
[email protected]28e20752013-07-10 00:45:362149 Base::TestCallSetup();
2150}
2151
Danil Chapovalov33b01f22016-05-11 17:55:272152TEST_F(VideoChannelSingleThreadTest, SendRtpToRtp) {
[email protected]28e20752013-07-10 00:45:362153 Base::SendRtpToRtp();
2154}
2155
Danil Chapovalov33b01f22016-05-11 17:55:272156TEST_F(VideoChannelSingleThreadTest, SendDtlsSrtpToDtlsSrtp) {
Zhi Huange830e682018-03-30 17:48:352157 Base::SendDtlsSrtpToDtlsSrtp(0, 0);
[email protected]28e20752013-07-10 00:45:362158}
2159
Danil Chapovalov33b01f22016-05-11 17:55:272160TEST_F(VideoChannelSingleThreadTest, SendDtlsSrtpToDtlsSrtpRtcpMux) {
Zhi Huange830e682018-03-30 17:48:352161 Base::SendDtlsSrtpToDtlsSrtp(RTCP_MUX, RTCP_MUX);
[email protected]28e20752013-07-10 00:45:362162}
2163
Danil Chapovalov33b01f22016-05-11 17:55:272164TEST_F(VideoChannelSingleThreadTest, SendEarlyMediaUsingRtcpMuxSrtp) {
[email protected]28e20752013-07-10 00:45:362165 Base::SendEarlyMediaUsingRtcpMuxSrtp();
2166}
2167
Danil Chapovalov33b01f22016-05-11 17:55:272168TEST_F(VideoChannelSingleThreadTest, SendRtpToRtpOnThread) {
[email protected]28e20752013-07-10 00:45:362169 Base::SendRtpToRtpOnThread();
2170}
2171
Danil Chapovalov33b01f22016-05-11 17:55:272172TEST_F(VideoChannelSingleThreadTest, SendWithWritabilityLoss) {
[email protected]28e20752013-07-10 00:45:362173 Base::SendWithWritabilityLoss();
2174}
2175
Danil Chapovalov33b01f22016-05-11 17:55:272176TEST_F(VideoChannelSingleThreadTest, TestSetContentFailure) {
[email protected]28e20752013-07-10 00:45:362177 Base::TestSetContentFailure();
2178}
2179
Danil Chapovalov33b01f22016-05-11 17:55:272180TEST_F(VideoChannelSingleThreadTest, TestSendTwoOffers) {
[email protected]28e20752013-07-10 00:45:362181 Base::TestSendTwoOffers();
2182}
2183
Danil Chapovalov33b01f22016-05-11 17:55:272184TEST_F(VideoChannelSingleThreadTest, TestReceiveTwoOffers) {
[email protected]28e20752013-07-10 00:45:362185 Base::TestReceiveTwoOffers();
2186}
2187
Danil Chapovalov33b01f22016-05-11 17:55:272188TEST_F(VideoChannelSingleThreadTest, TestSendPrAnswer) {
[email protected]28e20752013-07-10 00:45:362189 Base::TestSendPrAnswer();
2190}
2191
Danil Chapovalov33b01f22016-05-11 17:55:272192TEST_F(VideoChannelSingleThreadTest, TestReceivePrAnswer) {
[email protected]28e20752013-07-10 00:45:362193 Base::TestReceivePrAnswer();
2194}
2195
Danil Chapovalov33b01f22016-05-11 17:55:272196TEST_F(VideoChannelSingleThreadTest, SendBundleToBundle) {
Danil Chapovalov52c16dc2025-06-02 07:57:152197 Base::SendBundleToBundle(kVideoPts, false, false);
[email protected]28e20752013-07-10 00:45:362198}
2199
Danil Chapovalov33b01f22016-05-11 17:55:272200TEST_F(VideoChannelSingleThreadTest, SendBundleToBundleSecure) {
Danil Chapovalov52c16dc2025-06-02 07:57:152201 Base::SendBundleToBundle(kVideoPts, false, true);
[email protected]5ee0f052014-05-05 20:18:082202}
2203
Danil Chapovalov33b01f22016-05-11 17:55:272204TEST_F(VideoChannelSingleThreadTest, SendBundleToBundleWithRtcpMux) {
Danil Chapovalov52c16dc2025-06-02 07:57:152205 Base::SendBundleToBundle(kVideoPts, true, false);
[email protected]5ee0f052014-05-05 20:18:082206}
2207
Danil Chapovalov33b01f22016-05-11 17:55:272208TEST_F(VideoChannelSingleThreadTest, SendBundleToBundleWithRtcpMuxSecure) {
Danil Chapovalov52c16dc2025-06-02 07:57:152209 Base::SendBundleToBundle(kVideoPts, true, true);
[email protected]28e20752013-07-10 00:45:362210}
2211
zstein56162b92017-04-24 23:54:352212TEST_F(VideoChannelSingleThreadTest, TestOnTransportReadyToSend) {
2213 Base::TestOnTransportReadyToSend();
[email protected]28e20752013-07-10 00:45:362214}
2215
Danil Chapovalov33b01f22016-05-11 17:55:272216TEST_F(VideoChannelSingleThreadTest, DefaultMaxBitrateIsUnlimited) {
skvladdc1c62c2016-03-17 02:07:432217 Base::DefaultMaxBitrateIsUnlimited();
2218}
2219
Steve Anton8a63f782017-10-23 20:08:532220TEST_F(VideoChannelSingleThreadTest, SocketOptionsMergedOnSetTransport) {
2221 Base::SocketOptionsMergedOnSetTransport();
2222}
2223
Amit Hilbuchbcd39d42019-01-26 01:13:562224TEST_F(VideoChannelSingleThreadTest, UpdateLocalStreamsWithSimulcast) {
2225 Base::TestUpdateLocalStreamsWithSimulcast();
2226}
2227
Per K38bb3312025-08-19 13:46:242228TEST_F(VideoChannelSingleThreadTest, RemovesExtensionNotPresentInRemoteAnswer) {
2229 Base::TestRemovesExtensionNotPresentInRemoteAnswer();
2230}
2231
2232TEST_F(VideoChannelSingleThreadTest, RemovesExtensionNotPresentInLocalAnswer) {
2233 Base::TestRemovesExtensionNotPresentInLocalAnswer();
2234}
2235
Mirta Dvornicic479a3c02019-06-04 13:38:502236TEST_F(VideoChannelSingleThreadTest, TestSetLocalOfferWithPacketization) {
Evan Shrubsole0b212e32025-04-07 13:43:012237 const webrtc::Codec kVp8Codec = webrtc::CreateVideoCodec(97, "VP8");
2238 webrtc::Codec vp9_codec = webrtc::CreateVideoCodec(98, "VP9");
Evan Shrubsole945e5172025-04-08 14:11:452239 vp9_codec.packetization = webrtc::kPacketizationParamRaw;
Evan Shrubsole080cdac2025-03-20 09:34:482240 webrtc::VideoContentDescription video;
Mirta Dvornicic479a3c02019-06-04 13:38:502241 video.set_codecs({kVp8Codec, vp9_codec});
2242
2243 CreateChannels(0, 0);
2244
Tomas Gunnarssond908d742022-01-05 10:44:262245 std::string err;
2246 EXPECT_TRUE(channel1_->SetLocalContent(&video, SdpType::kOffer, err));
Harald Alvestrand2f553702023-03-07 10:10:032247 EXPECT_THAT(media_send_channel1_impl()->send_codecs(), testing::IsEmpty());
2248 ASSERT_THAT(media_receive_channel1_impl()->recv_codecs(), testing::SizeIs(2));
Emil Lundmarkf268afd2023-11-08 15:34:112249 EXPECT_TRUE(
2250 media_receive_channel1_impl()->recv_codecs()[0].Matches(kVp8Codec));
Harald Alvestrand2f553702023-03-07 10:10:032251 EXPECT_EQ(media_receive_channel1_impl()->recv_codecs()[0].packetization,
Florent Castelli8037fc62024-08-29 13:00:402252 std::nullopt);
Emil Lundmarkf268afd2023-11-08 15:34:112253 EXPECT_TRUE(
2254 media_receive_channel1_impl()->recv_codecs()[1].Matches(vp9_codec));
Harald Alvestrand2f553702023-03-07 10:10:032255 EXPECT_EQ(media_receive_channel1_impl()->recv_codecs()[1].packetization,
Evan Shrubsole945e5172025-04-08 14:11:452256 webrtc::kPacketizationParamRaw);
Mirta Dvornicic479a3c02019-06-04 13:38:502257}
2258
2259TEST_F(VideoChannelSingleThreadTest, TestSetRemoteOfferWithPacketization) {
Evan Shrubsole0b212e32025-04-07 13:43:012260 const webrtc::Codec kVp8Codec = webrtc::CreateVideoCodec(97, "VP8");
2261 webrtc::Codec vp9_codec = webrtc::CreateVideoCodec(98, "VP9");
Evan Shrubsole945e5172025-04-08 14:11:452262 vp9_codec.packetization = webrtc::kPacketizationParamRaw;
Evan Shrubsole080cdac2025-03-20 09:34:482263 webrtc::VideoContentDescription video;
Mirta Dvornicic479a3c02019-06-04 13:38:502264 video.set_codecs({kVp8Codec, vp9_codec});
2265
2266 CreateChannels(0, 0);
2267
Tomas Gunnarssond908d742022-01-05 10:44:262268 std::string err;
2269 EXPECT_TRUE(channel1_->SetRemoteContent(&video, SdpType::kOffer, err));
2270 EXPECT_TRUE(err.empty());
Harald Alvestrand2f553702023-03-07 10:10:032271 EXPECT_THAT(media_receive_channel1_impl()->recv_codecs(), testing::IsEmpty());
2272 ASSERT_THAT(media_send_channel1_impl()->send_codecs(), testing::SizeIs(2));
Emil Lundmarkf268afd2023-11-08 15:34:112273 EXPECT_TRUE(media_send_channel1_impl()->send_codecs()[0].Matches(kVp8Codec));
Harald Alvestrand2f553702023-03-07 10:10:032274 EXPECT_EQ(media_send_channel1_impl()->send_codecs()[0].packetization,
Florent Castelli8037fc62024-08-29 13:00:402275 std::nullopt);
Emil Lundmarkf268afd2023-11-08 15:34:112276 EXPECT_TRUE(media_send_channel1_impl()->send_codecs()[1].Matches(vp9_codec));
Harald Alvestrand2f553702023-03-07 10:10:032277 EXPECT_EQ(media_send_channel1_impl()->send_codecs()[1].packetization,
Evan Shrubsole945e5172025-04-08 14:11:452278 webrtc::kPacketizationParamRaw);
Mirta Dvornicic479a3c02019-06-04 13:38:502279}
2280
2281TEST_F(VideoChannelSingleThreadTest, TestSetAnswerWithPacketization) {
Evan Shrubsole0b212e32025-04-07 13:43:012282 const webrtc::Codec kVp8Codec = webrtc::CreateVideoCodec(97, "VP8");
2283 webrtc::Codec vp9_codec = webrtc::CreateVideoCodec(98, "VP9");
Evan Shrubsole945e5172025-04-08 14:11:452284 vp9_codec.packetization = webrtc::kPacketizationParamRaw;
Evan Shrubsole080cdac2025-03-20 09:34:482285 webrtc::VideoContentDescription video;
Mirta Dvornicic479a3c02019-06-04 13:38:502286 video.set_codecs({kVp8Codec, vp9_codec});
2287
2288 CreateChannels(0, 0);
2289
Tomas Gunnarssond908d742022-01-05 10:44:262290 std::string err;
2291 EXPECT_TRUE(channel1_->SetLocalContent(&video, SdpType::kOffer, err));
2292 EXPECT_TRUE(err.empty());
2293 EXPECT_TRUE(channel1_->SetRemoteContent(&video, SdpType::kAnswer, err));
2294 EXPECT_TRUE(err.empty());
Harald Alvestrand2f553702023-03-07 10:10:032295 ASSERT_THAT(media_receive_channel1_impl()->recv_codecs(), testing::SizeIs(2));
Emil Lundmarkf268afd2023-11-08 15:34:112296 EXPECT_TRUE(
2297 media_receive_channel1_impl()->recv_codecs()[0].Matches(kVp8Codec));
Harald Alvestrand2f553702023-03-07 10:10:032298 EXPECT_EQ(media_receive_channel1_impl()->recv_codecs()[0].packetization,
Florent Castelli8037fc62024-08-29 13:00:402299 std::nullopt);
Emil Lundmarkf268afd2023-11-08 15:34:112300 EXPECT_TRUE(
2301 media_receive_channel1_impl()->recv_codecs()[1].Matches(vp9_codec));
Harald Alvestrand2f553702023-03-07 10:10:032302 EXPECT_EQ(media_receive_channel1_impl()->recv_codecs()[1].packetization,
Evan Shrubsole945e5172025-04-08 14:11:452303 webrtc::kPacketizationParamRaw);
Harald Alvestrand2f553702023-03-07 10:10:032304 EXPECT_THAT(media_send_channel1_impl()->send_codecs(), testing::SizeIs(2));
Emil Lundmarkf268afd2023-11-08 15:34:112305 EXPECT_TRUE(media_send_channel1_impl()->send_codecs()[0].Matches(kVp8Codec));
Harald Alvestrand2f553702023-03-07 10:10:032306 EXPECT_EQ(media_send_channel1_impl()->send_codecs()[0].packetization,
Florent Castelli8037fc62024-08-29 13:00:402307 std::nullopt);
Emil Lundmarkf268afd2023-11-08 15:34:112308 EXPECT_TRUE(media_send_channel1_impl()->send_codecs()[1].Matches(vp9_codec));
Harald Alvestrand2f553702023-03-07 10:10:032309 EXPECT_EQ(media_send_channel1_impl()->send_codecs()[1].packetization,
Evan Shrubsole945e5172025-04-08 14:11:452310 webrtc::kPacketizationParamRaw);
Mirta Dvornicic479a3c02019-06-04 13:38:502311}
2312
2313TEST_F(VideoChannelSingleThreadTest, TestSetLocalAnswerWithoutPacketization) {
Evan Shrubsole0b212e32025-04-07 13:43:012314 const webrtc::Codec kLocalCodec = webrtc::CreateVideoCodec(98, "VP8");
2315 webrtc::Codec remote_codec = webrtc::CreateVideoCodec(99, "VP8");
Evan Shrubsole945e5172025-04-08 14:11:452316 remote_codec.packetization = webrtc::kPacketizationParamRaw;
Evan Shrubsole080cdac2025-03-20 09:34:482317 webrtc::VideoContentDescription local_video;
Mirta Dvornicic479a3c02019-06-04 13:38:502318 local_video.set_codecs({kLocalCodec});
Evan Shrubsole080cdac2025-03-20 09:34:482319 webrtc::VideoContentDescription remote_video;
Mirta Dvornicic479a3c02019-06-04 13:38:502320 remote_video.set_codecs({remote_codec});
2321
2322 CreateChannels(0, 0);
2323
Tomas Gunnarssond908d742022-01-05 10:44:262324 std::string err;
2325 EXPECT_TRUE(channel1_->SetRemoteContent(&remote_video, SdpType::kOffer, err));
2326 EXPECT_TRUE(channel1_->SetLocalContent(&local_video, SdpType::kAnswer, err));
Harald Alvestrand2f553702023-03-07 10:10:032327 ASSERT_THAT(media_receive_channel1_impl()->recv_codecs(), testing::SizeIs(1));
2328 EXPECT_EQ(media_receive_channel1_impl()->recv_codecs()[0].packetization,
Florent Castelli8037fc62024-08-29 13:00:402329 std::nullopt);
Harald Alvestrand2f553702023-03-07 10:10:032330 ASSERT_THAT(media_send_channel1_impl()->send_codecs(), testing::SizeIs(1));
2331 EXPECT_EQ(media_send_channel1_impl()->send_codecs()[0].packetization,
Florent Castelli8037fc62024-08-29 13:00:402332 std::nullopt);
Mirta Dvornicic479a3c02019-06-04 13:38:502333}
2334
2335TEST_F(VideoChannelSingleThreadTest, TestSetRemoteAnswerWithoutPacketization) {
Evan Shrubsole0b212e32025-04-07 13:43:012336 webrtc::Codec local_codec = webrtc::CreateVideoCodec(98, "VP8");
Evan Shrubsole945e5172025-04-08 14:11:452337 local_codec.packetization = webrtc::kPacketizationParamRaw;
Evan Shrubsole0b212e32025-04-07 13:43:012338 const webrtc::Codec kRemoteCodec = webrtc::CreateVideoCodec(99, "VP8");
Evan Shrubsole080cdac2025-03-20 09:34:482339 webrtc::VideoContentDescription local_video;
Mirta Dvornicic479a3c02019-06-04 13:38:502340 local_video.set_codecs({local_codec});
Evan Shrubsole080cdac2025-03-20 09:34:482341 webrtc::VideoContentDescription remote_video;
Mirta Dvornicic479a3c02019-06-04 13:38:502342 remote_video.set_codecs({kRemoteCodec});
2343
2344 CreateChannels(0, 0);
2345
Tomas Gunnarssond908d742022-01-05 10:44:262346 std::string err;
2347 EXPECT_TRUE(channel1_->SetLocalContent(&local_video, SdpType::kOffer, err));
Mirta Dvornicic479a3c02019-06-04 13:38:502348 EXPECT_TRUE(
Tomas Gunnarssond908d742022-01-05 10:44:262349 channel1_->SetRemoteContent(&remote_video, SdpType::kAnswer, err));
Harald Alvestrand2f553702023-03-07 10:10:032350 ASSERT_THAT(media_receive_channel1_impl()->recv_codecs(), testing::SizeIs(1));
2351 EXPECT_EQ(media_receive_channel1_impl()->recv_codecs()[0].packetization,
Florent Castelli8037fc62024-08-29 13:00:402352 std::nullopt);
Harald Alvestrand2f553702023-03-07 10:10:032353 ASSERT_THAT(media_send_channel1_impl()->send_codecs(), testing::SizeIs(1));
2354 EXPECT_EQ(media_send_channel1_impl()->send_codecs()[0].packetization,
Florent Castelli8037fc62024-08-29 13:00:402355 std::nullopt);
Mirta Dvornicic479a3c02019-06-04 13:38:502356}
2357
2358TEST_F(VideoChannelSingleThreadTest,
2359 TestSetRemoteAnswerWithInvalidPacketization) {
Evan Shrubsole0b212e32025-04-07 13:43:012360 webrtc::Codec local_codec = webrtc::CreateVideoCodec(98, "VP8");
Evan Shrubsole945e5172025-04-08 14:11:452361 local_codec.packetization = webrtc::kPacketizationParamRaw;
Evan Shrubsole0b212e32025-04-07 13:43:012362 webrtc::Codec remote_codec = webrtc::CreateVideoCodec(99, "VP8");
Mirta Dvornicic479a3c02019-06-04 13:38:502363 remote_codec.packetization = "unknownpacketizationattributevalue";
Evan Shrubsole080cdac2025-03-20 09:34:482364 webrtc::VideoContentDescription local_video;
Mirta Dvornicic479a3c02019-06-04 13:38:502365 local_video.set_codecs({local_codec});
Evan Shrubsole080cdac2025-03-20 09:34:482366 webrtc::VideoContentDescription remote_video;
Mirta Dvornicic479a3c02019-06-04 13:38:502367 remote_video.set_codecs({remote_codec});
2368
2369 CreateChannels(0, 0);
2370
Tomas Gunnarssond908d742022-01-05 10:44:262371 std::string err;
2372 EXPECT_TRUE(channel1_->SetLocalContent(&local_video, SdpType::kOffer, err));
2373 EXPECT_TRUE(err.empty());
Mirta Dvornicic479a3c02019-06-04 13:38:502374 EXPECT_FALSE(
Tomas Gunnarssond908d742022-01-05 10:44:262375 channel1_->SetRemoteContent(&remote_video, SdpType::kAnswer, err));
2376 EXPECT_FALSE(err.empty());
Harald Alvestrand2f553702023-03-07 10:10:032377 ASSERT_THAT(media_receive_channel1_impl()->recv_codecs(), testing::SizeIs(1));
2378 EXPECT_EQ(media_receive_channel1_impl()->recv_codecs()[0].packetization,
Evan Shrubsole945e5172025-04-08 14:11:452379 webrtc::kPacketizationParamRaw);
Harald Alvestrand2f553702023-03-07 10:10:032380 EXPECT_THAT(media_send_channel1_impl()->send_codecs(), testing::IsEmpty());
Mirta Dvornicic479a3c02019-06-04 13:38:502381}
2382
2383TEST_F(VideoChannelSingleThreadTest,
2384 TestSetLocalAnswerWithInvalidPacketization) {
Evan Shrubsole0b212e32025-04-07 13:43:012385 webrtc::Codec local_codec = webrtc::CreateVideoCodec(98, "VP8");
Evan Shrubsole945e5172025-04-08 14:11:452386 local_codec.packetization = webrtc::kPacketizationParamRaw;
Evan Shrubsole0b212e32025-04-07 13:43:012387 const webrtc::Codec kRemoteCodec = webrtc::CreateVideoCodec(99, "VP8");
Evan Shrubsole080cdac2025-03-20 09:34:482388 webrtc::VideoContentDescription local_video;
Mirta Dvornicic479a3c02019-06-04 13:38:502389 local_video.set_codecs({local_codec});
Evan Shrubsole080cdac2025-03-20 09:34:482390 webrtc::VideoContentDescription remote_video;
Mirta Dvornicic479a3c02019-06-04 13:38:502391 remote_video.set_codecs({kRemoteCodec});
2392
2393 CreateChannels(0, 0);
2394
Tomas Gunnarssond908d742022-01-05 10:44:262395 std::string err;
2396 EXPECT_TRUE(channel1_->SetRemoteContent(&remote_video, SdpType::kOffer, err));
2397 EXPECT_TRUE(err.empty());
2398 EXPECT_FALSE(channel1_->SetLocalContent(&local_video, SdpType::kAnswer, err));
2399 EXPECT_FALSE(err.empty());
Harald Alvestrand2f553702023-03-07 10:10:032400 EXPECT_THAT(media_receive_channel1_impl()->recv_codecs(), testing::IsEmpty());
2401 ASSERT_THAT(media_send_channel1_impl()->send_codecs(), testing::SizeIs(1));
2402 EXPECT_EQ(media_send_channel1_impl()->send_codecs()[0].packetization,
Florent Castelli8037fc62024-08-29 13:00:402403 std::nullopt);
Mirta Dvornicic479a3c02019-06-04 13:38:502404}
2405
Emil Lundmark17304c32023-09-15 14:33:032406TEST_F(VideoChannelSingleThreadTest,
2407 StopsPacketizationVerificationWhenMatchIsFoundInRemoteAnswer) {
Evan Shrubsole0b212e32025-04-07 13:43:012408 webrtc::Codec vp8_foo = webrtc::CreateVideoCodec(96, "VP8");
Emil Lundmark17304c32023-09-15 14:33:032409 vp8_foo.packetization = "foo";
Evan Shrubsole0b212e32025-04-07 13:43:012410 webrtc::Codec vp8_bar = webrtc::CreateVideoCodec(97, "VP8");
Emil Lundmark17304c32023-09-15 14:33:032411 vp8_bar.packetization = "bar";
Evan Shrubsole0b212e32025-04-07 13:43:012412 webrtc::Codec vp9 = webrtc::CreateVideoCodec(98, "VP9");
2413 webrtc::Codec vp9_foo = webrtc::CreateVideoCodec(99, "VP9");
Emil Lundmark17304c32023-09-15 14:33:032414 vp9_foo.packetization = "bar";
Evan Shrubsole080cdac2025-03-20 09:34:482415 webrtc::VideoContentDescription local;
Emil Lundmark17304c32023-09-15 14:33:032416 local.set_codecs({vp8_foo, vp8_bar, vp9_foo});
Evan Shrubsole080cdac2025-03-20 09:34:482417 webrtc::VideoContentDescription remote;
Emil Lundmark17304c32023-09-15 14:33:032418 remote.set_codecs({vp8_foo, vp9});
2419
2420 CreateChannels(0, 0);
2421 std::string err;
2422 ASSERT_TRUE(channel1_->SetLocalContent(&local, SdpType::kOffer, err)) << err;
2423 ASSERT_TRUE(channel1_->SetRemoteContent(&remote, SdpType::kAnswer, err))
2424 << err;
2425
2426 EXPECT_THAT(
2427 media_receive_channel1_impl()->recv_codecs(),
Evan Shrubsole0b212e32025-04-07 13:43:012428 ElementsAre(AllOf(Field(&webrtc::Codec::id, 96),
2429 Field(&webrtc::Codec::packetization, "foo")),
2430 AllOf(Field(&webrtc::Codec::id, 97),
2431 Field(&webrtc::Codec::packetization, "bar")),
2432 AllOf(Field(&webrtc::Codec::id, 99),
2433 Field(&webrtc::Codec::packetization, std::nullopt))));
Emil Lundmark17304c32023-09-15 14:33:032434 EXPECT_THAT(
2435 media_send_channel1_impl()->send_codecs(),
Evan Shrubsole0b212e32025-04-07 13:43:012436 ElementsAre(AllOf(Field(&webrtc::Codec::id, 96),
2437 Field(&webrtc::Codec::packetization, "foo")),
2438 AllOf(Field(&webrtc::Codec::id, 98),
2439 Field(&webrtc::Codec::packetization, std::nullopt))));
Emil Lundmark17304c32023-09-15 14:33:032440}
2441
2442TEST_F(VideoChannelSingleThreadTest,
2443 StopsPacketizationVerificationWhenMatchIsFoundInLocalAnswer) {
Evan Shrubsole0b212e32025-04-07 13:43:012444 webrtc::Codec vp8_foo = webrtc::CreateVideoCodec(96, "VP8");
Emil Lundmark17304c32023-09-15 14:33:032445 vp8_foo.packetization = "foo";
Evan Shrubsole0b212e32025-04-07 13:43:012446 webrtc::Codec vp8_bar = webrtc::CreateVideoCodec(97, "VP8");
Emil Lundmark17304c32023-09-15 14:33:032447 vp8_bar.packetization = "bar";
Evan Shrubsole0b212e32025-04-07 13:43:012448 webrtc::Codec vp9 = webrtc::CreateVideoCodec(98, "VP9");
2449 webrtc::Codec vp9_foo = webrtc::CreateVideoCodec(99, "VP9");
Emil Lundmark17304c32023-09-15 14:33:032450 vp9_foo.packetization = "bar";
Evan Shrubsole080cdac2025-03-20 09:34:482451 webrtc::VideoContentDescription local;
Emil Lundmark17304c32023-09-15 14:33:032452 local.set_codecs({vp8_foo, vp9});
Evan Shrubsole080cdac2025-03-20 09:34:482453 webrtc::VideoContentDescription remote;
Emil Lundmark17304c32023-09-15 14:33:032454 remote.set_codecs({vp8_foo, vp8_bar, vp9_foo});
2455
2456 CreateChannels(0, 0);
2457 std::string err;
2458 ASSERT_TRUE(channel1_->SetRemoteContent(&remote, SdpType::kOffer, err))
2459 << err;
2460 ASSERT_TRUE(channel1_->SetLocalContent(&local, SdpType::kAnswer, err)) << err;
2461
2462 EXPECT_THAT(
2463 media_receive_channel1_impl()->recv_codecs(),
Harald Alvestrande30dd592025-07-16 07:39:242464 ElementsAre(
2465 AllOf(Field("id", &webrtc::Codec::id, 96),
2466 Field("packetization", &webrtc::Codec::packetization, "foo")),
2467 AllOf(Field("id", &webrtc::Codec::id, 98),
2468 Field("packetization", &webrtc::Codec::packetization,
2469 std::nullopt))));
Emil Lundmark17304c32023-09-15 14:33:032470 EXPECT_THAT(
2471 media_send_channel1_impl()->send_codecs(),
Harald Alvestrande30dd592025-07-16 07:39:242472 ElementsAre(
2473 AllOf(Field("id", &webrtc::Codec::id, 96),
2474 Field("packetization", &webrtc::Codec::packetization, "foo")),
2475 AllOf(Field("id", &webrtc::Codec::id, 97),
2476 Field("packetization", &webrtc::Codec::packetization, "bar")),
2477 AllOf(Field("id", &webrtc::Codec::id, 99),
2478 Field("packetization", &webrtc::Codec::packetization,
2479 std::nullopt))));
Emil Lundmark17304c32023-09-15 14:33:032480}
2481
Emil Lundmarkec826272023-09-20 10:22:392482TEST_F(VideoChannelSingleThreadTest,
2483 ConsidersAllCodecsWithDiffrentPacketizationsInRemoteAnswer) {
Evan Shrubsole0b212e32025-04-07 13:43:012484 webrtc::Codec vp8 = webrtc::CreateVideoCodec(96, "VP8");
2485 webrtc::Codec vp8_raw = webrtc::CreateVideoCodec(97, "VP8");
Evan Shrubsole945e5172025-04-08 14:11:452486 vp8_raw.packetization = webrtc::kPacketizationParamRaw;
Evan Shrubsole080cdac2025-03-20 09:34:482487 webrtc::VideoContentDescription local;
Emil Lundmarkec826272023-09-20 10:22:392488 local.set_codecs({vp8, vp8_raw});
Evan Shrubsole080cdac2025-03-20 09:34:482489 webrtc::VideoContentDescription remote;
Emil Lundmarkec826272023-09-20 10:22:392490 remote.set_codecs({vp8_raw, vp8});
2491
2492 CreateChannels(0, 0);
2493 std::string err;
2494 ASSERT_TRUE(channel1_->SetLocalContent(&local, SdpType::kOffer, err)) << err;
2495 ASSERT_TRUE(channel1_->SetRemoteContent(&remote, SdpType::kAnswer, err))
2496 << err;
2497
Harald Alvestrand4a960602025-07-29 15:51:102498 EXPECT_THAT(media_receive_channel1_impl()->recv_codecs(),
2499 UnorderedElementsAre(
2500 AllOf(Field(&webrtc::Codec::id, 96),
Evan Shrubsole0b212e32025-04-07 13:43:012501 Field(&webrtc::Codec::packetization, std::nullopt)),
2502 AllOf(Field(&webrtc::Codec::id, 97),
2503 Field(&webrtc::Codec::packetization,
Evan Shrubsole945e5172025-04-08 14:11:452504 webrtc::kPacketizationParamRaw))));
Harald Alvestrand4a960602025-07-29 15:51:102505 EXPECT_THAT(media_send_channel1_impl()->send_codecs(),
2506 UnorderedElementsAre(
2507 AllOf(Field(&webrtc::Codec::id, 97),
Evan Shrubsole0b212e32025-04-07 13:43:012508 Field(&webrtc::Codec::packetization,
Evan Shrubsole945e5172025-04-08 14:11:452509 webrtc::kPacketizationParamRaw)),
Evan Shrubsole0b212e32025-04-07 13:43:012510 AllOf(Field(&webrtc::Codec::id, 96),
2511 Field(&webrtc::Codec::packetization, std::nullopt))));
Emil Lundmarkec826272023-09-20 10:22:392512}
2513
2514TEST_F(VideoChannelSingleThreadTest,
2515 ConsidersAllCodecsWithDiffrentPacketizationsInLocalAnswer) {
Evan Shrubsole0b212e32025-04-07 13:43:012516 webrtc::Codec vp8 = webrtc::CreateVideoCodec(96, "VP8");
2517 webrtc::Codec vp8_raw = webrtc::CreateVideoCodec(97, "VP8");
Evan Shrubsole945e5172025-04-08 14:11:452518 vp8_raw.packetization = webrtc::kPacketizationParamRaw;
Evan Shrubsole080cdac2025-03-20 09:34:482519 webrtc::VideoContentDescription local;
Emil Lundmarkec826272023-09-20 10:22:392520 local.set_codecs({vp8_raw, vp8});
Evan Shrubsole080cdac2025-03-20 09:34:482521 webrtc::VideoContentDescription remote;
Emil Lundmarkec826272023-09-20 10:22:392522 remote.set_codecs({vp8, vp8_raw});
2523
2524 CreateChannels(0, 0);
2525 std::string err;
2526 ASSERT_TRUE(channel1_->SetRemoteContent(&remote, SdpType::kOffer, err))
2527 << err;
2528 ASSERT_TRUE(channel1_->SetLocalContent(&local, SdpType::kAnswer, err)) << err;
2529
2530 EXPECT_THAT(
2531 media_receive_channel1_impl()->recv_codecs(),
Evan Shrubsole0b212e32025-04-07 13:43:012532 ElementsAre(AllOf(Field(&webrtc::Codec::id, 97),
2533 Field(&webrtc::Codec::packetization,
Evan Shrubsole945e5172025-04-08 14:11:452534 webrtc::kPacketizationParamRaw)),
Evan Shrubsole0b212e32025-04-07 13:43:012535 AllOf(Field(&webrtc::Codec::id, 96),
2536 Field(&webrtc::Codec::packetization, std::nullopt))));
Emil Lundmarkec826272023-09-20 10:22:392537 EXPECT_THAT(
2538 media_send_channel1_impl()->send_codecs(),
Evan Shrubsole0b212e32025-04-07 13:43:012539 ElementsAre(AllOf(Field(&webrtc::Codec::id, 96),
2540 Field(&webrtc::Codec::packetization, std::nullopt)),
2541 AllOf(Field(&webrtc::Codec::id, 97),
2542 Field(&webrtc::Codec::packetization,
Evan Shrubsole945e5172025-04-08 14:11:452543 webrtc::kPacketizationParamRaw))));
Emil Lundmarkec826272023-09-20 10:22:392544}
2545
Danil Chapovalov33b01f22016-05-11 17:55:272546// VideoChannelDoubleThreadTest
2547TEST_F(VideoChannelDoubleThreadTest, TestInit) {
2548 Base::TestInit();
2549}
[email protected]28e20752013-07-10 00:45:362550
Danil Chapovalovdae07ba2016-05-13 23:43:502551TEST_F(VideoChannelDoubleThreadTest, TestDeinit) {
2552 Base::TestDeinit();
2553}
2554
Danil Chapovalov33b01f22016-05-11 17:55:272555TEST_F(VideoChannelDoubleThreadTest, TestSetContents) {
2556 Base::TestSetContents();
2557}
2558
Johannes Kron9190b822018-10-29 10:22:052559TEST_F(VideoChannelDoubleThreadTest, TestSetContentsExtmapAllowMixedAsCaller) {
2560 Base::TestSetContentsExtmapAllowMixedCaller(/*offer=*/true, /*answer=*/true);
2561}
2562
2563TEST_F(VideoChannelDoubleThreadTest,
2564 TestSetContentsExtmapAllowMixedNotSupportedAsCaller) {
2565 Base::TestSetContentsExtmapAllowMixedCaller(/*offer=*/true, /*answer=*/false);
2566}
2567
2568TEST_F(VideoChannelDoubleThreadTest, TestSetContentsExtmapAllowMixedAsCallee) {
2569 Base::TestSetContentsExtmapAllowMixedCallee(/*offer=*/true, /*answer=*/true);
2570}
2571
2572TEST_F(VideoChannelDoubleThreadTest,
2573 TestSetContentsExtmapAllowMixedNotSupportedAsCallee) {
2574 Base::TestSetContentsExtmapAllowMixedCallee(/*offer=*/true, /*answer=*/false);
2575}
2576
Danil Chapovalov33b01f22016-05-11 17:55:272577TEST_F(VideoChannelDoubleThreadTest, TestSetContentsNullOffer) {
2578 Base::TestSetContentsNullOffer();
2579}
2580
2581TEST_F(VideoChannelDoubleThreadTest, TestSetContentsRtcpMux) {
2582 Base::TestSetContentsRtcpMux();
2583}
2584
2585TEST_F(VideoChannelDoubleThreadTest, TestSetContentsRtcpMuxWithPrAnswer) {
2586 Base::TestSetContentsRtcpMux();
2587}
2588
Danil Chapovalov33b01f22016-05-11 17:55:272589TEST_F(VideoChannelDoubleThreadTest, TestChangeStreamParamsInContent) {
2590 Base::TestChangeStreamParamsInContent();
2591}
2592
2593TEST_F(VideoChannelDoubleThreadTest, TestPlayoutAndSendingStates) {
2594 Base::TestPlayoutAndSendingStates();
2595}
2596
Danil Chapovalov33b01f22016-05-11 17:55:272597TEST_F(VideoChannelDoubleThreadTest, TestMediaContentDirection) {
2598 Base::TestMediaContentDirection();
2599}
2600
2601TEST_F(VideoChannelDoubleThreadTest, TestNetworkRouteChanges) {
2602 Base::TestNetworkRouteChanges();
2603}
2604
2605TEST_F(VideoChannelDoubleThreadTest, TestCallSetup) {
2606 Base::TestCallSetup();
2607}
2608
Danil Chapovalov33b01f22016-05-11 17:55:272609TEST_F(VideoChannelDoubleThreadTest, SendRtpToRtp) {
2610 Base::SendRtpToRtp();
2611}
2612
Danil Chapovalov33b01f22016-05-11 17:55:272613TEST_F(VideoChannelDoubleThreadTest, SendDtlsSrtpToDtlsSrtp) {
Zhi Huange830e682018-03-30 17:48:352614 Base::SendDtlsSrtpToDtlsSrtp(0, 0);
Danil Chapovalov33b01f22016-05-11 17:55:272615}
2616
2617TEST_F(VideoChannelDoubleThreadTest, SendDtlsSrtpToDtlsSrtpRtcpMux) {
Zhi Huange830e682018-03-30 17:48:352618 Base::SendDtlsSrtpToDtlsSrtp(RTCP_MUX, RTCP_MUX);
Danil Chapovalov33b01f22016-05-11 17:55:272619}
2620
2621TEST_F(VideoChannelDoubleThreadTest, SendEarlyMediaUsingRtcpMuxSrtp) {
2622 Base::SendEarlyMediaUsingRtcpMuxSrtp();
2623}
2624
2625TEST_F(VideoChannelDoubleThreadTest, SendRtpToRtpOnThread) {
2626 Base::SendRtpToRtpOnThread();
2627}
2628
Danil Chapovalov33b01f22016-05-11 17:55:272629TEST_F(VideoChannelDoubleThreadTest, SendWithWritabilityLoss) {
2630 Base::SendWithWritabilityLoss();
2631}
2632
Danil Chapovalov33b01f22016-05-11 17:55:272633TEST_F(VideoChannelDoubleThreadTest, TestSetContentFailure) {
2634 Base::TestSetContentFailure();
2635}
2636
2637TEST_F(VideoChannelDoubleThreadTest, TestSendTwoOffers) {
2638 Base::TestSendTwoOffers();
2639}
2640
2641TEST_F(VideoChannelDoubleThreadTest, TestReceiveTwoOffers) {
2642 Base::TestReceiveTwoOffers();
2643}
2644
2645TEST_F(VideoChannelDoubleThreadTest, TestSendPrAnswer) {
2646 Base::TestSendPrAnswer();
2647}
2648
2649TEST_F(VideoChannelDoubleThreadTest, TestReceivePrAnswer) {
2650 Base::TestReceivePrAnswer();
2651}
2652
Danil Chapovalov33b01f22016-05-11 17:55:272653TEST_F(VideoChannelDoubleThreadTest, SendBundleToBundle) {
Danil Chapovalov52c16dc2025-06-02 07:57:152654 Base::SendBundleToBundle(kVideoPts, false, false);
Danil Chapovalov33b01f22016-05-11 17:55:272655}
2656
2657TEST_F(VideoChannelDoubleThreadTest, SendBundleToBundleSecure) {
Danil Chapovalov52c16dc2025-06-02 07:57:152658 Base::SendBundleToBundle(kVideoPts, false, true);
Danil Chapovalov33b01f22016-05-11 17:55:272659}
2660
2661TEST_F(VideoChannelDoubleThreadTest, SendBundleToBundleWithRtcpMux) {
Danil Chapovalov52c16dc2025-06-02 07:57:152662 Base::SendBundleToBundle(kVideoPts, true, false);
Danil Chapovalov33b01f22016-05-11 17:55:272663}
2664
2665TEST_F(VideoChannelDoubleThreadTest, SendBundleToBundleWithRtcpMuxSecure) {
Danil Chapovalov52c16dc2025-06-02 07:57:152666 Base::SendBundleToBundle(kVideoPts, true, true);
Danil Chapovalov33b01f22016-05-11 17:55:272667}
2668
zstein56162b92017-04-24 23:54:352669TEST_F(VideoChannelDoubleThreadTest, TestOnTransportReadyToSend) {
2670 Base::TestOnTransportReadyToSend();
Danil Chapovalov33b01f22016-05-11 17:55:272671}
2672
Danil Chapovalov33b01f22016-05-11 17:55:272673TEST_F(VideoChannelDoubleThreadTest, DefaultMaxBitrateIsUnlimited) {
2674 Base::DefaultMaxBitrateIsUnlimited();
2675}
2676
Steve Anton8a63f782017-10-23 20:08:532677TEST_F(VideoChannelDoubleThreadTest, SocketOptionsMergedOnSetTransport) {
2678 Base::SocketOptionsMergedOnSetTransport();
2679}
2680
Emil Lundmark17304c32023-09-15 14:33:032681} // namespace