mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-16 23:30:48 +01:00
Remove lock from MediaChannel
Pending messages on network thread for MediaChannel, will be dropped when the MediaChannel object is deleted (without blocking). Remove MessageHandler inheritance from Channel since Post-ing to the network thread has been removed from there. Copy/pasted code for SendRtp/SendRtcp in WebRtcVideoChannel and WebRtcVoiceMediaChannel consolidated in MediaChannel. Bug: webrtc:11993 Change-Id: I05320eb7f86b98adba50ca5eb8b76b78f4111263 Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/217720 Commit-Queue: Tommi <tommi@webrtc.org> Reviewed-by: Niels Moller <nisse@webrtc.org> Cr-Commit-Position: refs/heads/master@{#33955}
This commit is contained in:
parent
5183f00d3a
commit
cf2aeffdc2
9 changed files with 131 additions and 212 deletions
|
@ -106,6 +106,8 @@ rtc_library("rtc_media_base") {
|
||||||
"../rtc_base/synchronization:mutex",
|
"../rtc_base/synchronization:mutex",
|
||||||
"../rtc_base/system:file_wrapper",
|
"../rtc_base/system:file_wrapper",
|
||||||
"../rtc_base/system:rtc_export",
|
"../rtc_base/system:rtc_export",
|
||||||
|
"../rtc_base/task_utils:pending_task_safety_flag",
|
||||||
|
"../rtc_base/task_utils:to_queued_task",
|
||||||
"../rtc_base/third_party/sigslot",
|
"../rtc_base/third_party/sigslot",
|
||||||
"../system_wrappers:field_trial",
|
"../system_wrappers:field_trial",
|
||||||
]
|
]
|
||||||
|
|
|
@ -10,12 +10,16 @@
|
||||||
|
|
||||||
#include "media/base/media_channel.h"
|
#include "media/base/media_channel.h"
|
||||||
|
|
||||||
|
#include "media/base/rtp_utils.h"
|
||||||
|
#include "rtc_base/task_utils/to_queued_task.h"
|
||||||
|
|
||||||
namespace cricket {
|
namespace cricket {
|
||||||
using webrtc::FrameDecryptorInterface;
|
using webrtc::FrameDecryptorInterface;
|
||||||
using webrtc::FrameEncryptorInterface;
|
using webrtc::FrameEncryptorInterface;
|
||||||
using webrtc::FrameTransformerInterface;
|
using webrtc::FrameTransformerInterface;
|
||||||
using webrtc::MutexLock;
|
using webrtc::PendingTaskSafetyFlag;
|
||||||
using webrtc::TaskQueueBase;
|
using webrtc::TaskQueueBase;
|
||||||
|
using webrtc::ToQueuedTask;
|
||||||
using webrtc::VideoTrackInterface;
|
using webrtc::VideoTrackInterface;
|
||||||
|
|
||||||
VideoOptions::VideoOptions()
|
VideoOptions::VideoOptions()
|
||||||
|
@ -24,10 +28,14 @@ VideoOptions::~VideoOptions() = default;
|
||||||
|
|
||||||
MediaChannel::MediaChannel(const MediaConfig& config,
|
MediaChannel::MediaChannel(const MediaConfig& config,
|
||||||
TaskQueueBase* network_thread)
|
TaskQueueBase* network_thread)
|
||||||
: enable_dscp_(config.enable_dscp), network_thread_(network_thread) {}
|
: enable_dscp_(config.enable_dscp),
|
||||||
|
network_safety_(PendingTaskSafetyFlag::CreateDetachedInactive()),
|
||||||
|
network_thread_(network_thread) {}
|
||||||
|
|
||||||
MediaChannel::MediaChannel(TaskQueueBase* network_thread)
|
MediaChannel::MediaChannel(TaskQueueBase* network_thread)
|
||||||
: enable_dscp_(false), network_thread_(network_thread) {}
|
: enable_dscp_(false),
|
||||||
|
network_safety_(PendingTaskSafetyFlag::CreateDetachedInactive()),
|
||||||
|
network_thread_(network_thread) {}
|
||||||
|
|
||||||
MediaChannel::~MediaChannel() {
|
MediaChannel::~MediaChannel() {
|
||||||
RTC_DCHECK(!network_interface_);
|
RTC_DCHECK(!network_interface_);
|
||||||
|
@ -35,7 +43,7 @@ MediaChannel::~MediaChannel() {
|
||||||
|
|
||||||
void MediaChannel::SetInterface(NetworkInterface* iface) {
|
void MediaChannel::SetInterface(NetworkInterface* iface) {
|
||||||
RTC_DCHECK_RUN_ON(network_thread_);
|
RTC_DCHECK_RUN_ON(network_thread_);
|
||||||
MutexLock lock(&network_interface_mutex_);
|
iface ? network_safety_->SetAlive() : network_safety_->SetNotAlive();
|
||||||
network_interface_ = iface;
|
network_interface_ = iface;
|
||||||
UpdateDscp();
|
UpdateDscp();
|
||||||
}
|
}
|
||||||
|
@ -70,9 +78,8 @@ bool MediaChannel::SendRtcp(rtc::CopyOnWriteBuffer* packet,
|
||||||
|
|
||||||
int MediaChannel::SetOption(NetworkInterface::SocketType type,
|
int MediaChannel::SetOption(NetworkInterface::SocketType type,
|
||||||
rtc::Socket::Option opt,
|
rtc::Socket::Option opt,
|
||||||
int option)
|
int option) {
|
||||||
RTC_LOCKS_EXCLUDED(network_interface_mutex_) {
|
RTC_DCHECK_RUN_ON(network_thread_);
|
||||||
MutexLock lock(&network_interface_mutex_);
|
|
||||||
return SetOptionLocked(type, opt, option);
|
return SetOptionLocked(type, opt, option);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,35 +118,45 @@ bool MediaChannel::DscpEnabled() const {
|
||||||
// This is the DSCP value used for both RTP and RTCP channels if DSCP is
|
// 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|.
|
// enabled. It can be changed at any time via |SetPreferredDscp|.
|
||||||
rtc::DiffServCodePoint MediaChannel::PreferredDscp() const {
|
rtc::DiffServCodePoint MediaChannel::PreferredDscp() const {
|
||||||
MutexLock lock(&network_interface_mutex_);
|
RTC_DCHECK_RUN_ON(network_thread_);
|
||||||
return preferred_dscp_;
|
return preferred_dscp_;
|
||||||
}
|
}
|
||||||
|
|
||||||
int MediaChannel::SetPreferredDscp(rtc::DiffServCodePoint preferred_dscp) {
|
void MediaChannel::SetPreferredDscp(rtc::DiffServCodePoint new_dscp) {
|
||||||
MutexLock lock(&network_interface_mutex_);
|
if (!network_thread_->IsCurrent()) {
|
||||||
if (preferred_dscp == preferred_dscp_) {
|
// This is currently the common path as the derived channel classes
|
||||||
return 0;
|
// get called on the worker thread. There are still some tests though
|
||||||
}
|
// that call directly on the network thread.
|
||||||
preferred_dscp_ = preferred_dscp;
|
network_thread_->PostTask(ToQueuedTask(
|
||||||
return UpdateDscp();
|
network_safety_, [this, new_dscp]() { SetPreferredDscp(new_dscp); }));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int MediaChannel::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_;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MediaChannel::UpdateDscp() {
|
||||||
rtc::DiffServCodePoint value =
|
rtc::DiffServCodePoint value =
|
||||||
enable_dscp_ ? preferred_dscp_ : rtc::DSCP_DEFAULT;
|
enable_dscp_ ? preferred_dscp_ : rtc::DSCP_DEFAULT;
|
||||||
int ret =
|
int ret =
|
||||||
SetOptionLocked(NetworkInterface::ST_RTP, rtc::Socket::OPT_DSCP, value);
|
SetOptionLocked(NetworkInterface::ST_RTP, rtc::Socket::OPT_DSCP, value);
|
||||||
if (ret == 0) {
|
if (ret == 0)
|
||||||
ret = SetOptionLocked(NetworkInterface::ST_RTCP, rtc::Socket::OPT_DSCP,
|
SetOptionLocked(NetworkInterface::ST_RTCP, rtc::Socket::OPT_DSCP, value);
|
||||||
value);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MediaChannel::DoSendPacket(rtc::CopyOnWriteBuffer* packet,
|
bool MediaChannel::DoSendPacket(rtc::CopyOnWriteBuffer* packet,
|
||||||
bool rtcp,
|
bool rtcp,
|
||||||
const rtc::PacketOptions& options) {
|
const rtc::PacketOptions& options) {
|
||||||
MutexLock lock(&network_interface_mutex_);
|
RTC_DCHECK_RUN_ON(network_thread_);
|
||||||
if (!network_interface_)
|
if (!network_interface_)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
@ -147,6 +164,54 @@ bool MediaChannel::DoSendPacket(rtc::CopyOnWriteBuffer* packet,
|
||||||
: network_interface_->SendRtcp(packet, options);
|
: 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;
|
||||||
MediaSenderInfo::~MediaSenderInfo() = default;
|
MediaSenderInfo::~MediaSenderInfo() = default;
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@
|
||||||
#include "rtc_base/socket.h"
|
#include "rtc_base/socket.h"
|
||||||
#include "rtc_base/string_encode.h"
|
#include "rtc_base/string_encode.h"
|
||||||
#include "rtc_base/strings/string_builder.h"
|
#include "rtc_base/strings/string_builder.h"
|
||||||
#include "rtc_base/synchronization/mutex.h"
|
#include "rtc_base/task_utils/pending_task_safety_flag.h"
|
||||||
|
|
||||||
namespace rtc {
|
namespace rtc {
|
||||||
class Timing;
|
class Timing;
|
||||||
|
@ -176,8 +176,7 @@ class MediaChannel {
|
||||||
virtual cricket::MediaType media_type() const = 0;
|
virtual cricket::MediaType media_type() const = 0;
|
||||||
|
|
||||||
// Sets the abstract interface class for sending RTP/RTCP data.
|
// Sets the abstract interface class for sending RTP/RTCP data.
|
||||||
virtual void SetInterface(NetworkInterface* iface)
|
virtual void SetInterface(NetworkInterface* iface);
|
||||||
RTC_LOCKS_EXCLUDED(network_interface_mutex_);
|
|
||||||
// Called on the network when an RTP packet is received.
|
// Called on the network when an RTP packet is received.
|
||||||
virtual void OnPacketReceived(rtc::CopyOnWriteBuffer packet,
|
virtual void OnPacketReceived(rtc::CopyOnWriteBuffer packet,
|
||||||
int64_t packet_time_us) = 0;
|
int64_t packet_time_us) = 0;
|
||||||
|
@ -249,7 +248,7 @@ class MediaChannel {
|
||||||
|
|
||||||
int SetOption(NetworkInterface::SocketType type,
|
int SetOption(NetworkInterface::SocketType type,
|
||||||
rtc::Socket::Option opt,
|
rtc::Socket::Option opt,
|
||||||
int option) RTC_LOCKS_EXCLUDED(network_interface_mutex_);
|
int option);
|
||||||
|
|
||||||
// Corresponds to the SDP attribute extmap-allow-mixed, see RFC8285.
|
// Corresponds to the SDP attribute extmap-allow-mixed, see RFC8285.
|
||||||
// Set to true if it's allowed to mix one- and two-byte RTP header extensions
|
// Set to true if it's allowed to mix one- and two-byte RTP header extensions
|
||||||
|
@ -273,40 +272,42 @@ class MediaChannel {
|
||||||
protected:
|
protected:
|
||||||
int SetOptionLocked(NetworkInterface::SocketType type,
|
int SetOptionLocked(NetworkInterface::SocketType type,
|
||||||
rtc::Socket::Option opt,
|
rtc::Socket::Option opt,
|
||||||
int option)
|
int option) RTC_RUN_ON(network_thread_);
|
||||||
RTC_EXCLUSIVE_LOCKS_REQUIRED(network_interface_mutex_);
|
|
||||||
|
|
||||||
bool DscpEnabled() const;
|
bool DscpEnabled() const;
|
||||||
|
|
||||||
// This is the DSCP value used for both RTP and RTCP channels if DSCP is
|
// 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|.
|
// enabled. It can be changed at any time via |SetPreferredDscp|.
|
||||||
rtc::DiffServCodePoint PreferredDscp() const
|
rtc::DiffServCodePoint PreferredDscp() const;
|
||||||
RTC_LOCKS_EXCLUDED(network_interface_mutex_);
|
void SetPreferredDscp(rtc::DiffServCodePoint new_dscp);
|
||||||
|
|
||||||
int SetPreferredDscp(rtc::DiffServCodePoint preferred_dscp)
|
rtc::scoped_refptr<webrtc::PendingTaskSafetyFlag> network_safety();
|
||||||
RTC_LOCKS_EXCLUDED(network_interface_mutex_);
|
|
||||||
|
// Utility implementation for derived classes (video/voice) that applies
|
||||||
|
// the packet options and passes the data onwards to `SendPacket`.
|
||||||
|
void SendRtp(const uint8_t* data,
|
||||||
|
size_t len,
|
||||||
|
const webrtc::PacketOptions& options);
|
||||||
|
|
||||||
|
void SendRtcp(const uint8_t* data, size_t len);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Apply the preferred DSCP setting to the underlying network interface RTP
|
// Apply the preferred DSCP setting to the underlying network interface RTP
|
||||||
// and RTCP channels. If DSCP is disabled, then apply the default DSCP value.
|
// and RTCP channels. If DSCP is disabled, then apply the default DSCP value.
|
||||||
int UpdateDscp() RTC_EXCLUSIVE_LOCKS_REQUIRED(network_interface_mutex_);
|
void UpdateDscp() RTC_RUN_ON(network_thread_);
|
||||||
|
|
||||||
bool DoSendPacket(rtc::CopyOnWriteBuffer* packet,
|
bool DoSendPacket(rtc::CopyOnWriteBuffer* packet,
|
||||||
bool rtcp,
|
bool rtcp,
|
||||||
const rtc::PacketOptions& options)
|
const rtc::PacketOptions& options);
|
||||||
RTC_LOCKS_EXCLUDED(network_interface_mutex_);
|
|
||||||
|
|
||||||
const bool enable_dscp_;
|
const bool enable_dscp_;
|
||||||
|
rtc::scoped_refptr<webrtc::PendingTaskSafetyFlag> network_safety_
|
||||||
|
RTC_PT_GUARDED_BY(network_thread_);
|
||||||
webrtc::TaskQueueBase* const network_thread_;
|
webrtc::TaskQueueBase* const network_thread_;
|
||||||
|
NetworkInterface* network_interface_ RTC_GUARDED_BY(network_thread_) =
|
||||||
// |network_interface_| can be accessed from the worker_thread and
|
nullptr;
|
||||||
// from any MediaEngine threads. This critical section is to protect accessing
|
rtc::DiffServCodePoint preferred_dscp_ RTC_GUARDED_BY(network_thread_) =
|
||||||
// of network_interface_ object.
|
rtc::DSCP_DEFAULT;
|
||||||
mutable webrtc::Mutex network_interface_mutex_;
|
|
||||||
NetworkInterface* network_interface_
|
|
||||||
RTC_GUARDED_BY(network_interface_mutex_) = nullptr;
|
|
||||||
rtc::DiffServCodePoint preferred_dscp_
|
|
||||||
RTC_GUARDED_BY(network_interface_mutex_) = rtc::DSCP_DEFAULT;
|
|
||||||
bool extmap_allow_mixed_ = false;
|
bool extmap_allow_mixed_ = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -2018,27 +2018,13 @@ std::vector<webrtc::RtpSource> WebRtcVideoChannel::GetSources(
|
||||||
bool WebRtcVideoChannel::SendRtp(const uint8_t* data,
|
bool WebRtcVideoChannel::SendRtp(const uint8_t* data,
|
||||||
size_t len,
|
size_t len,
|
||||||
const webrtc::PacketOptions& options) {
|
const webrtc::PacketOptions& options) {
|
||||||
rtc::CopyOnWriteBuffer packet(data, len, kMaxRtpPacketLen);
|
MediaChannel::SendRtp(data, len, options);
|
||||||
rtc::PacketOptions rtc_options;
|
return true;
|
||||||
rtc_options.packet_id = options.packet_id;
|
|
||||||
if (DscpEnabled()) {
|
|
||||||
rtc_options.dscp = PreferredDscp();
|
|
||||||
}
|
|
||||||
rtc_options.info_signaled_after_sent.included_in_feedback =
|
|
||||||
options.included_in_feedback;
|
|
||||||
rtc_options.info_signaled_after_sent.included_in_allocation =
|
|
||||||
options.included_in_allocation;
|
|
||||||
return MediaChannel::SendPacket(&packet, rtc_options);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WebRtcVideoChannel::SendRtcp(const uint8_t* data, size_t len) {
|
bool WebRtcVideoChannel::SendRtcp(const uint8_t* data, size_t len) {
|
||||||
rtc::CopyOnWriteBuffer packet(data, len, kMaxRtpPacketLen);
|
MediaChannel::SendRtcp(data, len);
|
||||||
rtc::PacketOptions rtc_options;
|
return true;
|
||||||
if (DscpEnabled()) {
|
|
||||||
rtc_options.dscp = PreferredDscp();
|
|
||||||
}
|
|
||||||
|
|
||||||
return MediaChannel::SendRtcp(&packet, rtc_options);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
WebRtcVideoChannel::WebRtcVideoSendStream::VideoSendStreamParameters::
|
WebRtcVideoChannel::WebRtcVideoSendStream::VideoSendStreamParameters::
|
||||||
|
|
|
@ -2554,6 +2554,18 @@ void WebRtcVoiceMediaChannel::SetDepacketizerToDecoderFrameTransformer(
|
||||||
std::move(frame_transformer));
|
std::move(frame_transformer));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool WebRtcVoiceMediaChannel::SendRtp(const uint8_t* data,
|
||||||
|
size_t len,
|
||||||
|
const webrtc::PacketOptions& options) {
|
||||||
|
MediaChannel::SendRtp(data, len, options);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WebRtcVoiceMediaChannel::SendRtcp(const uint8_t* data, size_t len) {
|
||||||
|
MediaChannel::SendRtcp(data, len);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool WebRtcVoiceMediaChannel::MaybeDeregisterUnsignaledRecvStream(
|
bool WebRtcVoiceMediaChannel::MaybeDeregisterUnsignaledRecvStream(
|
||||||
uint32_t ssrc) {
|
uint32_t ssrc) {
|
||||||
RTC_DCHECK_RUN_ON(worker_thread_);
|
RTC_DCHECK_RUN_ON(worker_thread_);
|
||||||
|
|
|
@ -241,29 +241,9 @@ class WebRtcVoiceMediaChannel final : public VoiceMediaChannel,
|
||||||
// implements Transport interface
|
// implements Transport interface
|
||||||
bool SendRtp(const uint8_t* data,
|
bool SendRtp(const uint8_t* data,
|
||||||
size_t len,
|
size_t len,
|
||||||
const webrtc::PacketOptions& options) override {
|
const webrtc::PacketOptions& options) override;
|
||||||
rtc::CopyOnWriteBuffer packet(data, len, kMaxRtpPacketLen);
|
|
||||||
rtc::PacketOptions rtc_options;
|
|
||||||
rtc_options.packet_id = options.packet_id;
|
|
||||||
if (DscpEnabled()) {
|
|
||||||
rtc_options.dscp = PreferredDscp();
|
|
||||||
}
|
|
||||||
rtc_options.info_signaled_after_sent.included_in_feedback =
|
|
||||||
options.included_in_feedback;
|
|
||||||
rtc_options.info_signaled_after_sent.included_in_allocation =
|
|
||||||
options.included_in_allocation;
|
|
||||||
return VoiceMediaChannel::SendPacket(&packet, rtc_options);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool SendRtcp(const uint8_t* data, size_t len) override {
|
bool SendRtcp(const uint8_t* data, size_t len) override;
|
||||||
rtc::CopyOnWriteBuffer packet(data, len, kMaxRtpPacketLen);
|
|
||||||
rtc::PacketOptions rtc_options;
|
|
||||||
if (DscpEnabled()) {
|
|
||||||
rtc_options.dscp = PreferredDscp();
|
|
||||||
}
|
|
||||||
|
|
||||||
return VoiceMediaChannel::SendRtcp(&packet, rtc_options);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool SetOptions(const AudioOptions& options);
|
bool SetOptions(const AudioOptions& options);
|
||||||
|
|
|
@ -44,11 +44,6 @@ using ::webrtc::PendingTaskSafetyFlag;
|
||||||
using ::webrtc::SdpType;
|
using ::webrtc::SdpType;
|
||||||
using ::webrtc::ToQueuedTask;
|
using ::webrtc::ToQueuedTask;
|
||||||
|
|
||||||
struct SendPacketMessageData : public rtc::MessageData {
|
|
||||||
rtc::CopyOnWriteBuffer packet;
|
|
||||||
rtc::PacketOptions options;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Finds a stream based on target's Primary SSRC or RIDs.
|
// Finds a stream based on target's Primary SSRC or RIDs.
|
||||||
// This struct is used in BaseChannel::UpdateLocalStreams_w.
|
// This struct is used in BaseChannel::UpdateLocalStreams_w.
|
||||||
struct StreamFinder {
|
struct StreamFinder {
|
||||||
|
@ -84,13 +79,6 @@ struct StreamFinder {
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
enum {
|
|
||||||
MSG_SEND_RTP_PACKET = 1,
|
|
||||||
MSG_SEND_RTCP_PACKET,
|
|
||||||
MSG_READYTOSENDDATA,
|
|
||||||
MSG_DATARECEIVED,
|
|
||||||
};
|
|
||||||
|
|
||||||
static void SafeSetError(const std::string& message, std::string* error_desc) {
|
static void SafeSetError(const std::string& message, std::string* error_desc) {
|
||||||
if (error_desc) {
|
if (error_desc) {
|
||||||
*error_desc = message;
|
*error_desc = message;
|
||||||
|
@ -224,13 +212,10 @@ void BaseChannel::Deinit() {
|
||||||
network_thread_->Invoke<void>(RTC_FROM_HERE, [&] {
|
network_thread_->Invoke<void>(RTC_FROM_HERE, [&] {
|
||||||
RTC_DCHECK_RUN_ON(network_thread());
|
RTC_DCHECK_RUN_ON(network_thread());
|
||||||
media_channel_->SetInterface(/*iface=*/nullptr);
|
media_channel_->SetInterface(/*iface=*/nullptr);
|
||||||
FlushRtcpMessages_n();
|
|
||||||
|
|
||||||
if (rtp_transport_) {
|
if (rtp_transport_) {
|
||||||
DisconnectFromRtpTransport();
|
DisconnectFromRtpTransport();
|
||||||
}
|
}
|
||||||
// Clear pending read packets/messages.
|
|
||||||
network_thread_->Clear(this);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -340,15 +325,7 @@ bool BaseChannel::SendRtcp(rtc::CopyOnWriteBuffer* packet,
|
||||||
int BaseChannel::SetOption(SocketType type,
|
int BaseChannel::SetOption(SocketType type,
|
||||||
rtc::Socket::Option opt,
|
rtc::Socket::Option opt,
|
||||||
int value) {
|
int value) {
|
||||||
return network_thread_->Invoke<int>(RTC_FROM_HERE, [this, type, opt, value] {
|
|
||||||
RTC_DCHECK_RUN_ON(network_thread());
|
RTC_DCHECK_RUN_ON(network_thread());
|
||||||
return SetOption_n(type, opt, value);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
int BaseChannel::SetOption_n(SocketType type,
|
|
||||||
rtc::Socket::Option opt,
|
|
||||||
int value) {
|
|
||||||
RTC_DCHECK(rtp_transport_);
|
RTC_DCHECK(rtp_transport_);
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case ST_RTP:
|
case ST_RTP:
|
||||||
|
@ -403,6 +380,7 @@ void BaseChannel::OnTransportReadyToSend(bool ready) {
|
||||||
bool BaseChannel::SendPacket(bool rtcp,
|
bool BaseChannel::SendPacket(bool rtcp,
|
||||||
rtc::CopyOnWriteBuffer* packet,
|
rtc::CopyOnWriteBuffer* packet,
|
||||||
const rtc::PacketOptions& options) {
|
const rtc::PacketOptions& options) {
|
||||||
|
RTC_DCHECK_RUN_ON(network_thread());
|
||||||
// Until all the code is migrated to use RtpPacketType instead of bool.
|
// Until all the code is migrated to use RtpPacketType instead of bool.
|
||||||
RtpPacketType packet_type = rtcp ? RtpPacketType::kRtcp : RtpPacketType::kRtp;
|
RtpPacketType packet_type = rtcp ? RtpPacketType::kRtcp : RtpPacketType::kRtp;
|
||||||
// SendPacket gets called from MediaEngine, on a pacer or an encoder thread.
|
// SendPacket gets called from MediaEngine, on a pacer or an encoder thread.
|
||||||
|
@ -412,16 +390,6 @@ bool BaseChannel::SendPacket(bool rtcp,
|
||||||
// SRTP and the inner workings of the transport channels.
|
// SRTP and the inner workings of the transport channels.
|
||||||
// The only downside is that we can't return a proper failure code if
|
// The only downside is that we can't return a proper failure code if
|
||||||
// needed. Since UDP is unreliable anyway, this should be a non-issue.
|
// needed. Since UDP is unreliable anyway, this should be a non-issue.
|
||||||
if (!network_thread_->IsCurrent()) {
|
|
||||||
// Avoid a copy by transferring the ownership of the packet data.
|
|
||||||
int message_id = rtcp ? MSG_SEND_RTCP_PACKET : MSG_SEND_RTP_PACKET;
|
|
||||||
SendPacketMessageData* data = new SendPacketMessageData;
|
|
||||||
data->packet = std::move(*packet);
|
|
||||||
data->options = options;
|
|
||||||
network_thread_->Post(RTC_FROM_HERE, this, message_id, data);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
RTC_DCHECK_RUN_ON(network_thread());
|
|
||||||
|
|
||||||
TRACE_EVENT0("webrtc", "BaseChannel::SendPacket");
|
TRACE_EVENT0("webrtc", "BaseChannel::SendPacket");
|
||||||
|
|
||||||
|
@ -794,22 +762,6 @@ RtpHeaderExtensions BaseChannel::GetFilteredRtpHeaderExtensions(
|
||||||
return webrtc::RtpExtension::FilterDuplicateNonEncrypted(extensions);
|
return webrtc::RtpExtension::FilterDuplicateNonEncrypted(extensions);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseChannel::OnMessage(rtc::Message* pmsg) {
|
|
||||||
TRACE_EVENT0("webrtc", "BaseChannel::OnMessage");
|
|
||||||
switch (pmsg->message_id) {
|
|
||||||
case MSG_SEND_RTP_PACKET:
|
|
||||||
case MSG_SEND_RTCP_PACKET: {
|
|
||||||
RTC_DCHECK_RUN_ON(network_thread());
|
|
||||||
SendPacketMessageData* data =
|
|
||||||
static_cast<SendPacketMessageData*>(pmsg->pdata);
|
|
||||||
bool rtcp = pmsg->message_id == MSG_SEND_RTCP_PACKET;
|
|
||||||
SendPacket(rtcp, &data->packet, data->options);
|
|
||||||
delete data;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void BaseChannel::MaybeAddHandledPayloadType(int payload_type) {
|
void BaseChannel::MaybeAddHandledPayloadType(int payload_type) {
|
||||||
if (payload_type_demuxing_enabled_) {
|
if (payload_type_demuxing_enabled_) {
|
||||||
demuxer_criteria_.payload_types.insert(static_cast<uint8_t>(payload_type));
|
demuxer_criteria_.payload_types.insert(static_cast<uint8_t>(payload_type));
|
||||||
|
@ -824,17 +776,6 @@ void BaseChannel::ClearHandledPayloadTypes() {
|
||||||
payload_types_.clear();
|
payload_types_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseChannel::FlushRtcpMessages_n() {
|
|
||||||
// Flush all remaining RTCP messages. This should only be called in
|
|
||||||
// destructor.
|
|
||||||
rtc::MessageList rtcp_messages;
|
|
||||||
network_thread_->Clear(this, MSG_SEND_RTCP_PACKET, &rtcp_messages);
|
|
||||||
for (const auto& message : rtcp_messages) {
|
|
||||||
network_thread_->Send(RTC_FROM_HERE, this, MSG_SEND_RTCP_PACKET,
|
|
||||||
message.pdata);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void BaseChannel::SignalSentPacket_n(const rtc::SentPacket& sent_packet) {
|
void BaseChannel::SignalSentPacket_n(const rtc::SentPacket& sent_packet) {
|
||||||
RTC_DCHECK_RUN_ON(network_thread());
|
RTC_DCHECK_RUN_ON(network_thread());
|
||||||
media_channel()->OnPacketSent(sent_packet);
|
media_channel()->OnPacketSent(sent_packet);
|
||||||
|
|
10
pc/channel.h
10
pc/channel.h
|
@ -54,7 +54,6 @@
|
||||||
#include "rtc_base/checks.h"
|
#include "rtc_base/checks.h"
|
||||||
#include "rtc_base/copy_on_write_buffer.h"
|
#include "rtc_base/copy_on_write_buffer.h"
|
||||||
#include "rtc_base/location.h"
|
#include "rtc_base/location.h"
|
||||||
#include "rtc_base/message_handler.h"
|
|
||||||
#include "rtc_base/network.h"
|
#include "rtc_base/network.h"
|
||||||
#include "rtc_base/network/sent_packet.h"
|
#include "rtc_base/network/sent_packet.h"
|
||||||
#include "rtc_base/network_route.h"
|
#include "rtc_base/network_route.h"
|
||||||
|
@ -93,8 +92,6 @@ struct CryptoParams;
|
||||||
// NetworkInterface.
|
// NetworkInterface.
|
||||||
|
|
||||||
class BaseChannel : public ChannelInterface,
|
class BaseChannel : public ChannelInterface,
|
||||||
// TODO(tommi): Remove MessageHandler inheritance.
|
|
||||||
public rtc::MessageHandler,
|
|
||||||
// TODO(tommi): Remove has_slots inheritance.
|
// TODO(tommi): Remove has_slots inheritance.
|
||||||
public sigslot::has_slots<>,
|
public sigslot::has_slots<>,
|
||||||
// TODO(tommi): Consider implementing these interfaces
|
// TODO(tommi): Consider implementing these interfaces
|
||||||
|
@ -186,8 +183,6 @@ class BaseChannel : public ChannelInterface,
|
||||||
|
|
||||||
// Only public for unit tests. Otherwise, consider protected.
|
// Only public for unit tests. Otherwise, consider protected.
|
||||||
int SetOption(SocketType type, rtc::Socket::Option o, int val) override;
|
int SetOption(SocketType type, rtc::Socket::Option o, int val) override;
|
||||||
int SetOption_n(SocketType type, rtc::Socket::Option o, int val)
|
|
||||||
RTC_RUN_ON(network_thread());
|
|
||||||
|
|
||||||
// RtpPacketSinkInterface overrides.
|
// RtpPacketSinkInterface overrides.
|
||||||
void OnRtpPacket(const webrtc::RtpPacketReceived& packet) override;
|
void OnRtpPacket(const webrtc::RtpPacketReceived& packet) override;
|
||||||
|
@ -223,8 +218,6 @@ class BaseChannel : public ChannelInterface,
|
||||||
bool IsReadyToSendMedia_w() const RTC_RUN_ON(worker_thread());
|
bool IsReadyToSendMedia_w() const RTC_RUN_ON(worker_thread());
|
||||||
rtc::Thread* signaling_thread() const { return signaling_thread_; }
|
rtc::Thread* signaling_thread() const { return signaling_thread_; }
|
||||||
|
|
||||||
void FlushRtcpMessages_n() RTC_RUN_ON(network_thread());
|
|
||||||
|
|
||||||
// NetworkInterface implementation, called by MediaEngine
|
// NetworkInterface implementation, called by MediaEngine
|
||||||
bool SendPacket(rtc::CopyOnWriteBuffer* packet,
|
bool SendPacket(rtc::CopyOnWriteBuffer* packet,
|
||||||
const rtc::PacketOptions& options) override;
|
const rtc::PacketOptions& options) override;
|
||||||
|
@ -285,9 +278,6 @@ class BaseChannel : public ChannelInterface,
|
||||||
RtpHeaderExtensions GetFilteredRtpHeaderExtensions(
|
RtpHeaderExtensions GetFilteredRtpHeaderExtensions(
|
||||||
const RtpHeaderExtensions& extensions);
|
const RtpHeaderExtensions& extensions);
|
||||||
|
|
||||||
// From MessageHandler
|
|
||||||
void OnMessage(rtc::Message* pmsg) override;
|
|
||||||
|
|
||||||
// Add |payload_type| to |demuxer_criteria_| if payload type demuxing is
|
// Add |payload_type| to |demuxer_criteria_| if payload type demuxing is
|
||||||
// enabled.
|
// enabled.
|
||||||
void MaybeAddHandledPayloadType(int payload_type) RTC_RUN_ON(worker_thread());
|
void MaybeAddHandledPayloadType(int payload_type) RTC_RUN_ON(worker_thread());
|
||||||
|
|
|
@ -398,25 +398,6 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Terminate() {
|
|
||||||
channel1_.reset();
|
|
||||||
channel2_.reset();
|
|
||||||
fake_rtp_dtls_transport1_.reset();
|
|
||||||
fake_rtcp_dtls_transport1_.reset();
|
|
||||||
fake_rtp_dtls_transport2_.reset();
|
|
||||||
fake_rtcp_dtls_transport2_.reset();
|
|
||||||
fake_rtp_packet_transport1_.reset();
|
|
||||||
fake_rtcp_packet_transport1_.reset();
|
|
||||||
fake_rtp_packet_transport2_.reset();
|
|
||||||
fake_rtcp_packet_transport2_.reset();
|
|
||||||
if (network_thread_keeper_) {
|
|
||||||
RTC_DCHECK_EQ(network_thread_, network_thread_keeper_.get());
|
|
||||||
network_thread_ = nullptr;
|
|
||||||
network_thread_keeper_.reset();
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SendRtp(typename T::MediaChannel* media_channel, rtc::Buffer data) {
|
void SendRtp(typename T::MediaChannel* media_channel, rtc::Buffer data) {
|
||||||
network_thread_->PostTask(webrtc::ToQueuedTask(
|
network_thread_->PostTask(webrtc::ToQueuedTask(
|
||||||
network_thread_safety_, [media_channel, data = std::move(data)]() {
|
network_thread_safety_, [media_channel, data = std::move(data)]() {
|
||||||
|
@ -917,29 +898,6 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> {
|
||||||
EXPECT_EQ(1U, media_channel2()->codecs().size());
|
EXPECT_EQ(1U, media_channel2()->codecs().size());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test that we don't crash if packets are sent during call teardown
|
|
||||||
// when RTCP mux is enabled. This is a regression test against a specific
|
|
||||||
// race condition that would only occur when a RTCP packet was sent during
|
|
||||||
// teardown of a channel on which RTCP mux was enabled.
|
|
||||||
void TestCallTeardownRtcpMux() {
|
|
||||||
class LastWordMediaChannel : public T::MediaChannel {
|
|
||||||
public:
|
|
||||||
explicit LastWordMediaChannel(rtc::Thread* network_thread)
|
|
||||||
: T::MediaChannel(NULL, typename T::Options(), network_thread) {}
|
|
||||||
~LastWordMediaChannel() {
|
|
||||||
T::MediaChannel::SendRtp(kPcmuFrame, sizeof(kPcmuFrame),
|
|
||||||
rtc::PacketOptions());
|
|
||||||
T::MediaChannel::SendRtcp(kRtcpReport, sizeof(kRtcpReport));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
CreateChannels(std::make_unique<LastWordMediaChannel>(network_thread_),
|
|
||||||
std::make_unique<LastWordMediaChannel>(network_thread_),
|
|
||||||
RTCP_MUX, RTCP_MUX);
|
|
||||||
EXPECT_TRUE(SendInitiate());
|
|
||||||
EXPECT_TRUE(SendAccept());
|
|
||||||
EXPECT_TRUE(Terminate());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send voice RTP data to the other side and ensure it gets there.
|
// Send voice RTP data to the other side and ensure it gets there.
|
||||||
void SendRtpToRtp() {
|
void SendRtpToRtp() {
|
||||||
CreateChannels(RTCP_MUX, RTCP_MUX);
|
CreateChannels(RTCP_MUX, RTCP_MUX);
|
||||||
|
@ -1668,10 +1626,6 @@ TEST_F(VoiceChannelSingleThreadTest, TestCallSetup) {
|
||||||
Base::TestCallSetup();
|
Base::TestCallSetup();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(VoiceChannelSingleThreadTest, TestCallTeardownRtcpMux) {
|
|
||||||
Base::TestCallTeardownRtcpMux();
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(VoiceChannelSingleThreadTest, SendRtpToRtp) {
|
TEST_F(VoiceChannelSingleThreadTest, SendRtpToRtp) {
|
||||||
Base::SendRtpToRtp();
|
Base::SendRtpToRtp();
|
||||||
}
|
}
|
||||||
|
@ -1809,10 +1763,6 @@ TEST_F(VoiceChannelDoubleThreadTest, TestCallSetup) {
|
||||||
Base::TestCallSetup();
|
Base::TestCallSetup();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(VoiceChannelDoubleThreadTest, TestCallTeardownRtcpMux) {
|
|
||||||
Base::TestCallTeardownRtcpMux();
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(VoiceChannelDoubleThreadTest, SendRtpToRtp) {
|
TEST_F(VoiceChannelDoubleThreadTest, SendRtpToRtp) {
|
||||||
Base::SendRtpToRtp();
|
Base::SendRtpToRtp();
|
||||||
}
|
}
|
||||||
|
@ -1948,10 +1898,6 @@ TEST_F(VideoChannelSingleThreadTest, TestCallSetup) {
|
||||||
Base::TestCallSetup();
|
Base::TestCallSetup();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(VideoChannelSingleThreadTest, TestCallTeardownRtcpMux) {
|
|
||||||
Base::TestCallTeardownRtcpMux();
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(VideoChannelSingleThreadTest, SendRtpToRtp) {
|
TEST_F(VideoChannelSingleThreadTest, SendRtpToRtp) {
|
||||||
Base::SendRtpToRtp();
|
Base::SendRtpToRtp();
|
||||||
}
|
}
|
||||||
|
@ -2237,10 +2183,6 @@ TEST_F(VideoChannelDoubleThreadTest, TestCallSetup) {
|
||||||
Base::TestCallSetup();
|
Base::TestCallSetup();
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_F(VideoChannelDoubleThreadTest, TestCallTeardownRtcpMux) {
|
|
||||||
Base::TestCallTeardownRtcpMux();
|
|
||||||
}
|
|
||||||
|
|
||||||
TEST_F(VideoChannelDoubleThreadTest, SendRtpToRtp) {
|
TEST_F(VideoChannelDoubleThreadTest, SendRtpToRtp) {
|
||||||
Base::SendRtpToRtp();
|
Base::SendRtpToRtp();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue