From 63f031be6dc042ea7d769d5de283af466399371e Mon Sep 17 00:00:00 2001
From: dknn <yoann.blein@free.fr>
Date: Tue, 3 Jul 2012 10:41:38 +0200
Subject: Abstract layer between Swiften & JRTPLIB


diff --git a/Swiften/ScreenSharing/RTPSession.cpp b/Swiften/ScreenSharing/RTPSession.cpp
new file mode 100644
index 0000000..9af62f1
--- /dev/null
+++ b/Swiften/ScreenSharing/RTPSession.cpp
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2012 Yoann Blein
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include <Swiften/ScreenSharing/RTPSession.h>
+
+namespace Swift {
+
+RTPSession::RTPSession(const HostAddressPort &remotePeer, PayloadType payloadType, int frequency)
+	: remotePeer(remotePeer), payloadType(payloadType), frequency(frequency)
+{
+}
+
+RTPSession::~RTPSession()
+{
+}
+
+}
diff --git a/Swiften/ScreenSharing/RTPSession.h b/Swiften/ScreenSharing/RTPSession.h
new file mode 100644
index 0000000..225132b
--- /dev/null
+++ b/Swiften/ScreenSharing/RTPSession.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2012 Yoann Blein
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <Swiften/Base/SafeByteArray.h>
+#include <Swiften/Network/HostAddressPort.h>
+#include <Swiften/Base/boost_bsignals.h>
+
+namespace Swift {
+	class RTPSession {
+		public:
+			enum PayloadType {
+				VP8 = 98,
+			};
+
+		public:
+			RTPSession(const HostAddressPort& remotePeer, PayloadType payloadType, int frequency);
+			virtual ~RTPSession();
+
+			virtual void poll() = 0;
+			virtual void checkIncomingPackets() = 0;
+			virtual void sendPacket(const SafeByteArray& data, int timestampinc, bool marker = false) = 0;
+			virtual void injectData(const SafeByteArray& data) = 0;
+			virtual void stop(int maxWaitMs = 100) = 0;
+
+		public:
+			boost::signal<void (uint8_t* data, size_t len, bool marker)> onIncomingPacket;
+
+		protected:
+			HostAddressPort remotePeer;
+			PayloadType payloadType;
+			int frequency;
+	};
+}
diff --git a/Swiften/ScreenSharing/RTPSessionImpl.cpp b/Swiften/ScreenSharing/RTPSessionImpl.cpp
new file mode 100644
index 0000000..d785ad1
--- /dev/null
+++ b/Swiften/ScreenSharing/RTPSessionImpl.cpp
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2012 Yoann Blein
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#include <Swiften/ScreenSharing/RTPSessionImpl.h>
+
+#include <Swiften/ScreenSharing/RTPException.h>
+
+//#include <algorithm>
+
+#include <boost/algorithm/string/split.hpp>
+#include <boost/algorithm/string/classification.hpp>
+#include <boost/lexical_cast.hpp>
+
+#include <rtppacket.h>
+#include <rtpsourcedata.h>
+#include <rtpsessionparams.h>
+
+namespace Swift {
+
+RTPSessionImpl::RTPSessionImpl(const HostAddressPort& remotePeer, PayloadType payloadType, int frequency)
+	: RTPSession(remotePeer, payloadType, frequency)
+{
+	jrtplib::RTPExternalTransmissionParams transparams(&sender, 0);
+
+	jrtplib::RTPSessionParams sessparams;
+	// IMPORTANT: The local timestamp unit MUST be set, otherwise RTCP Sender Report info will be calculated wrong
+	sessparams.SetOwnTimestampUnit(1.0 / frequency);
+
+	checkError(session.Create(sessparams, &transparams, jrtplib::RTPTransmitter::ExternalProto));
+
+	//session.SetDefaultPayloadType(VP8);
+
+	packetInjecter = static_cast<jrtplib::RTPExternalTransmissionInfo*>(session.GetTransmissionInfo())->GetPacketInjector();
+
+	nativeAddressToJRTPAddress(remotePeer, jRTPRemotePeer);
+}
+
+RTPSessionImpl::~RTPSessionImpl()
+{
+}
+
+void RTPSessionImpl::poll()
+{
+	checkError(session.Poll()); // Required if threading disabled
+}
+
+void RTPSessionImpl::checkIncomingPackets()
+{
+	// session.BeginDataAccess(); // useless without threading
+	if (session.GotoFirstSourceWithData() && session.GetCurrentSourceInfo()->GetRTPDataAddress()->IsSameAddress(&jRTPRemotePeer)) {
+		do {
+			jrtplib::RTPPacket *pack;
+			while ((pack = session.GetNextPacket()) != NULL) {
+				onIncomingPacket(pack->GetPayloadData(), pack->GetPayloadLength(), pack->HasMarker());
+				session.DeletePacket(pack);
+			}
+		} while (session.GotoNextSourceWithData());
+	}
+	// session.EndDataAccess(); // useless without threading
+}
+
+void RTPSessionImpl::sendPacket(const SafeByteArray& data, int timestampinc, bool marker)
+{
+	checkError(session.SendPacket((void*)(&data[0]), data.size(), payloadType, marker, timestampinc));
+	poll();
+}
+
+void RTPSessionImpl::injectData(const SafeByteArray& data)
+{
+	packetInjecter->InjectRTPorRTCP((void*)(&data[0]), data.size(), jRTPRemotePeer);
+	checkIncomingPackets();
+	poll();
+}
+
+void RTPSessionImpl::stop(int maxWaitMs)
+{
+	session.BYEDestroy(jrtplib::RTPTime(0, maxWaitMs * 1000), "", 0);
+	// TODO: shutdown socket
+}
+
+void RTPSessionImpl::checkError(int rtperr) const
+{
+	if (rtperr < 0)
+		throw RTPException(jrtplib::RTPGetErrorString(rtperr));
+}
+
+void RTPSessionImpl::nativeAddressToJRTPAddress(const HostAddressPort& hostAddressPort, jrtplib::RTPIPv4Address& jRTPAddress)
+{
+	// Split address
+	std::vector<std::string> subStrings;
+	std::string ipAddress = hostAddressPort.getAddress().toString();
+	boost::algorithm::split(subStrings, ipAddress, boost::is_any_of("."));
+	// Cast sub strings array to array of byte
+	uint8_t ipNumbers[4];
+	for (int i = 0; i < std::min(4, (int)subStrings.size()); ++i)
+		ipNumbers[i] = boost::numeric_cast<uint8_t>(boost::lexical_cast<int>(subStrings[i]));
+
+	jRTPAddress.SetIP(ipNumbers);
+	jRTPAddress.SetPort(boost::numeric_cast<uint16_t>(hostAddressPort.getPort()));
+}
+
+}
diff --git a/Swiften/ScreenSharing/RTPSessionImpl.h b/Swiften/ScreenSharing/RTPSessionImpl.h
new file mode 100644
index 0000000..15ca4b3
--- /dev/null
+++ b/Swiften/ScreenSharing/RTPSessionImpl.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2012 Yoann Blein
+ * Licensed under the simplified BSD license.
+ * See Documentation/Licenses/BSD-simplified.txt for more information.
+ */
+
+#pragma once
+
+#include <Swiften/ScreenSharing/RTPSession.h>
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wunused-parameter"
+#include <rtpsession.h>
+#pragma clang diagnostic pop
+#include <rtpexternaltransmitter.h>
+#include <rtpipv4address.h>
+
+namespace Swift {
+
+	// Temporary class
+	class Sender : public jrtplib::RTPExternalSender
+	{
+	public:
+		Sender() {}
+
+		virtual bool SendRTP (const void* /*data*/, size_t /*len*/)
+		{
+			return true;
+		}
+
+		virtual bool SendRTCP (const void* /*data*/, size_t /*len*/)
+		{
+			return true;
+		}
+
+		virtual bool ComesFromThisSender (const jrtplib::RTPAddress* /*address*/)
+		{
+			return false;
+		}
+	};
+
+	class RTPSessionImpl : public RTPSession {
+		public:
+			RTPSessionImpl(const HostAddressPort& remotePeer, PayloadType payloadType, int frequency);
+			virtual ~RTPSessionImpl();
+
+			virtual void poll();
+			virtual void checkIncomingPackets();
+			virtual void sendPacket(const SafeByteArray &data, int timestampinc, bool marker = false);
+			virtual void injectData(const SafeByteArray &data);
+			virtual void stop(int maxWaitMs = 100);
+
+		private:
+			static void nativeAddressToJRTPAddress(const HostAddressPort& hostAddressPort, jrtplib::RTPIPv4Address& jRTPAddress);
+
+		private:
+			inline void checkError(int rtperr) const;
+
+		private:
+			jrtplib::RTPIPv4Address jRTPRemotePeer;
+			jrtplib::RTPSession session;
+			Sender sender;
+			jrtplib::RTPExternalPacketInjecter *packetInjecter;
+	};
+}
diff --git a/Swiften/ScreenSharing/SConscript b/Swiften/ScreenSharing/SConscript
index 3658173..cc757a5 100644
--- a/Swiften/ScreenSharing/SConscript
+++ b/Swiften/ScreenSharing/SConscript
@@ -8,6 +8,16 @@ sources = [
 		"VP8RTPParser.cpp",
 	]
 
