aboutsummaryrefslogtreecommitdiff
path: root/media/base/media_channel.cc
diff options
context:
space:
mode:
Diffstat (limited to 'media/base/media_channel.cc')
-rw-r--r--media/base/media_channel.cc130
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;