Remove remaining trampoline functions from channel_manager

This is part of the project to delete the class entirely.
The CL also adds an "use_rtx" parameter to the function for listing
video codecs, rather than filtering those away afterwards.

Bug: webrtc:13931
Change-Id: I96b9b18c694a1c0986ccf22face76ef4c704d372
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/262666
Reviewed-by: Henrik Boström <hbos@webrtc.org>
Commit-Queue: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#36963}
This commit is contained in:
Harald Alvestrand 2022-05-22 10:57:01 +00:00 committed by WebRTC LUCI CQ
parent dbfa78114b
commit c3fa7c38b2
24 changed files with 231 additions and 221 deletions

View File

@ -527,11 +527,11 @@ void FakeVideoEngine::UnregisterChannel(VideoMediaChannel* channel) {
RTC_DCHECK(it != channels_.end());
channels_.erase(it);
}
std::vector<VideoCodec> FakeVideoEngine::send_codecs() const {
std::vector<VideoCodec> FakeVideoEngine::send_codecs(bool use_rtx) const {
return send_codecs_;
}
std::vector<VideoCodec> FakeVideoEngine::recv_codecs() const {
std::vector<VideoCodec> FakeVideoEngine::recv_codecs(bool use_rtx) const {
return recv_codecs_;
}

View File

@ -532,8 +532,14 @@ class FakeVideoEngine : public VideoEngineInterface {
override;
FakeVideoMediaChannel* GetChannel(size_t index);
void UnregisterChannel(VideoMediaChannel* channel);
std::vector<VideoCodec> send_codecs() const override;
std::vector<VideoCodec> recv_codecs() const override;
std::vector<VideoCodec> send_codecs() const override {
return send_codecs(true);
}
std::vector<VideoCodec> recv_codecs() const override {
return recv_codecs(true);
}
std::vector<VideoCodec> send_codecs(bool include_rtx) const override;
std::vector<VideoCodec> recv_codecs(bool include_rtx) const override;
void SetSendCodecs(const std::vector<VideoCodec>& codecs);
void SetRecvCodecs(const std::vector<VideoCodec>& codecs);
bool SetCapture(bool capture);

View File

@ -114,8 +114,20 @@ class VideoEngineInterface : public RtpHeaderExtensionQueryInterface {
webrtc::VideoBitrateAllocatorFactory*
video_bitrate_allocator_factory) = 0;
// Retrieve list of supported codecs.
virtual std::vector<VideoCodec> send_codecs() const = 0;
virtual std::vector<VideoCodec> recv_codecs() const = 0;
// As above, but if include_rtx is false, don't include RTX codecs.
// TODO(bugs.webrtc.org/13931): Remove default implementation once
// upstream subclasses have converted.
virtual std::vector<VideoCodec> send_codecs(bool include_rtx) const {
RTC_DCHECK(include_rtx);
return send_codecs();
}
virtual std::vector<VideoCodec> recv_codecs(bool include_rtx) const {
RTC_DCHECK(include_rtx);
return recv_codecs();
}
};
// MediaEngineInterface is an abstraction of a media engine which can be

View File

@ -37,6 +37,13 @@ class NullWebRtcVideoEngine : public VideoEngineInterface {
std::vector<VideoCodec> recv_codecs() const override {
return std::vector<VideoCodec>();
}
std::vector<VideoCodec> send_codecs(bool) const override {
return std::vector<VideoCodec>();
}
std::vector<VideoCodec> recv_codecs(bool) const override {
return std::vector<VideoCodec>();
}
std::vector<webrtc::RtpHeaderExtensionCapability> GetRtpHeaderExtensions()
const override {

View File

@ -163,6 +163,7 @@ template <class T>
std::vector<VideoCodec> GetPayloadTypesAndDefaultCodecs(
const T* factory,
bool is_decoder_factory,
bool include_rtx,
const webrtc::FieldTrialsView& trials) {
if (!factory) {
return {};
@ -234,23 +235,25 @@ std::vector<VideoCodec> GetPayloadTypesAndDefaultCodecs(
output_codecs.push_back(codec);
// Add associated RTX codec for non-FEC codecs.
if (!isFecCodec) {
// Check if we ran out of payload types.
if (payload_type_lower > kLastDynamicPayloadTypeLowerRange) {
// TODO(https://bugs.chromium.org/p/webrtc/issues/detail?id=12248):
// return an error.
RTC_LOG(LS_ERROR) << "Out of dynamic payload types [35,63] after "
"fallback from [96, 127], skipping the rest.";
RTC_DCHECK_EQ(payload_type_upper, kLastDynamicPayloadTypeUpperRange);
break;
}
if (IsCodecValidForLowerRange(codec) ||
payload_type_upper >= kLastDynamicPayloadTypeUpperRange) {
output_codecs.push_back(
VideoCodec::CreateRtxCodec(payload_type_lower++, codec.id));
} else {
output_codecs.push_back(
VideoCodec::CreateRtxCodec(payload_type_upper++, codec.id));
if (include_rtx) {
if (!isFecCodec) {
// Check if we ran out of payload types.
if (payload_type_lower > kLastDynamicPayloadTypeLowerRange) {
// TODO(https://bugs.chromium.org/p/webrtc/issues/detail?id=12248):
// return an error.
RTC_LOG(LS_ERROR) << "Out of dynamic payload types [35,63] after "
"fallback from [96, 127], skipping the rest.";
RTC_DCHECK_EQ(payload_type_upper, kLastDynamicPayloadTypeUpperRange);
break;
}
if (IsCodecValidForLowerRange(codec) ||
payload_type_upper >= kLastDynamicPayloadTypeUpperRange) {
output_codecs.push_back(
VideoCodec::CreateRtxCodec(payload_type_lower++, codec.id));
} else {
output_codecs.push_back(
VideoCodec::CreateRtxCodec(payload_type_upper++, codec.id));
}
}
}
}
@ -651,14 +654,16 @@ VideoMediaChannel* WebRtcVideoEngine::CreateMediaChannel(
encoder_factory_.get(), decoder_factory_.get(),
video_bitrate_allocator_factory);
}
std::vector<VideoCodec> WebRtcVideoEngine::send_codecs() const {
std::vector<VideoCodec> WebRtcVideoEngine::send_codecs(bool include_rtx) const {
return GetPayloadTypesAndDefaultCodecs(encoder_factory_.get(),
/*is_decoder_factory=*/false, trials_);
/*is_decoder_factory=*/false,
include_rtx, trials_);
}
std::vector<VideoCodec> WebRtcVideoEngine::recv_codecs() const {
std::vector<VideoCodec> WebRtcVideoEngine::recv_codecs(bool include_rtx) const {
return GetPayloadTypesAndDefaultCodecs(decoder_factory_.get(),
/*is_decoder_factory=*/true, trials_);
/*is_decoder_factory=*/true,
include_rtx, trials_);
}
std::vector<webrtc::RtpHeaderExtensionCapability>
@ -735,7 +740,8 @@ WebRtcVideoChannel::WebRtcVideoChannel(
rtcp_receiver_report_ssrc_ = kDefaultRtcpReceiverReportSsrc;
sending_ = false;
recv_codecs_ = MapCodecs(GetPayloadTypesAndDefaultCodecs(
decoder_factory_, /*is_decoder_factory=*/true, call_->trials()));
decoder_factory_, /*is_decoder_factory=*/true,
/*include_rtx=*/true, call_->trials()));
recv_flexfec_payload_type_ =
recv_codecs_.empty() ? 0 : recv_codecs_.front().flexfec_payload_type;
}
@ -1180,7 +1186,7 @@ bool WebRtcVideoChannel::GetChangedRecvParameters(
const std::vector<VideoCodec> local_supported_codecs =
GetPayloadTypesAndDefaultCodecs(decoder_factory_,
/*is_decoder_factory=*/true,
call_->trials());
/*include_rtx=*/true, call_->trials());
for (const VideoCodecSettings& mapped_codec : mapped_codecs) {
if (!FindMatchingCodec(local_supported_codecs, mapped_codec.codec)) {
RTC_LOG(LS_ERROR)

View File

@ -106,8 +106,14 @@ class WebRtcVideoEngine : public VideoEngineInterface {
webrtc::VideoBitrateAllocatorFactory* video_bitrate_allocator_factory)
override;
std::vector<VideoCodec> send_codecs() const override;
std::vector<VideoCodec> recv_codecs() const override;
std::vector<VideoCodec> send_codecs() const override {
return send_codecs(true);
}
std::vector<VideoCodec> recv_codecs() const override {
return recv_codecs(true);
}
std::vector<VideoCodec> send_codecs(bool include_rtx) const override;
std::vector<VideoCodec> recv_codecs(bool include_rtx) const override;
std::vector<webrtc::RtpHeaderExtensionCapability> GetRtpHeaderExtensions()
const override;

View File

@ -144,6 +144,17 @@ bool HasRtxCodec(const std::vector<cricket::VideoCodec>& codecs,
return false;
}
// Return true if any codec in `codecs` is an RTX codec, independent of
// payload type.
bool HasAnyRtxCodec(const std::vector<cricket::VideoCodec>& codecs) {
for (const cricket::VideoCodec& codec : codecs) {
if (absl::EqualsIgnoreCase(codec.name.c_str(), "rtx")) {
return true;
}
}
return false;
}
// TODO(nisse): Duplicated in call.cc.
const int* FindKeyByValue(const std::map<int, int>& m, int v) {
for (const auto& kv : m) {
@ -1373,6 +1384,24 @@ TEST_F(WebRtcVideoEngineTest, DISABLED_RecreatesEncoderOnContentTypeChange) {
EXPECT_EQ(0u, encoder_factory_->encoders().size());
}
TEST_F(WebRtcVideoEngineTest, SetVideoRtxEnabled) {
AddSupportedVideoCodecType("VP8");
std::vector<VideoCodec> send_codecs;
std::vector<VideoCodec> recv_codecs;
// Don't want RTX
send_codecs = engine_.send_codecs(false);
EXPECT_FALSE(HasAnyRtxCodec(send_codecs));
recv_codecs = engine_.recv_codecs(false);
EXPECT_FALSE(HasAnyRtxCodec(recv_codecs));
// Want RTX
send_codecs = engine_.send_codecs(true);
EXPECT_TRUE(HasAnyRtxCodec(send_codecs));
recv_codecs = engine_.recv_codecs(true);
EXPECT_TRUE(HasAnyRtxCodec(recv_codecs));
}
class WebRtcVideoChannelEncodedFrameCallbackTest : public ::testing::Test {
protected:
webrtc::Call::Config GetCallConfig(

View File

@ -1598,6 +1598,7 @@ rtc_library("rtp_transceiver") {
":channel",
":channel_interface",
":channel_manager",
":connection_context",
":peer_connection_sdp_methods",
":proxy",
":rtp_media_utils",

View File

@ -48,8 +48,7 @@ ChannelManager::ChannelManager(MediaEngineInterface* media_engine,
ssrc_generator_(ssrc_generator),
signaling_thread_(rtc::Thread::Current()),
worker_thread_(worker_thread),
network_thread_(network_thread),
enable_rtx_(enable_rtx) {
network_thread_(network_thread) {
RTC_DCHECK_RUN_ON(signaling_thread_);
RTC_DCHECK(worker_thread_);
RTC_DCHECK(network_thread_);
@ -65,56 +64,6 @@ ChannelManager::~ChannelManager() {
RTC_DCHECK_RUN_ON(signaling_thread_);
}
void ChannelManager::GetSupportedAudioSendCodecs(
std::vector<AudioCodec>* codecs) const {
if (!media_engine_) {
return;
}
*codecs = media_engine_->voice().send_codecs();
}
void ChannelManager::GetSupportedAudioReceiveCodecs(
std::vector<AudioCodec>* codecs) const {
if (!media_engine_) {
return;
}
*codecs = media_engine_->voice().recv_codecs();
}
void ChannelManager::GetSupportedVideoSendCodecs(
std::vector<VideoCodec>* codecs) const {
if (!media_engine_) {
return;
}
codecs->clear();
std::vector<VideoCodec> video_codecs = media_engine_->video().send_codecs();
for (const auto& video_codec : video_codecs) {
if (!enable_rtx_ &&
absl::EqualsIgnoreCase(kRtxCodecName, video_codec.name)) {
continue;
}
codecs->push_back(video_codec);
}
}
void ChannelManager::GetSupportedVideoReceiveCodecs(
std::vector<VideoCodec>* codecs) const {
if (!media_engine_) {
return;
}
codecs->clear();
std::vector<VideoCodec> video_codecs = media_engine_->video().recv_codecs();
for (const auto& video_codec : video_codecs) {
if (!enable_rtx_ &&
absl::EqualsIgnoreCase(kRtxCodecName, video_codec.name)) {
continue;
}
codecs->push_back(video_codec);
}
}
std::unique_ptr<VoiceChannel> ChannelManager::CreateVoiceChannel(
webrtc::Call* call,
const MediaConfig& media_config,

View File

@ -59,18 +59,6 @@ class ChannelManager : public ChannelFactoryInterface {
ChannelManager() = delete;
~ChannelManager() override;
rtc::Thread* worker_thread() const { return worker_thread_; }
rtc::Thread* network_thread() const { return network_thread_; }
MediaEngineInterface* media_engine() { return media_engine_; }
rtc::UniqueRandomIdGenerator& ssrc_generator() { return *ssrc_generator_; }
// Retrieves the list of supported audio & video codec types.
// Can be called before starting the media engine.
void GetSupportedAudioSendCodecs(std::vector<AudioCodec>* codecs) const;
void GetSupportedAudioReceiveCodecs(std::vector<AudioCodec>* codecs) const;
void GetSupportedVideoSendCodecs(std::vector<VideoCodec>* codecs) const;
void GetSupportedVideoReceiveCodecs(std::vector<VideoCodec>* codecs) const;
// The operations below all occur on the worker thread.
// The caller is responsible for ensuring that destruction happens
// on the worker thread.
@ -110,8 +98,6 @@ class ChannelManager : public ChannelFactoryInterface {
rtc::Thread* const signaling_thread_;
rtc::Thread* const worker_thread_;
rtc::Thread* const network_thread_;
const bool enable_rtx_;
};
} // namespace cricket

View File

@ -76,7 +76,6 @@ class ChannelManagerTest : public ::testing::Test {
cricket::CN_AUDIO, kDefaultSrtpRequired,
webrtc::CryptoOptions(), AudioOptions());
ASSERT_TRUE(voice_channel != nullptr);
std::unique_ptr<cricket::VideoChannel> video_channel =
cm_->CreateVideoChannel(&fake_call_, cricket::MediaConfig(),
cricket::CN_VIDEO, kDefaultSrtpRequired,
@ -99,34 +98,6 @@ class ChannelManagerTest : public ::testing::Test {
webrtc::test::ScopedKeyValueConfig field_trials_;
};
TEST_F(ChannelManagerTest, SetVideoRtxEnabled) {
std::vector<VideoCodec> send_codecs;
std::vector<VideoCodec> recv_codecs;
const VideoCodec rtx_codec(96, "rtx");
// By default RTX is disabled.
cm_->GetSupportedVideoSendCodecs(&send_codecs);
EXPECT_FALSE(ContainsMatchingCodec(send_codecs, rtx_codec, &field_trials_));
cm_->GetSupportedVideoSendCodecs(&recv_codecs);
EXPECT_FALSE(ContainsMatchingCodec(recv_codecs, rtx_codec, &field_trials_));
// Enable and check.
cm_ = cricket::ChannelManager::Create(media_engine_.get(), &ssrc_generator_,
true, worker_, network_.get());
cm_->GetSupportedVideoSendCodecs(&send_codecs);
EXPECT_TRUE(ContainsMatchingCodec(send_codecs, rtx_codec, &field_trials_));
cm_->GetSupportedVideoSendCodecs(&recv_codecs);
EXPECT_TRUE(ContainsMatchingCodec(recv_codecs, rtx_codec, &field_trials_));
// Disable and check.
cm_ = cricket::ChannelManager::Create(media_engine_.get(), &ssrc_generator_,
false, worker_, network_.get());
cm_->GetSupportedVideoSendCodecs(&send_codecs);
EXPECT_FALSE(ContainsMatchingCodec(send_codecs, rtx_codec, &field_trials_));
cm_->GetSupportedVideoSendCodecs(&recv_codecs);
EXPECT_FALSE(ContainsMatchingCodec(recv_codecs, rtx_codec, &field_trials_));
}
TEST_F(ChannelManagerTest, CreateDestroyChannels) {
auto rtp_dtls_transport = std::make_unique<FakeDtlsTransport>(
"fake_dtls_transport", cricket::ICE_CANDIDATE_COMPONENT_RTP,

View File

@ -39,6 +39,7 @@ class ChannelManager;
namespace rtc {
class BasicNetworkManager;
class BasicPacketSocketFactory;
class UniqueRandomIdGenerator;
} // namespace rtc
namespace webrtc {
@ -70,7 +71,9 @@ class ConnectionContext final
}
cricket::ChannelManager* channel_manager() const;
cricket::MediaEngineInterface* media_engine() const;
cricket::MediaEngineInterface* media_engine() const {
return media_engine_.get();
}
rtc::Thread* signaling_thread() { return signaling_thread_; }
const rtc::Thread* signaling_thread() const { return signaling_thread_; }
@ -98,6 +101,12 @@ class ConnectionContext final
RTC_DCHECK_RUN_ON(worker_thread());
return call_factory_.get();
}
rtc::UniqueRandomIdGenerator* ssrc_generator() { return &ssrc_generator_; }
// Note: There is lots of code that wants to know whether or not we
// use RTX, but so far, no code has been found that sets it to false.
// Kept in the API in order to ease introduction if we want to resurrect
// the functionality.
bool use_rtx() { return true; }
protected:
explicit ConnectionContext(PeerConnectionFactoryDependencies* dependencies);

View File

@ -25,6 +25,7 @@
#include "api/crypto_params.h"
#include "media/base/codec.h"
#include "media/base/media_constants.h"
#include "media/base/media_engine.h"
#include "media/base/sdp_video_format_utils.h"
#include "media/sctp/sctp_transport_internal.h"
#include "p2p/base/p2p_constants.h"
@ -1571,14 +1572,17 @@ MediaSessionDescriptionFactory::MediaSessionDescriptionFactory(
}
MediaSessionDescriptionFactory::MediaSessionDescriptionFactory(
ChannelManager* channel_manager,
cricket::MediaEngineInterface* media_engine,
bool rtx_enabled,
rtc::UniqueRandomIdGenerator* ssrc_generator,
const TransportDescriptionFactory* transport_desc_factory)
: MediaSessionDescriptionFactory(transport_desc_factory,
&channel_manager->ssrc_generator()) {
channel_manager->GetSupportedAudioSendCodecs(&audio_send_codecs_);
channel_manager->GetSupportedAudioReceiveCodecs(&audio_recv_codecs_);
channel_manager->GetSupportedVideoSendCodecs(&video_send_codecs_);
channel_manager->GetSupportedVideoReceiveCodecs(&video_recv_codecs_);
: MediaSessionDescriptionFactory(transport_desc_factory, ssrc_generator) {
if (media_engine) {
audio_send_codecs_ = media_engine->voice().send_codecs();
audio_recv_codecs_ = media_engine->voice().recv_codecs();
video_send_codecs_ = media_engine->video().send_codecs(rtx_enabled);
video_recv_codecs_ = media_engine->video().recv_codecs(rtx_enabled);
}
ComputeAudioCodecsIntersectionAndUnion();
ComputeVideoCodecsIntersectionAndUnion();
}

View File

@ -46,6 +46,7 @@ class ConnectionContext;
namespace cricket {
class ChannelManager;
class MediaEngineInterface;
// Default RTCP CNAME for unit tests.
const char kDefaultRtcpCname[] = "DefaultRtcpCname";
@ -147,8 +148,10 @@ class MediaSessionDescriptionFactory {
MediaSessionDescriptionFactory(const TransportDescriptionFactory* factory,
rtc::UniqueRandomIdGenerator* ssrc_generator);
// This helper automatically sets up the factory to get its configuration
// from the specified ChannelManager.
MediaSessionDescriptionFactory(ChannelManager* cmanager,
// from the specified MediaEngine
MediaSessionDescriptionFactory(cricket::MediaEngineInterface* media_engine,
bool rtx_enabled,
rtc::UniqueRandomIdGenerator* ssrc_generator,
const TransportDescriptionFactory* factory);
const AudioCodecs& audio_sendrecv_codecs() const;

View File

@ -644,8 +644,8 @@ RTCError PeerConnection::Initialize(
dependencies, context_.get());
rtp_manager_ = std::make_unique<RtpTransmissionManager>(
IsUnifiedPlan(), signaling_thread(), worker_thread(), channel_manager(),
&usage_pattern_, observer_, stats_.get(), [this]() {
IsUnifiedPlan(), context_.get(), &usage_pattern_, observer_, stats_.get(),
[this]() {
RTC_DCHECK_RUN_ON(signaling_thread());
sdp_handler_->UpdateNegotiationNeeded();
});
@ -654,14 +654,12 @@ RTCError PeerConnection::Initialize(
if (!IsUnifiedPlan()) {
rtp_manager()->transceivers()->Add(
RtpTransceiverProxyWithInternal<RtpTransceiver>::Create(
signaling_thread(),
rtc::make_ref_counted<RtpTransceiver>(cricket::MEDIA_TYPE_AUDIO,
channel_manager())));
signaling_thread(), rtc::make_ref_counted<RtpTransceiver>(
cricket::MEDIA_TYPE_AUDIO, context())));
rtp_manager()->transceivers()->Add(
RtpTransceiverProxyWithInternal<RtpTransceiver>::Create(
signaling_thread(),
rtc::make_ref_counted<RtpTransceiver>(cricket::MEDIA_TYPE_VIDEO,
channel_manager())));
signaling_thread(), rtc::make_ref_counted<RtpTransceiver>(
cricket::MEDIA_TYPE_VIDEO, context())));
}
int delay_ms = configuration.report_usage_pattern_delay_ms
@ -1677,8 +1675,7 @@ void PeerConnection::SetAudioPlayout(bool playout) {
RTC_FROM_HERE, [this, playout] { SetAudioPlayout(playout); });
return;
}
auto audio_state =
context_->channel_manager()->media_engine()->voice().GetAudioState();
auto audio_state = context_->media_engine()->voice().GetAudioState();
audio_state->SetPlayout(playout);
}
@ -1688,8 +1685,7 @@ void PeerConnection::SetAudioRecording(bool recording) {
RTC_FROM_HERE, [this, recording] { SetAudioRecording(recording); });
return;
}
auto audio_state =
context_->channel_manager()->media_engine()->voice().GetAudioState();
auto audio_state = context_->media_engine()->voice().GetAudioState();
audio_state->SetRecording(recording);
}
@ -1709,7 +1705,7 @@ void PeerConnection::AddAdaptationResource(
}
bool PeerConnection::ConfiguredForMedia() const {
return context_->channel_manager()->media_engine();
return context_->media_engine();
}
bool PeerConnection::StartRtcEventLog(std::unique_ptr<RtcEventLogOutput> output,

View File

@ -162,8 +162,8 @@ RtpCapabilities PeerConnectionFactory::GetRtpReceiverCapabilities(
return ToRtpCapabilities(cricket_codecs, extensions);
}
case cricket::MEDIA_TYPE_VIDEO: {
cricket::VideoCodecs cricket_codecs;
channel_manager()->GetSupportedVideoReceiveCodecs(&cricket_codecs);
cricket::VideoCodecs cricket_codecs =
media_engine()->video().recv_codecs(context_->use_rtx());
auto extensions =
GetDefaultEnabledRtpHeaderExtensions(media_engine()->video());
return ToRtpCapabilities(cricket_codecs, extensions);
@ -199,7 +199,7 @@ void PeerConnectionFactory::StopAecDump() {
cricket::MediaEngineInterface* PeerConnectionFactory::media_engine() const {
RTC_DCHECK(context_);
RTC_DCHECK(context_->channel_manager());
return context_->channel_manager()->media_engine();
return context_->media_engine();
}
RTCErrorOr<rtc::scoped_refptr<PeerConnectionInterface>>
@ -319,11 +319,10 @@ std::unique_ptr<Call> PeerConnectionFactory::CreateCall_w(
RTC_DCHECK_RUN_ON(worker_thread());
webrtc::Call::Config call_config(event_log, network_thread());
if (!channel_manager()->media_engine() || !context_->call_factory()) {
if (!media_engine() || !context_->call_factory()) {
return nullptr;
}
call_config.audio_state =
channel_manager()->media_engine()->voice().GetAudioState();
call_config.audio_state = media_engine()->voice().GetAudioState();
FieldTrialParameter<DataRate> min_bandwidth("min",
DataRate::KilobitsPerSec(30));

View File

@ -117,35 +117,34 @@ TaskQueueBase* GetCurrentTaskQueueOrThread() {
} // namespace
RtpTransceiver::RtpTransceiver(
cricket::MediaType media_type,
cricket::ChannelManager* channel_manager /* = nullptr*/)
RtpTransceiver::RtpTransceiver(cricket::MediaType media_type,
ConnectionContext* context)
: thread_(GetCurrentTaskQueueOrThread()),
unified_plan_(false),
media_type_(media_type),
channel_manager_(channel_manager) {
context_(context) {
RTC_DCHECK(media_type == cricket::MEDIA_TYPE_AUDIO ||
media_type == cricket::MEDIA_TYPE_VIDEO);
RTC_DCHECK(channel_manager_);
RTC_DCHECK(context_->channel_manager());
}
RtpTransceiver::RtpTransceiver(
rtc::scoped_refptr<RtpSenderProxyWithInternal<RtpSenderInternal>> sender,
rtc::scoped_refptr<RtpReceiverProxyWithInternal<RtpReceiverInternal>>
receiver,
cricket::ChannelManager* channel_manager,
ConnectionContext* context,
std::vector<RtpHeaderExtensionCapability> header_extensions_offered,
std::function<void()> on_negotiation_needed)
: thread_(GetCurrentTaskQueueOrThread()),
unified_plan_(true),
media_type_(sender->media_type()),
channel_manager_(channel_manager),
context_(context),
header_extensions_to_offer_(std::move(header_extensions_offered)),
on_negotiation_needed_(std::move(on_negotiation_needed)) {
RTC_DCHECK(media_type_ == cricket::MEDIA_TYPE_AUDIO ||
media_type_ == cricket::MEDIA_TYPE_VIDEO);
RTC_DCHECK_EQ(sender->media_type(), receiver->media_type());
RTC_DCHECK(channel_manager_);
RTC_DCHECK(context_->channel_manager());
senders_.push_back(sender);
receivers_.push_back(receiver);
}
@ -173,7 +172,7 @@ RTCError RtpTransceiver::CreateChannel(
VideoBitrateAllocatorFactory* video_bitrate_allocator_factory,
std::function<RtpTransportInternal*(absl::string_view)> transport_lookup) {
RTC_DCHECK_RUN_ON(thread_);
if (!channel_manager_->media_engine()) {
if (!media_engine()) {
// TODO(hta): Must be a better way
return RTCError(RTCErrorType::INTERNAL_ERROR,
"No media engine for mid=" + std::string(mid));
@ -183,7 +182,7 @@ RTCError RtpTransceiver::CreateChannel(
// TODO(bugs.webrtc.org/11992): CreateVideoChannel internally switches to
// the worker thread. We shouldn't be using the `call_ptr_` hack here but
// simply be on the worker thread and use `call_` (update upstream code).
new_channel = channel_manager_->CreateVoiceChannel(
new_channel = channel_manager()->CreateVoiceChannel(
call_ptr, media_config, mid, srtp_required, crypto_options,
audio_options);
@ -193,7 +192,7 @@ RTCError RtpTransceiver::CreateChannel(
// TODO(bugs.webrtc.org/11992): CreateVideoChannel internally switches to
// the worker thread. We shouldn't be using the `call_ptr_` hack here but
// simply be on the worker thread and use `call_` (update upstream code).
new_channel = channel_manager_->CreateVideoChannel(
new_channel = channel_manager()->CreateVideoChannel(
call_ptr, media_config, mid, srtp_required, crypto_options,
video_options, video_bitrate_allocator_factory);
}
@ -234,7 +233,7 @@ void RtpTransceiver::SetChannel(
// Similarly, if the channel() accessor is limited to the network thread, that
// helps with keeping the channel implementation requirements being met and
// avoids synchronization for accessing the pointer or network related state.
channel_manager_->network_thread()->Invoke<void>(RTC_FROM_HERE, [&]() {
context()->network_thread()->Invoke<void>(RTC_FROM_HERE, [&]() {
if (channel_) {
channel_->SetFirstPacketReceivedCallback(nullptr);
channel_->SetRtpTransport(nullptr);
@ -270,7 +269,7 @@ void RtpTransceiver::ClearChannel() {
}
std::unique_ptr<cricket::ChannelInterface> channel_to_delete;
channel_manager_->network_thread()->Invoke<void>(RTC_FROM_HERE, [&]() {
context()->network_thread()->Invoke<void>(RTC_FROM_HERE, [&]() {
if (channel_) {
channel_->SetFirstPacketReceivedCallback(nullptr);
channel_->SetRtpTransport(nullptr);
@ -291,7 +290,7 @@ void RtpTransceiver::PushNewMediaChannelAndDeleteChannel(
if (!channel_to_delete && senders_.empty() && receivers_.empty()) {
return;
}
channel_manager_->worker_thread()->Invoke<void>(RTC_FROM_HERE, [&]() {
context()->worker_thread()->Invoke<void>(RTC_FROM_HERE, [&]() {
// Push down the new media_channel, if any, otherwise clear it.
auto* media_channel = channel_ ? channel_->media_channel() : nullptr;
for (const auto& sender : senders_) {
@ -359,7 +358,7 @@ bool RtpTransceiver::RemoveReceiver(RtpReceiverInterface* receiver) {
}
(*it)->internal()->Stop();
channel_manager_->worker_thread()->Invoke<void>(RTC_FROM_HERE, [&]() {
context()->worker_thread()->Invoke<void>(RTC_FROM_HERE, [&]() {
// `Stop()` will clear the receiver's pointer to the media channel.
(*it)->internal()->SetMediaChannel(nullptr);
});
@ -493,7 +492,7 @@ void RtpTransceiver::StopSendingAndReceiving() {
for (const auto& receiver : receivers_)
receiver->internal()->Stop();
channel_manager_->worker_thread()->Invoke<void>(RTC_FROM_HERE, [&]() {
context()->worker_thread()->Invoke<void>(RTC_FROM_HERE, [&]() {
// 5 Stop receiving media with receiver.
for (const auto& receiver : receivers_)
receiver->internal()->SetMediaChannel(nullptr);
@ -581,15 +580,13 @@ RTCError RtpTransceiver::SetCodecPreferences(
RTCError result;
if (media_type_ == cricket::MEDIA_TYPE_AUDIO) {
std::vector<cricket::AudioCodec> recv_codecs, send_codecs;
channel_manager_->GetSupportedAudioReceiveCodecs(&recv_codecs);
channel_manager_->GetSupportedAudioSendCodecs(&send_codecs);
send_codecs = media_engine()->voice().send_codecs();
recv_codecs = media_engine()->voice().recv_codecs();
result = VerifyCodecPreferences(codecs, send_codecs, recv_codecs);
} else if (media_type_ == cricket::MEDIA_TYPE_VIDEO) {
std::vector<cricket::VideoCodec> recv_codecs, send_codecs;
channel_manager_->GetSupportedVideoReceiveCodecs(&recv_codecs);
channel_manager_->GetSupportedVideoSendCodecs(&send_codecs);
send_codecs = media_engine()->video().send_codecs(context()->use_rtx());
recv_codecs = media_engine()->video().recv_codecs(context()->use_rtx());
result = VerifyCodecPreferences(codecs, send_codecs, recv_codecs);
}

View File

@ -34,6 +34,7 @@
#include "api/video/video_bitrate_allocator_factory.h"
#include "media/base/media_channel.h"
#include "pc/channel_interface.h"
#include "pc/connection_context.h"
#include "pc/proxy.h"
#include "pc/rtp_receiver.h"
#include "pc/rtp_receiver_proxy.h"
@ -47,6 +48,7 @@
namespace cricket {
class ChannelManager;
class MediaEngineInterface;
}
namespace webrtc {
@ -88,8 +90,7 @@ class RtpTransceiver : public RtpTransceiverInterface,
// channel set.
// `media_type` specifies the type of RtpTransceiver (and, by transitivity,
// the type of senders, receivers, and channel). Can either by audio or video.
RtpTransceiver(cricket::MediaType media_type,
cricket::ChannelManager* channel_manager);
RtpTransceiver(cricket::MediaType media_type, ConnectionContext* context);
// Construct a Unified Plan-style RtpTransceiver with the given sender and
// receiver. The media type will be derived from the media types of the sender
// and receiver. The sender and receiver should have the same media type.
@ -99,11 +100,17 @@ class RtpTransceiver : public RtpTransceiverInterface,
rtc::scoped_refptr<RtpSenderProxyWithInternal<RtpSenderInternal>> sender,
rtc::scoped_refptr<RtpReceiverProxyWithInternal<RtpReceiverInternal>>
receiver,
cricket::ChannelManager* channel_manager,
ConnectionContext* context,
std::vector<RtpHeaderExtensionCapability> HeaderExtensionsToOffer,
std::function<void()> on_negotiation_needed);
~RtpTransceiver() override;
// Not copyable or movable.
RtpTransceiver(const RtpTransceiver&) = delete;
RtpTransceiver& operator=(const RtpTransceiver&) = delete;
// RtpTransceiver(RtpTransceiver&&) = delete;
RtpTransceiver& operator=(RtpTransceiver&&) = delete;
// Returns the Voice/VideoChannel set for this transceiver. May be null if
// the transceiver is not in the currently set local/remote description.
cricket::ChannelInterface* channel() const { return channel_.get(); }
@ -293,6 +300,13 @@ class RtpTransceiver : public RtpTransceiverInterface,
const cricket::MediaContentDescription* content);
private:
cricket::MediaEngineInterface* media_engine() const {
return context_->media_engine();
}
cricket::ChannelManager* channel_manager() const {
return context_->channel_manager();
}
ConnectionContext* context() const { return context_; }
void OnFirstPacketReceived();
void StopSendingAndReceiving();
// Delete a channel, and ensure that references to its media channel
@ -327,7 +341,7 @@ class RtpTransceiver : public RtpTransceiverInterface,
// because all access on the network thread is within an invoke()
// from thread_.
std::unique_ptr<cricket::ChannelInterface> channel_ = nullptr;
cricket::ChannelManager* channel_manager_ = nullptr;
ConnectionContext* const context_;
std::vector<RtpCodecCapability> codec_preferences_;
std::vector<RtpHeaderExtensionCapability> header_extensions_to_offer_;

View File

@ -17,10 +17,10 @@
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
#include "api/peer_connection_interface.h"
#include "api/rtp_parameters.h"
#include "media/base/fake_media_engine.h"
#include "media/base/media_engine.h"
#include "pc/channel_manager.h"
#include "pc/test/mock_channel_interface.h"
#include "pc/test/mock_rtp_receiver_internal.h"
#include "pc/test/mock_rtp_sender_internal.h"
@ -42,28 +42,36 @@ namespace {
class RtpTransceiverTest : public testing::Test {
public:
RtpTransceiverTest()
: channel_manager_(
cricket::ChannelManager::Create(&fake_media_engine_,
&ssrc_generator_,
true,
rtc::Thread::Current(),
rtc::Thread::Current())) {}
: dependencies_(MakeDependencies()),
context_(ConnectionContext::Create(&dependencies_)) {}
protected:
cricket::ChannelManager* channel_manager() { return channel_manager_.get(); }
cricket::MediaEngineInterface* media_engine() {
return context_->media_engine();
}
ConnectionContext* context() { return context_.get(); }
private:
rtc::AutoThread main_thread_;
cricket::FakeMediaEngine fake_media_engine_;
rtc::UniqueRandomIdGenerator ssrc_generator_;
std::unique_ptr<cricket::ChannelManager> channel_manager_;
static PeerConnectionFactoryDependencies MakeDependencies() {
PeerConnectionFactoryDependencies d;
d.network_thread = rtc::Thread::Current();
d.worker_thread = rtc::Thread::Current();
d.signaling_thread = rtc::Thread::Current();
d.media_engine = std::make_unique<cricket::FakeMediaEngine>();
return d;
}
PeerConnectionFactoryDependencies dependencies_;
rtc::scoped_refptr<ConnectionContext> context_;
};
// Checks that a channel cannot be set on a stopped `RtpTransceiver`.
TEST_F(RtpTransceiverTest, CannotSetChannelOnStoppedTransceiver) {
const std::string content_name("my_mid");
auto transceiver = rtc::make_ref_counted<RtpTransceiver>(
cricket::MediaType::MEDIA_TYPE_AUDIO, channel_manager());
cricket::MediaType::MEDIA_TYPE_AUDIO, context());
auto channel1 = std::make_unique<cricket::MockChannelInterface>();
EXPECT_CALL(*channel1, media_type())
.WillRepeatedly(Return(cricket::MediaType::MEDIA_TYPE_AUDIO));
@ -98,7 +106,7 @@ TEST_F(RtpTransceiverTest, CannotSetChannelOnStoppedTransceiver) {
TEST_F(RtpTransceiverTest, CanUnsetChannelOnStoppedTransceiver) {
const std::string content_name("my_mid");
auto transceiver = rtc::make_ref_counted<RtpTransceiver>(
cricket::MediaType::MEDIA_TYPE_VIDEO, channel_manager());
cricket::MediaType::MEDIA_TYPE_VIDEO, context());
auto channel = std::make_unique<cricket::MockChannelInterface>();
EXPECT_CALL(*channel, media_type())
.WillRepeatedly(Return(cricket::MediaType::MEDIA_TYPE_VIDEO));
@ -134,8 +142,8 @@ class RtpTransceiverUnifiedPlanTest : public RtpTransceiverTest {
rtc::Thread::Current(),
rtc::Thread::Current(),
receiver_),
channel_manager(),
channel_manager()->media_engine()->voice().GetRtpHeaderExtensions(),
context(),
media_engine()->voice().GetRtpHeaderExtensions(),
/* on_negotiation_needed= */ [] {})) {}
static rtc::scoped_refptr<MockRtpReceiverInternal> MockReceiver() {
@ -201,7 +209,7 @@ class RtpTransceiverTestForHeaderExtensions : public RtpTransceiverTest {
rtc::Thread::Current(),
rtc::Thread::Current(),
receiver_),
channel_manager(),
context(),
extensions_,
/* on_negotiation_needed= */ [] {})) {}

View File

@ -37,17 +37,13 @@ static const char kDefaultVideoSenderId[] = "defaultv0";
RtpTransmissionManager::RtpTransmissionManager(
bool is_unified_plan,
rtc::Thread* signaling_thread,
rtc::Thread* worker_thread,
cricket::ChannelManager* channel_manager,
ConnectionContext* context,
UsagePattern* usage_pattern,
PeerConnectionObserver* observer,
StatsCollectorInterface* stats,
std::function<void()> on_negotiation_needed)
: is_unified_plan_(is_unified_plan),
signaling_thread_(signaling_thread),
worker_thread_(worker_thread),
channel_manager_(channel_manager),
context_(context),
usage_pattern_(usage_pattern),
observer_(observer),
stats_(stats),
@ -271,7 +267,7 @@ RtpTransmissionManager::CreateAndAddTransceiver(
auto transceiver = RtpTransceiverProxyWithInternal<RtpTransceiver>::Create(
signaling_thread(),
rtc::make_ref_counted<RtpTransceiver>(
sender, receiver, channel_manager(),
sender, receiver, context_,
sender->media_type() == cricket::MEDIA_TYPE_AUDIO
? media_engine()->voice().GetRtpHeaderExtensions()
: media_engine()->video().GetRtpHeaderExtensions(),
@ -691,7 +687,7 @@ RtpTransmissionManager::FindReceiverById(const std::string& receiver_id) const {
}
cricket::MediaEngineInterface* RtpTransmissionManager::media_engine() const {
return channel_manager()->media_engine();
return context_->media_engine();
}
} // namespace webrtc

View File

@ -76,9 +76,7 @@ struct RtpSenderInfo {
class RtpTransmissionManager : public RtpSenderBase::SetStreamsObserver {
public:
RtpTransmissionManager(bool is_unified_plan,
rtc::Thread* signaling_thread,
rtc::Thread* worker_thread,
cricket::ChannelManager* channel_manager,
ConnectionContext* context,
UsagePattern* usage_pattern,
PeerConnectionObserver* observer,
StatsCollectorInterface* stats_,
@ -212,9 +210,8 @@ class RtpTransmissionManager : public RtpSenderBase::SetStreamsObserver {
cricket::VideoMediaChannel* video_media_channel() const;
private:
rtc::Thread* signaling_thread() const { return signaling_thread_; }
rtc::Thread* worker_thread() const { return worker_thread_; }
cricket::ChannelManager* channel_manager() const { return channel_manager_; }
rtc::Thread* signaling_thread() const { return context_->signaling_thread(); }
rtc::Thread* worker_thread() const { return context_->worker_thread(); }
bool IsUnifiedPlan() const { return is_unified_plan_; }
void NoteUsageEvent(UsageEvent event) {
usage_pattern_->NoteUsageEvent(event);
@ -246,6 +243,10 @@ class RtpTransmissionManager : public RtpSenderBase::SetStreamsObserver {
cricket::MediaEngineInterface* media_engine() const;
rtc::UniqueRandomIdGenerator* ssrc_generator() const {
return context_->ssrc_generator();
}
TransceiverList transceivers_;
// These lists store sender info seen in local/remote descriptions.
@ -260,9 +261,7 @@ class RtpTransmissionManager : public RtpSenderBase::SetStreamsObserver {
bool closed_ = false;
bool const is_unified_plan_;
rtc::Thread* const signaling_thread_;
rtc::Thread* const worker_thread_;
cricket::ChannelManager* const channel_manager_;
ConnectionContext* context_;
UsagePattern* usage_pattern_;
PeerConnectionObserver* observer_;
StatsCollectorInterface* const stats_;

View File

@ -1255,8 +1255,7 @@ cricket::ChannelManager* SdpOfferAnswerHandler::channel_manager() const {
cricket::MediaEngineInterface* SdpOfferAnswerHandler::media_engine() const {
RTC_DCHECK(context_);
RTC_DCHECK(context_->channel_manager());
return context_->channel_manager()->media_engine();
return context_->media_engine();
}
TransceiverList* SdpOfferAnswerHandler::transceivers() {

View File

@ -151,6 +151,9 @@ class FakePeerConnectionForStats : public FakePeerConnectionBase {
: network_thread_(rtc::Thread::Current()),
worker_thread_(rtc::Thread::Current()),
signaling_thread_(rtc::Thread::Current()),
// TODO(hta): remove separate thread variables and use context.
dependencies_(MakeDependencies()),
context_(ConnectionContext::Create(&dependencies_)),
local_streams_(StreamCollection::Create()),
remote_streams_(StreamCollection::Create()) {}
@ -160,6 +163,14 @@ class FakePeerConnectionForStats : public FakePeerConnectionBase {
}
}
static PeerConnectionFactoryDependencies MakeDependencies() {
PeerConnectionFactoryDependencies dependencies;
dependencies.network_thread = rtc::Thread::Current();
dependencies.worker_thread = rtc::Thread::Current();
dependencies.signaling_thread = rtc::Thread::Current();
return dependencies;
}
rtc::scoped_refptr<StreamCollection> mutable_local_streams() {
return local_streams_;
}
@ -213,8 +224,7 @@ class FakePeerConnectionForStats : public FakePeerConnectionBase {
auto voice_channel = std::make_unique<VoiceChannelForTesting>(
worker_thread_, network_thread_, signaling_thread_,
std::move(voice_media_channel), mid, kDefaultSrtpRequired,
webrtc::CryptoOptions(), &channel_manager_.ssrc_generator(),
transport_name);
webrtc::CryptoOptions(), context_->ssrc_generator(), transport_name);
GetOrCreateFirstTransceiverOfType(cricket::MEDIA_TYPE_AUDIO)
->internal()
->SetChannel(std::move(voice_channel),
@ -233,8 +243,7 @@ class FakePeerConnectionForStats : public FakePeerConnectionBase {
auto video_channel = std::make_unique<VideoChannelForTesting>(
worker_thread_, network_thread_, signaling_thread_,
std::move(video_media_channel), mid, kDefaultSrtpRequired,
webrtc::CryptoOptions(), &channel_manager_.ssrc_generator(),
transport_name);
webrtc::CryptoOptions(), context_->ssrc_generator(), transport_name);
GetOrCreateFirstTransceiverOfType(cricket::MEDIA_TYPE_VIDEO)
->internal()
->SetChannel(std::move(video_channel),
@ -407,7 +416,7 @@ class FakePeerConnectionForStats : public FakePeerConnectionBase {
}
auto transceiver = RtpTransceiverProxyWithInternal<RtpTransceiver>::Create(
signaling_thread_,
rtc::make_ref_counted<RtpTransceiver>(media_type, &channel_manager_));
rtc::make_ref_counted<RtpTransceiver>(media_type, context_.get()));
transceivers_.push_back(transceiver);
return transceiver;
}
@ -420,6 +429,7 @@ class FakePeerConnectionForStats : public FakePeerConnectionBase {
true,
worker,
network) {}
rtc::UniqueRandomIdGenerator* ssrc_generator() { return &ssrc_generator_; }
private:
rtc::UniqueRandomIdGenerator ssrc_generator_;
@ -429,7 +439,8 @@ class FakePeerConnectionForStats : public FakePeerConnectionBase {
rtc::Thread* const worker_thread_;
rtc::Thread* const signaling_thread_;
TestChannelManager channel_manager_{worker_thread_, network_thread_};
PeerConnectionFactoryDependencies dependencies_;
rtc::scoped_refptr<ConnectionContext> context_;
rtc::scoped_refptr<StreamCollection> local_streams_;
rtc::scoped_refptr<StreamCollection> remote_streams_;

View File

@ -139,7 +139,9 @@ WebRtcSessionDescriptionFactory::WebRtcSessionDescriptionFactory(
const FieldTrialsView& field_trials)
: signaling_thread_(context->signaling_thread()),
transport_desc_factory_(field_trials),
session_desc_factory_(context->channel_manager(),
session_desc_factory_(context->media_engine(),
context->use_rtx(),
context->ssrc_generator(),
&transport_desc_factory_),
// RFC 4566 suggested a Network Time Protocol (NTP) format timestamp
// as the session id and session version. To simplify, it should be fine