Three updates to RtpSender
1) Explicit injection of the signaling thread into senders. This removes
use of Thread::Current() for this.
2) When constructing a sender with a freshly constructed media channel,
construct the sender on the worker thread. This is so that the sender
can configure the media channel directly and adhere to the media
channel's thread requirements.
3) Hook up the OnRtpSendParametersChanged notification from the media
channel. The callback is pretty simple to start with and just
invalidates the last transaction ID thread when parameters change. This
has the effect that if parameters change during negotiation, a call to
GetParameters() before negotiation, must be made again before calling
SetParameters.
Bug: webrtc:42222804
Change-Id: Iebc5d7000305cd1a607c21d7778515b5beb5b55f
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/441600
Reviewed-by: Harald Alvestrand <hta@webrtc.org>
Commit-Queue: Tomas Gunnarsson <tommi@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#46674}
diff --git a/media/engine/webrtc_voice_engine.cc b/media/engine/webrtc_voice_engine.cc
index a8595b8..f42452b 100644
--- a/media/engine/webrtc_voice_engine.cc
+++ b/media/engine/webrtc_voice_engine.cc
@@ -2035,7 +2035,7 @@
RTCError error =
it->second->SetRtpParameters(reduced_params, std::move(callback));
if (error.ok()) {
- on_rtp_send_parameters_changed_callback_.Send(ssrc, parameters);
+ on_rtp_send_parameters_changed_callback_.Send(ssrc, reduced_params);
}
return error;
}
diff --git a/pc/peer_connection.cc b/pc/peer_connection.cc
index 58590ae..3aa6de6 100644
--- a/pc/peer_connection.cc
+++ b/pc/peer_connection.cc
@@ -1264,16 +1264,17 @@
scoped_refptr<RtpSenderProxyWithInternal<RtpSenderInternal>> new_sender;
if (kind == MediaStreamTrackInterface::kAudioKind) {
- auto audio_sender = AudioRtpSender::Create(
- env_, worker_thread(), CreateRandomUuid(), legacy_stats_.get(), nullptr,
- rtp_manager()->voice_media_send_channel());
+ auto audio_sender =
+ AudioRtpSender::Create(env_, signaling_thread(), worker_thread(),
+ CreateRandomUuid(), legacy_stats_.get(), nullptr,
+ rtp_manager()->voice_media_send_channel());
new_sender = RtpSenderProxyWithInternal<RtpSenderInternal>::Create(
signaling_thread(), audio_sender);
rtp_manager()->GetAudioTransceiver()->internal()->AddSenderPlanB(
new_sender);
} else if (kind == MediaStreamTrackInterface::kVideoKind) {
auto video_sender = VideoRtpSender::Create(
- env_, worker_thread(), CreateRandomUuid(), nullptr,
+ env_, signaling_thread(), worker_thread(), CreateRandomUuid(), nullptr,
rtp_manager()->video_media_send_channel());
new_sender = RtpSenderProxyWithInternal<RtpSenderInternal>::Create(
signaling_thread(), video_sender);
diff --git a/pc/rtp_sender.cc b/pc/rtp_sender.cc
index a3d1893..5b29d34 100644
--- a/pc/rtp_sender.cc
+++ b/pc/rtp_sender.cc
@@ -31,6 +31,7 @@
#include "api/frame_transformer_interface.h"
#include "api/make_ref_counted.h"
#include "api/media_stream_interface.h"
+#include "api/media_types.h"
#include "api/priority.h"
#include "api/rtc_error.h"
#include "api/rtp_parameters.h"
@@ -132,15 +133,18 @@
}
RtpSenderBase::RtpSenderBase(const Environment& env,
+ Thread* signaling_thread,
Thread* worker_thread,
absl::string_view id,
+ MediaType media_type,
SetStreamsObserver* set_streams_observer,
MediaSendChannelInterface* media_channel)
: env_(env),
- signaling_thread_(Thread::Current()),
+ signaling_thread_(signaling_thread),
worker_thread_(worker_thread),
id_(id),
- media_channel_(media_channel),
+ media_type_(media_type),
+ media_channel_(nullptr), // Will be set in SetMediaChannel().
set_streams_observer_(set_streams_observer),
worker_safety_(PendingTaskSafetyFlag::CreateAttachedToTaskQueue(
/*alive=*/media_channel != nullptr,
@@ -148,8 +152,17 @@
signaling_safety_(
PendingTaskSafetyFlag::CreateAttachedToTaskQueue(/*alive=*/true,
signaling_thread_)) {
- RTC_DCHECK(worker_thread);
+ RTC_DCHECK(worker_thread_);
init_parameters_.encodings.emplace_back();
+ if (media_channel) {
+ // When initialized with a valid media channel, we need to be running on the
+ // worker thread in order to set things up properly.
+ RTC_DCHECK_RUN_ON(worker_thread_);
+ SetMediaChannel(media_channel);
+ } else {
+ // Otherwise, we're less picky (but probably running on the signaling
+ // thread).
+ }
}
RtpSenderBase::~RtpSenderBase() {
@@ -194,15 +207,36 @@
void RtpSenderBase::SetMediaChannel(MediaSendChannelInterface* media_channel) {
RTC_DCHECK_RUN_ON(worker_thread_);
- RTC_DCHECK(media_channel == nullptr ||
- media_channel->media_type() == media_type());
+ RTC_DCHECK(!media_channel || media_channel->media_type() == media_type_);
+ if (media_channel_ == media_channel) {
+ return;
+ }
+
// Note that setting the media_channel_ to nullptr and clearing the send state
// via ClearSend_w, are separate operations. Stopping the actual send
// operation, needs to be done via any of the paths that end up with a call to
// ClearSend_w(), such as DetachTrackAndGetStopTask().
+ if (media_channel_) {
+ media_channel_->UnsubscribeRtpSendParametersChanged(this);
+ }
+
media_channel_ = media_channel;
- media_channel_ != nullptr ? worker_safety_->SetAlive()
- : worker_safety_->SetNotAlive();
+
+ if (media_channel_) {
+ worker_safety_->SetAlive();
+ media_channel_->SubscribeRtpSendParametersChanged(
+ this,
+ [this](std::optional<uint32_t> ssrc, const RtpParameters& parameters) {
+ RTC_DCHECK_RUN_ON(worker_thread_);
+ signaling_thread_->PostTask(
+ SafeTask(signaling_safety_.flag(), [this]() mutable {
+ RTC_DCHECK_RUN_ON(signaling_thread_);
+ last_transaction_id_.reset();
+ }));
+ });
+ } else {
+ worker_safety_->SetNotAlive();
+ }
}
RtpParameters RtpSenderBase::GetParametersInternal() const {
@@ -748,30 +782,35 @@
scoped_refptr<AudioRtpSender> AudioRtpSender::Create(
const Environment& env,
+ Thread* signaling_thread,
Thread* worker_thread,
absl::string_view id,
LegacyStatsCollectorInterface* stats,
SetStreamsObserver* set_streams_observer,
MediaSendChannelInterface* media_channel) {
- return make_ref_counted<AudioRtpSender>(env, worker_thread, id, stats,
- set_streams_observer, media_channel);
+ return make_ref_counted<AudioRtpSender>(env, signaling_thread, worker_thread,
+ id, stats, set_streams_observer,
+ media_channel);
}
AudioRtpSender::AudioRtpSender(const Environment& env,
+ Thread* signaling_thread,
Thread* worker_thread,
absl::string_view id,
LegacyStatsCollectorInterface* stats,
SetStreamsObserver* set_streams_observer,
MediaSendChannelInterface* media_channel)
: RtpSenderBase(env,
+ signaling_thread,
worker_thread,
id,
+ MediaType::AUDIO,
set_streams_observer,
media_channel),
legacy_stats_(stats),
- dtmf_sender_(DtmfSender::Create(Thread::Current(), this)),
+ dtmf_sender_(DtmfSender::Create(signaling_thread, this)),
dtmf_sender_proxy_(
- DtmfSenderProxy::Create(Thread::Current(), dtmf_sender_)),
+ DtmfSenderProxy::Create(signaling_thread, dtmf_sender_)),
sink_adapter_(new LocalAudioSinkAdapter()) {}
AudioRtpSender::~AudioRtpSender() {
@@ -915,22 +954,27 @@
scoped_refptr<VideoRtpSender> VideoRtpSender::Create(
const Environment& env,
+ Thread* signaling_thread,
Thread* worker_thread,
absl::string_view id,
SetStreamsObserver* set_streams_observer,
MediaSendChannelInterface* media_channel) {
- return make_ref_counted<VideoRtpSender>(env, worker_thread, id,
- set_streams_observer, media_channel);
+ return make_ref_counted<VideoRtpSender>(env, signaling_thread, worker_thread,
+ id, set_streams_observer,
+ media_channel);
}
VideoRtpSender::VideoRtpSender(const Environment& env,
+ Thread* signaling_thread,
Thread* worker_thread,
absl::string_view id,
SetStreamsObserver* set_streams_observer,
MediaSendChannelInterface* media_channel)
: RtpSenderBase(env,
+ signaling_thread,
worker_thread,
id,
+ MediaType::VIDEO,
set_streams_observer,
media_channel) {}
diff --git a/pc/rtp_sender.h b/pc/rtp_sender.h
index f4dbfce..ca82d13 100644
--- a/pc/rtp_sender.h
+++ b/pc/rtp_sender.h
@@ -138,6 +138,8 @@
return track_;
}
+ MediaType media_type() const final { return media_type_; }
+
RtpParameters GetParameters() const override;
RTCError SetParameters(const RtpParameters& parameters) override;
void SetParametersAsync(const RtpParameters& parameters,
@@ -234,8 +236,10 @@
// 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.
RtpSenderBase(const Environment& env,
+ Thread* signaling_thread,
Thread* worker_thread,
absl::string_view id,
+ MediaType media_type,
SetStreamsObserver* set_streams_observer,
MediaSendChannelInterface* media_channel);
@@ -271,6 +275,7 @@
bool stopped_ RTC_GUARDED_BY(signaling_thread_) = false;
int attachment_id_ = 0;
const std::string id_;
+ const MediaType media_type_;
std::vector<std::string> stream_ids_;
RtpParameters init_parameters_;
@@ -364,6 +369,7 @@
// null, it must be valid at least until this sender becomes stopped.
static scoped_refptr<AudioRtpSender> Create(
const Environment& env,
+ Thread* signaling_thread,
Thread* worker_thread,
absl::string_view id,
LegacyStatsCollectorInterface* stats,
@@ -378,7 +384,6 @@
// ObserverInterface implementation.
void OnChanged() override;
- MediaType media_type() const override { return MediaType::AUDIO; }
std::string track_kind() const override {
return MediaStreamTrackInterface::kAudioKind;
}
@@ -388,6 +393,7 @@
protected:
AudioRtpSender(const Environment& env,
+ Thread* signaling_thread,
Thread* worker_thread,
absl::string_view id,
LegacyStatsCollectorInterface* legacy_stats,
@@ -434,6 +440,7 @@
// null, it must be valid at least until this sender becomes stopped.
static scoped_refptr<VideoRtpSender> Create(
const Environment& env,
+ Thread* signaling_thread,
Thread* worker_thread,
absl::string_view id,
SetStreamsObserver* set_streams_observer,
@@ -443,7 +450,6 @@
// ObserverInterface implementation
void OnChanged() override;
- MediaType media_type() const override { return MediaType::VIDEO; }
std::string track_kind() const override {
return MediaStreamTrackInterface::kVideoKind;
}
@@ -453,6 +459,7 @@
protected:
VideoRtpSender(const Environment& env,
+ Thread* signaling_thread,
Thread* worker_thread,
absl::string_view id,
SetStreamsObserver* set_streams_observer,
diff --git a/pc/rtp_sender_receiver_unittest.cc b/pc/rtp_sender_receiver_unittest.cc
index 61f1d75..29f28bd 100644
--- a/pc/rtp_sender_receiver_unittest.cc
+++ b/pc/rtp_sender_receiver_unittest.cc
@@ -191,9 +191,12 @@
EXPECT_TRUE(local_stream_->AddTrack(audio_track_));
std::unique_ptr<MockSetStreamsObserver> set_streams_observer =
std::make_unique<MockSetStreamsObserver>();
- audio_rtp_sender_ = AudioRtpSender::Create(
- CreateEnvironment(), worker_thread_.get(), audio_track_->id(), nullptr,
- set_streams_observer.get(), voice_media_send_channel_.get());
+ worker_thread_->BlockingCall([&]() {
+ audio_rtp_sender_ = AudioRtpSender::Create(
+ CreateEnvironment(), signaling_thread_, worker_thread_.get(),
+ audio_track_->id(), nullptr, set_streams_observer.get(),
+ voice_media_send_channel_.get());
+ });
ASSERT_TRUE(audio_rtp_sender_->SetTrack(audio_track_.get()));
EXPECT_CALL(*set_streams_observer, OnSetStreams());
audio_rtp_sender_->SetStreams({local_stream_->id()});
@@ -202,9 +205,11 @@
}
void CreateAudioRtpSenderWithNoTrack() {
- audio_rtp_sender_ = AudioRtpSender::Create(
- CreateEnvironment(), worker_thread_.get(), /*id=*/"", nullptr, nullptr,
- voice_media_send_channel_.get());
+ worker_thread_->BlockingCall([&]() {
+ audio_rtp_sender_ = AudioRtpSender::Create(
+ CreateEnvironment(), signaling_thread_, worker_thread_.get(),
+ /*id=*/"", nullptr, nullptr, voice_media_send_channel_.get());
+ });
}
void CreateVideoRtpSender(uint32_t ssrc) {
@@ -252,9 +257,12 @@
AddVideoTrack(is_screencast);
std::unique_ptr<MockSetStreamsObserver> set_streams_observer =
std::make_unique<MockSetStreamsObserver>();
- video_rtp_sender_ = VideoRtpSender::Create(
- CreateEnvironment(), worker_thread_.get(), video_track_->id(),
- set_streams_observer.get(), video_media_send_channel());
+ worker_thread_->BlockingCall([&]() {
+ video_rtp_sender_ = VideoRtpSender::Create(
+ CreateEnvironment(), signaling_thread_, worker_thread_.get(),
+ video_track_->id(), set_streams_observer.get(),
+ video_media_send_channel());
+ });
ASSERT_TRUE(video_rtp_sender_->SetTrack(video_track_.get()));
EXPECT_CALL(*set_streams_observer, OnSetStreams());
video_rtp_sender_->SetStreams({local_stream_->id()});
@@ -262,9 +270,11 @@
VerifyVideoChannelInput(ssrc);
}
void CreateVideoRtpSenderWithNoTrack() {
- video_rtp_sender_ =
- VideoRtpSender::Create(CreateEnvironment(), worker_thread_.get(),
- /*id=*/"", nullptr, video_media_send_channel());
+ worker_thread_->BlockingCall([&]() {
+ video_rtp_sender_ = VideoRtpSender::Create(
+ CreateEnvironment(), signaling_thread_, worker_thread_.get(),
+ /*id=*/"", nullptr, video_media_send_channel());
+ });
}
void DestroyAudioRtpSender() {
@@ -464,8 +474,9 @@
void RunDisableSimulcastLayersWithoutMediaEngineTest(
const std::vector<std::string>& all_layers,
const std::vector<std::string>& disabled_layers) {
- auto sender = VideoRtpSender::Create(
- CreateEnvironment(), worker_thread_.get(), "1", nullptr, nullptr);
+ auto sender =
+ VideoRtpSender::Create(CreateEnvironment(), signaling_thread_,
+ worker_thread_.get(), "1", nullptr, nullptr);
RtpParameters parameters;
parameters.encodings.resize(all_layers.size());
for (size_t i = 0; i < all_layers.size(); ++i) {
@@ -529,6 +540,9 @@
}
test::RunLoop run_loop_;
+ // Initialize `signaling_thread_` to point to the current thread.
+ // This is the internal thread owned by `run_loop_`.
+ Thread* const signaling_thread_ = Thread::Current();
const std::unique_ptr<Thread> network_thread_;
const std::unique_ptr<Thread> worker_thread_;
const Environment env_ = CreateEnvironment();
@@ -915,9 +929,9 @@
}
TEST_F(RtpSenderReceiverTest, AudioSenderCanSetParametersBeforeNegotiation) {
- audio_rtp_sender_ =
- AudioRtpSender::Create(CreateEnvironment(), worker_thread_.get(),
- /*id=*/"", nullptr, nullptr, nullptr);
+ audio_rtp_sender_ = AudioRtpSender::Create(
+ CreateEnvironment(), signaling_thread_, worker_thread_.get(),
+ /*id=*/"", nullptr, nullptr, nullptr);
RtpParameters params = audio_rtp_sender_->GetParameters();
ASSERT_EQ(1u, params.encodings.size());
@@ -933,9 +947,9 @@
TEST_F(RtpSenderReceiverTest,
AudioSenderCanSetParametersAsyncBeforeNegotiation) {
- audio_rtp_sender_ =
- AudioRtpSender::Create(CreateEnvironment(), worker_thread_.get(),
- /*id=*/"", nullptr, nullptr, nullptr);
+ audio_rtp_sender_ = AudioRtpSender::Create(
+ CreateEnvironment(), signaling_thread_, worker_thread_.get(),
+ /*id=*/"", nullptr, nullptr, nullptr);
std::optional<RTCError> result;
RtpParameters params = audio_rtp_sender_->GetParameters();
@@ -969,8 +983,8 @@
std::unique_ptr<MockSetStreamsObserver> set_streams_observer =
std::make_unique<MockSetStreamsObserver>();
audio_rtp_sender_ = AudioRtpSender::Create(
- CreateEnvironment(), worker_thread_.get(), audio_track_->id(), nullptr,
- set_streams_observer.get(), nullptr);
+ CreateEnvironment(), signaling_thread_, worker_thread_.get(),
+ audio_track_->id(), nullptr, set_streams_observer.get(), nullptr);
ASSERT_TRUE(audio_rtp_sender_->SetTrack(audio_track_.get()));
EXPECT_CALL(*set_streams_observer, OnSetStreams());
audio_rtp_sender_->SetStreams({local_stream_->id()});
@@ -1002,9 +1016,9 @@
TEST_F(RtpSenderReceiverTest,
AudioSenderMustCallGetParametersBeforeSetParametersBeforeNegotiation) {
- audio_rtp_sender_ =
- AudioRtpSender::Create(CreateEnvironment(), worker_thread_.get(),
- /*id=*/"", nullptr, nullptr, nullptr);
+ audio_rtp_sender_ = AudioRtpSender::Create(
+ CreateEnvironment(), signaling_thread_, worker_thread_.get(),
+ /*id=*/"", nullptr, nullptr, nullptr);
RtpParameters params;
RTCError result = audio_rtp_sender_->SetParameters(params);
@@ -1181,8 +1195,9 @@
}
TEST_F(RtpSenderReceiverTest, VideoSenderCanSetParametersBeforeNegotiation) {
- video_rtp_sender_ = VideoRtpSender::Create(
- CreateEnvironment(), worker_thread_.get(), /*id=*/"", nullptr, nullptr);
+ video_rtp_sender_ =
+ VideoRtpSender::Create(CreateEnvironment(), signaling_thread_,
+ worker_thread_.get(), /*id=*/"", nullptr, nullptr);
RtpParameters params = video_rtp_sender_->GetParameters();
ASSERT_EQ(1u, params.encodings.size());
@@ -1198,8 +1213,9 @@
TEST_F(RtpSenderReceiverTest,
VideoSenderCanSetParametersAsyncBeforeNegotiation) {
- video_rtp_sender_ = VideoRtpSender::Create(
- CreateEnvironment(), worker_thread_.get(), /*id=*/"", nullptr, nullptr);
+ video_rtp_sender_ =
+ VideoRtpSender::Create(CreateEnvironment(), signaling_thread_,
+ worker_thread_.get(), /*id=*/"", nullptr, nullptr);
std::optional<RTCError> result;
RtpParameters params = video_rtp_sender_->GetParameters();
@@ -1230,8 +1246,8 @@
std::unique_ptr<MockSetStreamsObserver> set_streams_observer =
std::make_unique<MockSetStreamsObserver>();
video_rtp_sender_ = VideoRtpSender::Create(
- CreateEnvironment(), worker_thread_.get(), video_track_->id(),
- set_streams_observer.get(), nullptr);
+ CreateEnvironment(), signaling_thread_, worker_thread_.get(),
+ video_track_->id(), set_streams_observer.get(), nullptr);
ASSERT_TRUE(video_rtp_sender_->SetTrack(video_track_.get()));
EXPECT_CALL(*set_streams_observer, OnSetStreams());
video_rtp_sender_->SetStreams({local_stream_->id()});
@@ -1274,8 +1290,8 @@
std::unique_ptr<MockSetStreamsObserver> set_streams_observer =
std::make_unique<MockSetStreamsObserver>();
video_rtp_sender_ = VideoRtpSender::Create(
- CreateEnvironment(), worker_thread_.get(), video_track_->id(),
- set_streams_observer.get(), nullptr);
+ CreateEnvironment(), signaling_thread_, worker_thread_.get(),
+ video_track_->id(), set_streams_observer.get(), nullptr);
ASSERT_TRUE(video_rtp_sender_->SetTrack(video_track_.get()));
EXPECT_CALL(*set_streams_observer, OnSetStreams());
video_rtp_sender_->SetStreams({local_stream_->id()});
@@ -1336,8 +1352,9 @@
std::unique_ptr<MockSetStreamsObserver> set_streams_observer =
std::make_unique<MockSetStreamsObserver>();
- auto video_rtp_sender = VideoRtpSender::Create(
- env, thread, video_track->id(), set_streams_observer.get(), nullptr);
+ auto video_rtp_sender =
+ VideoRtpSender::Create(env, thread, thread, video_track->id(),
+ set_streams_observer.get(), nullptr);
ASSERT_TRUE(video_rtp_sender->SetTrack(video_track.get()));
EXPECT_CALL(*set_streams_observer, OnSetStreams());
@@ -1366,8 +1383,9 @@
TEST_F(RtpSenderReceiverTest,
VideoSenderMustCallGetParametersBeforeSetParametersBeforeNegotiation) {
- video_rtp_sender_ = VideoRtpSender::Create(
- CreateEnvironment(), worker_thread_.get(), /*id=*/"", nullptr, nullptr);
+ video_rtp_sender_ =
+ VideoRtpSender::Create(CreateEnvironment(), signaling_thread_,
+ worker_thread_.get(), /*id=*/"", nullptr, nullptr);
RtpParameters params;
RTCError result = video_rtp_sender_->SetParameters(params);
@@ -1779,8 +1797,8 @@
// applied even if the track is set on construction.
video_track_->set_content_hint(VideoTrackInterface::ContentHint::kDetailed);
video_rtp_sender_ = VideoRtpSender::Create(
- CreateEnvironment(), worker_thread_.get(), video_track_->id(),
- set_streams_observer.get(), nullptr);
+ CreateEnvironment(), signaling_thread_, worker_thread_.get(),
+ video_track_->id(), set_streams_observer.get(), nullptr);
ASSERT_TRUE(video_rtp_sender_->SetTrack(video_track_.get()));
EXPECT_CALL(*set_streams_observer, OnSetStreams());
video_rtp_sender_->SetStreams({local_stream_->id()});
@@ -1982,9 +2000,9 @@
// Checks that the senders SetStreams eliminates duplicate stream ids.
TEST_F(RtpSenderReceiverTest, SenderSetStreamsEliminatesDuplicateIds) {
AddVideoTrack();
- video_rtp_sender_ =
- VideoRtpSender::Create(CreateEnvironment(), worker_thread_.get(),
- video_track_->id(), nullptr, nullptr);
+ video_rtp_sender_ = VideoRtpSender::Create(
+ CreateEnvironment(), signaling_thread_, worker_thread_.get(),
+ video_track_->id(), nullptr, nullptr);
video_rtp_sender_->SetStreams({"1", "2", "1"});
EXPECT_EQ(video_rtp_sender_->stream_ids().size(), 2u);
}
diff --git a/pc/rtp_transceiver.cc b/pc/rtp_transceiver.cc
index 5b3087e..6530b71 100644
--- a/pc/rtp_transceiver.cc
+++ b/pc/rtp_transceiver.cc
@@ -162,39 +162,31 @@
return RtpSenderProxyWithInternal<RtpSenderInternal>::Create(
context->signaling_thread(),
AudioRtpSender::Create(
- env, context->worker_thread(), sender_id, legacy_stats,
- set_streams_observer,
+ env, context->signaling_thread(), context->worker_thread(),
+ sender_id, legacy_stats, set_streams_observer,
static_cast<VoiceMediaSendChannelInterface*>(media_send_channel)));
}
RTC_DCHECK_EQ(media_type, MediaType::VIDEO);
return RtpSenderProxyWithInternal<RtpSenderInternal>::Create(
context->signaling_thread(),
VideoRtpSender::Create(
- env, context->worker_thread(), sender_id, set_streams_observer,
+ env, context->signaling_thread(), context->worker_thread(), sender_id,
+ set_streams_observer,
static_cast<VideoMediaSendChannelInterface*>(media_send_channel)));
}
-scoped_refptr<RtpSenderProxyWithInternal<RtpSenderInternal>> CreateSender(
- MediaType media_type,
- const Environment& env,
- ConnectionContext* context,
- LegacyStatsCollectorInterface* legacy_stats,
- RtpSenderBase::SetStreamsObserver* set_streams_observer,
- absl::string_view sender_id,
- MediaSendChannelInterface* media_send_channel,
+void ConfigureSender(
+ scoped_refptr<RtpSenderProxyWithInternal<RtpSenderInternal>>& sender,
MediaStreamTrackInterface* track,
const std::vector<std::string>& stream_ids,
const std::vector<RtpEncodingParameters>& send_encodings,
CodecVendor& codec_vendor) {
- scoped_refptr<RtpSenderProxyWithInternal<RtpSenderInternal>> sender =
- CreateSender(media_type, env, context, legacy_stats, set_streams_observer,
- sender_id, media_send_channel);
bool set_track_succeeded = sender->SetTrack(track);
RTC_DCHECK(set_track_succeeded);
- sender->internal()->set_stream_ids(stream_ids);
- sender->internal()->set_init_send_encodings(send_encodings);
- ConfigureSendCodecs(codec_vendor, media_type, sender->internal());
- return sender;
+ auto* internal = sender->internal();
+ internal->set_stream_ids(stream_ids);
+ internal->set_init_send_encodings(send_encodings);
+ ConfigureSendCodecs(codec_vendor, sender->media_type(), internal);
}
template <typename RtpReceiverT, typename ReceiveInterface>
@@ -334,14 +326,15 @@
RTC_DCHECK_EQ(sender->media_type(), receiver->media_type());
RTC_DCHECK_EQ(media_type_, sender->media_type());
RTC_DCHECK_DISALLOW_THREAD_BLOCKING_CALLS();
+ auto* sender_internal = sender->internal();
senders_.push_back(std::move(sender));
receivers_.push_back(std::move(receiver));
if (media_type_ == MediaType::VIDEO) {
ConfigureExtraVideoHeaderExtensions(
- sender_internal()->GetParametersInternal().encodings,
+ sender_internal->GetParametersInternal().encodings,
header_extensions_to_negotiate_);
}
- ConfigureSendCodecs(codec_vendor(), media_type_, sender_internal().get());
+ ConfigureSendCodecs(codec_vendor(), media_type_, sender_internal);
}
RtpTransceiver::RtpTransceiver(
@@ -399,12 +392,14 @@
video_options, crypto_options, video_bitrate_allocator_factory);
owned_send_channel_ = std::move(channels.first);
owned_receive_channel_ = std::move(channels.second);
+ senders_.push_back(CreateSender(media_type_, env_, context_, legacy_stats_,
+ set_streams_observer_, sender_id,
+ owned_send_channel_.get()));
});
- senders_.push_back(CreateSender(
- media_type_, env_, context_, legacy_stats_, set_streams_observer_,
- sender_id, owned_send_channel_.get(), track.get(), stream_ids,
- init_send_encodings, codec_vendor()));
+ ConfigureSender(senders_.back(), track.get(), stream_ids, init_send_encodings,
+ codec_vendor());
+
receivers_.push_back(CreateReceiver(
media_type_, context_->signaling_thread(), context_->worker_thread(),
receiver_id.empty() ? CreateRandomUuid() : receiver_id,
@@ -692,13 +687,15 @@
RTC_DCHECK(!unified_plan_);
RTC_DCHECK(media_type_ == MediaType::AUDIO ||
media_type_ == MediaType::VIDEO);
- scoped_refptr<RtpSenderProxyWithInternal<RtpSenderInternal>> sender =
- CreateSender(media_type_, env_, context_, legacy_stats_,
- set_streams_observer_, sender_id,
- channel_ ? channel_->media_send_channel() : nullptr,
- track.get(), stream_ids, send_encodings, codec_vendor());
- senders_.push_back(sender);
- return sender;
+ context_->worker_thread()->BlockingCall([&]() mutable {
+ RTC_DCHECK_RUN_ON(context()->worker_thread());
+ senders_.push_back(CreateSender(
+ media_type_, env_, context_, legacy_stats_, set_streams_observer_,
+ sender_id, channel_ ? channel_->media_send_channel() : nullptr));
+ });
+ ConfigureSender(senders_.back(), track.get(), stream_ids, send_encodings,
+ codec_vendor());
+ return senders_.back();
}
bool RtpTransceiver::RemoveSenderPlanB(RtpSenderInterface* sender) {
diff --git a/pc/sdp_offer_answer.cc b/pc/sdp_offer_answer.cc
index 26287f0..73610e3 100644
--- a/pc/sdp_offer_answer.cc
+++ b/pc/sdp_offer_answer.cc
@@ -3460,11 +3460,12 @@
transceivers()->Remove(transceiver);
}
}
+ auto sender_internal = transceiver->internal()->sender_internal();
if (stable_state.init_send_encodings()) {
- transceiver->internal()->sender_internal()->set_init_send_encodings(
+ sender_internal->set_init_send_encodings(
stable_state.init_send_encodings().value());
}
- transceiver->internal()->sender_internal()->set_transport(nullptr);
+ sender_internal->set_transport(nullptr);
transceiver->internal()->receiver_internal()->set_transport(nullptr);
if (stable_state.has_m_section()) {
transceiver->internal()->set_mid(stable_state.mid());