diff options
Diffstat (limited to 'Swiften/ScreenSharing/RTPSessionImpl.cpp')
-rw-r--r-- | Swiften/ScreenSharing/RTPSessionImpl.cpp | 105 |
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())); +} + +} |