Browse Source

Merge pull request #351 from paullouisageneau/config-autonegotiation

Introduce configuration flag to disable auto negotiation
Paul-Louis Ageneau 4 years ago
parent
commit
ff34858e41

+ 19 - 19
examples/streamer/main.cpp

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

+ 1 - 0
include/rtc/configuration.hpp

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

+ 4 - 7
include/rtc/peerconnection.hpp

@@ -96,12 +96,13 @@ public:
 	void setRemoteDescription(Description description);
 	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 = {});
 
 	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 onLocalCandidate(std::function<void(Candidate candidate)> callback);
 	void onStateChange(std::function<void(State state)> callback);
@@ -113,10 +114,6 @@ public:
 	size_t bytesSent();
 	size_t bytesReceived();
 	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

+ 1 - 4
include/rtc/rtc.h

@@ -120,6 +120,7 @@ typedef struct {
 	const char **iceServers;
 	int iceServersCount;
 	bool enableIceTcp;
+	bool disableAutoNegotiation;
 	uint16_t portRangeBegin;
 	uint16_t portRangeEnd;
 	int mtu; // <= 0 means automatic
@@ -193,10 +194,6 @@ RTC_EXPORT int rtcGetSelectedCandidatePair(int pc, char *local, int localSize, c
 
 // DataChannel
 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 rtcCreateDataChannelEx(int pc, const char *label,
                                       const rtcDataChannelInit *init); // returns dc id

+ 6 - 13
src/capi.cpp

@@ -353,6 +353,7 @@ int rtcCreatePeerConnection(const rtcConfiguration *config) {
 			c.iceServers.emplace_back(string(config->iceServers[i]));
 
 		c.enableIceTcp = config->enableIceTcp;
+		c.disableAutoNegotiation = config->disableAutoNegotiation;
 
 		if (config->portRangeBegin > 0 || config->portRangeEnd > 0) {
 			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([&] {
 		DataChannelInit dci = {};
 		if (init) {
@@ -408,7 +411,7 @@ int rtcAddDataChannelEx(int pc, const char *label, const rtcDataChannelInit *ini
 
 		auto peerConnection = getPeerConnection(pc);
 		int dc = emplaceDataChannel(
-		    peerConnection->addDataChannel(string(label ? label : ""), std::move(dci)));
+		    peerConnection->createDataChannel(string(label ? label : ""), std::move(dci)));
 
 		if (auto ptr = getUserPointer(pc))
 			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) {
 	return wrap([dc] {
 		auto dataChannel = getDataChannel(dc);

+ 20 - 20
src/peerconnection.cpp

@@ -232,7 +232,8 @@ void PeerConnection::setRemoteDescription(Description description) {
 
 	if (type == Description::Type::Offer) {
 		// This is an offer, we need to answer
-		setLocalDescription(Description::Type::Answer);
+		if (!impl()->config.disableAutoNegotiation)
+			setLocalDescription(Description::Type::Answer);
 	} else {
 		// This is an answer
 		// 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;
 }
 
-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
 	// setup:passive. [...] Thus, setup:active is RECOMMENDED.
 	// 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 channelImpl = impl()->emplaceDataChannel(role, std::move(label), std::move(init));
+	auto channel = std::make_shared<DataChannel>(channelImpl);
 
 	if (auto transport = impl()->getSctpTransport())
 		if (transport->state() == impl::SctpTransport::State::Connected)
@@ -278,12 +280,9 @@ shared_ptr<DataChannel> PeerConnection::addDataChannel(string label, DataChannel
 	if (!local || !local->hasApplication())
 		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;
 }
 
@@ -292,6 +291,20 @@ void PeerConnection::onDataChannel(
 	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) {
 	impl()->localDescriptionCallback = callback;
 }
@@ -312,19 +325,6 @@ void PeerConnection::onSignalingStateChange(std::function<void(SignalingState st
 	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) {
 	auto iceTransport = impl()->getIceTransport();
 	return iceTransport ? iceTransport->getSelectedCandidatePair(local, remote) : false;