summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swiften/ScreenSharing/RTPSessionImpl.cpp')
-rw-r--r--Swiften/ScreenSharing/RTPSessionImpl.cpp105
1 files changed, 105 insertions, 0 deletions
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()));
+}
+
+}