Propagate environment to RtpSenders

Will be later used to conditionally enable mixed codec simulcast
with a field trial.

Bug: webrtc:42220378
Change-Id: I527a488c04cd2b5a9f4ec703504b67943e966ab0
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/361403
Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
Commit-Queue: Florent Castelli <orphis@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#42929}
This commit is contained in:
Florent Castelli 2024-09-03 09:13:23 +00:00 committed by WebRTC LUCI CQ
parent 8401f56a54
commit c5b9a609ea
13 changed files with 114 additions and 67 deletions

View File

@ -816,6 +816,8 @@ if (rtc_include_tests) {
"../rtc_base:timeutils", "../rtc_base:timeutils",
"../rtc_base/synchronization:mutex", "../rtc_base/synchronization:mutex",
"../rtc_base/third_party/sigslot", "../rtc_base/third_party/sigslot",
"../test:explicit_key_value_config",
"../test:scoped_key_value_config",
"../test:test_support", "../test:test_support",
"../video/config:streams_config", "../video/config:streams_config",
"//testing/gtest", "//testing/gtest",

View File

@ -37,6 +37,8 @@
#include "rtc_base/copy_on_write_buffer.h" #include "rtc_base/copy_on_write_buffer.h"
#include "rtc_base/network_route.h" #include "rtc_base/network_route.h"
#include "rtc_base/thread.h" #include "rtc_base/thread.h"
#include "test/explicit_key_value_config.h"
#include "test/scoped_key_value_config.h"
using webrtc::RtpExtension; using webrtc::RtpExtension;
@ -306,7 +308,8 @@ class RtpSendChannelHelper : public Base, public MediaChannelUtil {
auto parameters_iterator = rtp_send_parameters_.find(ssrc); auto parameters_iterator = rtp_send_parameters_.find(ssrc);
if (parameters_iterator != rtp_send_parameters_.end()) { if (parameters_iterator != rtp_send_parameters_.end()) {
auto result = CheckRtpParametersInvalidModificationAndValues( auto result = CheckRtpParametersInvalidModificationAndValues(
parameters_iterator->second, parameters); parameters_iterator->second, parameters,
webrtc::test::ExplicitKeyValueConfig(""));
if (!result.ok()) { if (!result.ok()) {
return webrtc::InvokeSetParametersCallback(callback, result); return webrtc::InvokeSetParametersCallback(callback, result);
} }

View File

@ -17,6 +17,7 @@
#include <utility> #include <utility>
#include "absl/algorithm/container.h" #include "absl/algorithm/container.h"
#include "api/field_trials_view.h"
#include "api/video/video_bitrate_allocation.h" #include "api/video/video_bitrate_allocation.h"
#include "rtc_base/checks.h" #include "rtc_base/checks.h"
#include "rtc_base/string_encode.h" #include "rtc_base/string_encode.h"
@ -140,7 +141,8 @@ webrtc::RTCError CheckScalabilityModeValues(
webrtc::RTCError CheckRtpParametersValues( webrtc::RTCError CheckRtpParametersValues(
const webrtc::RtpParameters& rtp_parameters, const webrtc::RtpParameters& rtp_parameters,
rtc::ArrayView<cricket::Codec> send_codecs, rtc::ArrayView<cricket::Codec> send_codecs,
std::optional<cricket::Codec> send_codec) { std::optional<cricket::Codec> send_codec,
const webrtc::FieldTrialsView& field_trials) {
using webrtc::RTCErrorType; using webrtc::RTCErrorType;
for (size_t i = 0; i < rtp_parameters.encodings.size(); ++i) { for (size_t i = 0; i < rtp_parameters.encodings.size(); ++i) {
@ -201,16 +203,18 @@ webrtc::RTCError CheckRtpParametersValues(
webrtc::RTCError CheckRtpParametersInvalidModificationAndValues( webrtc::RTCError CheckRtpParametersInvalidModificationAndValues(
const webrtc::RtpParameters& old_rtp_parameters, const webrtc::RtpParameters& old_rtp_parameters,
const webrtc::RtpParameters& rtp_parameters) { const webrtc::RtpParameters& rtp_parameters,
const webrtc::FieldTrialsView& field_trials) {
return CheckRtpParametersInvalidModificationAndValues( return CheckRtpParametersInvalidModificationAndValues(
old_rtp_parameters, rtp_parameters, {}, std::nullopt); old_rtp_parameters, rtp_parameters, {}, std::nullopt, field_trials);
} }
webrtc::RTCError CheckRtpParametersInvalidModificationAndValues( webrtc::RTCError CheckRtpParametersInvalidModificationAndValues(
const webrtc::RtpParameters& old_rtp_parameters, const webrtc::RtpParameters& old_rtp_parameters,
const webrtc::RtpParameters& rtp_parameters, const webrtc::RtpParameters& rtp_parameters,
rtc::ArrayView<cricket::Codec> send_codecs, rtc::ArrayView<cricket::Codec> send_codecs,
std::optional<cricket::Codec> send_codec) { std::optional<cricket::Codec> send_codec,
const webrtc::FieldTrialsView& field_trials) {
using webrtc::RTCErrorType; using webrtc::RTCErrorType;
if (rtp_parameters.encodings.size() != old_rtp_parameters.encodings.size()) { if (rtp_parameters.encodings.size() != old_rtp_parameters.encodings.size()) {
LOG_AND_RETURN_ERROR( LOG_AND_RETURN_ERROR(
@ -245,7 +249,8 @@ webrtc::RTCError CheckRtpParametersInvalidModificationAndValues(
"Attempted to set RtpParameters with modified SSRC"); "Attempted to set RtpParameters with modified SSRC");
} }
return CheckRtpParametersValues(rtp_parameters, send_codecs, send_codec); return CheckRtpParametersValues(rtp_parameters, send_codecs, send_codec,
field_trials);
} }
CompositeMediaEngine::CompositeMediaEngine( CompositeMediaEngine::CompositeMediaEngine(

View File

@ -48,7 +48,8 @@ webrtc::RTCError CheckScalabilityModeValues(
webrtc::RTCError CheckRtpParametersValues( webrtc::RTCError CheckRtpParametersValues(
const webrtc::RtpParameters& new_parameters, const webrtc::RtpParameters& new_parameters,
rtc::ArrayView<cricket::Codec> send_codecs, rtc::ArrayView<cricket::Codec> send_codecs,
std::optional<cricket::Codec> send_codec); std::optional<cricket::Codec> send_codec,
const webrtc::FieldTrialsView& field_trials);
// Checks that the immutable values have not changed in new_parameters and // Checks that the immutable values have not changed in new_parameters and
// checks all parameters with CheckRtpParametersValues(). // checks all parameters with CheckRtpParametersValues().
@ -56,14 +57,16 @@ webrtc::RTCError CheckRtpParametersInvalidModificationAndValues(
const webrtc::RtpParameters& old_parameters, const webrtc::RtpParameters& old_parameters,
const webrtc::RtpParameters& new_parameters, const webrtc::RtpParameters& new_parameters,
rtc::ArrayView<cricket::Codec> send_codecs, rtc::ArrayView<cricket::Codec> send_codecs,
std::optional<cricket::Codec> send_codec); std::optional<cricket::Codec> send_codec,
const webrtc::FieldTrialsView& field_trials);
// Checks that the immutable values have not changed in new_parameters and // Checks that the immutable values have not changed in new_parameters and
// checks parameters (except SVC) with CheckRtpParametersValues(). It should // checks parameters (except SVC) with CheckRtpParametersValues(). It should
// usually be paired with a call to CheckScalabilityModeValues(). // usually be paired with a call to CheckScalabilityModeValues().
webrtc::RTCError CheckRtpParametersInvalidModificationAndValues( webrtc::RTCError CheckRtpParametersInvalidModificationAndValues(
const webrtc::RtpParameters& old_parameters, const webrtc::RtpParameters& old_parameters,
const webrtc::RtpParameters& new_parameters); const webrtc::RtpParameters& new_parameters,
const webrtc::FieldTrialsView& field_trials);
struct RtpCapabilities { struct RtpCapabilities {
RtpCapabilities(); RtpCapabilities();

View File

@ -1990,7 +1990,7 @@ WebRtcVideoSendChannel::WebRtcVideoSendStream::SetRtpParameters(
// conformance. // conformance.
// TODO(orphis): Migrate tests to later make this a DCHECK only // TODO(orphis): Migrate tests to later make this a DCHECK only
webrtc::RTCError error = CheckRtpParametersInvalidModificationAndValues( webrtc::RTCError error = CheckRtpParametersInvalidModificationAndValues(
rtp_parameters_, new_parameters); rtp_parameters_, new_parameters, call_->trials());
if (!error.ok()) { if (!error.ok()) {
return webrtc::InvokeSetParametersCallback(callback, error); return webrtc::InvokeSetParametersCallback(callback, error);
} }

View File

@ -1039,7 +1039,7 @@ class WebRtcVoiceSendChannel::WebRtcAudioSendStream : public AudioSource::Sink {
webrtc::RTCError SetRtpParameters(const webrtc::RtpParameters& parameters, webrtc::RTCError SetRtpParameters(const webrtc::RtpParameters& parameters,
webrtc::SetParametersCallback callback) { webrtc::SetParametersCallback callback) {
webrtc::RTCError error = CheckRtpParametersInvalidModificationAndValues( webrtc::RTCError error = CheckRtpParametersInvalidModificationAndValues(
rtp_parameters_, parameters); rtp_parameters_, parameters, call_->trials());
if (!error.ok()) { if (!error.ok()) {
return webrtc::InvokeSetParametersCallback(callback, error); return webrtc::InvokeSetParametersCallback(callback, error);
} }

View File

@ -1578,6 +1578,7 @@ rtc_library("rtp_transmission_manager") {
"../api:rtp_transceiver_direction", "../api:rtp_transceiver_direction",
"../api:scoped_refptr", "../api:scoped_refptr",
"../api:sequence_checker", "../api:sequence_checker",
"../api/environment",
"../media:media_channel", "../media:media_channel",
"../rtc_base:checks", "../rtc_base:checks",
"../rtc_base:crypto_random", "../rtc_base:crypto_random",
@ -1810,6 +1811,7 @@ rtc_library("rtp_sender") {
"../api:audio_options_api", "../api:audio_options_api",
"../api:dtls_transport_interface", "../api:dtls_transport_interface",
"../api:dtmf_sender_interface", "../api:dtmf_sender_interface",
"../api:field_trials_view",
"../api:frame_transformer_interface", "../api:frame_transformer_interface",
"../api:libjingle_peerconnection_api", "../api:libjingle_peerconnection_api",
"../api:media_stream_interface", "../api:media_stream_interface",
@ -1820,6 +1822,7 @@ rtc_library("rtp_sender") {
"../api:scoped_refptr", "../api:scoped_refptr",
"../api:sequence_checker", "../api:sequence_checker",
"../api/crypto:frame_encryptor_interface", "../api/crypto:frame_encryptor_interface",
"../api/environment",
"../media:audio_source", "../media:audio_source",
"../media:media_channel", "../media:media_channel",
"../media:media_engine", "../media:media_engine",

View File

@ -705,7 +705,7 @@ RTCError PeerConnection::Initialize(
dependencies, context_.get()); dependencies, context_.get());
rtp_manager_ = std::make_unique<RtpTransmissionManager>( rtp_manager_ = std::make_unique<RtpTransmissionManager>(
IsUnifiedPlan(), context_.get(), &usage_pattern_, observer_, env_, IsUnifiedPlan(), context_.get(), &usage_pattern_, observer_,
legacy_stats_.get(), [this]() { legacy_stats_.get(), [this]() {
RTC_DCHECK_RUN_ON(signaling_thread()); RTC_DCHECK_RUN_ON(signaling_thread());
sdp_handler_->UpdateNegotiationNeeded(); sdp_handler_->UpdateNegotiationNeeded();
@ -1151,8 +1151,8 @@ PeerConnection::AddTransceiver(
codecs = context_->media_engine()->voice().send_codecs(); codecs = context_->media_engine()->voice().send_codecs();
} }
auto result = auto result = cricket::CheckRtpParametersValues(
cricket::CheckRtpParametersValues(parameters, codecs, std::nullopt); parameters, codecs, std::nullopt, env_.field_trials());
if (!result.ok()) { if (!result.ok()) {
if (result.type() == RTCErrorType::INVALID_MODIFICATION) { if (result.type() == RTCErrorType::INVALID_MODIFICATION) {
result.set_type(RTCErrorType::UNSUPPORTED_OPERATION); result.set_type(RTCErrorType::UNSUPPORTED_OPERATION);
@ -1219,7 +1219,7 @@ rtc::scoped_refptr<RtpSenderInterface> PeerConnection::CreateSender(
rtc::scoped_refptr<RtpSenderProxyWithInternal<RtpSenderInternal>> new_sender; rtc::scoped_refptr<RtpSenderProxyWithInternal<RtpSenderInternal>> new_sender;
if (kind == MediaStreamTrackInterface::kAudioKind) { if (kind == MediaStreamTrackInterface::kAudioKind) {
auto audio_sender = auto audio_sender =
AudioRtpSender::Create(worker_thread(), rtc::CreateRandomUuid(), AudioRtpSender::Create(env_, worker_thread(), rtc::CreateRandomUuid(),
legacy_stats_.get(), rtp_manager()); legacy_stats_.get(), rtp_manager());
audio_sender->SetMediaChannel(rtp_manager()->voice_media_send_channel()); audio_sender->SetMediaChannel(rtp_manager()->voice_media_send_channel());
new_sender = RtpSenderProxyWithInternal<RtpSenderInternal>::Create( new_sender = RtpSenderProxyWithInternal<RtpSenderInternal>::Create(
@ -1227,7 +1227,7 @@ rtc::scoped_refptr<RtpSenderInterface> PeerConnection::CreateSender(
rtp_manager()->GetAudioTransceiver()->internal()->AddSender(new_sender); rtp_manager()->GetAudioTransceiver()->internal()->AddSender(new_sender);
} else if (kind == MediaStreamTrackInterface::kVideoKind) { } else if (kind == MediaStreamTrackInterface::kVideoKind) {
auto video_sender = VideoRtpSender::Create( auto video_sender = VideoRtpSender::Create(
worker_thread(), rtc::CreateRandomUuid(), rtp_manager()); env_, worker_thread(), rtc::CreateRandomUuid(), rtp_manager());
video_sender->SetMediaChannel(rtp_manager()->video_media_send_channel()); video_sender->SetMediaChannel(rtp_manager()->video_media_send_channel());
new_sender = RtpSenderProxyWithInternal<RtpSenderInternal>::Create( new_sender = RtpSenderProxyWithInternal<RtpSenderInternal>::Create(
signaling_thread(), video_sender); signaling_thread(), video_sender);

View File

@ -18,6 +18,7 @@
#include "absl/algorithm/container.h" #include "absl/algorithm/container.h"
#include "api/audio_options.h" #include "api/audio_options.h"
#include "api/environment/environment.h"
#include "api/media_stream_interface.h" #include "api/media_stream_interface.h"
#include "api/priority.h" #include "api/priority.h"
#include "api/rtc_error.h" #include "api/rtc_error.h"
@ -148,10 +149,12 @@ bool UnimplementedRtpParameterHasValue(const RtpParameters& parameters) {
return false; return false;
} }
RtpSenderBase::RtpSenderBase(rtc::Thread* worker_thread, RtpSenderBase::RtpSenderBase(const Environment& env,
rtc::Thread* worker_thread,
const std::string& id, const std::string& id,
SetStreamsObserver* set_streams_observer) SetStreamsObserver* set_streams_observer)
: signaling_thread_(rtc::Thread::Current()), : env_(env),
signaling_thread_(rtc::Thread::Current()),
worker_thread_(worker_thread), worker_thread_(worker_thread),
id_(id), id_(id),
set_streams_observer_(set_streams_observer) { set_streams_observer_(set_streams_observer) {
@ -248,7 +251,8 @@ void RtpSenderBase::SetParametersInternal(const RtpParameters& parameters,
} }
if (!media_channel_ || !ssrc_) { if (!media_channel_ || !ssrc_) {
auto result = cricket::CheckRtpParametersInvalidModificationAndValues( auto result = cricket::CheckRtpParametersInvalidModificationAndValues(
init_parameters_, parameters, send_codecs_, std::nullopt); init_parameters_, parameters, send_codecs_, std::nullopt,
env_.field_trials());
if (result.ok()) { if (result.ok()) {
init_parameters_ = parameters; init_parameters_ = parameters;
} }
@ -266,7 +270,7 @@ void RtpSenderBase::SetParametersInternal(const RtpParameters& parameters,
} }
RTCError result = cricket::CheckRtpParametersInvalidModificationAndValues( RTCError result = cricket::CheckRtpParametersInvalidModificationAndValues(
old_parameters, rtp_parameters); old_parameters, rtp_parameters, env_.field_trials());
if (!result.ok()) { if (!result.ok()) {
InvokeSetParametersCallback(callback, result); InvokeSetParametersCallback(callback, result);
return; return;
@ -299,7 +303,8 @@ RTCError RtpSenderBase::SetParametersInternalWithAllLayers(
} }
if (!media_channel_ || !ssrc_) { if (!media_channel_ || !ssrc_) {
auto result = cricket::CheckRtpParametersInvalidModificationAndValues( auto result = cricket::CheckRtpParametersInvalidModificationAndValues(
init_parameters_, parameters, send_codecs_, std::nullopt); init_parameters_, parameters, send_codecs_, std::nullopt,
env_.field_trials());
if (result.ok()) { if (result.ok()) {
init_parameters_ = parameters; init_parameters_ = parameters;
} }
@ -624,19 +629,21 @@ void LocalAudioSinkAdapter::SetSink(cricket::AudioSource::Sink* sink) {
} }
rtc::scoped_refptr<AudioRtpSender> AudioRtpSender::Create( rtc::scoped_refptr<AudioRtpSender> AudioRtpSender::Create(
const webrtc::Environment& env,
rtc::Thread* worker_thread, rtc::Thread* worker_thread,
const std::string& id, const std::string& id,
LegacyStatsCollectorInterface* stats, LegacyStatsCollectorInterface* stats,
SetStreamsObserver* set_streams_observer) { SetStreamsObserver* set_streams_observer) {
return rtc::make_ref_counted<AudioRtpSender>(worker_thread, id, stats, return rtc::make_ref_counted<AudioRtpSender>(env, worker_thread, id, stats,
set_streams_observer); set_streams_observer);
} }
AudioRtpSender::AudioRtpSender(rtc::Thread* worker_thread, AudioRtpSender::AudioRtpSender(const webrtc::Environment& env,
rtc::Thread* worker_thread,
const std::string& id, const std::string& id,
LegacyStatsCollectorInterface* legacy_stats, LegacyStatsCollectorInterface* legacy_stats,
SetStreamsObserver* set_streams_observer) SetStreamsObserver* set_streams_observer)
: RtpSenderBase(worker_thread, id, set_streams_observer), : RtpSenderBase(env, worker_thread, id, set_streams_observer),
legacy_stats_(legacy_stats), legacy_stats_(legacy_stats),
dtmf_sender_(DtmfSender::Create(rtc::Thread::Current(), this)), dtmf_sender_(DtmfSender::Create(rtc::Thread::Current(), this)),
dtmf_sender_proxy_( dtmf_sender_proxy_(
@ -777,17 +784,19 @@ void AudioRtpSender::ClearSend() {
} }
rtc::scoped_refptr<VideoRtpSender> VideoRtpSender::Create( rtc::scoped_refptr<VideoRtpSender> VideoRtpSender::Create(
const Environment& env,
rtc::Thread* worker_thread, rtc::Thread* worker_thread,
const std::string& id, const std::string& id,
SetStreamsObserver* set_streams_observer) { SetStreamsObserver* set_streams_observer) {
return rtc::make_ref_counted<VideoRtpSender>(worker_thread, id, return rtc::make_ref_counted<VideoRtpSender>(env, worker_thread, id,
set_streams_observer); set_streams_observer);
} }
VideoRtpSender::VideoRtpSender(rtc::Thread* worker_thread, VideoRtpSender::VideoRtpSender(const Environment& env,
rtc::Thread* worker_thread,
const std::string& id, const std::string& id,
SetStreamsObserver* set_streams_observer) SetStreamsObserver* set_streams_observer)
: RtpSenderBase(worker_thread, id, set_streams_observer) {} : RtpSenderBase(env, worker_thread, id, set_streams_observer) {}
VideoRtpSender::~VideoRtpSender() { VideoRtpSender::~VideoRtpSender() {
Stop(); Stop();

View File

@ -26,6 +26,8 @@
#include "api/crypto/frame_encryptor_interface.h" #include "api/crypto/frame_encryptor_interface.h"
#include "api/dtls_transport_interface.h" #include "api/dtls_transport_interface.h"
#include "api/dtmf_sender_interface.h" #include "api/dtmf_sender_interface.h"
#include "api/environment/environment.h"
#include "api/field_trials_view.h"
#include "api/frame_transformer_interface.h" #include "api/frame_transformer_interface.h"
#include "api/media_stream_interface.h" #include "api/media_stream_interface.h"
#include "api/media_types.h" #include "api/media_types.h"
@ -228,7 +230,8 @@ class RtpSenderBase : public RtpSenderInternal, public ObserverInterface {
// If `set_streams_observer` is not null, it is invoked when SetStreams() // If `set_streams_observer` is not null, it is invoked when SetStreams()
// is called. `set_streams_observer` is not owned by this object. If not // is called. `set_streams_observer` is not owned by this object. If not
// null, it must be valid at least until this sender becomes stopped. // null, it must be valid at least until this sender becomes stopped.
RtpSenderBase(rtc::Thread* worker_thread, RtpSenderBase(const Environment& env,
rtc::Thread* worker_thread,
const std::string& id, const std::string& id,
SetStreamsObserver* set_streams_observer); SetStreamsObserver* set_streams_observer);
// TODO(bugs.webrtc.org/8694): Since SSRC == 0 is technically valid, figure // TODO(bugs.webrtc.org/8694): Since SSRC == 0 is technically valid, figure
@ -249,6 +252,7 @@ class RtpSenderBase : public RtpSenderInternal, public ObserverInterface {
virtual void AddTrackToStats() {} virtual void AddTrackToStats() {}
virtual void RemoveTrackFromStats() {} virtual void RemoveTrackFromStats() {}
const Environment env_;
rtc::Thread* const signaling_thread_; rtc::Thread* const signaling_thread_;
rtc::Thread* const worker_thread_; rtc::Thread* const worker_thread_;
uint32_t ssrc_ = 0; uint32_t ssrc_ = 0;
@ -338,6 +342,7 @@ class AudioRtpSender : public DtmfProviderInterface, public RtpSenderBase {
// is called. `set_streams_observer` is not owned by this object. If not // is called. `set_streams_observer` is not owned by this object. If not
// null, it must be valid at least until this sender becomes stopped. // null, it must be valid at least until this sender becomes stopped.
static rtc::scoped_refptr<AudioRtpSender> Create( static rtc::scoped_refptr<AudioRtpSender> Create(
const Environment& env,
rtc::Thread* worker_thread, rtc::Thread* worker_thread,
const std::string& id, const std::string& id,
LegacyStatsCollectorInterface* stats, LegacyStatsCollectorInterface* stats,
@ -362,7 +367,8 @@ class AudioRtpSender : public DtmfProviderInterface, public RtpSenderBase {
RTCError GenerateKeyFrame(const std::vector<std::string>& rids) override; RTCError GenerateKeyFrame(const std::vector<std::string>& rids) override;
protected: protected:
AudioRtpSender(rtc::Thread* worker_thread, AudioRtpSender(const Environment& env,
rtc::Thread* worker_thread,
const std::string& id, const std::string& id,
LegacyStatsCollectorInterface* legacy_stats, LegacyStatsCollectorInterface* legacy_stats,
SetStreamsObserver* set_streams_observer); SetStreamsObserver* set_streams_observer);
@ -403,6 +409,7 @@ class VideoRtpSender : public RtpSenderBase {
// is called. `set_streams_observer` is not owned by this object. If not // is called. `set_streams_observer` is not owned by this object. If not
// null, it must be valid at least until this sender becomes stopped. // null, it must be valid at least until this sender becomes stopped.
static rtc::scoped_refptr<VideoRtpSender> Create( static rtc::scoped_refptr<VideoRtpSender> Create(
const Environment& env,
rtc::Thread* worker_thread, rtc::Thread* worker_thread,
const std::string& id, const std::string& id,
SetStreamsObserver* set_streams_observer); SetStreamsObserver* set_streams_observer);
@ -422,7 +429,8 @@ class VideoRtpSender : public RtpSenderBase {
RTCError GenerateKeyFrame(const std::vector<std::string>& rids) override; RTCError GenerateKeyFrame(const std::vector<std::string>& rids) override;
protected: protected:
VideoRtpSender(rtc::Thread* worker_thread, VideoRtpSender(const Environment& env,
rtc::Thread* worker_thread,
const std::string& id, const std::string& id,
SetStreamsObserver* set_streams_observer); SetStreamsObserver* set_streams_observer);

View File

@ -199,8 +199,8 @@ class RtpSenderReceiverTest
EXPECT_TRUE(local_stream_->AddTrack(audio_track_)); EXPECT_TRUE(local_stream_->AddTrack(audio_track_));
std::unique_ptr<MockSetStreamsObserver> set_streams_observer = std::unique_ptr<MockSetStreamsObserver> set_streams_observer =
std::make_unique<MockSetStreamsObserver>(); std::make_unique<MockSetStreamsObserver>();
audio_rtp_sender_ = audio_rtp_sender_ = AudioRtpSender::Create(
AudioRtpSender::Create(worker_thread_, audio_track_->id(), nullptr, CreateEnvironment(), worker_thread_, audio_track_->id(), nullptr,
set_streams_observer.get()); set_streams_observer.get());
ASSERT_TRUE(audio_rtp_sender_->SetTrack(audio_track_.get())); ASSERT_TRUE(audio_rtp_sender_->SetTrack(audio_track_.get()));
EXPECT_CALL(*set_streams_observer, OnSetStreams()); EXPECT_CALL(*set_streams_observer, OnSetStreams());
@ -211,8 +211,8 @@ class RtpSenderReceiverTest
} }
void CreateAudioRtpSenderWithNoTrack() { void CreateAudioRtpSenderWithNoTrack() {
audio_rtp_sender_ = audio_rtp_sender_ = AudioRtpSender::Create(
AudioRtpSender::Create(worker_thread_, /*id=*/"", nullptr, nullptr); CreateEnvironment(), worker_thread_, /*id=*/"", nullptr, nullptr);
audio_rtp_sender_->SetMediaChannel(voice_media_send_channel_.get()); audio_rtp_sender_->SetMediaChannel(voice_media_send_channel_.get());
} }
@ -260,8 +260,9 @@ class RtpSenderReceiverTest
AddVideoTrack(is_screencast); AddVideoTrack(is_screencast);
std::unique_ptr<MockSetStreamsObserver> set_streams_observer = std::unique_ptr<MockSetStreamsObserver> set_streams_observer =
std::make_unique<MockSetStreamsObserver>(); std::make_unique<MockSetStreamsObserver>();
video_rtp_sender_ = VideoRtpSender::Create( video_rtp_sender_ =
worker_thread_, video_track_->id(), set_streams_observer.get()); VideoRtpSender::Create(CreateEnvironment(), worker_thread_,
video_track_->id(), set_streams_observer.get());
ASSERT_TRUE(video_rtp_sender_->SetTrack(video_track_.get())); ASSERT_TRUE(video_rtp_sender_->SetTrack(video_track_.get()));
EXPECT_CALL(*set_streams_observer, OnSetStreams()); EXPECT_CALL(*set_streams_observer, OnSetStreams());
video_rtp_sender_->SetStreams({local_stream_->id()}); video_rtp_sender_->SetStreams({local_stream_->id()});
@ -270,8 +271,8 @@ class RtpSenderReceiverTest
VerifyVideoChannelInput(ssrc); VerifyVideoChannelInput(ssrc);
} }
void CreateVideoRtpSenderWithNoTrack() { void CreateVideoRtpSenderWithNoTrack() {
video_rtp_sender_ = video_rtp_sender_ = VideoRtpSender::Create(
VideoRtpSender::Create(worker_thread_, /*id=*/"", nullptr); CreateEnvironment(), worker_thread_, /*id=*/"", nullptr);
video_rtp_sender_->SetMediaChannel(video_media_send_channel()); video_rtp_sender_->SetMediaChannel(video_media_send_channel());
} }
@ -452,7 +453,8 @@ class RtpSenderReceiverTest
void RunDisableSimulcastLayersWithoutMediaEngineTest( void RunDisableSimulcastLayersWithoutMediaEngineTest(
const std::vector<std::string>& all_layers, const std::vector<std::string>& all_layers,
const std::vector<std::string>& disabled_layers) { const std::vector<std::string>& disabled_layers) {
auto sender = VideoRtpSender::Create(rtc::Thread::Current(), "1", nullptr); auto sender = VideoRtpSender::Create(CreateEnvironment(),
rtc::Thread::Current(), "1", nullptr);
RtpParameters parameters; RtpParameters parameters;
parameters.encodings.resize(all_layers.size()); parameters.encodings.resize(all_layers.size());
for (size_t i = 0; i < all_layers.size(); ++i) { for (size_t i = 0; i < all_layers.size(); ++i) {
@ -898,8 +900,8 @@ TEST_F(RtpSenderReceiverTest, AudioSenderCanSetParametersAsync) {
} }
TEST_F(RtpSenderReceiverTest, AudioSenderCanSetParametersBeforeNegotiation) { TEST_F(RtpSenderReceiverTest, AudioSenderCanSetParametersBeforeNegotiation) {
audio_rtp_sender_ = audio_rtp_sender_ = AudioRtpSender::Create(
AudioRtpSender::Create(worker_thread_, /*id=*/"", nullptr, nullptr); CreateEnvironment(), worker_thread_, /*id=*/"", nullptr, nullptr);
RtpParameters params = audio_rtp_sender_->GetParameters(); RtpParameters params = audio_rtp_sender_->GetParameters();
ASSERT_EQ(1u, params.encodings.size()); ASSERT_EQ(1u, params.encodings.size());
@ -915,8 +917,8 @@ TEST_F(RtpSenderReceiverTest, AudioSenderCanSetParametersBeforeNegotiation) {
TEST_F(RtpSenderReceiverTest, TEST_F(RtpSenderReceiverTest,
AudioSenderCanSetParametersAsyncBeforeNegotiation) { AudioSenderCanSetParametersAsyncBeforeNegotiation) {
audio_rtp_sender_ = audio_rtp_sender_ = AudioRtpSender::Create(
AudioRtpSender::Create(worker_thread_, /*id=*/"", nullptr, nullptr); CreateEnvironment(), worker_thread_, /*id=*/"", nullptr, nullptr);
std::optional<RTCError> result; std::optional<RTCError> result;
RtpParameters params = audio_rtp_sender_->GetParameters(); RtpParameters params = audio_rtp_sender_->GetParameters();
@ -946,7 +948,8 @@ TEST_F(RtpSenderReceiverTest, AudioSenderInitParametersMovedAfterNegotiation) {
std::unique_ptr<MockSetStreamsObserver> set_streams_observer = std::unique_ptr<MockSetStreamsObserver> set_streams_observer =
std::make_unique<MockSetStreamsObserver>(); std::make_unique<MockSetStreamsObserver>();
audio_rtp_sender_ = AudioRtpSender::Create( audio_rtp_sender_ = AudioRtpSender::Create(
worker_thread_, audio_track_->id(), nullptr, set_streams_observer.get()); CreateEnvironment(), worker_thread_, audio_track_->id(), nullptr,
set_streams_observer.get());
ASSERT_TRUE(audio_rtp_sender_->SetTrack(audio_track_.get())); ASSERT_TRUE(audio_rtp_sender_->SetTrack(audio_track_.get()));
EXPECT_CALL(*set_streams_observer, OnSetStreams()); EXPECT_CALL(*set_streams_observer, OnSetStreams());
audio_rtp_sender_->SetStreams({local_stream_->id()}); audio_rtp_sender_->SetStreams({local_stream_->id()});
@ -977,8 +980,8 @@ TEST_F(RtpSenderReceiverTest, AudioSenderInitParametersMovedAfterNegotiation) {
TEST_F(RtpSenderReceiverTest, TEST_F(RtpSenderReceiverTest,
AudioSenderMustCallGetParametersBeforeSetParametersBeforeNegotiation) { AudioSenderMustCallGetParametersBeforeSetParametersBeforeNegotiation) {
audio_rtp_sender_ = audio_rtp_sender_ = AudioRtpSender::Create(
AudioRtpSender::Create(worker_thread_, /*id=*/"", nullptr, nullptr); CreateEnvironment(), worker_thread_, /*id=*/"", nullptr, nullptr);
RtpParameters params; RtpParameters params;
RTCError result = audio_rtp_sender_->SetParameters(params); RTCError result = audio_rtp_sender_->SetParameters(params);
@ -1149,8 +1152,8 @@ TEST_F(RtpSenderReceiverTest, VideoSenderCanSetParametersAsync) {
} }
TEST_F(RtpSenderReceiverTest, VideoSenderCanSetParametersBeforeNegotiation) { TEST_F(RtpSenderReceiverTest, VideoSenderCanSetParametersBeforeNegotiation) {
video_rtp_sender_ = video_rtp_sender_ = VideoRtpSender::Create(
VideoRtpSender::Create(worker_thread_, /*id=*/"", nullptr); CreateEnvironment(), worker_thread_, /*id=*/"", nullptr);
RtpParameters params = video_rtp_sender_->GetParameters(); RtpParameters params = video_rtp_sender_->GetParameters();
ASSERT_EQ(1u, params.encodings.size()); ASSERT_EQ(1u, params.encodings.size());
@ -1166,8 +1169,8 @@ TEST_F(RtpSenderReceiverTest, VideoSenderCanSetParametersBeforeNegotiation) {
TEST_F(RtpSenderReceiverTest, TEST_F(RtpSenderReceiverTest,
VideoSenderCanSetParametersAsyncBeforeNegotiation) { VideoSenderCanSetParametersAsyncBeforeNegotiation) {
video_rtp_sender_ = video_rtp_sender_ = VideoRtpSender::Create(
VideoRtpSender::Create(worker_thread_, /*id=*/"", nullptr); CreateEnvironment(), worker_thread_, /*id=*/"", nullptr);
std::optional<RTCError> result; std::optional<RTCError> result;
RtpParameters params = video_rtp_sender_->GetParameters(); RtpParameters params = video_rtp_sender_->GetParameters();
@ -1193,8 +1196,9 @@ TEST_F(RtpSenderReceiverTest, VideoSenderInitParametersMovedAfterNegotiation) {
std::unique_ptr<MockSetStreamsObserver> set_streams_observer = std::unique_ptr<MockSetStreamsObserver> set_streams_observer =
std::make_unique<MockSetStreamsObserver>(); std::make_unique<MockSetStreamsObserver>();
video_rtp_sender_ = VideoRtpSender::Create(worker_thread_, video_track_->id(), video_rtp_sender_ =
set_streams_observer.get()); VideoRtpSender::Create(CreateEnvironment(), worker_thread_,
video_track_->id(), set_streams_observer.get());
ASSERT_TRUE(video_rtp_sender_->SetTrack(video_track_.get())); ASSERT_TRUE(video_rtp_sender_->SetTrack(video_track_.get()));
EXPECT_CALL(*set_streams_observer, OnSetStreams()); EXPECT_CALL(*set_streams_observer, OnSetStreams());
video_rtp_sender_->SetStreams({local_stream_->id()}); video_rtp_sender_->SetStreams({local_stream_->id()});
@ -1235,8 +1239,9 @@ TEST_F(RtpSenderReceiverTest,
std::unique_ptr<MockSetStreamsObserver> set_streams_observer = std::unique_ptr<MockSetStreamsObserver> set_streams_observer =
std::make_unique<MockSetStreamsObserver>(); std::make_unique<MockSetStreamsObserver>();
video_rtp_sender_ = VideoRtpSender::Create(worker_thread_, video_track_->id(), video_rtp_sender_ =
set_streams_observer.get()); VideoRtpSender::Create(CreateEnvironment(), worker_thread_,
video_track_->id(), set_streams_observer.get());
ASSERT_TRUE(video_rtp_sender_->SetTrack(video_track_.get())); ASSERT_TRUE(video_rtp_sender_->SetTrack(video_track_.get()));
EXPECT_CALL(*set_streams_observer, OnSetStreams()); EXPECT_CALL(*set_streams_observer, OnSetStreams());
video_rtp_sender_->SetStreams({local_stream_->id()}); video_rtp_sender_->SetStreams({local_stream_->id()});
@ -1278,8 +1283,9 @@ TEST_F(RtpSenderReceiverDeathTest,
std::unique_ptr<MockSetStreamsObserver> set_streams_observer = std::unique_ptr<MockSetStreamsObserver> set_streams_observer =
std::make_unique<MockSetStreamsObserver>(); std::make_unique<MockSetStreamsObserver>();
video_rtp_sender_ = VideoRtpSender::Create(worker_thread_, video_track_->id(), video_rtp_sender_ =
set_streams_observer.get()); VideoRtpSender::Create(CreateEnvironment(), worker_thread_,
video_track_->id(), set_streams_observer.get());
ASSERT_TRUE(video_rtp_sender_->SetTrack(video_track_.get())); ASSERT_TRUE(video_rtp_sender_->SetTrack(video_track_.get()));
EXPECT_CALL(*set_streams_observer, OnSetStreams()); EXPECT_CALL(*set_streams_observer, OnSetStreams());
video_rtp_sender_->SetStreams({local_stream_->id()}); video_rtp_sender_->SetStreams({local_stream_->id()});
@ -1310,8 +1316,8 @@ TEST_F(RtpSenderReceiverDeathTest,
TEST_F(RtpSenderReceiverTest, TEST_F(RtpSenderReceiverTest,
VideoSenderMustCallGetParametersBeforeSetParametersBeforeNegotiation) { VideoSenderMustCallGetParametersBeforeSetParametersBeforeNegotiation) {
video_rtp_sender_ = video_rtp_sender_ = VideoRtpSender::Create(
VideoRtpSender::Create(worker_thread_, /*id=*/"", nullptr); CreateEnvironment(), worker_thread_, /*id=*/"", nullptr);
RtpParameters params; RtpParameters params;
RTCError result = video_rtp_sender_->SetParameters(params); RTCError result = video_rtp_sender_->SetParameters(params);
@ -1713,8 +1719,9 @@ TEST_F(RtpSenderReceiverTest,
// Setting detailed overrides the default non-screencast mode. This should be // Setting detailed overrides the default non-screencast mode. This should be
// applied even if the track is set on construction. // applied even if the track is set on construction.
video_track_->set_content_hint(VideoTrackInterface::ContentHint::kDetailed); video_track_->set_content_hint(VideoTrackInterface::ContentHint::kDetailed);
video_rtp_sender_ = VideoRtpSender::Create(worker_thread_, video_track_->id(), video_rtp_sender_ =
set_streams_observer.get()); VideoRtpSender::Create(CreateEnvironment(), worker_thread_,
video_track_->id(), set_streams_observer.get());
ASSERT_TRUE(video_rtp_sender_->SetTrack(video_track_.get())); ASSERT_TRUE(video_rtp_sender_->SetTrack(video_track_.get()));
EXPECT_CALL(*set_streams_observer, OnSetStreams()); EXPECT_CALL(*set_streams_observer, OnSetStreams());
video_rtp_sender_->SetStreams({local_stream_->id()}); video_rtp_sender_->SetStreams({local_stream_->id()});
@ -1903,8 +1910,8 @@ TEST_F(RtpSenderReceiverTest,
// Checks that the senders SetStreams eliminates duplicate stream ids. // Checks that the senders SetStreams eliminates duplicate stream ids.
TEST_F(RtpSenderReceiverTest, SenderSetStreamsEliminatesDuplicateIds) { TEST_F(RtpSenderReceiverTest, SenderSetStreamsEliminatesDuplicateIds) {
AddVideoTrack(); AddVideoTrack();
video_rtp_sender_ = video_rtp_sender_ = VideoRtpSender::Create(
VideoRtpSender::Create(worker_thread_, video_track_->id(), nullptr); CreateEnvironment(), worker_thread_, video_track_->id(), nullptr);
video_rtp_sender_->SetStreams({"1", "2", "1"}); video_rtp_sender_->SetStreams({"1", "2", "1"});
EXPECT_EQ(video_rtp_sender_->stream_ids().size(), 2u); EXPECT_EQ(video_rtp_sender_->stream_ids().size(), 2u);
} }

View File

@ -14,6 +14,7 @@
#include <type_traits> #include <type_traits>
#include <utility> #include <utility>
#include "api/environment/environment.h"
#include "api/peer_connection_interface.h" #include "api/peer_connection_interface.h"
#include "api/rtp_transceiver_direction.h" #include "api/rtp_transceiver_direction.h"
#include "pc/audio_rtp_receiver.h" #include "pc/audio_rtp_receiver.h"
@ -34,13 +35,15 @@ static const char kDefaultVideoSenderId[] = "defaultv0";
} // namespace } // namespace
RtpTransmissionManager::RtpTransmissionManager( RtpTransmissionManager::RtpTransmissionManager(
const Environment& env,
bool is_unified_plan, bool is_unified_plan,
ConnectionContext* context, ConnectionContext* context,
UsagePattern* usage_pattern, UsagePattern* usage_pattern,
PeerConnectionObserver* observer, PeerConnectionObserver* observer,
LegacyStatsCollectorInterface* legacy_stats, LegacyStatsCollectorInterface* legacy_stats,
std::function<void()> on_negotiation_needed) std::function<void()> on_negotiation_needed)
: is_unified_plan_(is_unified_plan), : env_(env),
is_unified_plan_(is_unified_plan),
context_(context), context_(context),
usage_pattern_(usage_pattern), usage_pattern_(usage_pattern),
observer_(observer), observer_(observer),
@ -245,14 +248,15 @@ RtpTransmissionManager::CreateSender(
(track->kind() == MediaStreamTrackInterface::kAudioKind)); (track->kind() == MediaStreamTrackInterface::kAudioKind));
sender = RtpSenderProxyWithInternal<RtpSenderInternal>::Create( sender = RtpSenderProxyWithInternal<RtpSenderInternal>::Create(
signaling_thread(), signaling_thread(),
AudioRtpSender::Create(worker_thread(), id, legacy_stats_, this)); AudioRtpSender::Create(env_, worker_thread(), id, legacy_stats_, this));
NoteUsageEvent(UsageEvent::AUDIO_ADDED); NoteUsageEvent(UsageEvent::AUDIO_ADDED);
} else { } else {
RTC_DCHECK_EQ(media_type, cricket::MEDIA_TYPE_VIDEO); RTC_DCHECK_EQ(media_type, cricket::MEDIA_TYPE_VIDEO);
RTC_DCHECK(!track || RTC_DCHECK(!track ||
(track->kind() == MediaStreamTrackInterface::kVideoKind)); (track->kind() == MediaStreamTrackInterface::kVideoKind));
sender = RtpSenderProxyWithInternal<RtpSenderInternal>::Create( sender = RtpSenderProxyWithInternal<RtpSenderInternal>::Create(
signaling_thread(), VideoRtpSender::Create(worker_thread(), id, this)); signaling_thread(),
VideoRtpSender::Create(env_, worker_thread(), id, this));
NoteUsageEvent(UsageEvent::VIDEO_ADDED); NoteUsageEvent(UsageEvent::VIDEO_ADDED);
} }
bool set_track_succeeded = sender->SetTrack(track.get()); bool set_track_succeeded = sender->SetTrack(track.get());

View File

@ -17,6 +17,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include "api/environment/environment.h"
#include "api/media_stream_interface.h" #include "api/media_stream_interface.h"
#include "api/media_types.h" #include "api/media_types.h"
#include "api/peer_connection_interface.h" #include "api/peer_connection_interface.h"
@ -70,7 +71,8 @@ struct RtpSenderInfo {
// RtpTransceiver. // RtpTransceiver.
class RtpTransmissionManager : public RtpSenderBase::SetStreamsObserver { class RtpTransmissionManager : public RtpSenderBase::SetStreamsObserver {
public: public:
RtpTransmissionManager(bool is_unified_plan, RtpTransmissionManager(const Environment& env,
bool is_unified_plan,
ConnectionContext* context, ConnectionContext* context,
UsagePattern* usage_pattern, UsagePattern* usage_pattern,
PeerConnectionObserver* observer, PeerConnectionObserver* observer,
@ -250,6 +252,7 @@ class RtpTransmissionManager : public RtpSenderBase::SetStreamsObserver {
return context_->ssrc_generator(); return context_->ssrc_generator();
} }
const Environment env_;
TransceiverList transceivers_; TransceiverList transceivers_;
// These lists store sender info seen in local/remote descriptions. // These lists store sender info seen in local/remote descriptions.