From 63f031be6dc042ea7d769d5de283af466399371e Mon Sep 17 00:00:00 2001 From: dknn 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 + +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 +#include +#include + +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 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 + +#include + +//#include + +#include +#include +#include + +#include +#include +#include + +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(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 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(boost::lexical_cast(subStrings[i])); + + jRTPAddress.SetIP(ipNumbers); + jRTPAddress.SetPort(boost::numeric_cast(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 + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunused-parameter" +#include +#pragma clang diagnostic pop +#include +#include + +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