Prevent channels being set on stopped transceiver.

Fixing bug that allows a channel to be set on a stopped transceiver.
This CL contains the following refactoring:
1. Extracted ChannelInterface from BaseChannel
2. Unified SetXxxMediaChannel (Voice, Video) into SetMediaChannel

Bug: webrtc:9932
Change-Id: I2fbf00c823b7848ad4f2acb6e80b1b58ac45ee38
Reviewed-on: https://webrtc-review.googlesource.com/c/110564
Reviewed-by: Seth Hampson <shampson@webrtc.org>
Reviewed-by: Steve Anton <steveanton@webrtc.org>
Commit-Queue: Amit Hilbuch <amithi@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#25641}
This commit is contained in:
Amit Hilbuch 2018-11-13 16:26:05 -08:00 committed by Commit Bot
parent 1724a80e2d
commit dd9390c491
21 changed files with 326 additions and 140 deletions

View File

@ -87,6 +87,10 @@ std::map<std::string, std::string> AudioSendParameters::ToStringMap() const {
return params; return params;
} }
cricket::MediaType VoiceMediaChannel::media_type() const {
return cricket::MediaType::MEDIA_TYPE_AUDIO;
}
VideoSendParameters::VideoSendParameters() = default; VideoSendParameters::VideoSendParameters() = default;
VideoSendParameters::~VideoSendParameters() = default; VideoSendParameters::~VideoSendParameters() = default;
@ -96,11 +100,19 @@ std::map<std::string, std::string> VideoSendParameters::ToStringMap() const {
return params; return params;
} }
cricket::MediaType VideoMediaChannel::media_type() const {
return cricket::MediaType::MEDIA_TYPE_VIDEO;
}
DataMediaChannel::DataMediaChannel() = default; DataMediaChannel::DataMediaChannel() = default;
DataMediaChannel::DataMediaChannel(const MediaConfig& config) DataMediaChannel::DataMediaChannel(const MediaConfig& config)
: MediaChannel(config) {} : MediaChannel(config) {}
DataMediaChannel::~DataMediaChannel() = default; DataMediaChannel::~DataMediaChannel() = default;
cricket::MediaType DataMediaChannel::media_type() const {
return cricket::MediaType::MEDIA_TYPE_DATA;
}
bool DataMediaChannel::GetStats(DataMediaInfo* info) { bool DataMediaChannel::GetStats(DataMediaInfo* info) {
return true; return true;
} }

View File