-swiften_env.Append(SWIFTEN_OBJECTS = swiften_env.SwiftenObject(sources))
+objects = swiften_env.SwiftenObject(sources)
 
-env.Append(UNITTEST_SOURCES = [])
+if swiften_env["experimental"] :
+	# JRTPLIB classes
+	jrtplib_env = swiften_env.Clone()
+	jrtplib_env.Append(CPPDEFINES = jrtplib_env["JRTPLIB_FLAGS"].get("INTERNAL_CPPDEFINES", []))
+	objects += jrtplib_env.SwiftenObject([
+				"RTPSessionImpl.cpp",
+			])
+
+swiften_env.Append(SWIFTEN_OBJECTS = [objects])
+
+#env.Append(UNITTEST_SOURCES = [])
diff --git a/Swiften/ScreenSharing/VP8RTPPacketizer.h b/Swiften/ScreenSharing/VP8RTPPacketizer.h
index 0ef48be..50cc8a0 100644
--- a/Swiften/ScreenSharing/VP8RTPPacketizer.h
+++ b/Swiften/ScreenSharing/VP8RTPPacketizer.h
@@ -14,8 +14,6 @@
 
 
 namespace Swift {
-	class SafeByteArray;
-
 	class VP8RTPPacketizer {
 		public:
 			VP8RTPPacketizer();
-- 
cgit v0.10.2-6-g49f6