Merge pull request #351 from paullouisageneau/config-autonegotiation

Introduce configuration flag to disable auto negotiation
This commit is contained in:
Paul-Louis Ageneau
2021-03-03 12:13:58 +01:00
committed by GitHub
6 changed files with 51 additions and 63 deletions

View File

@@ -161,12 +161,13 @@ int main(int argc, char **argv) try {
string stunServer = "stun:stun.l.google.com:19302"; string stunServer = "stun:stun.l.google.com:19302";
cout << "Stun server is " << stunServer << endl; cout << "Stun server is " << stunServer << endl;
config.iceServers.emplace_back(stunServer); config.iceServers.emplace_back(stunServer);
config.disableAutoNegotiation = true;
string localId = "server"; string localId = "server";
cout << "The local ID is: " << localId << endl; cout << "The local ID is: " << localId << endl;
auto ws = make_shared<WebSocket>(); auto ws = make_shared<WebSocket>();
ws->onOpen([]() { cout << "WebSocket connected, signaling ready" << endl; }); ws->onOpen([]() { cout << "WebSocket connected, signaling ready" << endl; });
ws->onClosed([]() { cout << "WebSocket closed" << endl; }); ws->onClosed([]() { cout << "WebSocket closed" << endl; });
@@ -219,15 +220,15 @@ shared_ptr<ClientTrackData> addVideo(const shared_ptr<PeerConnection> pc, const
// create RTP configuration // create RTP configuration
auto rtpConfig = shared_ptr<RtpPacketizationConfig>(new RtpPacketizationConfig(ssrc, cname, payloadType, H264RtpPacketizer::defaultClockRate)); auto rtpConfig = shared_ptr<RtpPacketizationConfig>(new RtpPacketizationConfig(ssrc, cname, payloadType, H264RtpPacketizer::defaultClockRate));
// create packetizer // create packetizer
auto packetizer = shared_ptr<H264RtpPacketizer>(new H264RtpPacketizer(H264RtpPacketizer::Separator::Length, rtpConfig)); auto packetizer = shared_ptr<H264RtpPacketizer>(new H264RtpPacketizer(H264RtpPacketizer::Separator::Length, rtpConfig));
// create H264 handler // create H264 handler
shared_ptr<H264PacketizationHandler> h264Handler(new H264PacketizationHandler(packetizer)); shared_ptr<H264PacketizationHandler> h264Handler(new H264PacketizationHandler(packetizer));
// add RTCP SR handler // add RTCP SR handler
auto srReporter = make_shared<RtcpSrReporter>(rtpConfig); auto srReporter = make_shared<RtcpSrReporter>(rtpConfig);
h264Handler->addToChain(srReporter); h264Handler->addToChain(srReporter);
// add RTCP NACK handler // add RTCP NACK handler
auto nackResponder = make_shared<RtcpNackResponder>(); auto nackResponder = make_shared<RtcpNackResponder>();
h264Handler->addToChain(nackResponder); h264Handler->addToChain(nackResponder);
// set handler // set handler
track->setRtcpHandler(h264Handler); track->setRtcpHandler(h264Handler);
track->onOpen(onOpen); track->onOpen(onOpen);
@@ -244,14 +245,14 @@ shared_ptr<ClientTrackData> addAudio(const shared_ptr<PeerConnection> pc, const
auto rtpConfig = shared_ptr<RtpPacketizationConfig>(new RtpPacketizationConfig(ssrc, cname, payloadType, OpusRtpPacketizer::defaultClockRate)); auto rtpConfig = shared_ptr<RtpPacketizationConfig>(new RtpPacketizationConfig(ssrc, cname, payloadType, OpusRtpPacketizer::defaultClockRate));
// create packetizer // create packetizer
auto packetizer = make_shared<OpusRtpPacketizer>(rtpConfig); auto packetizer = make_shared<OpusRtpPacketizer>(rtpConfig);
// create opus handler // create opus handler
auto opusHandler = make_shared<OpusPacketizationHandler>(packetizer); auto opusHandler = make_shared<OpusPacketizationHandler>(packetizer);
// add RTCP SR handler // add RTCP SR handler
auto srReporter = make_shared<RtcpSrReporter>(rtpConfig); auto srReporter = make_shared<RtcpSrReporter>(rtpConfig);
opusHandler->addToChain(srReporter); opusHandler->addToChain(srReporter);
// add RTCP NACK handler // add RTCP NACK handler
auto nackResponder = make_shared<RtcpNackResponder>(); auto nackResponder = make_shared<RtcpNackResponder>();
opusHandler->addToChain(nackResponder); opusHandler->addToChain(nackResponder);
// set handler // set handler
track->setRtcpHandler(opusHandler); track->setRtcpHandler(opusHandler);
track->onOpen(onOpen); track->onOpen(onOpen);
@@ -263,7 +264,6 @@ shared_ptr<ClientTrackData> addAudio(const shared_ptr<PeerConnection> pc, const
shared_ptr<Client> createPeerConnection(const Configuration &config, shared_ptr<Client> createPeerConnection(const Configuration &config,
weak_ptr<WebSocket> wws, weak_ptr<WebSocket> wws,
string id) { string id) {
auto pc = make_shared<PeerConnection>(config); auto pc = make_shared<PeerConnection>(config);
shared_ptr<Client> client(new Client(pc)); shared_ptr<Client> client(new Client(pc));
@@ -316,7 +316,7 @@ shared_ptr<Client> createPeerConnection(const Configuration &config,
cout << "Audio from " << id << " opened" << endl; cout << "Audio from " << id << " opened" << endl;
}); });
auto dc = pc->addDataChannel("ping-pong"); auto dc = pc->createDataChannel("ping-pong");
dc->onOpen([id, wdc = make_weak_ptr(dc)]() { dc->onOpen([id, wdc = make_weak_ptr(dc)]() {
if (auto dc = wdc.lock()) { if (auto dc = wdc.lock()) {
dc->send("Ping"); dc->send("Ping");

View File

@@ -68,6 +68,7 @@ struct RTC_CPP_EXPORT Configuration {
std::vector<IceServer> iceServers; std::vector<IceServer> iceServers;
std::optional<ProxyServer> proxyServer; std::optional<ProxyServer> proxyServer;
bool enableIceTcp = false; bool enableIceTcp = false;
bool disableAutoNegotiation = false;
uint16_t portRangeBegin = 1024; uint16_t portRangeBegin = 1024;
uint16_t portRangeEnd = 65535; uint16_t portRangeEnd = 65535;
std::optional<size_t> mtu; std::optional<size_t> mtu;

View File

@@ -96,12 +96,13 @@ public:
void setRemoteDescription(Description description); void setRemoteDescription(Description description);
void addRemoteCandidate(Candidate candidate); void addRemoteCandidate(Candidate candidate);
std::shared_ptr<DataChannel> addDataChannel(string label, DataChannelInit init = {});
// Equivalent to calling addDataChannel() and setLocalDescription()
std::shared_ptr<DataChannel> createDataChannel(string label, DataChannelInit init = {}); std::shared_ptr<DataChannel> createDataChannel(string label, DataChannelInit init = {});
void onDataChannel(std::function<void(std::shared_ptr<DataChannel> dataChannel)> callback); void onDataChannel(std::function<void(std::shared_ptr<DataChannel> dataChannel)> callback);
std::shared_ptr<Track> addTrack(Description::Media description);
void onTrack(std::function<void(std::shared_ptr<Track> track)> callback);
void onLocalDescription(std::function<void(Description description)> callback); void onLocalDescription(std::function<void(Description description)> callback);
void onLocalCandidate(std::function<void(Candidate candidate)> callback); void onLocalCandidate(std::function<void(Candidate candidate)> callback);
void onStateChange(std::function<void(State state)> callback); void onStateChange(std::function<void(State state)> callback);
@@ -113,10 +114,6 @@ public:
size_t bytesSent(); size_t bytesSent();
size_t bytesReceived(); size_t bytesReceived();
std::optional<std::chrono::milliseconds> rtt(); std::optional<std::chrono::milliseconds> rtt();
// Track media support requires compiling with libSRTP
std::shared_ptr<Track> addTrack(Description::Media description);
void onTrack(std::function<void(std::shared_ptr<Track> track)> callback);
}; };
} // namespace rtc } // namespace rtc

View File

@@ -120,6 +120,7 @@ typedef struct {
const char **iceServers; const char **iceServers;
int iceServersCount; int iceServersCount;
bool enableIceTcp; bool enableIceTcp;
bool disableAutoNegotiation;
uint16_t portRangeBegin; uint16_t portRangeBegin;
uint16_t portRangeEnd; uint16_t portRangeEnd;
int mtu; // <= 0 means automatic int mtu; // <= 0 means automatic
@@ -193,10 +194,6 @@ RTC_EXPORT int rtcGetSelectedCandidatePair(int pc, char *local, int localSize, c
// DataChannel // DataChannel
RTC_EXPORT int rtcSetDataChannelCallback(int pc, rtcDataChannelCallbackFunc cb); RTC_EXPORT int rtcSetDataChannelCallback(int pc, rtcDataChannelCallbackFunc cb);
RTC_EXPORT int rtcAddDataChannel(int pc, const char *label); // returns dc id
RTC_EXPORT int rtcAddDataChannelEx(int pc, const char *label,
const rtcDataChannelInit *init); // returns dc id
// Equivalent to calling rtcAddDataChannel() and rtcSetLocalDescription()
RTC_EXPORT int rtcCreateDataChannel(int pc, const char *label); // returns dc id RTC_EXPORT int rtcCreateDataChannel(int pc, const char *label); // returns dc id
RTC_EXPORT int rtcCreateDataChannelEx(int pc, const char *label, RTC_EXPORT int rtcCreateDataChannelEx(int pc, const char *label,
const rtcDataChannelInit *init); // returns dc id const rtcDataChannelInit *init); // returns dc id

View File

@@ -353,6 +353,7 @@ int rtcCreatePeerConnection(const rtcConfiguration *config) {
c.iceServers.emplace_back(string(config->iceServers[i])); c.iceServers.emplace_back(string(config->iceServers[i]));
c.enableIceTcp = config->enableIceTcp; c.enableIceTcp = config->enableIceTcp;
c.disableAutoNegotiation = config->disableAutoNegotiation;
if (config->portRangeBegin > 0 || config->portRangeEnd > 0) { if (config->portRangeBegin > 0 || config->portRangeEnd > 0) {
c.portRangeBegin = config->portRangeBegin; c.portRangeBegin = config->portRangeBegin;
@@ -381,9 +382,11 @@ int rtcDeletePeerConnection(int pc) {
}); });
} }
int rtcAddDataChannel(int pc, const char *label) { return rtcAddDataChannelEx(pc, label, nullptr); } int rtcCreateDataChannel(int pc, const char *label) {
return rtcCreateDataChannelEx(pc, label, nullptr);
}
int rtcAddDataChannelEx(int pc, const char *label, const rtcDataChannelInit *init) { int rtcCreateDataChannelEx(int pc, const char *label, const rtcDataChannelInit *init) {
return wrap([&] { return wrap([&] {
DataChannelInit dci = {}; DataChannelInit dci = {};
if (init) { if (init) {
@@ -408,7 +411,7 @@ int rtcAddDataChannelEx(int pc, const char *label, const rtcDataChannelInit *ini
auto peerConnection = getPeerConnection(pc); auto peerConnection = getPeerConnection(pc);
int dc = emplaceDataChannel( int dc = emplaceDataChannel(
peerConnection->addDataChannel(string(label ? label : ""), std::move(dci))); peerConnection->createDataChannel(string(label ? label : ""), std::move(dci)));
if (auto ptr = getUserPointer(pc)) if (auto ptr = getUserPointer(pc))
rtcSetUserPointer(dc, *ptr); rtcSetUserPointer(dc, *ptr);
@@ -417,16 +420,6 @@ int rtcAddDataChannelEx(int pc, const char *label, const rtcDataChannelInit *ini
}); });
} }
int rtcCreateDataChannel(int pc, const char *label) {
return rtcCreateDataChannelEx(pc, label, nullptr);
}
int rtcCreateDataChannelEx(int pc, const char *label, const rtcDataChannelInit *init) {
int dc = rtcAddDataChannelEx(pc, label, init);
rtcSetLocalDescription(pc, NULL);
return dc;
}
int rtcDeleteDataChannel(int dc) { int rtcDeleteDataChannel(int dc) {
return wrap([dc] { return wrap([dc] {
auto dataChannel = getDataChannel(dc); auto dataChannel = getDataChannel(dc);

View File

@@ -232,7 +232,8 @@ void PeerConnection::setRemoteDescription(Description description) {
if (type == Description::Type::Offer) { if (type == Description::Type::Offer) {
// This is an offer, we need to answer // This is an offer, we need to answer
setLocalDescription(Description::Type::Answer); if (!impl()->config.disableAutoNegotiation)
setLocalDescription(Description::Type::Answer);
} else { } else {
// This is an answer // This is an answer
// Since we assumed passive role during DataChannel creation, we need to shift the // Since we assumed passive role during DataChannel creation, we need to shift the
@@ -259,7 +260,7 @@ std::optional<string> PeerConnection::remoteAddress() const {
return iceTransport ? iceTransport->getRemoteAddress() : nullopt; return iceTransport ? iceTransport->getRemoteAddress() : nullopt;
} }
shared_ptr<DataChannel> PeerConnection::addDataChannel(string label, DataChannelInit init) { shared_ptr<DataChannel> PeerConnection::createDataChannel(string label, DataChannelInit init) {
// RFC 5763: The answerer MUST use either a setup attribute value of setup:active or // RFC 5763: The answerer MUST use either a setup attribute value of setup:active or
// setup:passive. [...] Thus, setup:active is RECOMMENDED. // setup:passive. [...] Thus, setup:active is RECOMMENDED.
// See https://tools.ietf.org/html/rfc5763#section-5 // See https://tools.ietf.org/html/rfc5763#section-5
@@ -268,6 +269,7 @@ shared_ptr<DataChannel> PeerConnection::addDataChannel(string label, DataChannel
auto role = iceTransport ? iceTransport->role() : Description::Role::Passive; auto role = iceTransport ? iceTransport->role() : Description::Role::Passive;
auto channelImpl = impl()->emplaceDataChannel(role, std::move(label), std::move(init)); auto channelImpl = impl()->emplaceDataChannel(role, std::move(label), std::move(init));
auto channel = std::make_shared<DataChannel>(channelImpl);
if (auto transport = impl()->getSctpTransport()) if (auto transport = impl()->getSctpTransport())
if (transport->state() == impl::SctpTransport::State::Connected) if (transport->state() == impl::SctpTransport::State::Connected)
@@ -278,12 +280,9 @@ shared_ptr<DataChannel> PeerConnection::addDataChannel(string label, DataChannel
if (!local || !local->hasApplication()) if (!local || !local->hasApplication())
impl()->negotiationNeeded = true; impl()->negotiationNeeded = true;
return std::make_shared<DataChannel>(channelImpl); if (!impl()->config.disableAutoNegotiation)
} setLocalDescription();
shared_ptr<DataChannel> PeerConnection::createDataChannel(string label, DataChannelInit init) {
auto channel = addDataChannel(std::move(label), std::move(init));
setLocalDescription();
return channel; return channel;
} }
@@ -292,6 +291,20 @@ void PeerConnection::onDataChannel(
impl()->dataChannelCallback = callback; impl()->dataChannelCallback = callback;
} }
std::shared_ptr<Track> PeerConnection::addTrack(Description::Media description) {
auto trackImpl = impl()->emplaceTrack(std::move(description));
auto track = std::make_shared<Track>(trackImpl);
// Renegotiation is needed for the new or updated track
impl()->negotiationNeeded = true;
return track;
}
void PeerConnection::onTrack(std::function<void(std::shared_ptr<Track>)> callback) {
impl()->trackCallback = callback;
}
void PeerConnection::onLocalDescription(std::function<void(Description description)> callback) { void PeerConnection::onLocalDescription(std::function<void(Description description)> callback) {
impl()->localDescriptionCallback = callback; impl()->localDescriptionCallback = callback;
} }
@@ -312,19 +325,6 @@ void PeerConnection::onSignalingStateChange(std::function<void(SignalingState st
impl()->signalingStateChangeCallback = callback; impl()->signalingStateChangeCallback = callback;
} }
std::shared_ptr<Track> PeerConnection::addTrack(Description::Media description) {
auto trackImpl = impl()->emplaceTrack(std::move(description));
// Renegotiation is needed for the new or updated track
impl()->negotiationNeeded = true;
return std::make_shared<Track>(trackImpl);
}
void PeerConnection::onTrack(std::function<void(std::shared_ptr<Track>)> callback) {
impl()->trackCallback = callback;
}
bool PeerConnection::getSelectedCandidatePair(Candidate *local, Candidate *remote) { bool PeerConnection::getSelectedCandidatePair(Candidate *local, Candidate *remote) {
auto iceTransport = impl()->getIceTransport(); auto iceTransport = impl()->getIceTransport();
return iceTransport ? iceTransport->getSelectedCandidatePair(local, remote) : false; return iceTransport ? iceTransport->getSelectedCandidatePair(local, remote) : false;