@ -184,6 +184,8 @@ class MediaChannel : public sigslot::has_slots<> {
MediaChannel(); MediaChannel();
~MediaChannel() override; ~MediaChannel() override;
virtual cricket::MediaType media_type() const = 0;
// Sets the abstract interface class for sending RTP/RTCP data and // Sets the abstract interface class for sending RTP/RTCP data and
// interface for media transport (experimental). If media transport is // interface for media transport (experimental). If media transport is
// provided, it should be used instead of RTP/RTCP. // provided, it should be used instead of RTP/RTCP.
@ -700,6 +702,8 @@ class VoiceMediaChannel : public MediaChannel {
explicit VoiceMediaChannel(const MediaConfig& config) explicit VoiceMediaChannel(const MediaConfig& config)
: MediaChannel(config) {} : MediaChannel(config) {}
~VoiceMediaChannel() override {} ~VoiceMediaChannel() override {}
cricket::MediaType media_type() const override;
virtual bool SetSendParameters(const AudioSendParameters& params) = 0; virtual bool SetSendParameters(const AudioSendParameters& params) = 0;
virtual bool SetRecvParameters(const AudioRecvParameters& params) = 0; virtual bool SetRecvParameters(const AudioRecvParameters& params) = 0;
virtual webrtc::RtpParameters GetRtpSendParameters(uint32_t ssrc) const = 0; virtual webrtc::RtpParameters GetRtpSendParameters(uint32_t ssrc) const = 0;
@ -772,6 +776,7 @@ class VideoMediaChannel : public MediaChannel {
: MediaChannel(config) {} : MediaChannel(config) {}
~VideoMediaChannel() override {} ~VideoMediaChannel() override {}
cricket::MediaType media_type() const override;
virtual bool SetSendParameters(const VideoSendParameters& params) = 0; virtual bool SetSendParameters(const VideoSendParameters& params) = 0;
virtual bool SetRecvParameters(const VideoRecvParameters& params) = 0; virtual bool SetRecvParameters(const VideoRecvParameters& params) = 0;
virtual webrtc::RtpParameters GetRtpSendParameters(uint32_t ssrc) const = 0; virtual webrtc::RtpParameters GetRtpSendParameters(uint32_t ssrc) const = 0;
@ -883,6 +888,7 @@ class DataMediaChannel : public MediaChannel {
explicit DataMediaChannel(const MediaConfig& config); explicit DataMediaChannel(const MediaConfig& config);
~DataMediaChannel() override; ~DataMediaChannel() override;
cricket::MediaType media_type() const override;
virtual bool SetSendParameters(const DataSendParameters& params) = 0; virtual bool SetSendParameters(const DataSendParameters& params) = 0;
virtual bool SetRecvParameters(const DataRecvParameters& params) = 0; virtual bool SetRecvParameters(const DataRecvParameters& params) = 0;

View File

@ -31,6 +31,7 @@ rtc_static_library("rtc_pc_base") {
sources = [ sources = [
"channel.cc", "channel.cc",
"channel.h", "channel.h",
"channelinterface.h",
"channelmanager.cc", "channelmanager.cc",
"channelmanager.h", "channelmanager.h",
"dtlssrtptransport.cc", "dtlssrtptransport.cc",
@ -380,6 +381,7 @@ if (rtc_include_tests) {
"test/fakevideotrackrenderer.h", "test/fakevideotrackrenderer.h",
"test/fakevideotracksource.h", "test/fakevideotracksource.h",
"test/framegeneratorcapturervideotracksource.h", "test/framegeneratorcapturervideotracksource.h",
"test/mock_channelinterface.h",
"test/mock_datachannel.h", "test/mock_datachannel.h",
"test/mock_rtpreceiverinternal.h", "test/mock_rtpreceiverinternal.h",
"test/mock_rtpsenderinternal.h", "test/mock_rtpsenderinternal.h",
@ -460,6 +462,7 @@ if (rtc_include_tests) {
"rtpmediautils_unittest.cc", "rtpmediautils_unittest.cc",
"rtpparametersconversion_unittest.cc", "rtpparametersconversion_unittest.cc",
"rtpsenderreceiver_unittest.cc", "rtpsenderreceiver_unittest.cc",
"rtptransceiver_unittest.cc",
"sctputils_unittest.cc", "sctputils_unittest.cc",
"statscollector_unittest.cc", "statscollector_unittest.cc",
"test/fakeaudiocapturemodule_unittest.cc", "test/fakeaudiocapturemodule_unittest.cc",

View File

@ -702,7 +702,7 @@ void BaseChannel::OnMessage(rtc::Message* pmsg) {
break; break;
} }
case MSG_FIRSTPACKETRECEIVED: { case MSG_FIRSTPACKETRECEIVED: {
SignalFirstPacketReceived(this); SignalFirstPacketReceived_(this);
break; break;
} }
} }

View File

@ -29,6 +29,7 @@
#include "media/base/streamparams.h" #include "media/base/streamparams.h"
#include "p2p/base/dtlstransportinternal.h" #include "p2p/base/dtlstransportinternal.h"
#include "p2p/base/packettransportinternal.h" #include "p2p/base/packettransportinternal.h"
#include "pc/channelinterface.h"
#include "pc/dtlssrtptransport.h" #include "pc/dtlssrtptransport.h"
#include "pc/mediasession.h" #include "pc/mediasession.h"
#include "pc/rtptransport.h" #include "pc/rtptransport.h"
@ -48,7 +49,6 @@ class MediaTransportInterface;
namespace cricket { namespace cricket {
struct CryptoParams; struct CryptoParams;
class MediaContentDescription;
// BaseChannel contains logic common to voice and video, including enable, // BaseChannel contains logic common to voice and video, including enable,
// marshaling calls to a worker and network threads, and connection and media // marshaling calls to a worker and network threads, and connection and media
@ -68,7 +68,8 @@ class MediaContentDescription;
// vtable, and the media channel's thread using BaseChannel as the // vtable, and the media channel's thread using BaseChannel as the
// NetworkInterface. // NetworkInterface.
class BaseChannel : public rtc::MessageHandler, class BaseChannel : public ChannelInterface,
public rtc::MessageHandler,
public sigslot::has_slots<>, public sigslot::has_slots<>,
public MediaChannel::NetworkInterface, public MediaChannel::NetworkInterface,
public webrtc::RtpPacketSinkInterface { public webrtc::RtpPacketSinkInterface {
@ -94,10 +95,10 @@ class BaseChannel : public rtc::MessageHandler,
rtc::Thread* worker_thread() const { return worker_thread_; } rtc::Thread* worker_thread() const { return worker_thread_; }
rtc::Thread* network_thread() const { return network_thread_; } rtc::Thread* network_thread() const { return network_thread_; }
const std::string& content_name() const { return content_name_; } const std::string& content_name() const override { return content_name_; }
// TODO(deadbeef): This is redundant; remove this. // TODO(deadbeef): This is redundant; remove this.
const std::string& transport_name() const { return transport_name_; } const std::string& transport_name() const override { return transport_name_; }
bool enabled() const { return enabled_; } bool enabled() const override { return enabled_; }
// This function returns true if using SRTP (DTLS-based keying or SDES). // This function returns true if using SRTP (DTLS-based keying or SDES).
bool srtp_active() const { bool srtp_active() const {
@ -110,17 +111,17 @@ class BaseChannel : public rtc::MessageHandler,
// encryption, an SrtpTransport for SDES or a DtlsSrtpTransport for DTLS-SRTP. // encryption, an SrtpTransport for SDES or a DtlsSrtpTransport for DTLS-SRTP.
// This can be called from any thread and it hops to the network thread // This can be called from any thread and it hops to the network thread
// internally. It would replace the |SetTransports| and its variants. // internally. It would replace the |SetTransports| and its variants.
bool SetRtpTransport(webrtc::RtpTransportInternal* rtp_transport); bool SetRtpTransport(webrtc::RtpTransportInternal* rtp_transport) override;
// Channel control // Channel control
bool SetLocalContent(const MediaContentDescription* content, bool SetLocalContent(const MediaContentDescription* content,
webrtc::SdpType type, webrtc::SdpType type,
std::string* error_desc); std::string* error_desc) override;
bool SetRemoteContent(const MediaContentDescription* content, bool SetRemoteContent(const MediaContentDescription* content,
webrtc::SdpType type, webrtc::SdpType type,
std::string* error_desc); std::string* error_desc) override;
bool Enable(bool enable); bool Enable(bool enable) override;
// TODO(zhihuang): These methods are used for testing and can be removed. // TODO(zhihuang): These methods are used for testing and can be removed.
bool AddRecvStream(const StreamParams& sp); bool AddRecvStream(const StreamParams& sp);
@ -140,7 +141,9 @@ class BaseChannel : public rtc::MessageHandler,
void SignalDtlsSrtpSetupFailure_s(bool rtcp); void SignalDtlsSrtpSetupFailure_s(bool rtcp);
// Used for latency measurements. // Used for latency measurements.
sigslot::signal1<BaseChannel*> SignalFirstPacketReceived; sigslot::signal1<ChannelInterface*>& SignalFirstPacketReceived() override {
return SignalFirstPacketReceived_;
}
// Forward SignalSentPacket to worker thread. // Forward SignalSentPacket to worker thread.
sigslot::signal1<const rtc::SentPacket&> SignalSentPacket; sigslot::signal1<const rtc::SentPacket&> SignalSentPacket;
@ -176,8 +179,6 @@ class BaseChannel : public rtc::MessageHandler,
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); int SetOption_n(SocketType type, rtc::Socket::Option o, int val);
virtual cricket::MediaType media_type() = 0;
// RtpPacketSinkInterface overrides. // RtpPacketSinkInterface overrides.
void OnRtpPacket(const webrtc::RtpPacketReceived& packet) override; void OnRtpPacket(const webrtc::RtpPacketReceived& packet) override;
@ -187,9 +188,9 @@ class BaseChannel : public rtc::MessageHandler,
transport_name_ = transport_name; transport_name_ = transport_name;
} }
protected: MediaChannel* media_channel() const override { return media_channel_.get(); }
virtual MediaChannel* media_channel() const { return media_channel_.get(); }
protected:
bool was_ever_writable() const { return was_ever_writable_; } bool was_ever_writable() const { return was_ever_writable_; }
void set_local_content_direction(webrtc::RtpTransceiverDirection direction) { void set_local_content_direction(webrtc::RtpTransceiverDirection direction) {
local_content_direction_ = direction; local_content_direction_ = direction;
@ -306,6 +307,7 @@ class BaseChannel : public rtc::MessageHandler,
rtc::Thread* const network_thread_; rtc::Thread* const network_thread_;
rtc::Thread* const signaling_thread_; rtc::Thread* const signaling_thread_;
rtc::AsyncInvoker invoker_; rtc::AsyncInvoker invoker_;
sigslot::signal1<ChannelInterface*> SignalFirstPacketReceived_;
const std::string content_name_; const std::string content_name_;
@ -363,7 +365,9 @@ class VoiceChannel : public BaseChannel {
return static_cast<VoiceMediaChannel*>(BaseChannel::media_channel()); return static_cast<VoiceMediaChannel*>(BaseChannel::media_channel());
} }
cricket::MediaType media_type() override { return cricket::MEDIA_TYPE_AUDIO; } cricket::MediaType media_type() const override {
return cricket::MEDIA_TYPE_AUDIO;
}
private: private:
// overrides from BaseChannel // overrides from BaseChannel
@ -402,7 +406,9 @@ class VideoChannel : public BaseChannel {
void FillBitrateInfo(BandwidthEstimationInfo* bwe_info); void FillBitrateInfo(BandwidthEstimationInfo* bwe_info);
cricket::MediaType media_type() override { return cricket::MEDIA_TYPE_VIDEO; } cricket::MediaType media_type() const override {
return cricket::MEDIA_TYPE_VIDEO;
}
private: private:
// overrides from BaseChannel // overrides from BaseChannel
@ -454,7 +460,9 @@ class RtpDataChannel : public BaseChannel {
// That occurs when the channel is enabled, the transport is writable, // That occurs when the channel is enabled, the transport is writable,
// both local and remote descriptions are set, and the channel is unblocked. // both local and remote descriptions are set, and the channel is unblocked.
sigslot::signal1<bool> SignalReadyToSendData; sigslot::signal1<bool> SignalReadyToSendData;
cricket::MediaType media_type() override { return cricket::MEDIA_TYPE_DATA; } cricket::MediaType media_type() const override {
return cricket::MEDIA_TYPE_DATA;
}
protected: protected:
// downcasts a MediaChannel. // downcasts a MediaChannel.

68
pc/channelinterface.h Normal file
View File

@ -0,0 +1,68 @@
/*
* Copyright 2018 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef PC_CHANNELINTERFACE_H_
#define PC_CHANNELINTERFACE_H_
#include <string>
#include "api/jsep.h"
#include "api/mediatypes.h"
#include "media/base/mediachannel.h"
#include "pc/rtptransportinternal.h"
namespace cricket {
class MediaContentDescription;
// ChannelInterface contains methods common to voice, video and data channels.
// As more methods are added to BaseChannel, they should be included in the
// interface as well.
class ChannelInterface {
public:
virtual cricket::MediaType media_type() const = 0;
virtual MediaChannel* media_channel() const = 0;
// TODO(deadbeef): This is redundant; remove this.
virtual const std::string& transport_name() const = 0;
virtual const std::string& content_name() const = 0;
virtual bool enabled() const = 0;
// Enables or disables this channel
virtual bool Enable(bool enable) = 0;
// Used for latency measurements.
virtual sigslot::signal1<ChannelInterface*>& SignalFirstPacketReceived() = 0;
// Channel control
virtual bool SetLocalContent(const MediaContentDescription* content,
webrtc::SdpType type,
std::string* error_desc) = 0;
virtual bool SetRemoteContent(const MediaContentDescription* content,
webrtc::SdpType type,
std::string* error_desc) = 0;
// Set an RTP level transport.
// Some examples:
// * An RtpTransport without encryption.
// * An SrtpTransport for SDES.
// * A DtlsSrtpTransport for DTLS-SRTP.
virtual bool SetRtpTransport(webrtc::RtpTransportInternal* rtp_transport) = 0;
protected:
virtual ~ChannelInterface() = default;
};
} // namespace cricket
#endif // PC_CHANNELINTERFACE_H_

View File

@ -1253,7 +1253,7 @@ PeerConnection::AddTrackPlanB(
auto new_sender = auto new_sender =
CreateSender(media_type, track->id(), track, adjusted_stream_ids, {}); CreateSender(media_type, track->id(), track, adjusted_stream_ids, {});
if (track->kind() == MediaStreamTrackInterface::kAudioKind) { if (track->kind() == MediaStreamTrackInterface::kAudioKind) {
new_sender->internal()->SetVoiceMediaChannel(voice_media_channel()); new_sender->internal()->SetMediaChannel(voice_media_channel());
GetAudioTransceiver()->internal()->AddSender(new_sender); GetAudioTransceiver()->internal()->AddSender(new_sender);
const RtpSenderInfo* sender_info = const RtpSenderInfo* sender_info =
FindSenderInfo(local_audio_sender_infos_, FindSenderInfo(local_audio_sender_infos_,
@ -1263,7 +1263,7 @@ PeerConnection::AddTrackPlanB(
} }
} else { } else {
RTC_DCHECK_EQ(MediaStreamTrackInterface::kVideoKind, track->kind()); RTC_DCHECK_EQ(MediaStreamTrackInterface::kVideoKind, track->kind());
new_sender->internal()->SetVideoMediaChannel(video_media_channel()); new_sender->internal()->SetMediaChannel(video_media_channel());
GetVideoTransceiver()->internal()->AddSender(new_sender); GetVideoTransceiver()->internal()->AddSender(new_sender);
const RtpSenderInfo* sender_info = const RtpSenderInfo* sender_info =
FindSenderInfo(local_video_sender_infos_, FindSenderInfo(local_video_sender_infos_,
@ -1593,14 +1593,14 @@ rtc::scoped_refptr<RtpSenderInterface> PeerConnection::CreateSender(
if (kind == MediaStreamTrackInterface::kAudioKind) { if (kind == MediaStreamTrackInterface::kAudioKind) {
auto* audio_sender = new AudioRtpSender( auto* audio_sender = new AudioRtpSender(
worker_thread(), rtc::CreateRandomUuid(), stats_.get()); worker_thread(), rtc::CreateRandomUuid(), stats_.get());
audio_sender->SetVoiceMediaChannel(voice_media_channel()); audio_sender->SetMediaChannel(voice_media_channel());
new_sender = RtpSenderProxyWithInternal<RtpSenderInternal>::Create( new_sender = RtpSenderProxyWithInternal<RtpSenderInternal>::Create(
signaling_thread(), audio_sender); signaling_thread(), audio_sender);
GetAudioTransceiver()->internal()->AddSender(new_sender); GetAudioTransceiver()->internal()->AddSender(new_sender);
} else if (kind == MediaStreamTrackInterface::kVideoKind) { } else if (kind == MediaStreamTrackInterface::kVideoKind) {
auto* video_sender = auto* video_sender =
new VideoRtpSender(worker_thread(), rtc::CreateRandomUuid()); new VideoRtpSender(worker_thread(), rtc::CreateRandomUuid());
video_sender->SetVideoMediaChannel(video_media_channel()); video_sender->SetMediaChannel(video_media_channel());
new_sender = RtpSenderProxyWithInternal<RtpSenderInternal>::Create( new_sender = RtpSenderProxyWithInternal<RtpSenderInternal>::Create(
signaling_thread(), video_sender); signaling_thread(), video_sender);
GetVideoTransceiver()->internal()->AddSender(new_sender); GetVideoTransceiver()->internal()->AddSender(new_sender);
@ -2736,11 +2736,11 @@ RTCError PeerConnection::UpdateTransceiverChannel(
const cricket::ContentGroup* bundle_group) { const cricket::ContentGroup* bundle_group) {
RTC_DCHECK(IsUnifiedPlan()); RTC_DCHECK(IsUnifiedPlan());
RTC_DCHECK(transceiver); RTC_DCHECK(transceiver);
cricket::BaseChannel* channel = transceiver->internal()->channel(); cricket::ChannelInterface* channel = transceiver->internal()->channel();
if (content.rejected) { if (content.rejected) {
if (channel) { if (channel) {
transceiver->internal()->SetChannel(nullptr); transceiver->internal()->SetChannel(nullptr);
DestroyBaseChannel(channel); DestroyChannelInterface(channel);
} }
} else { } else {
if (!channel) { if (!channel) {
@ -3482,7 +3482,7 @@ void PeerConnection::CreateAudioReceiver(
// the constructor taking stream IDs instead. // the constructor taking stream IDs instead.
auto* audio_receiver = new AudioRtpReceiver( auto* audio_receiver = new AudioRtpReceiver(
worker_thread(), remote_sender_info.sender_id, streams); worker_thread(), remote_sender_info.sender_id, streams);
audio_receiver->SetVoiceMediaChannel(voice_media_channel()); audio_receiver->SetMediaChannel(voice_media_channel());
audio_receiver->SetupMediaChannel(remote_sender_info.first_ssrc); audio_receiver->SetupMediaChannel(remote_sender_info.first_ssrc);
auto receiver = RtpReceiverProxyWithInternal<RtpReceiverInternal>::Create( auto receiver = RtpReceiverProxyWithInternal<RtpReceiverInternal>::Create(
signaling_thread(), audio_receiver); signaling_thread(), audio_receiver);
@ -3500,7 +3500,7 @@ void PeerConnection::CreateVideoReceiver(
// the constructor taking stream IDs instead. // the constructor taking stream IDs instead.
auto* video_receiver = new VideoRtpReceiver( auto* video_receiver = new VideoRtpReceiver(
worker_thread(), remote_sender_info.sender_id, streams); worker_thread(), remote_sender_info.sender_id, streams);
video_receiver->SetVideoMediaChannel(video_media_channel()); video_receiver->SetMediaChannel(video_media_channel());
video_receiver->SetupMediaChannel(remote_sender_info.first_ssrc); video_receiver->SetupMediaChannel(remote_sender_info.first_ssrc);
auto receiver = RtpReceiverProxyWithInternal<RtpReceiverInternal>::Create( auto receiver = RtpReceiverProxyWithInternal<RtpReceiverInternal>::Create(
signaling_thread(), video_receiver); signaling_thread(), video_receiver);
@ -3543,7 +3543,7 @@ void PeerConnection::AddAudioTrack(AudioTrackInterface* track,
// Normal case; we've never seen this track before. // Normal case; we've never seen this track before.
auto new_sender = CreateSender(cricket::MEDIA_TYPE_AUDIO, track->id(), track, auto new_sender = CreateSender(cricket::MEDIA_TYPE_AUDIO, track->id(), track,
{stream->id()}, {}); {stream->id()}, {});
new_sender->internal()->SetVoiceMediaChannel(voice_media_channel()); new_sender->internal()->SetMediaChannel(voice_media_channel());
GetAudioTransceiver()->internal()->AddSender(new_sender); GetAudioTransceiver()->internal()->AddSender(new_sender);
// If the sender has already been configured in SDP, we call SetSsrc, // If the sender has already been configured in SDP, we call SetSsrc,
// which will connect the sender to the underlying transport. This can // which will connect the sender to the underlying transport. This can
@ -3588,7 +3588,7 @@ void PeerConnection::AddVideoTrack(VideoTrackInterface* track,
// Normal case; we've never seen this track before. // Normal case; we've never seen this track before.
auto new_sender = CreateSender(cricket::MEDIA_TYPE_VIDEO, track->id(), track, auto new_sender = CreateSender(cricket::MEDIA_TYPE_VIDEO, track->id(), track,
{stream->id()}, {}); {stream->id()}, {});
new_sender->internal()->SetVideoMediaChannel(video_media_channel()); new_sender->internal()->SetMediaChannel(video_media_channel());
GetVideoTransceiver()->internal()->AddSender(new_sender); GetVideoTransceiver()->internal()->AddSender(new_sender);
const RtpSenderInfo* sender_info = const RtpSenderInfo* sender_info =
FindSenderInfo(local_video_sender_infos_, stream->id(), track->id()); FindSenderInfo(local_video_sender_infos_, stream->id(), track->id());
@ -4966,10 +4966,10 @@ void PeerConnection::StopRtcEventLog_w() {
} }
} }
cricket::BaseChannel* PeerConnection::GetChannel( cricket::ChannelInterface* PeerConnection::GetChannel(
const std::string& content_name) { const std::string& content_name) {
for (auto transceiver : transceivers_) { for (auto transceiver : transceivers_) {
cricket::BaseChannel* channel = transceiver->internal()->channel(); cricket::ChannelInterface* channel = transceiver->internal()->channel();
if (channel && channel->content_name() == content_name) { if (channel && channel->content_name() == content_name) {
return channel; return channel;
} }
@ -5086,7 +5086,7 @@ RTCError PeerConnection::PushdownMediaDescription(
for (auto transceiver : transceivers_) { for (auto transceiver : transceivers_) {
const ContentInfo* content_info = const ContentInfo* content_info =
FindMediaSectionForTransceiver(transceiver, sdesc); FindMediaSectionForTransceiver(transceiver, sdesc);
cricket::BaseChannel* channel = transceiver->internal()->channel(); cricket::ChannelInterface* channel = transceiver->internal()->channel();
if (!channel || !content_info || content_info->rejected) { if (!channel || !content_info || content_info->rejected) {
continue; continue;
} }
@ -5421,7 +5421,7 @@ std::map<std::string, std::string> PeerConnection::GetTransportNamesByMid()
const { const {
std::map<std::string, std::string> transport_names_by_mid; std::map<std::string, std::string> transport_names_by_mid;
for (auto transceiver : transceivers_) { for (auto transceiver : transceivers_) {
cricket::BaseChannel* channel = transceiver->internal()->channel(); cricket::ChannelInterface* channel = transceiver->internal()->channel();
if (channel) { if (channel) {
transport_names_by_mid[channel->content_name()] = transport_names_by_mid[channel->content_name()] =
channel->transport_name(); channel->transport_name();
@ -5598,7 +5598,7 @@ void PeerConnection::OnTransportControllerDtlsHandshakeError(
void PeerConnection::EnableSending() { void PeerConnection::EnableSending() {
for (auto transceiver : transceivers_) { for (auto transceiver : transceivers_) {
cricket::BaseChannel* channel = transceiver->internal()->channel(); cricket::ChannelInterface* channel = transceiver->internal()->channel();
if (channel && !channel->enabled()) { if (channel && !channel->enabled()) {
channel->Enable(true); channel->Enable(true);
} }
@ -6484,7 +6484,7 @@ void PeerConnection::OnSentPacket_w(const rtc::SentPacket& sent_packet) {
const std::string PeerConnection::GetTransportName( const std::string PeerConnection::GetTransportName(
const std::string& content_name) { const std::string& content_name) {
cricket::BaseChannel* channel = GetChannel(content_name); cricket::ChannelInterface* channel = GetChannel(content_name);
if (channel) { if (channel) {
return channel->transport_name(); return channel->transport_name();
} }
@ -6503,17 +6503,17 @@ void PeerConnection::DestroyTransceiverChannel(
transceiver) { transceiver) {
RTC_DCHECK(transceiver); RTC_DCHECK(transceiver);
cricket::BaseChannel* channel = transceiver->internal()->channel(); cricket::ChannelInterface* channel = transceiver->internal()->channel();
if (channel) { if (channel) {
transceiver->internal()->SetChannel(nullptr); transceiver->internal()->SetChannel(nullptr);
DestroyBaseChannel(channel); DestroyChannelInterface(channel);
} }
} }
void PeerConnection::DestroyDataChannel() { void PeerConnection::DestroyDataChannel() {
if (rtp_data_channel_) { if (rtp_data_channel_) {
OnDataChannelDestroyed(); OnDataChannelDestroyed();
DestroyBaseChannel(rtp_data_channel_); DestroyChannelInterface(rtp_data_channel_);
rtp_data_channel_ = nullptr; rtp_data_channel_ = nullptr;
} }
@ -6538,7 +6538,8 @@ void PeerConnection::DestroyDataChannel() {
} }
} }
void PeerConnection::DestroyBaseChannel(cricket::BaseChannel* channel) { void PeerConnection::DestroyChannelInterface(
cricket::ChannelInterface* channel) {
RTC_DCHECK(channel); RTC_DCHECK(channel);
switch (channel->media_type()) { switch (channel->media_type()) {
case cricket::MEDIA_TYPE_AUDIO: case cricket::MEDIA_TYPE_AUDIO:

View File

@ -719,7 +719,7 @@ class PeerConnection : public PeerConnectionInternal,
SessionError session_error() const { return session_error_; } SessionError session_error() const { return session_error_; }
const std::string& session_error_desc() const { return session_error_desc_; } const std::string& session_error_desc() const { return session_error_desc_; }
cricket::BaseChannel* GetChannel(const std::string& content_name); cricket::ChannelInterface* GetChannel(const std::string& content_name);
// Get current SSL role used by SCTP's underlying transport. // Get current SSL role used by SCTP's underlying transport.
bool GetSctpSslRole(rtc::SSLRole* role); bool GetSctpSslRole(rtc::SSLRole* role);
@ -922,9 +922,9 @@ class PeerConnection : public PeerConnectionInternal,
// Destroys the RTP data channel and/or the SCTP data channel and clears it. // Destroys the RTP data channel and/or the SCTP data channel and clears it.
void DestroyDataChannel(); void DestroyDataChannel();
// Destroys the given BaseChannel. The channel cannot be accessed after this // Destroys the given ChannelInterface.
// method is called. // The channel cannot be accessed after this method is called.
void DestroyBaseChannel(cricket::BaseChannel* channel); void DestroyChannelInterface(cricket::ChannelInterface* channel);
// JsepTransportController::Observer override. // JsepTransportController::Observer override.
// //

View File

@ -212,7 +212,12 @@ class PeerConnectionIceBaseTest : public ::testing::Test {
PeerConnection* pc = static_cast<PeerConnection*>(pc_proxy->internal()); PeerConnection* pc = static_cast<PeerConnection*>(pc_proxy->internal());
for (auto transceiver : pc->GetTransceiversInternal()) { for (auto transceiver : pc->GetTransceiversInternal()) {
if (transceiver->media_type() == cricket::MEDIA_TYPE_AUDIO) { if (transceiver->media_type() == cricket::MEDIA_TYPE_AUDIO) {
cricket::BaseChannel* channel = transceiver->internal()->channel(); // TODO(amithi): This test seems to be using a method that should not
// be public |rtp_packet_transport|. Because the test is not mocking
// the channels or transceiver, workaround will be to |static_cast|
// the channel until the method is rewritten.
cricket::BaseChannel* channel = static_cast<cricket::BaseChannel*>(
transceiver->internal()->channel());
if (channel) { if (channel) {
auto dtls_transport = static_cast<cricket::DtlsTransportInternal*>( auto dtls_transport = static_cast<cricket::DtlsTransportInternal*>(
channel->rtp_packet_transport()); channel->rtp_packet_transport());

View File

@ -1426,7 +1426,7 @@ RTCStatsCollector::PrepareTransceiverStatsInfos_s() const {
stats.transceiver = transceiver->internal(); stats.transceiver = transceiver->internal();
stats.media_type = media_type; stats.media_type = media_type;
cricket::BaseChannel* channel = transceiver->internal()->channel(); cricket::ChannelInterface* channel = transceiver->internal()->channel();
if (!channel) { if (!channel) {
// The remaining fields require a BaseChannel. // The remaining fields require a BaseChannel.
continue; continue;

View File

@ -268,9 +268,10 @@ void AudioRtpReceiver::SetObserver(RtpReceiverObserverInterface* observer) {
} }
} }
void AudioRtpReceiver::SetVoiceMediaChannel( void AudioRtpReceiver::SetMediaChannel(cricket::MediaChannel* media_channel) {
cricket::VoiceMediaChannel* voice_media_channel) { RTC_DCHECK(media_channel == nullptr ||
media_channel_ = voice_media_channel; media_channel->media_type() == media_type());
media_channel_ = static_cast<cricket::VoiceMediaChannel*>(media_channel);
} }
void AudioRtpReceiver::NotifyFirstPacketReceived() { void AudioRtpReceiver::NotifyFirstPacketReceived() {
@ -443,9 +444,10 @@ void VideoRtpReceiver::SetObserver(RtpReceiverObserverInterface* observer) {
} }
} }
void VideoRtpReceiver::SetVideoMediaChannel( void VideoRtpReceiver::SetMediaChannel(cricket::MediaChannel* media_channel) {
cricket::VideoMediaChannel* video_media_channel) { RTC_DCHECK(media_channel == nullptr ||
media_channel_ = video_media_channel; media_channel->media_type() == media_type());
media_channel_ = static_cast<cricket::VideoMediaChannel*>(media_channel);
} }
void VideoRtpReceiver::NotifyFirstPacketReceived() { void VideoRtpReceiver::NotifyFirstPacketReceived() {

View File

@ -34,14 +34,10 @@ class RtpReceiverInternal : public RtpReceiverInterface {
virtual void Stop() = 0; virtual void Stop() = 0;
// Sets the underlying MediaEngine channel associated with this RtpSender. // Sets the underlying MediaEngine channel associated with this RtpSender.
// SetVoiceMediaChannel should be used for audio RtpSenders and // A VoiceMediaChannel should be used for audio RtpSenders and
// SetVideoMediaChannel should be used for video RtpSenders. Must call the // a VideoMediaChannel should be used for video RtpSenders.
// appropriate SetXxxMediaChannel(nullptr) before the media channel is // Must call SetMediaChannel(nullptr) before the media channel is destroyed.
// destroyed. virtual void SetMediaChannel(cricket::MediaChannel* media_channel) = 0;
virtual void SetVoiceMediaChannel(
cricket::VoiceMediaChannel* voice_media_channel) = 0;
virtual void SetVideoMediaChannel(
cricket::VideoMediaChannel* video_media_channel) = 0;
// Configures the RtpReceiver with the underlying media channel, with the // Configures the RtpReceiver with the underlying media channel, with the
// given SSRC as the stream identifier. If |ssrc| is 0, the receiver will // given SSRC as the stream identifier. If |ssrc| is 0, the receiver will
@ -130,13 +126,8 @@ class AudioRtpReceiver : public ObserverInterface,
void SetStreams(const std::vector<rtc::scoped_refptr<MediaStreamInterface>>& void SetStreams(const std::vector<rtc::scoped_refptr<MediaStreamInterface>>&
streams) override; streams) override;
void SetObserver(RtpReceiverObserverInterface* observer) override; void SetObserver(RtpReceiverObserverInterface* observer) override;
void SetVoiceMediaChannel(
cricket::VoiceMediaChannel* voice_media_channel) override;
void SetVideoMediaChannel( void SetMediaChannel(cricket::MediaChannel* media_channel) override;
cricket::VideoMediaChannel* video_media_channel) override {
RTC_NOTREACHED();
}
std::vector<RtpSource> GetSources() const override; std::vector<RtpSource> GetSources() const override;
int AttachmentId() const override { return attachment_id_; } int AttachmentId() const override { return attachment_id_; }
@ -217,13 +208,7 @@ class VideoRtpReceiver : public rtc::RefCountedObject<RtpReceiverInternal> {
void SetObserver(RtpReceiverObserverInterface* observer) override; void SetObserver(RtpReceiverObserverInterface* observer) override;
void SetVoiceMediaChannel( void SetMediaChannel(cricket::MediaChannel* media_channel) override;
cricket::VoiceMediaChannel* voice_media_channel) override {
RTC_NOTREACHED();
}
void SetVideoMediaChannel(
cricket::VideoMediaChannel* video_media_channel) override;
int AttachmentId() const override { return attachment_id_; } int AttachmentId() const override { return attachment_id_; }

View File

@ -386,9 +386,10 @@ void AudioRtpSender::Stop() {
stopped_ = true; stopped_ = true;
} }
void AudioRtpSender::SetVoiceMediaChannel( void AudioRtpSender::SetMediaChannel(cricket::MediaChannel* media_channel) {
cricket::VoiceMediaChannel* voice_media_channel) { RTC_DCHECK(media_channel == nullptr ||
media_channel_ = voice_media_channel; media_channel->media_type() == media_type());
media_channel_ = static_cast<cricket::VoiceMediaChannel*>(media_channel);
} }
void AudioRtpSender::SetAudioSend() { void AudioRtpSender::SetAudioSend() {
@ -629,9 +630,10 @@ void VideoRtpSender::Stop() {
stopped_ = true; stopped_ = true;
} }
void VideoRtpSender::SetVideoMediaChannel( void VideoRtpSender::SetMediaChannel(cricket::MediaChannel* media_channel) {
cricket::VideoMediaChannel* video_media_channel) { RTC_DCHECK(media_channel == nullptr ||
media_channel_ = video_media_channel; media_channel->media_type() == media_type());
media_channel_ = static_cast<cricket::VideoMediaChannel*>(media_channel);
} }
void VideoRtpSender::SetVideoSend() { void VideoRtpSender::SetVideoSend() {

View File

@ -36,14 +36,10 @@ bool UnimplementedRtpParameterHasValue(const RtpParameters& parameters);
class RtpSenderInternal : public RtpSenderInterface { class RtpSenderInternal : public RtpSenderInterface {
public: public:
// Sets the underlying MediaEngine channel associated with this RtpSender. // Sets the underlying MediaEngine channel associated with this RtpSender.
// SetVoiceMediaChannel should be used for audio RtpSenders and // A VoiceMediaChannel should be used for audio RtpSenders and
// SetVideoMediaChannel should be used for video RtpSenders. Must call the // a VideoMediaChannel should be used for video RtpSenders.
// appropriate SetXxxMediaChannel(nullptr) before the media channel is // Must call SetMediaChannel(nullptr) before the media channel is destroyed.
// destroyed. virtual void SetMediaChannel(cricket::MediaChannel* media_channel) = 0;
virtual void SetVoiceMediaChannel(
cricket::VoiceMediaChannel* voice_media_channel) = 0;
virtual void SetVideoMediaChannel(
cricket::VideoMediaChannel* video_media_channel) = 0;
// Used to set the SSRC of the sender, once a local description has been set. // Used to set the SSRC of the sender, once a local description has been set.
// If |ssrc| is 0, this indiates that the sender should disconnect from the // If |ssrc| is 0, this indiates that the sender should disconnect from the
@ -156,13 +152,7 @@ class AudioRtpSender : public DtmfProviderInterface,
int AttachmentId() const override { return attachment_id_; } int AttachmentId() const override { return attachment_id_; }
void SetVoiceMediaChannel( void SetMediaChannel(cricket::MediaChannel* media_channel) override;
cricket::VoiceMediaChannel* voice_media_channel) override;
void SetVideoMediaChannel(
cricket::VideoMediaChannel* video_media_channel) override {
RTC_NOTREACHED();
}
private: private:
// TODO(nisse): Since SSRC == 0 is technically valid, figure out // TODO(nisse): Since SSRC == 0 is technically valid, figure out
@ -253,13 +243,7 @@ class VideoRtpSender : public ObserverInterface,
void Stop() override; void Stop() override;
int AttachmentId() const override { return attachment_id_; } int AttachmentId() const override { return attachment_id_; }
void SetVoiceMediaChannel( void SetMediaChannel(cricket::MediaChannel* media_channel) override;
cricket::VoiceMediaChannel* voice_media_channel) override {
RTC_NOTREACHED();
}
void SetVideoMediaChannel(
cricket::VideoMediaChannel* video_media_channel) override;
private: private:
bool can_send_track() const { return track_ && ssrc_; } bool can_send_track() const { return track_ && ssrc_; }

View File

@ -154,7 +154,7 @@ class RtpSenderReceiverTest : public testing::Test,
new AudioRtpSender(worker_thread_, audio_track_->id(), nullptr); new AudioRtpSender(worker_thread_, audio_track_->id(), nullptr);
ASSERT_TRUE(audio_rtp_sender_->SetTrack(audio_track_)); ASSERT_TRUE(audio_rtp_sender_->SetTrack(audio_track_));
audio_rtp_sender_->set_stream_ids({local_stream_->id()}); audio_rtp_sender_->set_stream_ids({local_stream_->id()});
audio_rtp_sender_->SetVoiceMediaChannel(voice_media_channel_); audio_rtp_sender_->SetMediaChannel(voice_media_channel_);
audio_rtp_sender_->SetSsrc(kAudioSsrc); audio_rtp_sender_->SetSsrc(kAudioSsrc);
audio_rtp_sender_->GetOnDestroyedSignal()->connect( audio_rtp_sender_->GetOnDestroyedSignal()->connect(
this, &RtpSenderReceiverTest::OnAudioSenderDestroyed); this, &RtpSenderReceiverTest::OnAudioSenderDestroyed);
@ -163,7 +163,7 @@ class RtpSenderReceiverTest : public testing::Test,
void CreateAudioRtpSenderWithNoTrack() { void CreateAudioRtpSenderWithNoTrack() {
audio_rtp_sender_ = new AudioRtpSender(worker_thread_, /*id=*/"", nullptr); audio_rtp_sender_ = new AudioRtpSender(worker_thread_, /*id=*/"", nullptr);
audio_rtp_sender_->SetVoiceMediaChannel(voice_media_channel_); audio_rtp_sender_->SetMediaChannel(voice_media_channel_);
} }
void OnAudioSenderDestroyed() { audio_sender_destroyed_signal_fired_ = true; } void OnAudioSenderDestroyed() { audio_sender_destroyed_signal_fired_ = true; }
@ -191,13 +191,13 @@ class RtpSenderReceiverTest : public testing::Test,
video_rtp_sender_ = new VideoRtpSender(worker_thread_, video_track_->id()); video_rtp_sender_ = new VideoRtpSender(worker_thread_, video_track_->id());
ASSERT_TRUE(video_rtp_sender_->SetTrack(video_track_)); ASSERT_TRUE(video_rtp_sender_->SetTrack(video_track_));
video_rtp_sender_->set_stream_ids({local_stream_->id()}); video_rtp_sender_->set_stream_ids({local_stream_->id()});
video_rtp_sender_->SetVideoMediaChannel(video_media_channel_); video_rtp_sender_->SetMediaChannel(video_media_channel_);
video_rtp_sender_->SetSsrc(ssrc); video_rtp_sender_->SetSsrc(ssrc);
VerifyVideoChannelInput(ssrc); VerifyVideoChannelInput(ssrc);
} }
void CreateVideoRtpSenderWithNoTrack() { void CreateVideoRtpSenderWithNoTrack() {
video_rtp_sender_ = new VideoRtpSender(worker_thread_, /*id=*/""); video_rtp_sender_ = new VideoRtpSender(worker_thread_, /*id=*/"");
video_rtp_sender_->SetVideoMediaChannel(video_media_channel_); video_rtp_sender_->SetMediaChannel(video_media_channel_);
} }
void DestroyAudioRtpSender() { void DestroyAudioRtpSender() {
@ -214,7 +214,7 @@ class RtpSenderReceiverTest : public testing::Test,
std::vector<rtc::scoped_refptr<MediaStreamInterface>> streams = {}) { std::vector<rtc::scoped_refptr<MediaStreamInterface>> streams = {}) {
audio_rtp_receiver_ = new AudioRtpReceiver( audio_rtp_receiver_ = new AudioRtpReceiver(
rtc::Thread::Current(), kAudioTrackId, std::move(streams)); rtc::Thread::Current(), kAudioTrackId, std::move(streams));
audio_rtp_receiver_->SetVoiceMediaChannel(voice_media_channel_); audio_rtp_receiver_->SetMediaChannel(voice_media_channel_);
audio_rtp_receiver_->SetupMediaChannel(kAudioSsrc); audio_rtp_receiver_->SetupMediaChannel(kAudioSsrc);
audio_track_ = audio_rtp_receiver_->audio_track(); audio_track_ = audio_rtp_receiver_->audio_track();
VerifyVoiceChannelOutput(); VerifyVoiceChannelOutput();
@ -224,7 +224,7 @@ class RtpSenderReceiverTest : public testing::Test,
std::vector<rtc::scoped_refptr<MediaStreamInterface>> streams = {}) { std::vector<rtc::scoped_refptr<MediaStreamInterface>> streams = {}) {
video_rtp_receiver_ = new VideoRtpReceiver( video_rtp_receiver_ = new VideoRtpReceiver(
rtc::Thread::Current(), kVideoTrackId, std::move(streams)); rtc::Thread::Current(), kVideoTrackId, std::move(streams));
video_rtp_receiver_->SetVideoMediaChannel(video_media_channel_); video_rtp_receiver_->SetMediaChannel(video_media_channel_);
video_rtp_receiver_->SetupMediaChannel(kVideoSsrc); video_rtp_receiver_->SetupMediaChannel(kVideoSsrc);
video_track_ = video_rtp_receiver_->video_track(); video_track_ = video_rtp_receiver_->video_track();
VerifyVideoChannelOutput(); VerifyVideoChannelOutput();
@ -664,7 +664,7 @@ TEST_F(RtpSenderReceiverTest, AudioSenderInitParametersMovedAfterNegotiation) {
cricket::StreamParams stream_params = cricket::StreamParams stream_params =
cricket::CreateSimStreamParams("cname", ssrcs); cricket::CreateSimStreamParams("cname", ssrcs);
voice_media_channel_->AddSendStream(stream_params); voice_media_channel_->AddSendStream(stream_params);
audio_rtp_sender_->SetVoiceMediaChannel(voice_media_channel_); audio_rtp_sender_->SetMediaChannel(voice_media_channel_);
audio_rtp_sender_->SetSsrc(1); audio_rtp_sender_->SetSsrc(1);
params = audio_rtp_sender_->GetParameters(); params = audio_rtp_sender_->GetParameters();
@ -903,7 +903,7 @@ TEST_F(RtpSenderReceiverTest, VideoSenderInitParametersMovedAfterNegotiation) {
cricket::StreamParams stream_params = cricket::StreamParams stream_params =
cricket::CreateSimStreamParams("cname", ssrcs); cricket::CreateSimStreamParams("cname", ssrcs);
video_media_channel_->AddSendStream(stream_params); video_media_channel_->AddSendStream(stream_params);
video_rtp_sender_->SetVideoMediaChannel(video_media_channel_); video_rtp_sender_->SetMediaChannel(video_media_channel_);
video_rtp_sender_->SetSsrc(kVideoSsrcSimulcast); video_rtp_sender_->SetSsrc(kVideoSsrcSimulcast);
params = video_rtp_sender_->GetParameters(); params = video_rtp_sender_->GetParameters();
@ -938,7 +938,7 @@ TEST_F(RtpSenderReceiverTest,
cricket::StreamParams stream_params = cricket::StreamParams stream_params =
cricket::CreateSimStreamParams("cname", ssrcs); cricket::CreateSimStreamParams("cname", ssrcs);
video_media_channel_->AddSendStream(stream_params); video_media_channel_->AddSendStream(stream_params);
video_rtp_sender_->SetVideoMediaChannel(video_media_channel_); video_rtp_sender_->SetMediaChannel(video_media_channel_);
video_rtp_sender_->SetSsrc(kVideoSsrcSimulcast); video_rtp_sender_->SetSsrc(kVideoSsrcSimulcast);
params = video_rtp_sender_->GetParameters(); params = video_rtp_sender_->GetParameters();
@ -1332,7 +1332,7 @@ TEST_F(RtpSenderReceiverTest,
video_rtp_sender_ = new VideoRtpSender(worker_thread_, video_track_->id()); video_rtp_sender_ = new VideoRtpSender(worker_thread_, video_track_->id());
ASSERT_TRUE(video_rtp_sender_->SetTrack(video_track_)); ASSERT_TRUE(video_rtp_sender_->SetTrack(video_track_));
video_rtp_sender_->set_stream_ids({local_stream_->id()}); video_rtp_sender_->set_stream_ids({local_stream_->id()});
video_rtp_sender_->SetVideoMediaChannel(video_media_channel_); video_rtp_sender_->SetMediaChannel(video_media_channel_);
video_track_->set_enabled(true); video_track_->set_enabled(true);
// Sender is not ready to send (no SSRC) so no option should have been set. // Sender is not ready to send (no SSRC) so no option should have been set.

View File

@ -38,52 +38,45 @@ RtpTransceiver::~RtpTransceiver() {
Stop(); Stop();
} }
void RtpTransceiver::SetChannel(cricket::BaseChannel* channel) { void RtpTransceiver::SetChannel(cricket::ChannelInterface* channel) {
// Cannot set a non-null channel on a stopped transceiver.
if (stopped_ && channel) {
return;
}
if (channel) { if (channel) {
RTC_DCHECK_EQ(media_type(), channel->media_type()); RTC_DCHECK_EQ(media_type(), channel->media_type());
} }
if (channel_) { if (channel_) {
channel_->SignalFirstPacketReceived.disconnect(this); channel_->SignalFirstPacketReceived().disconnect(this);
} }
channel_ = channel; channel_ = channel;
if (channel_) { if (channel_) {
channel_->SignalFirstPacketReceived.connect( channel_->SignalFirstPacketReceived().connect(
this, &RtpTransceiver::OnFirstPacketReceived); this, &RtpTransceiver::OnFirstPacketReceived);
} }
for (auto sender : senders_) { for (auto sender : senders_) {
if (media_type() == cricket::MEDIA_TYPE_AUDIO) { sender->internal()->SetMediaChannel(channel_ ? channel_->media_channel()
auto* voice_channel = static_cast<cricket::VoiceChannel*>(channel); : nullptr);
sender->internal()->SetVoiceMediaChannel(
voice_channel ? voice_channel->media_channel() : nullptr);
} else {
auto* video_channel = static_cast<cricket::VideoChannel*>(channel);
sender->internal()->SetVideoMediaChannel(
video_channel ? video_channel->media_channel() : nullptr);
}
} }
for (auto receiver : receivers_) { for (auto receiver : receivers_) {
if (!channel) { if (!channel_) {
receiver->internal()->Stop(); receiver->internal()->Stop();
} }
if (media_type() == cricket::MEDIA_TYPE_AUDIO) {
auto* voice_channel = static_cast<cricket::VoiceChannel*>(channel); receiver->internal()->SetMediaChannel(channel_ ? channel_->media_channel()
receiver->internal()->SetVoiceMediaChannel( : nullptr);
voice_channel ? voice_channel->media_channel() : nullptr);
} else {
auto* video_channel = static_cast<cricket::VideoChannel*>(channel);
receiver->internal()->SetVideoMediaChannel(
video_channel ? video_channel->media_channel() : nullptr);
}
} }
} }
void RtpTransceiver::AddSender( void RtpTransceiver::AddSender(
rtc::scoped_refptr<RtpSenderProxyWithInternal<RtpSenderInternal>> sender) { rtc::scoped_refptr<RtpSenderProxyWithInternal<RtpSenderInternal>> sender) {
RTC_DCHECK(!stopped_);
RTC_DCHECK(!unified_plan_); RTC_DCHECK(!unified_plan_);
RTC_DCHECK(sender); RTC_DCHECK(sender);
RTC_DCHECK_EQ(media_type(), sender->media_type()); RTC_DCHECK_EQ(media_type(), sender->media_type());
@ -109,6 +102,7 @@ bool RtpTransceiver::RemoveSender(RtpSenderInterface* sender) {
void RtpTransceiver::AddReceiver( void RtpTransceiver::AddReceiver(
rtc::scoped_refptr<RtpReceiverProxyWithInternal<RtpReceiverInternal>> rtc::scoped_refptr<RtpReceiverProxyWithInternal<RtpReceiverInternal>>
receiver) { receiver) {
RTC_DCHECK(!stopped_);
RTC_DCHECK(!unified_plan_); RTC_DCHECK(!unified_plan_);
RTC_DCHECK(receiver); RTC_DCHECK(receiver);
RTC_DCHECK_EQ(media_type(), receiver->media_type()); RTC_DCHECK_EQ(media_type(), receiver->media_type());
@ -152,7 +146,7 @@ absl::optional<std::string> RtpTransceiver::mid() const {
return mid_; return mid_;
} }
void RtpTransceiver::OnFirstPacketReceived(cricket::BaseChannel* channel) { void RtpTransceiver::OnFirstPacketReceived(cricket::ChannelInterface*) {
for (auto receiver : receivers_) { for (auto receiver : receivers_) {
receiver->internal()->NotifyFirstPacketReceived(); receiver->internal()->NotifyFirstPacketReceived();
} }

View File

@ -70,11 +70,11 @@ class RtpTransceiver final
// Returns the Voice/VideoChannel set for this transceiver. May be null if // Returns the Voice/VideoChannel set for this transceiver. May be null if
// the transceiver is not in the currently set local/remote description. // the transceiver is not in the currently set local/remote description.
cricket::BaseChannel* channel() const { return channel_; } cricket::ChannelInterface* channel() const { return channel_; }
// Sets the Voice/VideoChannel. The caller must pass in the correct channel // Sets the Voice/VideoChannel. The caller must pass in the correct channel
// implementation based on the type of the transceiver. // implementation based on the type of the transceiver.
void SetChannel(cricket::BaseChannel* channel); void SetChannel(cricket::ChannelInterface* channel);
// Adds an RtpSender of the appropriate type to be owned by this transceiver. // Adds an RtpSender of the appropriate type to be owned by this transceiver.
// Must not be null. // Must not be null.
@ -177,7 +177,7 @@ class RtpTransceiver final
void SetCodecPreferences(rtc::ArrayView<RtpCodecCapability> codecs) override; void SetCodecPreferences(rtc::ArrayView<RtpCodecCapability> codecs) override;
private: private:
void OnFirstPacketReceived(cricket::BaseChannel* channel); void OnFirstPacketReceived(cricket::ChannelInterface* channel);
const bool unified_plan_; const bool unified_plan_;
const cricket::MediaType media_type_; const cricket::MediaType media_type_;
@ -196,7 +196,7 @@ class RtpTransceiver final
bool created_by_addtrack_ = false; bool created_by_addtrack_ = false;
bool has_ever_been_used_to_send_ = false; bool has_ever_been_used_to_send_ = false;
cricket::BaseChannel* channel_ = nullptr; cricket::ChannelInterface* channel_ = nullptr;
}; };
BEGIN_SIGNALING_PROXY_MAP(RtpTransceiver) BEGIN_SIGNALING_PROXY_MAP(RtpTransceiver)

View File

@ -0,0 +1,71 @@
/*
* Copyright 2018 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
// This file contains tests for |RtpTransceiver|.
#include "pc/rtptransceiver.h"
#include "rtc_base/gunit.h"
#include "test/gmock.h"
#include "test/mock_channelinterface.h"
using ::testing::Return;
using ::testing::ReturnRef;
namespace webrtc {
// Checks that a channel cannot be set on a stopped |RtpTransceiver|.
TEST(RtpTransceiverTest, CannotSetChannelOnStoppedTransceiver) {
RtpTransceiver transceiver(cricket::MediaType::MEDIA_TYPE_AUDIO);
cricket::MockChannelInterface channel1;
sigslot::signal1<cricket::ChannelInterface*> signal;
EXPECT_CALL(channel1, media_type())
.WillRepeatedly(Return(cricket::MediaType::MEDIA_TYPE_AUDIO));
EXPECT_CALL(channel1, SignalFirstPacketReceived())
.WillRepeatedly(ReturnRef(signal));
transceiver.SetChannel(&channel1);
EXPECT_EQ(&channel1, transceiver.channel());
// Stop the transceiver.
transceiver.Stop();
EXPECT_EQ(&channel1, transceiver.channel());
cricket::MockChannelInterface channel2;
EXPECT_CALL(channel2, media_type())
.WillRepeatedly(Return(cricket::MediaType::MEDIA_TYPE_AUDIO));
// Channel can no longer be set, so this call should be a no-op.
transceiver.SetChannel(&channel2);
EXPECT_EQ(&channel1, transceiver.channel());
}
// Checks that a channel can be unset on a stopped |RtpTransceiver|
TEST(RtpTransceiverTest, CanUnsetChannelOnStoppedTransceiver) {
RtpTransceiver transceiver(cricket::MediaType::MEDIA_TYPE_VIDEO);
cricket::MockChannelInterface channel;
sigslot::signal1<cricket::ChannelInterface*> signal;
EXPECT_CALL(channel, media_type())
.WillRepeatedly(Return(cricket::MediaType::MEDIA_TYPE_VIDEO));
EXPECT_CALL(channel, SignalFirstPacketReceived())
.WillRepeatedly(ReturnRef(signal));
transceiver.SetChannel(&channel);
EXPECT_EQ(&channel, transceiver.channel());
// Stop the transceiver.
transceiver.Stop();
EXPECT_EQ(&channel, transceiver.channel());
// Set the channel to |nullptr|.
transceiver.SetChannel(nullptr);
EXPECT_EQ(nullptr, transceiver.channel());
}
} // namespace webrtc

View File

@ -0,0 +1,47 @@
/*
* Copyright 2018 The WebRTC project authors. All Rights Reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
#ifndef PC_TEST_MOCK_CHANNELINTERFACE_H_
#define PC_TEST_MOCK_CHANNELINTERFACE_H_
#include <string>
#include "pc/channelinterface.h"
#include "test/gmock.h"
namespace cricket {
// Mock class for BaseChannel.
// Use this class in unit tests to avoid dependecy on a specific
// implementation of BaseChannel.
class MockChannelInterface : public cricket::ChannelInterface {
public:
MOCK_CONST_METHOD0(media_type, cricket::MediaType());
MOCK_CONST_METHOD0(media_channel, MediaChannel*());
MOCK_CONST_METHOD0(transport_name, const std::string&());
MOCK_CONST_METHOD0(content_name, const std::string&());
MOCK_CONST_METHOD0(enabled, bool());
MOCK_METHOD1(Enable, bool(bool));
MOCK_METHOD0(SignalFirstPacketReceived,
sigslot::signal1<ChannelInterface*>&());
MOCK_METHOD3(SetLocalContent,
bool(const cricket::MediaContentDescription*,
webrtc::SdpType,
std::string*));
MOCK_METHOD3(SetRemoteContent,
bool(const cricket::MediaContentDescription*,
webrtc::SdpType,
std::string*));
MOCK_METHOD1(SetRtpTransport, bool(webrtc::RtpTransportInternal*));
};
} // namespace cricket
#endif // PC_TEST_MOCK_CHANNELINTERFACE_H_

View File

@ -41,8 +41,7 @@ class MockRtpReceiverInternal : public RtpReceiverInternal {
// RtpReceiverInternal methods. // RtpReceiverInternal methods.
MOCK_METHOD0(Stop, void()); MOCK_METHOD0(Stop, void());
MOCK_METHOD1(SetVoiceMediaChannel, void(cricket::VoiceMediaChannel*)); MOCK_METHOD1(SetMediaChannel, void(cricket::MediaChannel*));
MOCK_METHOD1(SetVideoMediaChannel, void(cricket::VideoMediaChannel*));
MOCK_METHOD1(SetupMediaChannel, void(uint32_t)); MOCK_METHOD1(SetupMediaChannel, void(uint32_t));
MOCK_CONST_METHOD0(ssrc, uint32_t()); MOCK_CONST_METHOD0(ssrc, uint32_t());
MOCK_METHOD0(NotifyFirstPacketReceived, void()); MOCK_METHOD0(NotifyFirstPacketReceived, void());

View File

@ -39,8 +39,7 @@ class MockRtpSenderInternal : public RtpSenderInternal {
rtc::scoped_refptr<FrameEncryptorInterface>()); rtc::scoped_refptr<FrameEncryptorInterface>());
// RtpSenderInternal methods. // RtpSenderInternal methods.
MOCK_METHOD1(SetVoiceMediaChannel, void(cricket::VoiceMediaChannel*)); MOCK_METHOD1(SetMediaChannel, void(cricket::MediaChannel*));
MOCK_METHOD1(SetVideoMediaChannel, void(cricket::VideoMediaChannel*));
MOCK_METHOD1(SetSsrc, void(uint32_t)); MOCK_METHOD1(SetSsrc, void(uint32_t));
MOCK_METHOD1(set_stream_ids, void(const std::vector<std::string>&)); MOCK_METHOD1(set_stream_ids, void(const std::vector<std::string>&));
MOCK_METHOD1(set_init_send_encodings, MOCK_METHOD1(set_init_send_encodings,