Propagate media transport to media channel.
1. Pass media transport factory to JSEP transport controller. 2. Pass media transport to voice media channel. 3. Add basic unit test that make sure if peer connection is created with media transport, it is propagated to voice media channel. Change-Id: Ie922db78ade0efd893e019cd2b4441a9947a2f71 Bug: webrtc:9719 Reviewed-on: https://webrtc-review.googlesource.com/c/105542 Reviewed-by: Steve Anton <steveanton@webrtc.org> Reviewed-by: Niels Moller <nisse@webrtc.org> Reviewed-by: Peter Slatala <psla@webrtc.org> Commit-Queue: Anton Sukhanov <sukhanov@google.com> Cr-Commit-Position: refs/heads/master@{#25152}
This commit is contained in:
parent
dbc2ea7590
commit
8c16f745ab
@ -62,9 +62,6 @@ class FakeMediaTransportFactory : public MediaTransportFactory {
|
||||
rtc::PacketTransportInternal* packet_transport,
|
||||
rtc::Thread* network_thread,
|
||||
bool is_caller) override {
|
||||
RTC_CHECK(network_thread != nullptr);
|
||||
RTC_CHECK(packet_transport != nullptr);
|
||||
|
||||
std::unique_ptr<MediaTransportInterface> media_transport =
|
||||
absl::make_unique<FakeMediaTransport>(is_caller);
|
||||
|
||||
|
||||
@ -16,15 +16,18 @@ VideoOptions::VideoOptions() = default;
|
||||
VideoOptions::~VideoOptions() = default;
|
||||
|
||||
MediaChannel::MediaChannel(const MediaConfig& config)
|
||||
: enable_dscp_(config.enable_dscp), network_interface_(NULL) {}
|
||||
: enable_dscp_(config.enable_dscp) {}
|
||||
|
||||
MediaChannel::MediaChannel() : enable_dscp_(false), network_interface_(NULL) {}
|
||||
MediaChannel::MediaChannel() : enable_dscp_(false) {}
|
||||
|
||||
MediaChannel::~MediaChannel() {}
|
||||
|
||||
void MediaChannel::SetInterface(NetworkInterface* iface) {
|
||||
void MediaChannel::SetInterface(
|
||||
NetworkInterface* iface,
|
||||
webrtc::MediaTransportInterface* media_transport) {
|
||||
rtc::CritScope cs(&network_interface_crit_);
|
||||
network_interface_ = iface;
|
||||
media_transport_ = media_transport;
|
||||
SetDscp(enable_dscp_ ? PreferredDscp() : rtc::DSCP_DEFAULT);
|
||||
}
|
||||
|
||||
|
||||
@ -22,6 +22,7 @@
|
||||
#include "api/audio_options.h"
|
||||
#include "api/crypto/framedecryptorinterface.h"
|
||||
#include "api/crypto/frameencryptorinterface.h"
|
||||
#include "api/media_transport_interface.h"
|
||||
#include "api/rtcerror.h"
|
||||
#include "api/rtpparameters.h"
|
||||
#include "api/rtpreceiverinterface.h"
|
||||
@ -183,8 +184,14 @@ class MediaChannel : public sigslot::has_slots<> {
|
||||
MediaChannel();
|
||||
~MediaChannel() override;
|
||||
|
||||
// Sets the abstract interface class for sending RTP/RTCP data.
|
||||
virtual void SetInterface(NetworkInterface* iface);
|
||||
// Sets the abstract interface class for sending RTP/RTCP data and
|
||||
// interface for media transport (experimental). If media transport is
|
||||
// provided, it should be used instead of RTP/RTCP.
|
||||
// TODO(sukhanov): Currently media transport can co-exist with RTP/RTCP, but
|
||||
// in the future we will refactor code to send all frames with media
|
||||
// transport.
|
||||
virtual void SetInterface(NetworkInterface* iface,
|
||||
webrtc::MediaTransportInterface* media_transport);
|
||||
// Called when a RTP packet is received.
|
||||
virtual void OnPacketReceived(rtc::CopyOnWriteBuffer* packet,
|
||||
const rtc::PacketTime& packet_time) = 0;
|
||||
@ -251,6 +258,10 @@ class MediaChannel : public sigslot::has_slots<> {
|
||||
return network_interface_->SetOption(type, opt, option);
|
||||
}
|
||||
|
||||
webrtc::MediaTransportInterface* media_transport() {
|
||||
return media_transport_;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual rtc::DiffServCodePoint PreferredDscp() const;
|
||||
|
||||
@ -283,7 +294,8 @@ class MediaChannel : public sigslot::has_slots<> {
|
||||
// from any MediaEngine threads. This critical section is to protect accessing
|
||||
// of network_interface_ object.
|
||||
rtc::CriticalSection network_interface_crit_;
|
||||
NetworkInterface* network_interface_;
|
||||
NetworkInterface* network_interface_ = nullptr;
|
||||
webrtc::MediaTransportInterface* media_transport_ = nullptr;
|
||||
};
|
||||
|
||||
// The stats information is structured as follows:
|
||||
|
||||
@ -73,7 +73,7 @@ class RtpDataMediaChannelTest : public testing::Test {
|
||||
cricket::MediaConfig config;
|
||||
cricket::RtpDataMediaChannel* channel =
|
||||
static_cast<cricket::RtpDataMediaChannel*>(dme->CreateChannel(config));
|
||||
channel->SetInterface(iface_.get());
|
||||
channel->SetInterface(iface_.get(), /*media_transport=*/nullptr);
|
||||
channel->SignalDataReceived.connect(receiver_.get(),
|
||||
&FakeDataReceiver::OnDataReceived);
|
||||
return channel;
|
||||
|
||||
@ -1417,8 +1417,13 @@ void WebRtcVideoChannel::OnNetworkRouteChanged(
|
||||
network_route.packet_overhead);
|
||||
}
|
||||
|
||||
void WebRtcVideoChannel::SetInterface(NetworkInterface* iface) {
|
||||
MediaChannel::SetInterface(iface);
|
||||
void WebRtcVideoChannel::SetInterface(
|
||||
NetworkInterface* iface,
|
||||
webrtc::MediaTransportInterface* media_transport) {
|
||||
// TODO(sukhanov): Video is not currently supported with media transport.
|
||||
RTC_CHECK(media_transport == nullptr);
|
||||
|
||||
MediaChannel::SetInterface(iface, media_transport);
|
||||
// Set the RTP recv/send buffer to a bigger size.
|
||||
|
||||
// The group here can be either a positive integer with an explicit size, in
|
||||
|
||||
@ -153,7 +153,8 @@ class WebRtcVideoChannel : public VideoMediaChannel, public webrtc::Transport {
|
||||
void OnReadyToSend(bool ready) override;
|
||||
void OnNetworkRouteChanged(const std::string& transport_name,
|
||||
const rtc::NetworkRoute& network_route) override;
|
||||
void SetInterface(NetworkInterface* iface) override;
|
||||
void SetInterface(NetworkInterface* iface,
|
||||
webrtc::MediaTransportInterface* media_transport) override;
|
||||
|
||||
// Implemented for VideoMediaChannelTest.
|
||||
bool sending() const { return sending_; }
|
||||
|
||||
@ -1260,7 +1260,7 @@ class WebRtcVideoChannelBaseTest : public testing::Test {
|
||||
channel_->OnReadyToSend(true);
|
||||
EXPECT_TRUE(channel_.get() != NULL);
|
||||
network_interface_.SetDestination(channel_.get());
|
||||
channel_->SetInterface(&network_interface_);
|
||||
channel_->SetInterface(&network_interface_, /*media_transport=*/nullptr);
|
||||
cricket::VideoRecvParameters parameters;
|
||||
parameters.codecs = engine_.codecs();
|
||||
channel_->SetRecvParameters(parameters);
|
||||
@ -4597,14 +4597,14 @@ TEST_F(WebRtcVideoChannelTest, TestSetDscpOptions) {
|
||||
|
||||
channel.reset(static_cast<cricket::WebRtcVideoChannel*>(
|
||||
engine_.CreateChannel(call_.get(), config, VideoOptions())));
|
||||
channel->SetInterface(network_interface.get());
|
||||
channel->SetInterface(network_interface.get(), /*media_transport=*/nullptr);
|
||||
// Default value when DSCP is disabled should be DSCP_DEFAULT.
|
||||
EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface->dscp());
|
||||
|
||||
config.enable_dscp = true;
|
||||
channel.reset(static_cast<cricket::WebRtcVideoChannel*>(
|
||||
engine_.CreateChannel(call_.get(), config, VideoOptions())));
|
||||
channel->SetInterface(network_interface.get());
|
||||
channel->SetInterface(network_interface.get(), /*media_transport=*/nullptr);
|
||||
EXPECT_EQ(rtc::DSCP_AF41, network_interface->dscp());
|
||||
|
||||
// Packets should also self-identify their dscp in PacketOptions.
|
||||
@ -4618,7 +4618,7 @@ TEST_F(WebRtcVideoChannelTest, TestSetDscpOptions) {
|
||||
config.enable_dscp = false;
|
||||
channel.reset(static_cast<cricket::WebRtcVideoChannel*>(
|
||||
engine_.CreateChannel(call_.get(), config, VideoOptions())));
|
||||
channel->SetInterface(network_interface.get());
|
||||
channel->SetInterface(network_interface.get(), /*media_transport=*/nullptr);
|
||||
EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface->dscp());
|
||||
}
|
||||
|
||||
|
||||
@ -3027,14 +3027,14 @@ TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
|
||||
|
||||
channel.reset(static_cast<cricket::WebRtcVoiceMediaChannel*>(
|
||||
engine_->CreateChannel(&call_, config, cricket::AudioOptions())));
|
||||
channel->SetInterface(&network_interface);
|
||||
channel->SetInterface(&network_interface, /*media_transport=*/nullptr);
|
||||
// Default value when DSCP is disabled should be DSCP_DEFAULT.
|
||||
EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
|
||||
|
||||
config.enable_dscp = true;
|
||||
channel.reset(static_cast<cricket::WebRtcVoiceMediaChannel*>(
|
||||
engine_->CreateChannel(&call_, config, cricket::AudioOptions())));
|
||||
channel->SetInterface(&network_interface);
|
||||
channel->SetInterface(&network_interface, /*media_transport=*/nullptr);
|
||||
EXPECT_EQ(rtc::DSCP_EF, network_interface.dscp());
|
||||
|
||||
// Packets should also self-identify their dscp in PacketOptions.
|
||||
@ -3047,11 +3047,11 @@ TEST_F(WebRtcVoiceEngineTestFake, TestSetDscpOptions) {
|
||||
config.enable_dscp = false;
|
||||
channel.reset(static_cast<cricket::WebRtcVoiceMediaChannel*>(
|
||||
engine_->CreateChannel(&call_, config, cricket::AudioOptions())));
|
||||
channel->SetInterface(&network_interface);
|
||||
channel->SetInterface(&network_interface, /*media_transport=*/nullptr);
|
||||
// Default value when DSCP is disabled should be DSCP_DEFAULT.
|
||||
EXPECT_EQ(rtc::DSCP_DEFAULT, network_interface.dscp());
|
||||
|
||||
channel->SetInterface(nullptr);
|
||||
channel->SetInterface(nullptr, nullptr);
|
||||
}
|
||||
|
||||
TEST_F(WebRtcVoiceEngineTestFake, SetOutputVolume) {
|
||||
|
||||
@ -514,6 +514,7 @@ if (rtc_include_tests) {
|
||||
":pc_test_utils",
|
||||
"..:webrtc_common",
|
||||
"../api:callfactory_api",
|
||||
"../api:fake_media_transport",
|
||||
"../api:libjingle_peerconnection_test_api",
|
||||
"../api:rtc_stats_api",
|
||||
"../api/audio_codecs:audio_codecs_api",
|
||||
|
||||
@ -155,19 +155,21 @@ void BaseChannel::DisconnectFromRtpTransport() {
|
||||
rtp_transport_->SignalSentPacket.disconnect(this);
|
||||
}
|
||||
|
||||
void BaseChannel::Init_w(webrtc::RtpTransportInternal* rtp_transport) {
|
||||
void BaseChannel::Init_w(webrtc::RtpTransportInternal* rtp_transport,
|
||||
webrtc::MediaTransportInterface* media_transport) {
|
||||
RTC_DCHECK_RUN_ON(worker_thread_);
|
||||
network_thread_->Invoke<void>(
|
||||
RTC_FROM_HERE, [this, rtp_transport] { SetRtpTransport(rtp_transport); });
|
||||
|
||||
// Both RTP and RTCP channels should be set, we can call SetInterface on
|
||||
// the media channel and it can set network options.
|
||||
media_channel_->SetInterface(this);
|
||||
media_channel_->SetInterface(this, media_transport);
|
||||
}
|
||||
|
||||
void BaseChannel::Deinit() {
|
||||
RTC_DCHECK(worker_thread_->IsCurrent());
|
||||
media_channel_->SetInterface(NULL);
|
||||
media_channel_->SetInterface(/*iface=*/nullptr,
|
||||
/*media_transport=*/nullptr);
|
||||
// Packets arrive on the network thread, processing packets calls virtual
|
||||
// functions, so need to stop this process in Deinit that is called in
|
||||
// derived classes destructor.
|
||||
@ -1036,7 +1038,7 @@ RtpDataChannel::~RtpDataChannel() {
|
||||
}
|
||||
|
||||
void RtpDataChannel::Init_w(webrtc::RtpTransportInternal* rtp_transport) {
|
||||
BaseChannel::Init_w(rtp_transport);
|
||||
BaseChannel::Init_w(rtp_transport, /*media_transport=*/nullptr);
|
||||
media_channel()->SignalDataReceived.connect(this,
|
||||
&RtpDataChannel::OnDataReceived);
|
||||
media_channel()->SignalReadyToSend.connect(
|
||||
|
||||
14
pc/channel.h
14
pc/channel.h
@ -42,6 +42,7 @@
|
||||
|
||||
namespace webrtc {
|
||||
class AudioSinkInterface;
|
||||
class MediaTransportInterface;
|
||||
} // namespace webrtc
|
||||
|
||||
namespace cricket {
|
||||
@ -84,7 +85,8 @@ class BaseChannel : public rtc::MessageHandler,
|
||||
bool srtp_required,
|
||||
webrtc::CryptoOptions crypto_options);
|
||||
virtual ~BaseChannel();
|
||||
void Init_w(webrtc::RtpTransportInternal* rtp_transport);
|
||||
void Init_w(webrtc::RtpTransportInternal* rtp_transport,
|
||||
webrtc::MediaTransportInterface* media_transport);
|
||||
|
||||
// Deinit may be called multiple times and is simply ignored if it's already
|
||||
// done.
|
||||
@ -162,6 +164,11 @@ class BaseChannel : public rtc::MessageHandler,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Returns media transport, can be null if media transport is not available.
|
||||
webrtc::MediaTransportInterface* media_transport() {
|
||||
return media_transport_;
|
||||
}
|
||||
|
||||
// From RtpTransport - public for testing only
|
||||
void OnTransportReadyToSend(bool ready);
|
||||
|
||||
@ -307,6 +314,11 @@ class BaseChannel : public rtc::MessageHandler,
|
||||
|
||||
webrtc::RtpTransportInternal* rtp_transport_ = nullptr;
|
||||
|
||||
// Optional media transport (experimental).
|
||||
// If provided, audio and video will be sent through media_transport instead
|
||||
// of RTP/RTCP. Currently media_transport can co-exist with rtp_transport.
|
||||
webrtc::MediaTransportInterface* media_transport_ = nullptr;
|
||||
|
||||
std::vector<std::pair<rtc::Socket::Option, int> > socket_options_;
|
||||
std::vector<std::pair<rtc::Socket::Option, int> > rtcp_socket_options_;
|
||||
bool writable_ = false;
|
||||
|
||||
@ -251,7 +251,7 @@ class ChannelTest : public testing::Test, public sigslot::has_slots<> {
|
||||
auto channel = absl::make_unique<typename T::Channel>(
|
||||
worker_thread, network_thread, signaling_thread, engine, std::move(ch),
|
||||
cricket::CN_AUDIO, (flags & DTLS) != 0, webrtc::CryptoOptions());
|
||||
channel->Init_w(rtp_transport);
|
||||
channel->Init_w(rtp_transport, /*media_transport=*/nullptr);
|
||||
return channel;
|
||||
}
|
||||
|
||||
@ -1546,7 +1546,7 @@ std::unique_ptr<cricket::VideoChannel> ChannelTest<VideoTraits>::CreateChannel(
|
||||
auto channel = absl::make_unique<cricket::VideoChannel>(
|
||||
worker_thread, network_thread, signaling_thread, std::move(ch),
|
||||
cricket::CN_VIDEO, (flags & DTLS) != 0, webrtc::CryptoOptions());
|
||||
channel->Init_w(rtp_transport);
|
||||
channel->Init_w(rtp_transport, /*media_transport=*/nullptr);
|
||||
return channel;
|
||||
}
|
||||
|
||||
|
||||
@ -156,6 +156,7 @@ VoiceChannel* ChannelManager::CreateVoiceChannel(
|
||||
webrtc::Call* call,
|
||||
const cricket::MediaConfig& media_config,
|
||||
webrtc::RtpTransportInternal* rtp_transport,
|
||||
webrtc::MediaTransportInterface* media_transport,
|
||||
rtc::Thread* signaling_thread,
|
||||
const std::string& content_name,
|
||||
bool srtp_required,
|
||||
@ -164,8 +165,8 @@ VoiceChannel* ChannelManager::CreateVoiceChannel(
|
||||
if (!worker_thread_->IsCurrent()) {
|
||||
return worker_thread_->Invoke<VoiceChannel*>(RTC_FROM_HERE, [&] {
|
||||
return CreateVoiceChannel(call, media_config, rtp_transport,
|
||||
signaling_thread, content_name, srtp_required,
|
||||
crypto_options, options);
|
||||
media_transport, signaling_thread, content_name,
|
||||
srtp_required, crypto_options, options);
|
||||
});
|
||||
}
|
||||
|
||||
@ -187,7 +188,7 @@ VoiceChannel* ChannelManager::CreateVoiceChannel(
|
||||
absl::WrapUnique(media_channel), content_name, srtp_required,
|
||||
crypto_options);
|
||||
|
||||
voice_channel->Init_w(rtp_transport);
|
||||
voice_channel->Init_w(rtp_transport, media_transport);
|
||||
|
||||
VoiceChannel* voice_channel_ptr = voice_channel.get();
|
||||
voice_channels_.push_back(std::move(voice_channel));
|
||||
@ -253,7 +254,9 @@ VideoChannel* ChannelManager::CreateVideoChannel(
|
||||
worker_thread_, network_thread_, signaling_thread,
|
||||
absl::WrapUnique(media_channel), content_name, srtp_required,
|
||||
crypto_options);
|
||||
video_channel->Init_w(rtp_transport);
|
||||
|
||||
// TODO(sukhanov): Add media_transport support for video channel.
|
||||
video_channel->Init_w(rtp_transport, /*media_transport=*/nullptr);
|
||||
|
||||
VideoChannel* video_channel_ptr = video_channel.get();
|
||||
video_channels_.push_back(std::move(video_channel));
|
||||
|
||||
@ -80,14 +80,16 @@ class ChannelManager final {
|
||||
// call the appropriate Destroy*Channel method when done.
|
||||
|
||||
// Creates a voice channel, to be associated with the specified session.
|
||||
VoiceChannel* CreateVoiceChannel(webrtc::Call* call,
|
||||
const cricket::MediaConfig& media_config,
|
||||
webrtc::RtpTransportInternal* rtp_transport,
|
||||
rtc::Thread* signaling_thread,
|
||||
const std::string& content_name,
|
||||
bool srtp_required,
|
||||
const webrtc::CryptoOptions& crypto_options,
|
||||
const AudioOptions& options);
|
||||
VoiceChannel* CreateVoiceChannel(
|
||||
webrtc::Call* call,
|
||||
const cricket::MediaConfig& media_config,
|
||||
webrtc::RtpTransportInternal* rtp_transport,
|
||||
webrtc::MediaTransportInterface* media_transport,
|
||||
rtc::Thread* signaling_thread,
|
||||
const std::string& content_name,
|
||||
bool srtp_required,
|
||||
const webrtc::CryptoOptions& crypto_options,
|
||||
const AudioOptions& options);
|
||||
// Destroys a voice channel created by CreateVoiceChannel.
|
||||
void DestroyVoiceChannel(VoiceChannel* voice_channel);
|
||||
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include "api/test/fake_media_transport.h"
|
||||
#include "media/base/fakemediaengine.h"
|
||||
#include "media/base/testutils.h"
|
||||
#include "media/engine/fakewebrtccall.h"
|
||||
@ -61,9 +62,21 @@ class ChannelManagerTest : public testing::Test {
|
||||
return dtls_srtp_transport;
|
||||
}
|
||||
|
||||
void TestCreateDestroyChannels(webrtc::RtpTransportInternal* rtp_transport) {
|
||||
std::unique_ptr<webrtc::MediaTransportInterface> CreateMediaTransport(
|
||||
rtc::PacketTransportInternal* packet_transport) {
|
||||
auto media_transport_result =
|
||||
fake_media_transport_factory_.CreateMediaTransport(packet_transport,
|
||||
network_.get(),
|
||||
/*is_caller=*/true);
|
||||
RTC_CHECK(media_transport_result.ok());
|
||||
return media_transport_result.MoveValue();
|
||||
}
|
||||
|
||||
void TestCreateDestroyChannels(
|
||||
webrtc::RtpTransportInternal* rtp_transport,
|
||||
webrtc::MediaTransportInterface* media_transport) {
|
||||
cricket::VoiceChannel* voice_channel = cm_->CreateVoiceChannel(
|
||||
&fake_call_, cricket::MediaConfig(), rtp_transport,
|
||||
&fake_call_, cricket::MediaConfig(), rtp_transport, media_transport,
|
||||
rtc::Thread::Current(), cricket::CN_AUDIO, kDefaultSrtpRequired,
|
||||
webrtc::CryptoOptions(), AudioOptions());
|
||||
EXPECT_TRUE(voice_channel != nullptr);
|
||||
@ -90,6 +103,7 @@ class ChannelManagerTest : public testing::Test {
|
||||
cricket::FakeDataEngine* fdme_;
|
||||
std::unique_ptr<cricket::ChannelManager> cm_;
|
||||
cricket::FakeCall fake_call_;
|
||||
webrtc::FakeMediaTransportFactory fake_media_transport_factory_;
|
||||
};
|
||||
|
||||
// Test that we startup/shutdown properly.
|
||||
@ -154,7 +168,15 @@ TEST_F(ChannelManagerTest, SetVideoRtxEnabled) {
|
||||
TEST_F(ChannelManagerTest, CreateDestroyChannels) {
|
||||
EXPECT_TRUE(cm_->Init());
|
||||
auto rtp_transport = CreateDtlsSrtpTransport();
|
||||
TestCreateDestroyChannels(rtp_transport.get());
|
||||
TestCreateDestroyChannels(rtp_transport.get(), /*media_transport=*/nullptr);
|
||||
}
|
||||
|
||||
TEST_F(ChannelManagerTest, CreateDestroyChannelsWithMediaTransport) {
|
||||
EXPECT_TRUE(cm_->Init());
|
||||
auto rtp_transport = CreateDtlsSrtpTransport();
|
||||
auto media_transport =
|
||||
CreateMediaTransport(rtp_transport->rtcp_packet_transport());
|
||||
TestCreateDestroyChannels(rtp_transport.get(), media_transport.get());
|
||||
}
|
||||
|
||||
TEST_F(ChannelManagerTest, CreateDestroyChannelsOnThread) {
|
||||
@ -164,7 +186,7 @@ TEST_F(ChannelManagerTest, CreateDestroyChannelsOnThread) {
|
||||
EXPECT_TRUE(cm_->set_network_thread(network_.get()));
|
||||
EXPECT_TRUE(cm_->Init());
|
||||
auto rtp_transport = CreateDtlsSrtpTransport();
|
||||
TestCreateDestroyChannels(rtp_transport.get());
|
||||
TestCreateDestroyChannels(rtp_transport.get(), /*media_transport=*/nullptr);
|
||||
}
|
||||
|
||||
} // namespace cricket
|
||||
|
||||
@ -939,6 +939,18 @@ bool PeerConnection::Initialize(
|
||||
config.enable_external_auth = true;
|
||||
#endif
|
||||
config.active_reset_srtp_params = configuration.active_reset_srtp_params;
|
||||
|
||||
if (configuration.use_media_transport) {
|
||||
if (!factory_->media_transport_factory()) {
|
||||
RTC_DCHECK(false)
|
||||
<< "PeerConnecton is initialized with use_media_transport = true, "
|
||||
<< "but media transport factory is not set in PeerConnectioFactory";
|
||||
return false;
|
||||
}
|
||||
|
||||
config.media_transport_factory = factory_->media_transport_factory();
|
||||
}
|
||||
|
||||
transport_controller_.reset(new JsepTransportController(
|
||||
signaling_thread(), network_thread(), port_allocator_.get(),
|
||||
async_resolver_factory_.get(), config));
|
||||
@ -5512,11 +5524,11 @@ RTCError PeerConnection::CreateChannels(const SessionDescription& desc) {
|
||||
// TODO(steveanton): Perhaps this should be managed by the RtpTransceiver.
|
||||
cricket::VoiceChannel* PeerConnection::CreateVoiceChannel(
|
||||
const std::string& mid) {
|
||||
RtpTransportInternal* rtp_transport =
|
||||
transport_controller_->GetRtpTransport(mid);
|
||||
RTC_DCHECK(rtp_transport);
|
||||
RtpTransportInternal* rtp_transport = GetRtpTransport(mid);
|
||||
MediaTransportInterface* media_transport = GetMediaTransport(mid);
|
||||
|
||||
cricket::VoiceChannel* voice_channel = channel_manager()->CreateVoiceChannel(
|
||||
call_.get(), configuration_.media_config, rtp_transport,
|
||||
call_.get(), configuration_.media_config, rtp_transport, media_transport,
|
||||
signaling_thread(), mid, SrtpRequired(),
|
||||
factory_->options().crypto_options, audio_options_);
|
||||
if (!voice_channel) {
|
||||
@ -5534,9 +5546,9 @@ cricket::VoiceChannel* PeerConnection::CreateVoiceChannel(
|
||||
// TODO(steveanton): Perhaps this should be managed by the RtpTransceiver.
|
||||
cricket::VideoChannel* PeerConnection::CreateVideoChannel(
|
||||
const std::string& mid) {
|
||||
RtpTransportInternal* rtp_transport =
|
||||
transport_controller_->GetRtpTransport(mid);
|
||||
RTC_DCHECK(rtp_transport);
|
||||
RtpTransportInternal* rtp_transport = GetRtpTransport(mid);
|
||||
|
||||
// TODO(sukhanov): Propagate media_transport to video channel.
|
||||
cricket::VideoChannel* video_channel = channel_manager()->CreateVideoChannel(
|
||||
call_.get(), configuration_.media_config, rtp_transport,
|
||||
signaling_thread(), mid, SrtpRequired(),
|
||||
@ -5571,9 +5583,7 @@ bool PeerConnection::CreateDataChannel(const std::string& mid) {
|
||||
channel->OnTransportChannelCreated();
|
||||
}
|
||||
} else {
|
||||
RtpTransportInternal* rtp_transport =
|
||||
transport_controller_->GetRtpTransport(mid);
|
||||
RTC_DCHECK(rtp_transport);
|
||||
RtpTransportInternal* rtp_transport = GetRtpTransport(mid);
|
||||
rtp_data_channel_ = channel_manager()->CreateRtpDataChannel(
|
||||
configuration_.media_config, rtp_transport, signaling_thread(), mid,
|
||||
SrtpRequired(), factory_->options().crypto_options);
|
||||
|
||||
@ -915,6 +915,22 @@ class PeerConnection : public PeerConnectionInternal,
|
||||
// Returns the observer. Will crash on CHECK if the observer is removed.
|
||||
PeerConnectionObserver* Observer() const;
|
||||
|
||||
// Returns rtp transport, result can not be nullptr.
|
||||
RtpTransportInternal* GetRtpTransport(const std::string& mid) {
|
||||
auto rtp_transport = transport_controller_->GetRtpTransport(mid);
|
||||
RTC_DCHECK(rtp_transport);
|
||||
return rtp_transport;
|
||||
}
|
||||
|
||||
// Returns media transport, if PeerConnection was created with configuration
|
||||
// to use media transport. Otherwise returns nullptr.
|
||||
MediaTransportInterface* GetMediaTransport(const std::string& mid) {
|
||||
auto media_transport = transport_controller_->GetMediaTransport(mid);
|
||||
RTC_DCHECK(configuration_.use_media_transport ==
|
||||
(media_transport != nullptr));
|
||||
return media_transport;
|
||||
}
|
||||
|
||||
sigslot::signal1<DataChannel*> SignalDataChannelCreated_;
|
||||
|
||||
// Storing the factory as a scoped reference pointer ensures that the memory
|
||||
|
||||
@ -15,6 +15,7 @@
|
||||
#include <tuple>
|
||||
|
||||
#include "api/call/callfactoryinterface.h"
|
||||
#include "api/test/fake_media_transport.h"
|
||||
#include "logging/rtc_event_log/rtc_event_log_factory.h"
|
||||
#include "media/base/fakemediaengine.h"
|
||||
#include "p2p/base/fakeportallocator.h"
|
||||
@ -71,13 +72,26 @@ class PeerConnectionMediaBaseTest : public ::testing::Test {
|
||||
return CreatePeerConnection(RTCConfiguration());
|
||||
}
|
||||
|
||||
// Creates PeerConnectionFactory and PeerConnection for given configuration.
|
||||
// Note that PeerConnectionFactory is created with MediaTransportFactory,
|
||||
// because some tests pass config.use_media_transport = true.
|
||||
WrapperPtr CreatePeerConnection(const RTCConfiguration& config) {
|
||||
auto media_engine = absl::make_unique<FakeMediaEngine>();
|
||||
auto* media_engine_ptr = media_engine.get();
|
||||
auto pc_factory = CreateModularPeerConnectionFactory(
|
||||
rtc::Thread::Current(), rtc::Thread::Current(), rtc::Thread::Current(),
|
||||
std::move(media_engine), CreateCallFactory(),
|
||||
CreateRtcEventLogFactory());
|
||||
|
||||
PeerConnectionFactoryDependencies factory_dependencies;
|
||||
|
||||
factory_dependencies.network_thread = rtc::Thread::Current();
|
||||
factory_dependencies.worker_thread = rtc::Thread::Current();
|
||||
factory_dependencies.signaling_thread = rtc::Thread::Current();
|
||||
factory_dependencies.media_engine = std::move(media_engine);
|
||||
factory_dependencies.call_factory = CreateCallFactory();
|
||||
factory_dependencies.event_log_factory = CreateRtcEventLogFactory();
|
||||
factory_dependencies.media_transport_factory =
|
||||
absl::make_unique<FakeMediaTransportFactory>();
|
||||
|
||||
auto pc_factory =
|
||||
CreateModularPeerConnectionFactory(std::move(factory_dependencies));
|
||||
|
||||
auto fake_port_allocator = absl::make_unique<cricket::FakePortAllocator>(
|
||||
rtc::Thread::Current(), nullptr);
|
||||
@ -1072,6 +1086,69 @@ TEST_P(PeerConnectionMediaTest,
|
||||
audio_options.combined_audio_video_bwe);
|
||||
}
|
||||
|
||||
TEST_P(PeerConnectionMediaTest, MediaTransportPropagatedToVoiceEngine) {
|
||||
RTCConfiguration config;
|
||||
|
||||
// Setup PeerConnection to use media transport.
|
||||
config.use_media_transport = true;
|
||||
|
||||
auto caller = CreatePeerConnectionWithAudioVideo(config);
|
||||
auto callee = CreatePeerConnectionWithAudioVideo(config);
|
||||
|
||||
ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
|
||||
auto answer = callee->CreateAnswer();
|
||||
ASSERT_TRUE(callee->SetLocalDescription(std::move(answer)));
|
||||
|
||||
auto caller_voice = caller->media_engine()->GetVoiceChannel(0);
|
||||
auto callee_voice = callee->media_engine()->GetVoiceChannel(0);
|
||||
ASSERT_TRUE(caller_voice);
|
||||
ASSERT_TRUE(callee_voice);
|
||||
|
||||
// Make sure media transport is propagated to voice channel.
|
||||
FakeMediaTransport* caller_voice_media_transport =
|
||||
static_cast<FakeMediaTransport*>(caller_voice->media_transport());
|
||||
FakeMediaTransport* callee_voice_media_transport =
|
||||
static_cast<FakeMediaTransport*>(callee_voice->media_transport());
|
||||
ASSERT_NE(nullptr, caller_voice_media_transport);
|
||||
ASSERT_NE(nullptr, callee_voice_media_transport);
|
||||
|
||||
// Make sure media transport is created with correct is_caller.
|
||||
EXPECT_TRUE(caller_voice_media_transport->is_caller());
|
||||
EXPECT_FALSE(callee_voice_media_transport->is_caller());
|
||||
|
||||
// TODO(sukhanov): Propagate media transport to video channel. This test
|
||||
// will fail once media transport is propagated to video channel and it will
|
||||
// serve as a reminder to add a test for video channel propagation.
|
||||
auto caller_video = caller->media_engine()->GetVideoChannel(0);
|
||||
auto callee_video = callee->media_engine()->GetVideoChannel(0);
|
||||
ASSERT_EQ(nullptr, caller_video->media_transport());
|
||||
ASSERT_EQ(nullptr, callee_video->media_transport());
|
||||
}
|
||||
|
||||
TEST_P(PeerConnectionMediaTest, MediaTransportNotPropagatedToVoiceEngine) {
|
||||
auto caller = CreatePeerConnectionWithAudioVideo();
|
||||
auto callee = CreatePeerConnectionWithAudioVideo();
|
||||
|
||||
ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));
|
||||
auto answer = callee->CreateAnswer();
|
||||
ASSERT_TRUE(callee->SetLocalDescription(std::move(answer)));
|
||||
|
||||
auto caller_voice = caller->media_engine()->GetVoiceChannel(0);
|
||||
auto callee_voice = callee->media_engine()->GetVoiceChannel(0);
|
||||
ASSERT_TRUE(caller_voice);
|
||||
ASSERT_TRUE(callee_voice);
|
||||
|
||||
// Since we did not setup PeerConnection to use media transport, media
|
||||
// transport should not be created / propagated to the voice engine.
|
||||
ASSERT_EQ(nullptr, caller_voice->media_transport());
|
||||
ASSERT_EQ(nullptr, callee_voice->media_transport());
|
||||
|
||||
auto caller_video = caller->media_engine()->GetVideoChannel(0);
|
||||
auto callee_video = callee->media_engine()->GetVideoChannel(0);
|
||||
ASSERT_EQ(nullptr, caller_video->media_transport());
|
||||
ASSERT_EQ(nullptr, callee_video->media_transport());
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(PeerConnectionMediaTest,
|
||||
PeerConnectionMediaTest,
|
||||
Values(SdpSemantics::kPlanB,
|
||||
|
||||
@ -80,8 +80,8 @@ class RtpSenderReceiverTest : public testing::Test,
|
||||
|
||||
voice_channel_ = channel_manager_.CreateVoiceChannel(
|
||||
&fake_call_, cricket::MediaConfig(), rtp_transport_.get(),
|
||||
rtc::Thread::Current(), cricket::CN_AUDIO, srtp_required,
|
||||
webrtc::CryptoOptions(), cricket::AudioOptions());
|
||||
/*media_transport=*/nullptr, rtc::Thread::Current(), cricket::CN_AUDIO,
|
||||
srtp_required, webrtc::CryptoOptions(), cricket::AudioOptions());
|
||||
video_channel_ = channel_manager_.CreateVideoChannel(
|
||||
&fake_call_, cricket::MediaConfig(), rtp_transport_.get(),
|
||||
rtc::Thread::Current(), cricket::CN_VIDEO, srtp_required,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user