diff options
Diffstat (limited to 'media/base/media_channel.cc')
-rw-r--r-- | media/base/media_channel.cc | 130 |
1 files changed, 103 insertions, 27 deletions
diff --git a/media/base/media_channel.cc b/media/base/media_channel.cc index d2370d2ccf..01b043b828 100644 --- a/media/base/media_channel.cc +++ b/media/base/media_channel.cc @@ -10,21 +10,40 @@ #include "media/base/media_channel.h" +#include "media/base/rtp_utils.h" +#include "rtc_base/task_utils/to_queued_task.h" + namespace cricket { +using webrtc::FrameDecryptorInterface; +using webrtc::FrameEncryptorInterface; +using webrtc::FrameTransformerInterface; +using webrtc::PendingTaskSafetyFlag; +using webrtc::TaskQueueBase; +using webrtc::ToQueuedTask; +using webrtc::VideoTrackInterface; VideoOptions::VideoOptions() - : content_hint(webrtc::VideoTrackInterface::ContentHint::kNone) {} + : content_hint(VideoTrackInterface::ContentHint::kNone) {} VideoOptions::~VideoOptions() = default; -MediaChannel::MediaChannel(const MediaConfig& config) - : enable_dscp_(config.enable_dscp) {} +MediaChannel::MediaChannel(const MediaConfig& config, + TaskQueueBase* network_thread) + : enable_dscp_(config.enable_dscp), + network_safety_(PendingTaskSafetyFlag::CreateDetachedInactive()), + network_thread_(network_thread) {} -MediaChannel::MediaChannel() : enable_dscp_(false) {} +MediaChannel::MediaChannel(TaskQueueBase* network_thread) + : enable_dscp_(false), + network_safety_(PendingTaskSafetyFlag::CreateDetachedInactive()), + network_thread_(network_thread) {} -MediaChannel::~MediaChannel() {} +MediaChannel::~MediaChannel() { + RTC_DCHECK(!network_interface_); +} void MediaChannel::SetInterface(NetworkInterface* iface) { - webrtc::MutexLock lock(&network_interface_mutex_); + RTC_DCHECK_RUN_ON(network_thread_); + iface ? network_safety_->SetAlive() : network_safety_->SetNotAlive(); network_interface_ = iface; UpdateDscp(); } @@ -35,13 +54,13 @@ int MediaChannel::GetRtpSendTimeExtnId() const { void MediaChannel::SetFrameEncryptor( uint32_t ssrc, - rtc::scoped_refptr<webrtc::FrameEncryptorInterface> frame_encryptor) { + rtc::scoped_refptr<FrameEncryptorInterface> frame_encryptor) { // Placeholder should be pure virtual once internal supports it. } void MediaChannel::SetFrameDecryptor( uint32_t ssrc, - rtc::scoped_refptr<webrtc::FrameDecryptorInterface> frame_decryptor) { + rtc::scoped_refptr<FrameDecryptorInterface> frame_decryptor) { // Placeholder should be pure virtual once internal supports it. } @@ -59,9 +78,8 @@ bool MediaChannel::SendRtcp(rtc::CopyOnWriteBuffer* packet, int MediaChannel::SetOption(NetworkInterface::SocketType type, rtc::Socket::Option opt, - int option) - RTC_LOCKS_EXCLUDED(network_interface_mutex_) { - webrtc::MutexLock lock(&network_interface_mutex_); + int option) { + RTC_DCHECK_RUN_ON(network_thread_); return SetOptionLocked(type, opt, option); } @@ -79,11 +97,11 @@ bool MediaChannel::ExtmapAllowMixed() const { void MediaChannel::SetEncoderToPacketizerFrameTransformer( uint32_t ssrc, - rtc::scoped_refptr<webrtc::FrameTransformerInterface> frame_transformer) {} + rtc::scoped_refptr<FrameTransformerInterface> frame_transformer) {} void MediaChannel::SetDepacketizerToDecoderFrameTransformer( uint32_t ssrc, - rtc::scoped_refptr<webrtc::FrameTransformerInterface> frame_transformer) {} + rtc::scoped_refptr<FrameTransformerInterface> frame_transformer) {} int MediaChannel::SetOptionLocked(NetworkInterface::SocketType type, rtc::Socket::Option opt, @@ -100,35 +118,45 @@ bool MediaChannel::DscpEnabled() const { // This is the DSCP value used for both RTP and RTCP channels if DSCP is // enabled. It can be changed at any time via |SetPreferredDscp|. rtc::DiffServCodePoint MediaChannel::PreferredDscp() const { - webrtc::MutexLock lock(&network_interface_mutex_); + RTC_DCHECK_RUN_ON(network_thread_); return preferred_dscp_; } -int MediaChannel::SetPreferredDscp(rtc::DiffServCodePoint preferred_dscp) { - webrtc::MutexLock lock(&network_interface_mutex_); - if (preferred_dscp == preferred_dscp_) { - return 0; +void MediaChannel::SetPreferredDscp(rtc::DiffServCodePoint new_dscp) { + if (!network_thread_->IsCurrent()) { + // This is currently the common path as the derived channel classes + // get called on the worker thread. There are still some tests though + // that call directly on the network thread. + network_thread_->PostTask(ToQueuedTask( + network_safety_, [this, new_dscp]() { SetPreferredDscp(new_dscp); })); + return; } - preferred_dscp_ = preferred_dscp; - return UpdateDscp(); + + RTC_DCHECK_RUN_ON(network_thread_); + if (new_dscp == preferred_dscp_) + return; + + preferred_dscp_ = new_dscp; + UpdateDscp(); +} + +rtc::scoped_refptr<PendingTaskSafetyFlag> MediaChannel::network_safety() { + return network_safety_; } -int MediaChannel::UpdateDscp() { +void MediaChannel::UpdateDscp() { rtc::DiffServCodePoint value = enable_dscp_ ? preferred_dscp_ : rtc::DSCP_DEFAULT; int ret = SetOptionLocked(NetworkInterface::ST_RTP, rtc::Socket::OPT_DSCP, value); - if (ret == 0) { - ret = SetOptionLocked(NetworkInterface::ST_RTCP, rtc::Socket::OPT_DSCP, - value); - } - return ret; + if (ret == 0) + SetOptionLocked(NetworkInterface::ST_RTCP, rtc::Socket::OPT_DSCP, value); } bool MediaChannel::DoSendPacket(rtc::CopyOnWriteBuffer* packet, bool rtcp, const rtc::PacketOptions& options) { - webrtc::MutexLock lock(&network_interface_mutex_); + RTC_DCHECK_RUN_ON(network_thread_); if (!network_interface_) return false; @@ -136,6 +164,54 @@ bool MediaChannel::DoSendPacket(rtc::CopyOnWriteBuffer* packet, : network_interface_->SendRtcp(packet, options); } +void MediaChannel::SendRtp(const uint8_t* data, + size_t len, + const webrtc::PacketOptions& options) { + auto send = + [this, packet_id = options.packet_id, + included_in_feedback = options.included_in_feedback, + included_in_allocation = options.included_in_allocation, + packet = rtc::CopyOnWriteBuffer(data, len, kMaxRtpPacketLen)]() mutable { + rtc::PacketOptions rtc_options; + rtc_options.packet_id = packet_id; + if (DscpEnabled()) { + rtc_options.dscp = PreferredDscp(); + } + rtc_options.info_signaled_after_sent.included_in_feedback = + included_in_feedback; + rtc_options.info_signaled_after_sent.included_in_allocation = + included_in_allocation; + SendPacket(&packet, rtc_options); + }; + + // TODO(bugs.webrtc.org/11993): ModuleRtpRtcpImpl2 and related classes (e.g. + // RTCPSender) aren't aware of the network thread and may trigger calls to + // this function from different threads. Update those classes to keep + // network traffic on the network thread. + if (network_thread_->IsCurrent()) { + send(); + } else { + network_thread_->PostTask(ToQueuedTask(network_safety_, std::move(send))); + } +} + +void MediaChannel::SendRtcp(const uint8_t* data, size_t len) { + auto send = [this, packet = rtc::CopyOnWriteBuffer( + data, len, kMaxRtpPacketLen)]() mutable { + rtc::PacketOptions rtc_options; + if (DscpEnabled()) { + rtc_options.dscp = PreferredDscp(); + } + SendRtcp(&packet, rtc_options); + }; + + if (network_thread_->IsCurrent()) { + send(); + } else { + network_thread_->PostTask(ToQueuedTask(network_safety_, std::move(send))); + } +} + MediaSenderInfo::MediaSenderInfo() = default; MediaSenderInfo::~MediaSenderInfo() = default; |