Skip to content
This repository has been archived by the owner on Oct 23, 2024. It is now read-only.

Support webrtc unbundle audio/video and separated port setting #977

Open
wants to merge 5 commits into
base: 5.0.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
From 86a18375674dd3255b4ed373e0f5a62884c08f7a Mon Sep 17 00:00:00 2001
From: Chen Li1 <li1.chen@intel.com>
Date: Wed, 14 Apr 2021 15:53:11 +0800
Subject: [PATCH] Support unbundle audio/video and port setting

---
erizo/src/erizo/WebRtcConnection.cpp | 31 +++++++++++++++++++++++++---
erizo/src/erizo/WebRtcConnection.h | 6 ++++++
2 files changed, 34 insertions(+), 3 deletions(-)

diff --git a/erizo/src/erizo/WebRtcConnection.cpp b/erizo/src/erizo/WebRtcConnection.cpp
index b1438118..1846f14e 100644
--- a/erizo/src/erizo/WebRtcConnection.cpp
+++ b/erizo/src/erizo/WebRtcConnection.cpp
@@ -339,6 +339,9 @@ bool WebRtcConnection::processRemoteSdp(std::string stream_id) {
if (video_transport_.get() == nullptr) {
ELOG_DEBUG("%s message: Creating videoTransport, ufrag: %s, pass: %s",
toLog(), username.c_str(), password.c_str());
+ if (!bundle_ && video_ice_config_.media_type == VIDEO_TYPE) {
+ ice_config_ = video_ice_config_;
+ }
video_transport_.reset(new DtlsTransport(VIDEO_TYPE, "video", connection_id_, bundle_, remote_sdp_->isRtcpMux,
listener, ice_config_ , username, password, false,
worker_, io_worker_));
@@ -356,6 +359,9 @@ bool WebRtcConnection::processRemoteSdp(std::string stream_id) {
if (audio_transport_.get() == nullptr) {
ELOG_DEBUG("%s message: Creating audioTransport, ufrag: %s, pass: %s",
toLog(), username.c_str(), password.c_str());
+ if (audio_ice_config_.media_type == AUDIO_TYPE) {
+ ice_config_ = audio_ice_config_;
+ }
audio_transport_.reset(new DtlsTransport(AUDIO_TYPE, "audio", connection_id_, bundle_, remote_sdp_->isRtcpMux,
listener, ice_config_, username, password, false,
worker_, io_worker_));
@@ -588,10 +594,13 @@ void WebRtcConnection::onTransportData(std::shared_ptr<DataPacket> packet, Trans

if (mapping_ssrcs_.count(streamId) == 0) {
// Set SSRC for mid/rsid
- forEachMediaStream([this, streamId, ssrc] (const std::shared_ptr<MediaStream> &media_stream) {
+ forEachMediaStream([this, streamId, ssrc, transport] (const std::shared_ptr<MediaStream> &media_stream) {
if (media_stream->getId() == streamId) {
- media_stream->setVideoSourceSSRC(ssrc);
- media_stream->setVideoSourceSSRC(ssrc);
+ if (transport->mediaType == AUDIO_TYPE) {
+ media_stream->setAudioSourceSSRC(ssrc);
+ } else if (transport->mediaType == VIDEO_TYPE) {
+ media_stream->setVideoSourceSSRC(ssrc);
+ }
mapping_ssrcs_[streamId] = ssrc;
}
});
@@ -791,4 +800,20 @@ void WebRtcConnection::setTransport(std::shared_ptr<Transport> transport) { //
bundle_ = true;
}

+void WebRtcConnection::setUnbundleAudioPort(int minport, int maxport) {
+ ELOG_DEBUG("Audio port range: %d, %d", minport, maxport);
+ audio_ice_config_ = ice_config_;
+ audio_ice_config_.media_type = AUDIO_TYPE;
+ audio_ice_config_.min_port = (uint16_t) minport;
+ audio_ice_config_.max_port = (uint16_t) maxport;
+}
+
+void WebRtcConnection::setUnbundleVideoPort(int minport, int maxport) {
+ ELOG_DEBUG("Video port range: %d, %d", minport, maxport);
+ video_ice_config_ = ice_config_;
+ video_ice_config_.media_type = VIDEO_TYPE;
+ video_ice_config_.min_port = (uint16_t) minport;
+ video_ice_config_.max_port = (uint16_t) maxport;
+}
+
} // namespace erizo
diff --git a/erizo/src/erizo/WebRtcConnection.h b/erizo/src/erizo/WebRtcConnection.h
index 4a9fa449..9fbb1262 100644
--- a/erizo/src/erizo/WebRtcConnection.h
+++ b/erizo/src/erizo/WebRtcConnection.h
@@ -159,6 +159,9 @@ class WebRtcConnection: public TransportListener, public LogContext,
return "id: " + connection_id_ + ", " + printLogContext();
}

+ void setUnbundleAudioPort(int minport, int maxport);
+ void setUnbundleVideoPort(int minport, int maxport);
+
private:
bool processRemoteSdp(std::string stream_id);
void setRemoteSdpsToMediaStreams(std::string stream_id);
@@ -180,6 +183,9 @@ class WebRtcConnection: public TransportListener, public LogContext,
int bundle_;
WebRtcConnectionEventListener* conn_event_listener_;
IceConfig ice_config_;
+ IceConfig audio_ice_config_;
+ IceConfig video_ice_config_ ;
+
std::vector<RtpMap> rtp_mappings_;
RtpExtensionProcessor extension_processor_;
boost::condition_variable cond_;
--
2.17.1

2 changes: 2 additions & 0 deletions source/agent/conference/conference.js
Original file line number Diff line number Diff line change
Expand Up @@ -1355,6 +1355,8 @@ var Conference = function (rpcClient, selfRpcId) {
source.optional && source.optional.format && (formatPreference.optional = formatPreference.optional.concat(source.optional.format));
}
track.formatPreference = formatPreference;
// Pass subscribe source type (screen-cast...) to rtc node
track.source = source.source;
});
}

Expand Down
2 changes: 1 addition & 1 deletion source/agent/video/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -750,7 +750,7 @@ function VTranscoder(rpcClient, clusterIP) {

motion_factor = 1.0,
default_resolution = {width: 0, height: 0},
default_framerate = 30,
default_framerate = 0,
default_kfi = 1000,

input_id = undefined,
Expand Down
8 changes: 8 additions & 0 deletions source/agent/webrtc/agent.toml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,14 @@ keystorePath = "./cert/certificate.pfx"
maxport = 0 #default: 0
minport = 0 #default: 0

# The webrtc unbundle port range
#audio_minport = 10000
#audio_maxport = 11000
#video_minport = 20000
#video_maxport = 21000
#screen_minport = 30000
#screen_maxport = 31000

#STUN server IP address and port to be used by the server.
#if "" is used, the address is discovered locally
stunport = 0 #default: 0
Expand Down
7 changes: 7 additions & 0 deletions source/agent/webrtc/configLoader.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,13 @@ module.exports.load = () => {
config.webrtc.io_workers = config.webrtc.io_workers || 8;
config.webrtc.network_interfaces = config.webrtc.network_interfaces || [];

config.webrtc.audio_minport = config.webrtc.audio_minport || 0;
config.webrtc.audio_maxport = config.webrtc.audio_maxport || 0;
config.webrtc.video_minport = config.webrtc.video_minport || 0;
config.webrtc.video_maxport = config.webrtc.video_maxport || 0;
config.webrtc.screen_minport = config.webrtc.screen_minport || 0;
config.webrtc.screen_maxport = config.webrtc.screen_maxport || 0;

config.webrtc.network_interfaces.forEach(item => {
let addr = networkHelper.getAddress(item.name);
if (!addr) {
Expand Down
19 changes: 19 additions & 0 deletions source/agent/webrtc/connection.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ class Connection extends EventEmitter {
this.metadata = this.options.metadata || {};
this.isProcessingRemoteSdp = false;
this.ready = false;
this.isScreen = options.isScreen || false;
this.wrtc = this._createWrtc();
}

Expand Down Expand Up @@ -98,6 +99,24 @@ class Connection extends EventEmitter {
this.ipAddresses
);

if (global.config.webrtc.audio_minport ||
global.config.webrtc.audio_maxport ||
global.config.webrtc.video_minport ||
global.config.webrtc.video_maxport) {
const videoMinPort = this.isScreen ?
global.config.webrtc.screen_minport :
global.config.webrtc.video_minport;
const videoMaxPort = this.isScreen ?
global.config.webrtc.screen_maxport :
global.config.webrtc.video_maxport;
wrtc.setUnbundleMediaPort(
global.config.webrtc.audio_minport,
global.config.webrtc.audio_maxport,
videoMinPort,
videoMaxPort,
);
}

return wrtc;
}

Expand Down
13 changes: 10 additions & 3 deletions source/agent/webrtc/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ module.exports = function (rpcClient, selfRpcId, parentRpcId, clusterWorkerIP) {
}
};

var createWebRTCConnection = function (transportId, controller, owner) {
var createWebRTCConnection = function (transportId, controller, owner, isScreen) {
if (peerConnections.has(transportId)) {
log.debug('PeerConnection already created:', transportId);
return peerConnections.get(transportId);
Expand All @@ -132,6 +132,7 @@ module.exports = function (rpcClient, selfRpcId, parentRpcId, clusterWorkerIP) {
ioThreadPool: ioThreadPool,
network_interfaces: global.config.webrtc.network_interfaces,
owner,
isScreen,
}, function onTransportStatus(status) {
notifyTransportStatus(controller, transportId, status);
}, function onTrack(trackInfo) {
Expand Down Expand Up @@ -235,7 +236,10 @@ module.exports = function (rpcClient, selfRpcId, parentRpcId, clusterWorkerIP) {
// Generate a transportId

}
conn = createWebRTCConnection(options.transportId, options.controller, options.owner);
const isScreen = !!options.tracks.find((track) => (
track.type === 'video' && track.source === 'screen-cast'
));
conn = createWebRTCConnection(options.transportId, options.controller, options.owner, isScreen);
options.tracks.forEach(function trackOp(t) {
conn.addTrackOperation(operationId, t.mid, t.type, 'sendonly', t.formatPreference);
});
Expand Down Expand Up @@ -288,7 +292,10 @@ module.exports = function (rpcClient, selfRpcId, parentRpcId, clusterWorkerIP) {
// Generate a transportId

}
conn = createWebRTCConnection(options.transportId, options.controller, options.owner);
const isScreen = !!options.tracks.find((track) => (
track.type === 'video' && track.source === 'screen-cast'
));
conn = createWebRTCConnection(options.transportId, options.controller, options.owner, isScreen);
options.tracks.forEach(function trackOp(t) {
conn.addTrackOperation(operationId, t.mid, t.type, 'recvonly', t.formatPreference);
});
Expand Down
15 changes: 15 additions & 0 deletions source/agent/webrtc/rtcConn/WebRtcConnection.cc
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ NAN_MODULE_INIT(WebRtcConnection::Init) {
Nan::SetPrototypeMethod(tpl, "setVideoSsrcList", setVideoSsrcList);
Nan::SetPrototypeMethod(tpl, "getVideoSsrcMap", getVideoSsrcMap);

Nan::SetPrototypeMethod(tpl, "setUnbundleMediaPort", setUnbundleMediaPort);

constructor.Reset(tpl->GetFunction());
Nan::Set(target, Nan::New("WebRtcConnection").ToLocalChecked(), Nan::GetFunction(tpl).ToLocalChecked());
}
Expand Down Expand Up @@ -457,6 +459,19 @@ NAN_METHOD(WebRtcConnection::getCurrentState) {
info.GetReturnValue().Set(Nan::New(state));
}

NAN_METHOD(WebRtcConnection::setUnbundleMediaPort) {
WebRtcConnection* obj = Nan::ObjectWrap::Unwrap<WebRtcConnection>(info.Holder());
std::shared_ptr<erizo::WebRtcConnection> me = obj->me;

int audioMinPort = Nan::To<int>(info[0]).FromJust();;
int audioMaxPort = Nan::To<int>(info[1]).FromJust();;
int videoMinPort = Nan::To<int>(info[2]).FromJust();;
int videoMaxPort = Nan::To<int>(info[3]).FromJust();;

me->setUnbundleAudioPort(audioMinPort, audioMaxPort);
me->setUnbundleVideoPort(videoMinPort, videoMaxPort);
}

// Async methods
void WebRtcConnection::notifyEvent(erizo::WebRTCEvent event, const std::string& message, const std::string& stream_id) {
boost::mutex::scoped_lock lock(mutex);
Expand Down
4 changes: 4 additions & 0 deletions source/agent/webrtc/rtcConn/WebRtcConnection.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,10 @@ class WebRtcConnection : public Nan::ObjectWrap, public erizo::WebRtcConnectionE
* Returns the state.
*/
static NAN_METHOD(getCurrentState);
/*
* Set port range for unbundle audio/video
*/
static NAN_METHOD(setUnbundleMediaPort);

static Nan::Persistent<v8::Function> constructor;

Expand Down
45 changes: 32 additions & 13 deletions source/agent/webrtc/sdpInfo.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,31 @@ class SdpInfo {
this.obj = transform.parse(str);
this.obj.media.forEach((media, i) => {
if (media.mid === undefined) {
log.warn(`Media ${i} missing mid`);
media.mid = -1;
log.debug(`Bundle media ${i} missing mid`);
media.mid = -(i+1);
}
});
}

bundleMids() {
const bundles = this.obj.groups.find(g => g.type === 'BUNDLE');
return bundles.mids.split(' ');
const bundles = this.obj.groups ?
this.obj.groups.find(g => g.type === 'BUNDLE') : null;
return bundles ? bundles.mids.toString().split(' ') : null;
}

setBundleMids(mids) {
const bundles = this.obj.groups.find(g => g.type === 'BUNDLE');
bundles.mids = mids.join(' ');
if (!this.obj.groups) {
this.obj.groups = [];
}
if (!mids) {
this.obj.groups = this.obj.groups.filter(g => g.type !== 'BUNDLE');
} else {
const bundles = this.obj.groups.find(g => g.type === 'BUNDLE');
if (bundles) {
bundles.mids += '';
bundles.mids = mids.join(' ');
}
}
}

mids() {
Expand Down Expand Up @@ -325,11 +336,13 @@ class SdpInfo {
}
}

setCredentials({iceUfrag, icePwd, fingerprint}) {
setCredentials({iceUfrag, icePwd, fingerprint}, type) {
this.obj.media.forEach(mediaInfo => {
mediaInfo.iceUfrag = iceUfrag;
mediaInfo.icePwd = icePwd;
mediaInfo.fingerprint = fingerprint;
if (!type || type === mediaInfo.type) {
mediaInfo.iceUfrag = iceUfrag;
mediaInfo.icePwd = icePwd;
mediaInfo.fingerprint = fingerprint;
}
});
}

Expand All @@ -350,9 +363,11 @@ class SdpInfo {
}
}

setCandidates(candidates) {
setCandidates(candidates, type) {
this.obj.media.forEach(mediaInfo => {
mediaInfo.candidates = candidates;
if (!type || type === mediaInfo.type) {
mediaInfo.candidates = candidates;
}
});
}

Expand Down Expand Up @@ -577,7 +592,6 @@ class SdpInfo {
if (mediaInfo.ext && Array.isArray(mediaInfo.ext)) {
const extMappings = [
'urn:ietf:params:rtp-hdrext:ssrc-audio-level',
'http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01',
'urn:ietf:params:rtp-hdrext:sdes:mid',
'urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id',
'urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id',
Expand All @@ -586,6 +600,11 @@ class SdpInfo {
// 'urn:3gpp:video-orientation',
// 'http://www.webrtc.org/experiments/rtp-hdrext/playout-delay',
];
if (mediaInfo.type === 'video') {
extMappings.push(
'http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01'
);
}
mediaInfo.ext = mediaInfo.ext.filter((e) => {
return extMappings.includes(e.uri);
});
Expand Down
Loading