Change MediaChannel to have a Role parameter

This allows MediaChannel to know whether it's being used
for sending, receiving, or both. This is a preparatory CL
for landing the split of MediaChannel usage into sending and
receiving objects.

Bug: webrtc:13931
Change-Id: If518c8b53d5256771200a42e1b5f2b3321d26d8c
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/292860
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Commit-Queue: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#39283}
This commit is contained in:
Harald Alvestrand 2023-02-09 13:01:24 +00:00 committed by WebRTC LUCI CQ
parent d59c0c35c6
commit 16579cc81d
19 changed files with 383 additions and 117 deletions

View File

@ -50,10 +50,11 @@ AudioSource* FakeVoiceMediaChannel::VoiceChannelAudioSink::source() const {
return source_;
}
FakeVoiceMediaChannel::FakeVoiceMediaChannel(FakeVoiceEngine* engine,
FakeVoiceMediaChannel::FakeVoiceMediaChannel(MediaChannel::Role role,
FakeVoiceEngine* engine,
const AudioOptions& options,
TaskQueueBase* network_thread)
: RtpHelper<VoiceMediaChannel>(network_thread),
: RtpHelper<VoiceMediaChannel>(role, network_thread),
engine_(engine),
max_bps_(-1) {
output_scalings_[0] = 1.0; // For default channel.
@ -260,10 +261,11 @@ bool CompareDtmfInfo(const FakeVoiceMediaChannel::DtmfInfo& info,
info.ssrc == ssrc);
}
FakeVideoMediaChannel::FakeVideoMediaChannel(FakeVideoEngine* engine,
FakeVideoMediaChannel::FakeVideoMediaChannel(MediaChannel::Role role,
FakeVideoEngine* engine,
const VideoOptions& options,
TaskQueueBase* network_thread)
: RtpHelper<VideoMediaChannel>(network_thread),
: RtpHelper<VideoMediaChannel>(role, network_thread),
engine_(engine),
max_bps_(-1) {
SetOptions(options);
@ -449,6 +451,7 @@ rtc::scoped_refptr<webrtc::AudioState> FakeVoiceEngine::GetAudioState() const {
return rtc::scoped_refptr<webrtc::AudioState>();
}
VoiceMediaChannel* FakeVoiceEngine::CreateMediaChannel(
MediaChannel::Role role,
webrtc::Call* call,
const MediaConfig& config,
const AudioOptions& options,
@ -458,7 +461,7 @@ VoiceMediaChannel* FakeVoiceEngine::CreateMediaChannel(
}
FakeVoiceMediaChannel* ch =
new FakeVoiceMediaChannel(this, options, call->network_thread());
new FakeVoiceMediaChannel(role, this, options, call->network_thread());
channels_.push_back(ch);
return ch;
}
@ -519,6 +522,7 @@ bool FakeVideoEngine::SetOptions(const VideoOptions& options) {
return true;
}
VideoMediaChannel* FakeVideoEngine::CreateMediaChannel(
MediaChannel::Role role,
webrtc::Call* call,
const MediaConfig& config,
const VideoOptions& options,
@ -529,7 +533,7 @@ VideoMediaChannel* FakeVideoEngine::CreateMediaChannel(
}
FakeVideoMediaChannel* ch =
new FakeVideoMediaChannel(this, options, call->network_thread());
new FakeVideoMediaChannel(role, this, options, call->network_thread());
channels_.emplace_back(ch);
return ch;
}

View File

@ -45,8 +45,9 @@ class FakeVoiceEngine;
template <class Base>
class RtpHelper : public Base {
public:
explicit RtpHelper(webrtc::TaskQueueBase* network_thread)
: Base(network_thread),
explicit RtpHelper(MediaChannel::Role role,
webrtc::TaskQueueBase* network_thread)
: Base(role, network_thread),
sending_(false),
playout_(false),
fail_set_send_codecs_(false),
@ -125,6 +126,7 @@ class RtpHelper : public Base {
virtual absl::optional<uint32_t> GetUnsignaledSsrc() const {
return absl::nullopt;
}
virtual bool SetLocalSsrc(const StreamParams& sp) { return true; }
virtual void OnDemuxerCriteriaUpdatePending() {}
virtual void OnDemuxerCriteriaUpdateComplete() {}
@ -260,6 +262,14 @@ class RtpHelper : public Base {
rtc::scoped_refptr<webrtc::FrameTransformerInterface> frame_transformer)
override {}
void SetInterface(MediaChannelNetworkInterface* iface) override {
network_interface_ = iface;
MediaChannel::SetInterface(iface);
}
bool HasNetworkInterface() const override {
return network_interface_ != nullptr;
}
protected:
bool MuteStream(uint32_t ssrc, bool mute) {
if (!HasSendStream(ssrc) && ssrc != 0) {
@ -337,6 +347,7 @@ class RtpHelper : public Base {
int transport_overhead_per_packet_;
rtc::NetworkRoute last_network_route_;
int num_network_route_changes_;
MediaChannelNetworkInterface* network_interface_ = nullptr;
};
class FakeVoiceMediaChannel : public RtpHelper<VoiceMediaChannel> {
@ -347,7 +358,8 @@ class FakeVoiceMediaChannel : public RtpHelper<VoiceMediaChannel> {
int event_code;
int duration;
};
FakeVoiceMediaChannel(FakeVoiceEngine* engine,
FakeVoiceMediaChannel(MediaChannel::Role role,
FakeVoiceEngine* engine,
const AudioOptions& options,
webrtc::TaskQueueBase* network_thread);
~FakeVoiceMediaChannel();
@ -442,7 +454,8 @@ bool CompareDtmfInfo(const FakeVoiceMediaChannel::DtmfInfo& info,
class FakeVideoMediaChannel : public RtpHelper<VideoMediaChannel> {
public:
FakeVideoMediaChannel(FakeVideoEngine* engine,
FakeVideoMediaChannel(MediaChannel::Role role,
FakeVideoEngine* engine,
const VideoOptions& options,
webrtc::TaskQueueBase* network_thread);
@ -520,6 +533,7 @@ class FakeVoiceEngine : public VoiceEngineInterface {
rtc::scoped_refptr<webrtc::AudioState> GetAudioState() const override;
VoiceMediaChannel* CreateMediaChannel(
MediaChannel::Role role,
webrtc::Call* call,
const MediaConfig& config,
const AudioOptions& options,
@ -559,6 +573,7 @@ class FakeVideoEngine : public VideoEngineInterface {
FakeVideoEngine();
bool SetOptions(const VideoOptions& options);
VideoMediaChannel* CreateMediaChannel(
MediaChannel::Role role,
webrtc::Call* call,
const MediaConfig& config,
const VideoOptions& options,

View File

@ -73,6 +73,7 @@ webrtc::RTCError InvokeSetParametersCallback(SetParametersCallback& callback,
namespace cricket {
class AudioSource;
class MediaChannel; // TODO(bugs.webrtc.org/13931): Delete when irrelevant
class VideoCapturer;
struct RtpHeader;
struct VideoFormat;
@ -212,6 +213,17 @@ class MediaBaseChannelInterface {
// worker_thread.
virtual void SetExtmapAllowMixed(bool extmap_allow_mixed) = 0;
virtual bool ExtmapAllowMixed() const = 0;
// Sets the abstract interface class for sending RTP/RTCP data.
virtual void SetInterface(MediaChannelNetworkInterface* iface) = 0;
// Returns `true` if a non-null MediaChannelNetworkInterface pointer is held.
// Must be called on the network thread.
virtual bool HasNetworkInterface() const = 0;
// Get the underlying send/receive implementation channel for testing.
// TODO(bugs.webrtc.org/13931): Remove method and the fakes that depend on it.
virtual MediaChannel* ImplForTesting() = 0;
};
class MediaSendChannelInterface
@ -263,14 +275,9 @@ class MediaReceiveChannelInterface
public:
virtual ~MediaReceiveChannelInterface() = default;
virtual VideoMediaReceiveChannelInterface* AsVideoReceiveChannel() {
RTC_CHECK_NOTREACHED();
return nullptr;
}
virtual VoiceMediaReceiveChannelInterface* AsVoiceReceiveChannel() {
RTC_CHECK_NOTREACHED();
return nullptr;
}
virtual VideoMediaReceiveChannelInterface* AsVideoReceiveChannel() = 0;
virtual VoiceMediaReceiveChannelInterface* AsVoiceReceiveChannel() = 0;
// Creates a new incoming media stream with SSRCs, CNAME as described
// by sp. In the case of a sp without SSRCs, the unsignaled sp is cached
// to be used later for unsignaled streams received.
@ -284,6 +291,9 @@ class MediaReceiveChannelInterface
virtual void ResetUnsignaledRecvStream() = 0;
// Gets the current unsignaled receive stream's SSRC, if there is one.
virtual absl::optional<uint32_t> GetUnsignaledSsrc() const = 0;
// Sets the local SSRC for listening to incoming RTCP reports.
virtual bool SetLocalSsrc(const StreamParams& sp) = 0;
// This is currently a workaround because of the demuxer state being managed
// across two separate threads. Once the state is consistently managed on
// the same thread (network), this workaround can be removed.

View File

@ -57,8 +57,11 @@ VideoOptions::VideoOptions()
: content_hint(VideoTrackInterface::ContentHint::kNone) {}
VideoOptions::~VideoOptions() = default;
MediaChannel::MediaChannel(TaskQueueBase* network_thread, bool enable_dscp)
: enable_dscp_(enable_dscp),
MediaChannel::MediaChannel(Role role,
TaskQueueBase* network_thread,
bool enable_dscp)
: role_(role),
enable_dscp_(enable_dscp),
network_safety_(PendingTaskSafetyFlag::CreateDetachedInactive()),
network_thread_(network_thread) {}

View File

@ -71,10 +71,22 @@ class VideoMediaChannel;
class MediaChannel : public MediaSendChannelInterface,
public MediaReceiveChannelInterface {
public:
explicit MediaChannel(webrtc::TaskQueueBase* network_thread,
// Role of the channel. Used to describe which interface it supports.
// This is temporary until we stop using the same implementation for both
// interfaces.
enum class Role {
kSend,
kReceive,
kBoth // Temporary value for non-converted test code
};
explicit MediaChannel(Role role,
webrtc::TaskQueueBase* network_thread,
bool enable_dscp = false);
virtual ~MediaChannel();
Role role() { return role_; }
// Downcasting to the subclasses.
virtual VideoMediaChannel* AsVideoChannel() {
RTC_CHECK_NOTREACHED();
@ -85,7 +97,6 @@ class MediaChannel : public MediaSendChannelInterface,
RTC_CHECK_NOTREACHED();
return nullptr;
}
// Must declare the methods inherited from the base interface template,
// even when abstract, to tell the compiler that all instances of the name
// referred to by subclasses of this share the same implementation.
@ -97,8 +108,6 @@ class MediaChannel : public MediaSendChannelInterface,
const rtc::NetworkRoute& network_route) override =
0;
// Sets the abstract interface class for sending RTP/RTCP data.
virtual void SetInterface(MediaChannelNetworkInterface* iface);
// Returns the absolute sendtime extension id value from media channel.
virtual int GetRtpSendTimeExtnId() const;
// Base method to send packet using MediaChannelNetworkInterface.
@ -119,9 +128,10 @@ class MediaChannel : public MediaSendChannelInterface,
void SetExtmapAllowMixed(bool extmap_allow_mixed) override;
bool ExtmapAllowMixed() const override;
void SetInterface(MediaChannelNetworkInterface* iface) override;
// Returns `true` if a non-null MediaChannelNetworkInterface pointer is held.
// Must be called on the network thread.
bool HasNetworkInterface() const;
bool HasNetworkInterface() const override;
void SetFrameEncryptor(uint32_t ssrc,
rtc::scoped_refptr<webrtc::FrameEncryptorInterface>
@ -170,6 +180,7 @@ class MediaChannel : public MediaSendChannelInterface,
bool rtcp,
const rtc::PacketOptions& options);
const Role role_;
const bool enable_dscp_;
const rtc::scoped_refptr<webrtc::PendingTaskSafetyFlag> network_safety_
RTC_PT_GUARDED_BY(network_thread_);
@ -187,9 +198,10 @@ class VideoMediaChannel : public MediaChannel,
public VideoMediaSendChannelInterface,
public VideoMediaReceiveChannelInterface {
public:
explicit VideoMediaChannel(webrtc::TaskQueueBase* network_thread,
explicit VideoMediaChannel(MediaChannel::Role role,
webrtc::TaskQueueBase* network_thread,
bool enable_dscp = false)
: MediaChannel(network_thread, enable_dscp) {}
: MediaChannel(role, network_thread, enable_dscp) {}
~VideoMediaChannel() override {}
// Downcasting to the implemented interfaces.
@ -202,6 +214,10 @@ class VideoMediaChannel : public MediaChannel,
VideoMediaReceiveChannelInterface* AsVideoReceiveChannel() override {
return this;
}
VoiceMediaReceiveChannelInterface* AsVoiceReceiveChannel() override {
RTC_CHECK_NOTREACHED();
return nullptr;
}
cricket::MediaType media_type() const override;
// Downcasting to the subclasses.
@ -213,6 +229,12 @@ class VideoMediaChannel : public MediaChannel,
bool ExtmapAllowMixed() const override {
return MediaChannel::ExtmapAllowMixed();
}
void SetInterface(MediaChannelNetworkInterface* iface) override {
return MediaChannel::SetInterface(iface);
}
// Declared here in order to avoid "found by multiple paths" compile error
bool AddSendStream(const StreamParams& sp) override = 0;
// This fills the "bitrate parts" (rtx, video bitrate) of the
// BandwidthEstimationInfo, since that part that isn't possible to get
// through webrtc::Call::GetStats, as they are statistics of the send
@ -225,8 +247,6 @@ class VideoMediaChannel : public MediaChannel,
// Gets quality stats for the channel.
virtual bool GetSendStats(VideoMediaSendInfo* info) = 0;
virtual bool GetReceiveStats(VideoMediaReceiveInfo* info) = 0;
// Enable network condition based codec switching.
void SetVideoCodecSwitchingEnabled(bool enabled) override;
private:
// Functions not implemented on this interface
@ -238,6 +258,16 @@ class VideoMediaChannel : public MediaChannel,
RTC_CHECK_NOTREACHED();
return false;
}
bool HasNetworkInterface() const override {
return MediaChannel::HasNetworkInterface();
}
// Enable network condition based codec switching.
void SetVideoCodecSwitchingEnabled(bool enabled) override;
MediaChannel* ImplForTesting() override {
// This class and its subclasses are not interface classes.
RTC_CHECK_NOTREACHED();
}
};
// Base class for implementation classes
@ -246,9 +276,10 @@ class VoiceMediaChannel : public MediaChannel,
public VoiceMediaReceiveChannelInterface {
public:
MediaType media_type() const override;
VoiceMediaChannel(webrtc::TaskQueueBase* network_thread,
VoiceMediaChannel(MediaChannel::Role role,
webrtc::TaskQueueBase* network_thread,
bool enable_dscp = false)
: MediaChannel(network_thread, enable_dscp) {}
: MediaChannel(role, network_thread, enable_dscp) {}
~VoiceMediaChannel() override {}
// Downcasting to the implemented interfaces.
@ -264,6 +295,10 @@ class VoiceMediaChannel : public MediaChannel,
RTC_CHECK_NOTREACHED();
return nullptr;
}
VideoMediaReceiveChannelInterface* AsVideoReceiveChannel() override {
RTC_CHECK_NOTREACHED();
return nullptr;
}
void SetExtmapAllowMixed(bool mixed) override {
MediaChannel::SetExtmapAllowMixed(mixed);
@ -271,6 +306,12 @@ class VoiceMediaChannel : public MediaChannel,
bool ExtmapAllowMixed() const override {
return MediaChannel::ExtmapAllowMixed();
}
void SetInterface(MediaChannelNetworkInterface* iface) override {
return MediaChannel::SetInterface(iface);
}
bool HasNetworkInterface() const override {
return MediaChannel::HasNetworkInterface();
}
// Gets quality stats for the channel.
virtual bool GetSendStats(VoiceMediaSendInfo* info) = 0;
@ -288,6 +329,10 @@ class VoiceMediaChannel : public MediaChannel,
RTC_CHECK_NOTREACHED();
return false;
}
MediaChannel* ImplForTesting() override {
// This class and its subclasses are not interface classes.
RTC_CHECK_NOTREACHED();
}
};
// The externally exposed objects that support the Send and Receive interfaces.
@ -320,6 +365,12 @@ class VoiceMediaSendChannel : public VoiceMediaSendChannelInterface {
impl()->SetExtmapAllowMixed(extmap_allow_mixed);
}
bool ExtmapAllowMixed() const override { return impl()->ExtmapAllowMixed(); }
void SetInterface(MediaChannelNetworkInterface* iface) override {
return impl()->SetInterface(iface);
}
bool HasNetworkInterface() const override {
return impl()->HasNetworkInterface();
}
// Implementation of MediaSendChannelInterface
bool AddSendStream(const StreamParams& sp) override {
return impl()->AddSendStream(sp);
@ -372,6 +423,7 @@ class VoiceMediaSendChannel : public VoiceMediaSendChannelInterface {
bool GetStats(VoiceMediaSendInfo* info) override {
return impl_->GetSendStats(info);
}
MediaChannel* ImplForTesting() override { return impl_; }
private:
VoiceMediaSendChannelInterface* impl() { return impl_; }
@ -383,6 +435,14 @@ class VoiceMediaReceiveChannel : public VoiceMediaReceiveChannelInterface {
public:
explicit VoiceMediaReceiveChannel(VoiceMediaChannel* impl) : impl_(impl) {}
virtual ~VoiceMediaReceiveChannel() {}
VoiceMediaReceiveChannelInterface* AsVoiceReceiveChannel() override {
return this;
}
VideoMediaReceiveChannelInterface* AsVideoReceiveChannel() override {
RTC_DCHECK_NOTREACHED();
return nullptr;
}
// Implementation of MediaBaseChannelInterface
cricket::MediaType media_type() const override { return MEDIA_TYPE_AUDIO; }
void OnPacketReceived(const webrtc::RtpPacketReceived& packet) override {
@ -400,6 +460,12 @@ class VoiceMediaReceiveChannel : public VoiceMediaReceiveChannelInterface {
impl()->SetExtmapAllowMixed(extmap_allow_mixed);
}
bool ExtmapAllowMixed() const override { return impl()->ExtmapAllowMixed(); }
void SetInterface(MediaChannelNetworkInterface* iface) override {
return impl()->SetInterface(iface);
}
bool HasNetworkInterface() const override {
return impl()->HasNetworkInterface();
}
// Implementation of Delayable
bool SetBaseMinimumPlayoutDelayMs(uint32_t ssrc, int delay_ms) override {
return impl()->SetBaseMinimumPlayoutDelayMs(ssrc, delay_ms);
@ -418,6 +484,9 @@ class VoiceMediaReceiveChannel : public VoiceMediaReceiveChannelInterface {
void ResetUnsignaledRecvStream() override {
return impl()->ResetUnsignaledRecvStream();
}
bool SetLocalSsrc(const StreamParams& sp) override {
return impl()->SetLocalSsrc(sp);
}
absl::optional<uint32_t> GetUnsignaledSsrc() const override {
return impl()->GetUnsignaledSsrc();
}
@ -470,6 +539,7 @@ class VoiceMediaReceiveChannel : public VoiceMediaReceiveChannelInterface {
bool GetStats(VoiceMediaReceiveInfo* info, bool reset_legacy) override {
return impl_->GetReceiveStats(info, reset_legacy);
}
MediaChannel* ImplForTesting() override { return impl_; }
private:
VoiceMediaReceiveChannelInterface* impl() { return impl_; }
@ -503,7 +573,13 @@ class VideoMediaSendChannel : public VideoMediaSendChannelInterface {
void SetExtmapAllowMixed(bool extmap_allow_mixed) override {
impl()->SetExtmapAllowMixed(extmap_allow_mixed);
}
bool HasNetworkInterface() const override {
return impl()->HasNetworkInterface();
}
bool ExtmapAllowMixed() const override { return impl()->ExtmapAllowMixed(); }
void SetInterface(MediaChannelNetworkInterface* iface) override {
return impl()->SetInterface(iface);
}
// Implementation of MediaSendChannelInterface
bool AddSendStream(const StreamParams& sp) override {
return impl()->AddSendStream(sp);
@ -566,6 +642,8 @@ class VideoMediaSendChannel : public VideoMediaSendChannelInterface {
return impl_->FillBitrateInfo(bwe_info);
}
MediaChannel* ImplForTesting() override { return impl_; }
private:
VideoMediaSendChannelInterface* impl() { return impl_; }
const VideoMediaSendChannelInterface* impl() const { return impl_; }
@ -575,6 +653,15 @@ class VideoMediaSendChannel : public VideoMediaSendChannelInterface {
class VideoMediaReceiveChannel : public VideoMediaReceiveChannelInterface {
public:
explicit VideoMediaReceiveChannel(VideoMediaChannel* impl) : impl_(impl) {}
VideoMediaReceiveChannelInterface* AsVideoReceiveChannel() override {
return this;
}
VoiceMediaReceiveChannelInterface* AsVoiceReceiveChannel() override {
RTC_DCHECK_NOTREACHED();
return nullptr;
}
// Implementation of MediaBaseChannelInterface
cricket::MediaType media_type() const override { return MEDIA_TYPE_VIDEO; }
void OnPacketReceived(const webrtc::RtpPacketReceived& packet) override {
@ -592,6 +679,12 @@ class VideoMediaReceiveChannel : public VideoMediaReceiveChannelInterface {
impl()->SetExtmapAllowMixed(extmap_allow_mixed);
}
bool ExtmapAllowMixed() const override { return impl()->ExtmapAllowMixed(); }
void SetInterface(MediaChannelNetworkInterface* iface) override {
return impl()->SetInterface(iface);
}
bool HasNetworkInterface() const override {
return impl()->HasNetworkInterface();
}
// Implementation of Delayable
bool SetBaseMinimumPlayoutDelayMs(uint32_t ssrc, int delay_ms) override {
return impl()->SetBaseMinimumPlayoutDelayMs(ssrc, delay_ms);
@ -601,9 +694,6 @@ class VideoMediaReceiveChannel : public VideoMediaReceiveChannelInterface {
return impl()->GetBaseMinimumPlayoutDelayMs(ssrc);
}
// Implementation of MediaReceiveChannelInterface
VideoMediaReceiveChannelInterface* AsVideoReceiveChannel() override {
return this;
}
bool AddRecvStream(const StreamParams& sp) override {
return impl()->AddRecvStream(sp);
}
@ -616,6 +706,9 @@ class VideoMediaReceiveChannel : public VideoMediaReceiveChannelInterface {
absl::optional<uint32_t> GetUnsignaledSsrc() const override {
return impl()->GetUnsignaledSsrc();
}
bool SetLocalSsrc(const StreamParams& sp) override {
return impl()->SetLocalSsrc(sp);
}
void OnDemuxerCriteriaUpdatePending() override {
impl()->OnDemuxerCriteriaUpdatePending();
}
@ -671,6 +764,7 @@ class VideoMediaReceiveChannel : public VideoMediaReceiveChannelInterface {
bool GetStats(VideoMediaReceiveInfo* info) override {
return impl_->GetReceiveStats(info);
}
MediaChannel* ImplForTesting() override { return impl_; }
private:
VideoMediaReceiveChannelInterface* impl() { return impl_; }

View File

@ -24,6 +24,7 @@
#include "call/audio_state.h"
#include "media/base/codec.h"
#include "media/base/media_channel.h"
#include "media/base/media_channel_impl.h"
#include "media/base/media_config.h"
#include "media/base/video_common.h"
#include "rtc_base/system/file_wrapper.h"
@ -100,10 +101,25 @@ class VoiceEngineInterface : public RtpHeaderExtensionQueryInterface {
// MediaChannel creation
// Creates a voice media channel. Returns NULL on failure.
virtual VoiceMediaChannel* CreateMediaChannel(
MediaChannel::Role role,
webrtc::Call* call,
const MediaConfig& config,
const AudioOptions& options,
const webrtc::CryptoOptions& crypto_options) = 0;
const webrtc::CryptoOptions& crypto_options) {
// TODO(bugs.webrtc.org/13931): Remove default implementation
// when downstream has migrated to new API.
RTC_CHECK_NOTREACHED();
}
// Backwards compatible version
[[deprecated("Use version with role parameter")]] virtual VoiceMediaChannel*
CreateMediaChannel(webrtc::Call* call,
const MediaConfig& config,
const AudioOptions& options,
const webrtc::CryptoOptions& crypto_options) {
return CreateMediaChannel(MediaChannel::Role::kBoth, call, config, options,
crypto_options);
}
virtual const std::vector<AudioCodec>& send_codecs() const = 0;
virtual const std::vector<AudioCodec>& recv_codecs() const = 0;
@ -129,15 +145,34 @@ class VideoEngineInterface : public RtpHeaderExtensionQueryInterface {
VideoEngineInterface(const VideoEngineInterface&) = delete;
VideoEngineInterface& operator=(const VideoEngineInterface&) = delete;
// Creates a video media channel, paired with the specified voice channel.
// Creates a video media channel.
// Returns NULL on failure.
virtual VideoMediaChannel* CreateMediaChannel(
MediaChannel::Role role,
webrtc::Call* call,
const MediaConfig& config,
const VideoOptions& options,
const webrtc::CryptoOptions& crypto_options,
webrtc::VideoBitrateAllocatorFactory*
video_bitrate_allocator_factory) = 0;
webrtc::VideoBitrateAllocatorFactory* video_bitrate_allocator_factory) {
// TODO(bugs.webrtc.org/13931): Remove default implementation
// when downstream has migrated.
RTC_CHECK_NOTREACHED();
return nullptr;
}
// Creates a video media channel.
// Returns NULL on failure.
// TODO(bugs.webrtc.org/13931): Stop downstream usage of this function.
[[deprecated("Please specify the role")]] virtual VideoMediaChannel*
CreateMediaChannel(
webrtc::Call* call,
const MediaConfig& config,
const VideoOptions& options,
const webrtc::CryptoOptions& crypto_options,
webrtc::VideoBitrateAllocatorFactory* video_bitrate_allocator_factory) {
return CreateMediaChannel(MediaChannel::Role::kBoth, call, config, options,
crypto_options, video_bitrate_allocator_factory);
}
// Retrieve list of supported codecs.
virtual std::vector<VideoCodec> send_codecs() const = 0;

View File

@ -51,6 +51,7 @@ class NullWebRtcVideoEngine : public VideoEngineInterface {
}
VideoMediaChannel* CreateMediaChannel(
MediaChannel::Role role,
webrtc::Call* call,
const MediaConfig& config,
const VideoOptions& options,

View File

@ -600,13 +600,14 @@ WebRtcVideoEngine::~WebRtcVideoEngine() {
}
VideoMediaChannel* WebRtcVideoEngine::CreateMediaChannel(
MediaChannel::Role role,
webrtc::Call* call,
const MediaConfig& config,
const VideoOptions& options,
const webrtc::CryptoOptions& crypto_options,
webrtc::VideoBitrateAllocatorFactory* video_bitrate_allocator_factory) {
RTC_LOG(LS_INFO) << "CreateMediaChannel. Options: " << options.ToString();
return new WebRtcVideoChannel(call, config, options, crypto_options,
return new WebRtcVideoChannel(role, call, config, options, crypto_options,
encoder_factory_.get(), decoder_factory_.get(),
video_bitrate_allocator_factory);
}
@ -664,6 +665,7 @@ WebRtcVideoEngine::GetRtpHeaderExtensions() const {
}
WebRtcVideoChannel::WebRtcVideoChannel(
MediaChannel::Role role,
webrtc::Call* call,
const MediaConfig& config,
const VideoOptions& options,
@ -671,7 +673,7 @@ WebRtcVideoChannel::WebRtcVideoChannel(
webrtc::VideoEncoderFactory* encoder_factory,
webrtc::VideoDecoderFactory* decoder_factory,
webrtc::VideoBitrateAllocatorFactory* bitrate_allocator_factory)
: VideoMediaChannel(call->network_thread(), config.enable_dscp),
: VideoMediaChannel(role, call->network_thread(), config.enable_dscp),
worker_thread_(call->worker_thread()),
call_(call),
default_sink_(nullptr),
@ -1326,6 +1328,9 @@ bool WebRtcVideoChannel::ValidateReceiveSsrcAvailability(
bool WebRtcVideoChannel::AddSendStream(const StreamParams& sp) {
RTC_DCHECK_RUN_ON(&thread_checker_);
RTC_DCHECK(role() == MediaChannel::Role::kSend ||
role() == MediaChannel::Role::kBoth);
RTC_LOG(LS_INFO) << "AddSendStream: " << sp.ToString();
if (!ValidateStreamParams(sp))
return false;
@ -1364,8 +1369,12 @@ bool WebRtcVideoChannel::AddSendStream(const StreamParams& sp) {
RTC_DCHECK(ssrc != 0);
send_streams_[ssrc] = stream;
if (rtcp_receiver_report_ssrc_ == kDefaultRtcpReceiverReportSsrc) {
SetReceiverReportSsrc(ssrc);
// If legacy kBoth mode, tell my receiver part about its SSRC.
// In kSend mode, this is the responsibility of the caller.
if (role() == MediaChannel::Role::kBoth) {
if (rtcp_receiver_report_ssrc_ == kDefaultRtcpReceiverReportSsrc) {
SetReceiverReportSsrc(ssrc);
}
}
if (sending_) {
@ -1554,6 +1563,15 @@ void WebRtcVideoChannel::ResetUnsignaledRecvStream() {
}
}
bool WebRtcVideoChannel::SetLocalSsrc(const StreamParams& sp) {
RTC_DCHECK_RUN_ON(&thread_checker_);
RTC_DCHECK(role() == MediaChannel::Role::kReceive);
if (rtcp_receiver_report_ssrc_ == kDefaultRtcpReceiverReportSsrc) {
SetReceiverReportSsrc(sp.first_ssrc());
}
return true;
}
absl::optional<uint32_t> WebRtcVideoChannel::GetUnsignaledSsrc() const {
RTC_DCHECK_RUN_ON(&thread_checker_);
absl::optional<uint32_t> ssrc;
@ -1617,6 +1635,7 @@ bool WebRtcVideoChannel::GetSendStats(VideoMediaSendInfo* info) {
log_stats = true;
}
info->Clear();
FillSenderStats(info, log_stats);
FillSendCodecStats(info);
// TODO(holmer): We should either have rtt available as a metric on

View File

@ -74,6 +74,7 @@ class WebRtcVideoEngine : public VideoEngineInterface {
~WebRtcVideoEngine() override;
VideoMediaChannel* CreateMediaChannel(
MediaChannel::Role role,
webrtc::Call* call,
const MediaConfig& config,
const VideoOptions& options,
@ -105,6 +106,7 @@ class WebRtcVideoChannel : public VideoMediaChannel,
public webrtc::EncoderSwitchRequestCallback {
public:
WebRtcVideoChannel(
MediaChannel::Role role,
webrtc::Call* call,
const MediaConfig& config,
const VideoOptions& options,
@ -137,6 +139,7 @@ class WebRtcVideoChannel : public VideoMediaChannel,
bool RemoveRecvStream(uint32_t ssrc) override;
void ResetUnsignaledRecvStream() override;
absl::optional<uint32_t> GetUnsignaledSsrc() const override;
bool SetLocalSsrc(const StreamParams& sp) override;
void OnDemuxerCriteriaUpdatePending() override;
void OnDemuxerCriteriaUpdateComplete() override;
bool SetSink(uint32_t ssrc,

View File

@ -613,7 +613,8 @@ TEST_F(WebRtcVideoEngineTest, SetSendFailsBeforeSettingCodecs) {
AddSupportedVideoCodecType("VP8");
std::unique_ptr<VideoMediaChannel> channel(engine_.CreateMediaChannel(
call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
cricket::MediaChannel::Role::kBoth, call_.get(), GetMediaConfig(),
VideoOptions(), webrtc::CryptoOptions(),
video_bitrate_allocator_factory_.get()));
auto send_channel = std::make_unique<VideoMediaSendChannel>(channel.get());
@ -629,7 +630,8 @@ TEST_F(WebRtcVideoEngineTest, GetStatsWithoutSendCodecsSetDoesNotCrash) {
AddSupportedVideoCodecType("VP8");
std::unique_ptr<VideoMediaChannel> channel(engine_.CreateMediaChannel(
call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
cricket::MediaChannel::Role::kBoth, call_.get(), GetMediaConfig(),
VideoOptions(), webrtc::CryptoOptions(),
video_bitrate_allocator_factory_.get()));
auto send_channel = std::make_unique<VideoMediaSendChannel>(channel.get());
@ -856,7 +858,8 @@ void WebRtcVideoEngineTest::AddSupportedVideoCodecType(
VideoMediaChannel*
WebRtcVideoEngineTest::SetSendParamsWithAllSupportedCodecs() {
VideoMediaChannel* channel = engine_.CreateMediaChannel(
call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
cricket::MediaChannel::Role::kBoth, call_.get(), GetMediaConfig(),
VideoOptions(), webrtc::CryptoOptions(),
video_bitrate_allocator_factory_.get());
cricket::VideoSendParameters parameters;
// We need to look up the codec in the engine to get the correct payload type.
@ -876,7 +879,8 @@ WebRtcVideoEngineTest::SetSendParamsWithAllSupportedCodecs() {
VideoMediaChannel* WebRtcVideoEngineTest::SetRecvParamsWithSupportedCodecs(
const std::vector<VideoCodec>& codecs) {
VideoMediaChannel* channel = engine_.CreateMediaChannel(
call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
cricket::MediaChannel::Role::kBoth, call_.get(), GetMediaConfig(),
VideoOptions(), webrtc::CryptoOptions(),
video_bitrate_allocator_factory_.get());
cricket::VideoRecvParameters parameters;
parameters.codecs = codecs;
@ -913,8 +917,8 @@ TEST_F(WebRtcVideoEngineTest, SendsFeedbackAfterUnsignaledRtxPacket) {
}),
Return(true)));
std::unique_ptr<VideoMediaChannel> channel(engine_.CreateMediaChannel(
call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
video_bitrate_allocator_factory_.get()));
MediaChannel::Role::kBoth, call_.get(), GetMediaConfig(), VideoOptions(),
webrtc::CryptoOptions(), video_bitrate_allocator_factory_.get()));
cricket::VideoRecvParameters parameters;
parameters.codecs = supported_codecs;
const int kTransportSeqExtensionId = 1;
@ -952,8 +956,8 @@ TEST_F(WebRtcVideoEngineTest, UpdatesUnsignaledRtxSsrcAndRecoversPayload) {
int rtx_payload_type = supported_codecs[1].id;
std::unique_ptr<VideoMediaChannel> channel(engine_.CreateMediaChannel(
call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
video_bitrate_allocator_factory_.get()));
MediaChannel::Role::kBoth, call_.get(), GetMediaConfig(), VideoOptions(),
webrtc::CryptoOptions(), video_bitrate_allocator_factory_.get()));
cricket::VideoRecvParameters parameters;
parameters.codecs = supported_codecs;
ASSERT_TRUE(channel->SetRecvParameters(parameters));
@ -1034,7 +1038,8 @@ TEST_F(WebRtcVideoEngineTest, ChannelWithH264CanChangeToVp8) {
rtc::kNumMicrosecsPerSec / 30);
std::unique_ptr<VideoMediaChannel> channel(engine_.CreateMediaChannel(
call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
cricket::MediaChannel::Role::kBoth, call_.get(), GetMediaConfig(),
VideoOptions(), webrtc::CryptoOptions(),
video_bitrate_allocator_factory_.get()));
auto send_channel = std::make_unique<VideoMediaSendChannel>(channel.get());
cricket::VideoSendParameters parameters;
@ -1067,7 +1072,8 @@ TEST_F(WebRtcVideoEngineTest,
AddSupportedVideoCodecType("H264");
std::unique_ptr<VideoMediaChannel> channel(engine_.CreateMediaChannel(
call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
cricket::MediaChannel::Role::kBoth, call_.get(), GetMediaConfig(),
VideoOptions(), webrtc::CryptoOptions(),
video_bitrate_allocator_factory_.get()));
auto send_channel = std::make_unique<VideoMediaSendChannel>(channel.get());
cricket::VideoSendParameters parameters;
@ -1106,7 +1112,8 @@ TEST_F(WebRtcVideoEngineTest,
AddSupportedVideoCodecType("H264");
std::unique_ptr<VideoMediaChannel> channel(engine_.CreateMediaChannel(
call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
cricket::MediaChannel::Role::kBoth, call_.get(), GetMediaConfig(),
VideoOptions(), webrtc::CryptoOptions(),
video_bitrate_allocator_factory_.get()));
auto send_channel = std::make_unique<VideoMediaSendChannel>(channel.get());
cricket::VideoSendParameters parameters;
@ -1140,7 +1147,8 @@ TEST_F(WebRtcVideoEngineTest, SimulcastEnabledForH264BehindFieldTrial) {
AddSupportedVideoCodecType("H264");
std::unique_ptr<VideoMediaChannel> channel(engine_.CreateMediaChannel(
call_.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
cricket::MediaChannel::Role::kBoth, call_.get(), GetMediaConfig(),
VideoOptions(), webrtc::CryptoOptions(),
video_bitrate_allocator_factory_.get()));
auto send_channel = std::make_unique<VideoMediaSendChannel>(channel.get());
@ -1441,8 +1449,8 @@ TEST(WebRtcVideoEngineNewVideoCodecFactoryTest, Vp8) {
// Create send channel.
const int send_ssrc = 123;
std::unique_ptr<VideoMediaChannel> send_channel(engine.CreateMediaChannel(
call.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
rate_allocator_factory.get()));
cricket::MediaChannel::Role::kBoth, call.get(), GetMediaConfig(),
VideoOptions(), webrtc::CryptoOptions(), rate_allocator_factory.get()));
auto send_send_channel =
std::make_unique<VideoMediaSendChannel>(send_channel.get());
@ -1466,8 +1474,8 @@ TEST(WebRtcVideoEngineNewVideoCodecFactoryTest, Vp8) {
// Create recv channel.
const int recv_ssrc = 321;
std::unique_ptr<VideoMediaChannel> recv_channel(engine.CreateMediaChannel(
call.get(), GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
rate_allocator_factory.get()));
cricket::MediaChannel::Role::kBoth, call.get(), GetMediaConfig(),
VideoOptions(), webrtc::CryptoOptions(), rate_allocator_factory.get()));
auto receive_channel =
std::make_unique<VideoMediaReceiveChannel>(recv_channel.get());
@ -1592,6 +1600,7 @@ class WebRtcVideoChannelEncodedFrameCallbackTest : public ::testing::Test {
field_trials_),
channel_(absl::WrapUnique(static_cast<cricket::WebRtcVideoChannel*>(
engine_.CreateMediaChannel(
cricket::MediaChannel::Role::kBoth,
call_.get(),
cricket::MediaConfig(),
cricket::VideoOptions(),
@ -1738,8 +1747,9 @@ class WebRtcVideoChannelBaseTest : public ::testing::Test {
media_config.video.enable_cpu_adaptation = false;
channel_.reset(
static_cast<cricket::WebRtcVideoChannel*>(engine_.CreateMediaChannel(
call_.get(), media_config, cricket::VideoOptions(),
webrtc::CryptoOptions(), video_bitrate_allocator_factory_.get())));
cricket::MediaChannel::Role::kBoth, call_.get(), media_config,
cricket::VideoOptions(), webrtc::CryptoOptions(),
video_bitrate_allocator_factory_.get())));
send_channel_ = std::make_unique<VideoMediaSendChannel>(channel_.get());
receive_channel_ =
std::make_unique<VideoMediaReceiveChannel>(channel_.get());
@ -2604,8 +2614,9 @@ class WebRtcVideoChannelTest : public WebRtcVideoEngineTest {
fake_call_.reset(new FakeCall(&field_trials_));
channel_.reset(engine_.CreateMediaChannel(
fake_call_.get(), GetMediaConfig(), VideoOptions(),
webrtc::CryptoOptions(), video_bitrate_allocator_factory_.get()));
cricket::MediaChannel::Role::kBoth, fake_call_.get(), GetMediaConfig(),
VideoOptions(), webrtc::CryptoOptions(),
video_bitrate_allocator_factory_.get()));
send_channel_ =
std::make_unique<cricket::VideoMediaSendChannel>(channel_.get());
receive_channel_ =
@ -3483,9 +3494,12 @@ TEST_F(WebRtcVideoChannelTest, SetMediaConfigSuspendBelowMinBitrate) {
media_config.video.suspend_below_min_bitrate = true;
channel_.reset(engine_.CreateMediaChannel(
fake_call_.get(), media_config, VideoOptions(), webrtc::CryptoOptions(),
cricket::MediaChannel::Role::kBoth, fake_call_.get(), media_config,
VideoOptions(), webrtc::CryptoOptions(),
video_bitrate_allocator_factory_.get()));
send_channel_.reset(new VideoMediaSendChannel(channel_.get()));
receive_channel_ =
std::make_unique<cricket::VideoMediaReceiveChannel>(channel_.get());
send_channel_->OnReadyToSend(true);
channel_->SetSendParameters(send_parameters_);
@ -3495,9 +3509,12 @@ TEST_F(WebRtcVideoChannelTest, SetMediaConfigSuspendBelowMinBitrate) {
media_config.video.suspend_below_min_bitrate = false;
channel_.reset(engine_.CreateMediaChannel(
fake_call_.get(), media_config, VideoOptions(), webrtc::CryptoOptions(),
cricket::MediaChannel::Role::kBoth, fake_call_.get(), media_config,
VideoOptions(), webrtc::CryptoOptions(),
video_bitrate_allocator_factory_.get()));
send_channel_.reset(new VideoMediaSendChannel(channel_.get()));
receive_channel_ =
std::make_unique<cricket::VideoMediaReceiveChannel>(channel_.get());
send_channel_->OnReadyToSend(true);
channel_->SetSendParameters(send_parameters_);
@ -4037,9 +4054,12 @@ TEST_F(WebRtcVideoChannelTest, PreviousAdaptationDoesNotApplyToScreenshare) {
MediaConfig media_config = GetMediaConfig();
media_config.video.enable_cpu_adaptation = true;
channel_.reset(engine_.CreateMediaChannel(
fake_call_.get(), media_config, VideoOptions(), webrtc::CryptoOptions(),
cricket::MediaChannel::Role::kBoth, fake_call_.get(), media_config,
VideoOptions(), webrtc::CryptoOptions(),
video_bitrate_allocator_factory_.get()));
send_channel_.reset(new VideoMediaSendChannel(channel_.get()));
receive_channel_ =
std::make_unique<cricket::VideoMediaReceiveChannel>(channel_.get());
send_channel_->OnReadyToSend(true);
ASSERT_TRUE(channel_->SetSendParameters(parameters));
@ -4089,9 +4109,12 @@ void WebRtcVideoChannelTest::TestDegradationPreference(
MediaConfig media_config = GetMediaConfig();
media_config.video.enable_cpu_adaptation = true;
channel_.reset(engine_.CreateMediaChannel(
fake_call_.get(), media_config, VideoOptions(), webrtc::CryptoOptions(),
cricket::MediaChannel::Role::kBoth, fake_call_.get(), media_config,
VideoOptions(), webrtc::CryptoOptions(),
video_bitrate_allocator_factory_.get()));
send_channel_.reset(new VideoMediaSendChannel(channel_.get()));
receive_channel_ =
std::make_unique<cricket::VideoMediaReceiveChannel>(channel_.get());
send_channel_->OnReadyToSend(true);
EXPECT_TRUE(channel_->SetSendParameters(parameters));
@ -4123,9 +4146,12 @@ void WebRtcVideoChannelTest::TestCpuAdaptation(bool enable_overuse,
media_config.video.enable_cpu_adaptation = true;
}
channel_.reset(engine_.CreateMediaChannel(
fake_call_.get(), media_config, VideoOptions(), webrtc::CryptoOptions(),
cricket::MediaChannel::Role::kBoth, fake_call_.get(), media_config,
VideoOptions(), webrtc::CryptoOptions(),
video_bitrate_allocator_factory_.get()));
send_channel_.reset(new VideoMediaSendChannel(channel_.get()));
receive_channel_ =
std::make_unique<cricket::VideoMediaReceiveChannel>(channel_.get());
send_channel_->OnReadyToSend(true);
EXPECT_TRUE(channel_->SetSendParameters(parameters));
@ -5455,7 +5481,8 @@ TEST_F(WebRtcVideoChannelTest, TestSetDscpOptions) {
channel.reset(
static_cast<cricket::WebRtcVideoChannel*>(engine_.CreateMediaChannel(
call_.get(), config, VideoOptions(), webrtc::CryptoOptions(),
cricket::MediaChannel::Role::kBoth, call_.get(), config,
VideoOptions(), webrtc::CryptoOptions(),
video_bitrate_allocator_factory_.get())));
send_channel.reset(new VideoMediaSendChannel(channel_.get()));
@ -5469,7 +5496,8 @@ TEST_F(WebRtcVideoChannelTest, TestSetDscpOptions) {
config.enable_dscp = true;
channel.reset(
static_cast<cricket::WebRtcVideoChannel*>(engine_.CreateMediaChannel(
call_.get(), config, VideoOptions(), webrtc::CryptoOptions(),
cricket::MediaChannel::Role::kBoth, call_.get(), config,
VideoOptions(), webrtc::CryptoOptions(),
video_bitrate_allocator_factory_.get())));
send_channel.reset(new VideoMediaSendChannel(channel.get()));
channel->SetInterface(network_interface.get());
@ -5502,7 +5530,8 @@ TEST_F(WebRtcVideoChannelTest, TestSetDscpOptions) {
config.enable_dscp = false;
channel.reset(
static_cast<cricket::WebRtcVideoChannel*>(engine_.CreateMediaChannel(
call_.get(), config, VideoOptions(), webrtc::CryptoOptions(),
cricket::MediaChannel::Role::kBoth, call_.get(), config,
VideoOptions(), webrtc::CryptoOptions(),
video_bitrate_allocator_factory_.get())));
channel->SetInterface(network_interface.get());
EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface->dscp());
@ -9401,7 +9430,8 @@ class WebRtcVideoChannelSimulcastTest : public ::testing::Test {
encoder_factory_->AddSupportedVideoCodecType("VP8");
decoder_factory_->AddSupportedVideoCodecType("VP8");
channel_.reset(engine_.CreateMediaChannel(
&fake_call_, GetMediaConfig(), VideoOptions(), webrtc::CryptoOptions(),
cricket::MediaChannel::Role::kBoth, &fake_call_, GetMediaConfig(),
VideoOptions(), webrtc::CryptoOptions(),
mock_rate_allocator_factory_.get()));
send_channel_ = std::make_unique<VideoMediaSendChannel>(channel_.get());
receive_channel_ =

View File

@ -409,13 +409,14 @@ rtc::scoped_refptr<webrtc::AudioState> WebRtcVoiceEngine::GetAudioState()
}
VoiceMediaChannel* WebRtcVoiceEngine::CreateMediaChannel(
MediaChannel::Role role,
webrtc::Call* call,
const MediaConfig& config,
const AudioOptions& options,
const webrtc::CryptoOptions& crypto_options) {
RTC_DCHECK_RUN_ON(call->worker_thread());
return new WebRtcVoiceMediaChannel(this, config, options, crypto_options,
call);
return new WebRtcVoiceMediaChannel(role, this, config, options,
crypto_options, call);
}
void WebRtcVoiceEngine::ApplyOptions(const AudioOptions& options_in) {
@ -1249,12 +1250,13 @@ class WebRtcVoiceMediaChannel::WebRtcAudioReceiveStream {
};
WebRtcVoiceMediaChannel::WebRtcVoiceMediaChannel(
MediaChannel::Role role,
WebRtcVoiceEngine* engine,
const MediaConfig& config,
const AudioOptions& options,
const webrtc::CryptoOptions& crypto_options,
webrtc::Call* call)
: VoiceMediaChannel(call->network_thread(), config.enable_dscp),
: VoiceMediaChannel(role, call->network_thread(), config.enable_dscp),
worker_thread_(call->worker_thread()),
engine_(engine),
call_(call),
@ -1822,6 +1824,8 @@ bool WebRtcVoiceMediaChannel::AddSendStream(const StreamParams& sp) {
TRACE_EVENT0("webrtc", "WebRtcVoiceMediaChannel::AddSendStream");
RTC_DCHECK_RUN_ON(worker_thread_);
RTC_LOG(LS_INFO) << "AddSendStream: " << sp.ToString();
RTC_DCHECK(role() == MediaChannel::Role::kSend ||
role() == MediaChannel::Role::kBoth);
uint32_t ssrc = sp.first_ssrc();
RTC_DCHECK(0 != ssrc);
@ -1840,14 +1844,19 @@ bool WebRtcVoiceMediaChannel::AddSendStream(const StreamParams& sp) {
call_, this, engine()->encoder_factory_, codec_pair_id_, nullptr,
crypto_options_);
send_streams_.insert(std::make_pair(ssrc, stream));
if (role() == MediaChannel::Role::kBoth) {
// In legacy kBoth mode, the MediaChannel takes the responsibility for
// telling the receiver about the local SSRC.
// In kSend mode, this is the caller's responsibility.
// At this point the stream's local SSRC has been updated. If it is the first
// send stream, make sure that all the receive streams are updated with the
// same SSRC in order to send receiver reports.
if (send_streams_.size() == 1) {
receiver_reports_ssrc_ = ssrc;
for (auto& kv : recv_streams_) {
call_->OnLocalSsrcUpdated(kv.second->stream(), ssrc);
// At this point the stream's local SSRC has been updated. If it is the
// first send stream, make sure that all the receive streams are updated
// with the same SSRC in order to send receiver reports.
if (send_streams_.size() == 1) {
receiver_reports_ssrc_ = ssrc;
for (auto& kv : recv_streams_) {
call_->OnLocalSsrcUpdated(kv.second->stream(), ssrc);
}
}
}
@ -1884,6 +1893,8 @@ bool WebRtcVoiceMediaChannel::RemoveSendStream(uint32_t ssrc) {
bool WebRtcVoiceMediaChannel::AddRecvStream(const StreamParams& sp) {
TRACE_EVENT0("webrtc", "WebRtcVoiceMediaChannel::AddRecvStream");
RTC_DCHECK_RUN_ON(worker_thread_);
RTC_DCHECK(role() == MediaChannel::Role::kReceive ||
role() == MediaChannel::Role::kBoth);
RTC_LOG(LS_INFO) << "AddRecvStream: " << sp.ToString();
if (!sp.has_ssrcs()) {
@ -1970,6 +1981,16 @@ absl::optional<uint32_t> WebRtcVoiceMediaChannel::GetUnsignaledSsrc() const {
return unsignaled_recv_ssrcs_.back();
}
bool WebRtcVoiceMediaChannel::SetLocalSsrc(const StreamParams& sp) {
RTC_DCHECK(role() == MediaChannel::Role::kReceive);
uint32_t ssrc = sp.first_ssrc();
receiver_reports_ssrc_ = ssrc;
for (auto& kv : recv_streams_) {
call_->OnLocalSsrcUpdated(kv.second->stream(), ssrc);
}
return true;
}
// Not implemented.
// TODO(https://crbug.com/webrtc/12676): Implement a fix for the unsignalled
// SSRC race that can happen when an m= section goes from receiving to not
@ -2282,7 +2303,10 @@ bool WebRtcVoiceMediaChannel::GetSendStats(VoiceMediaSendInfo* info) {
RTC_DCHECK(info);
// Get SSRC and stats for each sender.
RTC_DCHECK_EQ(info->senders.size(), 0U);
// With separate send and receive channels, we expect GetStats to be called on
// both, and accumulate info, but only one channel (the send one) should have
// senders.
RTC_DCHECK(info->senders.size() == 0U || send_streams_.size() == 0);
for (const auto& stream : send_streams_) {
webrtc::AudioSendStream::Stats stats =
stream.second->GetStats(recv_streams_.size() > 0);

View File

@ -69,6 +69,7 @@ class WebRtcVoiceEngine final : public VoiceEngineInterface {
rtc::scoped_refptr<webrtc::AudioState> GetAudioState() const override;
VoiceMediaChannel* CreateMediaChannel(
MediaChannel::Role role,
webrtc::Call* call,
const MediaConfig& config,
const AudioOptions& options,
@ -139,7 +140,8 @@ class WebRtcVoiceEngine final : public VoiceEngineInterface {
class WebRtcVoiceMediaChannel final : public VoiceMediaChannel,
public webrtc::Transport {
public:
WebRtcVoiceMediaChannel(WebRtcVoiceEngine* engine,
WebRtcVoiceMediaChannel(MediaChannel::Role role,
WebRtcVoiceEngine* engine,
const MediaConfig& config,
const AudioOptions& options,
const webrtc::CryptoOptions& crypto_options,
@ -175,6 +177,9 @@ class WebRtcVoiceMediaChannel final : public VoiceMediaChannel,
bool RemoveRecvStream(uint32_t ssrc) override;
void ResetUnsignaledRecvStream() override;
absl::optional<uint32_t> GetUnsignaledSsrc() const override;
bool SetLocalSsrc(const StreamParams& sp) override;
void OnDemuxerCriteriaUpdatePending() override;
void OnDemuxerCriteriaUpdateComplete() override;

View File

@ -230,9 +230,9 @@ class WebRtcVoiceEngineTestFake : public ::testing::TestWithParam<bool> {
}
bool SetupChannel() {
channel_ = engine_->CreateMediaChannel(&call_, cricket::MediaConfig(),
cricket::AudioOptions(),
webrtc::CryptoOptions());
channel_ = engine_->CreateMediaChannel(
cricket::MediaChannel::Role::kBoth, &call_, cricket::MediaConfig(),
cricket::AudioOptions(), webrtc::CryptoOptions());
send_channel_ = std::make_unique<cricket::VoiceMediaSendChannel>(channel_);
receive_channel_ =
std::make_unique<cricket::VoiceMediaReceiveChannel>(channel_);
@ -3029,9 +3029,9 @@ TEST_P(WebRtcVoiceEngineTestFake, InitRecordingOnSend) {
EXPECT_CALL(*adm_, InitRecording()).Times(1);
std::unique_ptr<cricket::VoiceMediaChannel> channel(
engine_->CreateMediaChannel(&call_, cricket::MediaConfig(),
cricket::AudioOptions(),
webrtc::CryptoOptions()));
engine_->CreateMediaChannel(
cricket::MediaChannel::Role::kBoth, &call_, cricket::MediaConfig(),
cricket::AudioOptions(), webrtc::CryptoOptions()));
channel->SetSend(true);
}
@ -3045,7 +3045,8 @@ TEST_P(WebRtcVoiceEngineTestFake, SkipInitRecordingOnSend) {
options.init_recording_on_send = false;
std::unique_ptr<cricket::VoiceMediaChannel> channel(
engine_->CreateMediaChannel(&call_, cricket::MediaConfig(), options,
engine_->CreateMediaChannel(cricket::MediaChannel::Role::kBoth, &call_,
cricket::MediaConfig(), options,
webrtc::CryptoOptions()));
channel->SetSend(true);
@ -3071,12 +3072,14 @@ TEST_P(WebRtcVoiceEngineTestFake, SetOptionOverridesViaChannels) {
std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel1(
static_cast<cricket::WebRtcVoiceMediaChannel*>(
engine_->CreateMediaChannel(&call_, cricket::MediaConfig(),
engine_->CreateMediaChannel(cricket::MediaChannel::Role::kBoth,
&call_, cricket::MediaConfig(),
cricket::AudioOptions(),
webrtc::CryptoOptions())));
std::unique_ptr<cricket::WebRtcVoiceMediaChannel> channel2(
static_cast<cricket::WebRtcVoiceMediaChannel*>(
engine_->CreateMediaChannel(&call_, cricket::MediaConfig(),
engine_->CreateMediaChannel(cricket::MediaChannel::Role::kBoth,
&call_, cricket::MediaConfig(),
cricket::AudioOptions(),
webrtc::CryptoOptions())));
@ -3188,7 +3191,8 @@ TEST_P(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
webrtc::RtpParameters parameters;
channel.reset(static_cast<cricket::WebRtcVoiceMediaChannel*>(
engine_->CreateMediaChannel(&call_, config, cricket::AudioOptions(),
engine_->CreateMediaChannel(cricket::MediaChannel::Role::kBoth, &call_,
config, cricket::AudioOptions(),
webrtc::CryptoOptions())));
channel->SetInterface(&network_interface);
// Default value when DSCP is disabled should be DSCP_DEFAULT.
@ -3197,7 +3201,8 @@ TEST_P(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
config.enable_dscp = true;
channel.reset(static_cast<cricket::WebRtcVoiceMediaChannel*>(
engine_->CreateMediaChannel(&call_, config, cricket::AudioOptions(),
engine_->CreateMediaChannel(cricket::MediaChannel::Role::kBoth, &call_,
config, cricket::AudioOptions(),
webrtc::CryptoOptions())));
channel->SetInterface(&network_interface);
EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
@ -3226,7 +3231,8 @@ TEST_P(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
// DiffServCodePoint.
config.enable_dscp = false;
channel.reset(static_cast<cricket::WebRtcVoiceMediaChannel*>(
engine_->CreateMediaChannel(&call_, config, cricket::AudioOptions(),
engine_->CreateMediaChannel(cricket::MediaChannel::Role::kBoth, &call_,
config, cricket::AudioOptions(),
webrtc::CryptoOptions())));
channel->SetInterface(&network_interface);
// Default value when DSCP is disabled should be DSCP_DEFAULT.
@ -3473,6 +3479,7 @@ TEST_P(WebRtcVoiceEngineTestFake, AssociateFirstSendChannel_RecvCreatedFirst) {
EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
EXPECT_TRUE(send_channel_->AddSendStream(
cricket::StreamParams::CreateLegacy(kSsrcW)));
EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcX).rtp.local_ssrc);
EXPECT_EQ(kSsrcY, GetRecvStreamConfig(kSsrcZ).rtp.local_ssrc);
}
@ -3636,8 +3643,8 @@ TEST(WebRtcVoiceEngineTest, StartupShutdown) {
call_config.task_queue_factory = task_queue_factory.get();
auto call = absl::WrapUnique(webrtc::Call::Create(call_config));
cricket::VoiceMediaChannel* channel = engine.CreateMediaChannel(
call.get(), cricket::MediaConfig(), cricket::AudioOptions(),
webrtc::CryptoOptions());
cricket::MediaChannel::Role::kBoth, call.get(), cricket::MediaConfig(),
cricket::AudioOptions(), webrtc::CryptoOptions());
EXPECT_TRUE(channel != nullptr);
delete channel;
}
@ -3667,7 +3674,8 @@ TEST(WebRtcVoiceEngineTest, StartupShutdownWithExternalADM) {
call_config.task_queue_factory = task_queue_factory.get();
auto call = absl::WrapUnique(webrtc::Call::Create(call_config));
cricket::VoiceMediaChannel* channel = engine.CreateMediaChannel(
call.get(), cricket::MediaConfig(), cricket::AudioOptions(),
cricket::MediaChannel::Role::kBoth, call.get(),
cricket::MediaConfig(), cricket::AudioOptions(),
webrtc::CryptoOptions());
EXPECT_TRUE(channel != nullptr);
delete channel;
@ -3756,7 +3764,8 @@ TEST(WebRtcVoiceEngineTest, Has32Channels) {
size_t num_channels = 0;
while (num_channels < arraysize(channels)) {
cricket::VoiceMediaChannel* channel = engine.CreateMediaChannel(
call.get(), cricket::MediaConfig(), cricket::AudioOptions(),
cricket::MediaChannel::Role::kBoth, call.get(),
cricket::MediaConfig(), cricket::AudioOptions(),
webrtc::CryptoOptions());
if (!channel)
break;
@ -3802,8 +3811,8 @@ TEST(WebRtcVoiceEngineTest, SetRecvCodecs) {
call_config.task_queue_factory = task_queue_factory.get();
auto call = absl::WrapUnique(webrtc::Call::Create(call_config));
cricket::WebRtcVoiceMediaChannel channel(
&engine, cricket::MediaConfig(), cricket::AudioOptions(),
webrtc::CryptoOptions(), call.get());
cricket::MediaChannel::Role::kReceive, &engine, cricket::MediaConfig(),
cricket::AudioOptions(), webrtc::CryptoOptions(), call.get());
cricket::AudioRecvParameters parameters;
parameters.codecs = engine.recv_codecs();
EXPECT_TRUE(channel.SetRecvParameters(parameters));
@ -3835,9 +3844,9 @@ TEST(WebRtcVoiceEngineTest, SetRtpSendParametersMaxBitrate) {
call_config.audio_state = webrtc::AudioState::Create(config);
}
auto call = absl::WrapUnique(webrtc::Call::Create(call_config));
cricket::WebRtcVoiceMediaChannel channel(&engine, cricket::MediaConfig(),
cricket::AudioOptions(),
webrtc::CryptoOptions(), call.get());
cricket::WebRtcVoiceMediaChannel channel(
cricket::MediaChannel::Role::kSend, &engine, cricket::MediaConfig(),
cricket::AudioOptions(), webrtc::CryptoOptions(), call.get());
{
cricket::AudioSendParameters params;
params.codecs.push_back(cricket::AudioCodec(1, "opus", 48000, 32000, 2));

View File

@ -151,9 +151,11 @@ class ChannelTest : public ::testing::Test, public sigslot::has_slots<> {
void CreateChannels(int flags1, int flags2) {
CreateChannels(std::make_unique<typename T::MediaChannel>(
nullptr, typename T::Options(), network_thread_),
cricket::MediaChannel::Role::kBoth, nullptr,
typename T::Options(), network_thread_),
std::make_unique<typename T::MediaChannel>(
nullptr, typename T::Options(), network_thread_),
cricket::MediaChannel::Role::kBoth, nullptr,
typename T::Options(), network_thread_),
flags1, flags2);
}
void CreateChannels(std::unique_ptr<typename T::MediaChannel> ch1,

View File

@ -119,11 +119,13 @@ class RtpSenderReceiverTest
// Create the channels, discard the result; we get them later.
// Fake media channels are owned by the media engine.
media_engine_->voice().CreateMediaChannel(
&fake_call_, cricket::MediaConfig(), cricket::AudioOptions(),
webrtc::CryptoOptions());
cricket::MediaChannel::Role::kBoth, &fake_call_, cricket::MediaConfig(),
cricket::AudioOptions(), webrtc::CryptoOptions());
media_engine_->video().CreateMediaChannel(
&fake_call_, cricket::MediaConfig(), cricket::VideoOptions(),
webrtc::CryptoOptions(), video_bitrate_allocator_factory_.get());
cricket::MediaChannel::Role::kBoth, &fake_call_, cricket::MediaConfig(),
cricket::VideoOptions(), webrtc::CryptoOptions(),
video_bitrate_allocator_factory_.get());
// TODO(hta): Split into sender and receiver channels
voice_media_channel_ = absl::WrapUnique(media_engine_->GetVoiceChannel(0));
video_media_channel_ = absl::WrapUnique(media_engine_->GetVideoChannel(0));

View File

@ -211,7 +211,8 @@ RTCError RtpTransceiver::CreateChannel(
cricket::VoiceMediaChannel* media_channel =
media_engine()->voice().CreateMediaChannel(
call_ptr, media_config, audio_options, crypto_options);
cricket::MediaChannel::Role::kBoth, call_ptr, media_config,
audio_options, crypto_options);
if (!media_channel) {
return;
}
@ -231,8 +232,8 @@ RTCError RtpTransceiver::CreateChannel(
RTC_DCHECK_RUN_ON(context()->worker_thread());
cricket::VideoMediaChannel* media_channel =
media_engine()->video().CreateMediaChannel(
call_ptr, media_config, video_options, crypto_options,
video_bitrate_allocator_factory);
cricket::MediaChannel::Role::kBoth, call_ptr, media_config,
video_options, crypto_options, video_bitrate_allocator_factory);
if (!media_channel) {
return;
}

View File

@ -30,7 +30,8 @@ namespace webrtc {
class FakeVoiceMediaChannelForStats : public cricket::FakeVoiceMediaChannel {
public:
explicit FakeVoiceMediaChannelForStats(TaskQueueBase* network_thread)
: cricket::FakeVoiceMediaChannel(nullptr,
: cricket::FakeVoiceMediaChannel(MediaChannel::Role::kBoth,
nullptr,
cricket::AudioOptions(),
network_thread) {}
@ -70,7 +71,8 @@ class FakeVoiceMediaChannelForStats : public cricket::FakeVoiceMediaChannel {
class FakeVideoMediaChannelForStats : public cricket::FakeVideoMediaChannel {
public:
explicit FakeVideoMediaChannelForStats(TaskQueueBase* network_thread)
: cricket::FakeVideoMediaChannel(nullptr,
: cricket::FakeVideoMediaChannel(MediaChannel::Role::kBoth,
nullptr,
cricket::VideoOptions(),
network_thread) {}

View File

@ -29,7 +29,7 @@ namespace cricket {
class MockVoiceMediaChannel : public VoiceMediaChannel {
public:
explicit MockVoiceMediaChannel(webrtc::TaskQueueBase* network_thread)
: VoiceMediaChannel(network_thread) {}
: VoiceMediaChannel(MediaChannel::Role::kBoth, network_thread) {}
MOCK_METHOD(void,
SetInterface,
@ -49,6 +49,9 @@ class MockVoiceMediaChannel : public VoiceMediaChannel {
(absl::string_view transport_name,
const rtc::NetworkRoute& network_route),
(override));
MOCK_METHOD(void, SetExtmapAllowMixed, (bool extmap_allow_mixed), (override));
MOCK_METHOD(bool, ExtmapAllowMixed, (), (const, override));
MOCK_METHOD(bool, HasNetworkInterface, (), (const, override));
MOCK_METHOD(bool, AddSendStream, (const StreamParams& sp), (override));
MOCK_METHOD(bool, RemoveSendStream, (uint32_t ssrc), (override));
MOCK_METHOD(bool, AddRecvStream, (const StreamParams& sp), (override));
@ -58,6 +61,7 @@ class MockVoiceMediaChannel : public VoiceMediaChannel {
GetUnsignaledSsrc,
(),
(const, override));
MOCK_METHOD(bool, SetLocalSsrc, (const StreamParams& sp), (override));
MOCK_METHOD(void, OnDemuxerCriteriaUpdatePending, (), (override));
MOCK_METHOD(void, OnDemuxerCriteriaUpdateComplete, (), (override));
MOCK_METHOD(int, GetRtpSendTimeExtnId, (), (const, override));

View File

@ -40,7 +40,10 @@ class VideoRtpReceiverTest : public testing::Test {
cricket::FakeVideoEngine* engine,
const cricket::VideoOptions& options,
TaskQueueBase* network_thread = rtc::Thread::Current())
: FakeVideoMediaChannel(engine, options, network_thread) {}
: FakeVideoMediaChannel(cricket::MediaChannel::Role::kBoth,
engine,
options,
network_thread) {}
MOCK_METHOD(void,
SetRecordableEncodedFrameCallback,
(uint32_t, std::function<void(const RecordableEncodedFrame&)>),