diff options
Diffstat (limited to 'Swiften/ScreenSharing')
-rw-r--r-- | Swiften/ScreenSharing/OutgoingScreenSharing.cpp | 18 | ||||
-rw-r--r-- | Swiften/ScreenSharing/OutgoingScreenSharing.h | 4 | ||||
-rw-r--r-- | Swiften/ScreenSharing/RTPSession.h | 6 | ||||
-rw-r--r-- | Swiften/ScreenSharing/RTPSessionImpl.cpp | 45 | ||||
-rw-r--r-- | Swiften/ScreenSharing/RTPSessionImpl.h | 42 | ||||
-rw-r--r-- | Swiften/ScreenSharing/ScreenSharing.cpp | 16 | ||||
-rw-r--r-- | Swiften/ScreenSharing/ScreenSharing.h | 2 | ||||
-rw-r--r-- | Swiften/ScreenSharing/ScreenSharingManagerImpl.cpp | 49 | ||||
-rw-r--r-- | Swiften/ScreenSharing/ScreenSharingManagerImpl.h | 12 |
9 files changed, 115 insertions, 79 deletions
diff --git a/Swiften/ScreenSharing/OutgoingScreenSharing.cpp b/Swiften/ScreenSharing/OutgoingScreenSharing.cpp index 3aa460c..da7eb3e 100644 --- a/Swiften/ScreenSharing/OutgoingScreenSharing.cpp +++ b/Swiften/ScreenSharing/OutgoingScreenSharing.cpp @@ -13,6 +13,7 @@ #include <Swiften/Network/UDPSocket.h> #include <Swiften/Network/TimerFactory.h> #include <Swiften/Network/Timer.h> +#include <Swiften/ScreenSharing/RTPSessionImpl.h> #include <boost/bind.hpp> @@ -21,8 +22,9 @@ namespace Swift { OutgoingScreenSharing::OutgoingScreenSharing(boost::shared_ptr<JingleSession> session, UDPSocketFactory* udpSocketFactory, TimerFactory* timerFactory) : ScreenSharing(session, udpSocketFactory), contentID(JingleContentID(idGenerator.generateID(), JingleContentPayload::InitiatorCreator)), canceled(false), - sessionAccepted(false), socketConnected(false), timerFactory(timerFactory) + sessionAccepted(false), socketConnected(false), rtpSession(0), timerFactory(timerFactory) { + session->onSessionAcceptReceived.connect(boost::bind(&OutgoingScreenSharing::handleSessionAcceptReceived, this, _1, _2, _3)); } OutgoingScreenSharing::~OutgoingScreenSharing() @@ -43,7 +45,8 @@ void OutgoingScreenSharing::start() SWIFT_LOG(debug) << "Screen sharing: start" << std::endl; JingleRTPDescription::ref desc = boost::make_shared<JingleRTPDescription>(JingleRTPDescription::Video); - desc->addPayloadType(RTPPayloadType(98, "VP8", 90000)); + payloadTypeUsed = RTPPayloadType(98, "VP8", 90000); + desc->addPayloadType(payloadTypeUsed); JingleRawUDPTransportPayload::ref transport = boost::make_shared<JingleRawUDPTransportPayload>(); addBestCandidate(transport); @@ -57,10 +60,9 @@ void OutgoingScreenSharing::start() void OutgoingScreenSharing::handleSocketConnected() { - SWIFT_LOG(debug) << "Screen sharing: UDP socket connected" << std::endl; - if (canceled) return; + SWIFT_LOG(debug) << "Screen sharing: UDP socket connected" << std::endl; socketConnected = true; if (sessionAccepted) @@ -69,10 +71,11 @@ void OutgoingScreenSharing::handleSocketConnected() void OutgoingScreenSharing::handleSessionAcceptReceived(const JingleContentID& /*id*/, boost::shared_ptr<JingleDescription> /*desc*/, boost::shared_ptr<JingleTransportPayload> /*transport*/) { - SWIFT_LOG(debug) << "Screen sharing: accepted" << std::endl; - if (canceled) return; + SWIFT_LOG(debug) << "Screen sharing: accepted" << std::endl; + + // TODO: check desc and transport sessionAccepted = true; if (socketConnected) { @@ -97,9 +100,10 @@ void OutgoingScreenSharing::handleConnectionFailed() void OutgoingScreenSharing::startRTPSession() { - SWIFT_LOG(debug) << "Screen sharing: accepted and connect, start screen sharing" << std::endl; + SWIFT_LOG(debug) << "Screen sharing: accepted and connected, start sharing" << std::endl; // Session accepted and socket connected, we can start the rtp session + rtpSession = new RTPSessionImpl(serverSocket, payloadTypeUsed); } } diff --git a/Swiften/ScreenSharing/OutgoingScreenSharing.h b/Swiften/ScreenSharing/OutgoingScreenSharing.h index d93b476..c00d11e 100644 --- a/Swiften/ScreenSharing/OutgoingScreenSharing.h +++ b/Swiften/ScreenSharing/OutgoingScreenSharing.h @@ -8,6 +8,7 @@ #include <Swiften/ScreenSharing/ScreenSharing.h> #include <Swiften/Jingle/JingleContentID.h> +#include <Swiften/Elements/RTPPayloadType.h> namespace Swift { class ConnectivityManager; @@ -15,6 +16,7 @@ namespace Swift { class JingleTransportPayload; class TimerFactory; class Timer; + class RTPSession; class OutgoingScreenSharing : public ScreenSharing { public: @@ -39,6 +41,8 @@ namespace Swift { bool canceled; bool sessionAccepted; bool socketConnected; + RTPSession* rtpSession; + RTPPayloadType payloadTypeUsed; TimerFactory* timerFactory; boost::shared_ptr<Timer> connectionTimer; diff --git a/Swiften/ScreenSharing/RTPSession.h b/Swiften/ScreenSharing/RTPSession.h index bdb2861..4399b2d 100644 --- a/Swiften/ScreenSharing/RTPSession.h +++ b/Swiften/ScreenSharing/RTPSession.h @@ -14,19 +14,15 @@ namespace Swift { class UDPSocket; + class RTPPayloadType; class RTPSession { public: typedef boost::shared_ptr<RTPSession> ref; - enum PayloadType { - VP8 = 98, - }; - public: virtual ~RTPSession() {} - virtual void create(boost::shared_ptr<UDPSocket> udpSocket, const HostAddressPort& remotePeer, PayloadType payloadType, int frequency) = 0; virtual void poll() = 0; virtual void checkIncomingPackets() = 0; virtual void sendPacket(const SafeByteArray& data, int timestampinc, bool marker = false) = 0; diff --git a/Swiften/ScreenSharing/RTPSessionImpl.cpp b/Swiften/ScreenSharing/RTPSessionImpl.cpp index eb67d4e..62b05d5 100644 --- a/Swiften/ScreenSharing/RTPSessionImpl.cpp +++ b/Swiften/ScreenSharing/RTPSessionImpl.cpp @@ -9,6 +9,7 @@ #include <Swiften/ScreenSharing/RTPException.h> #include <Swiften/Network/BoostUDPSocket.h> #include <Swiften/Base/boost_bsignals.h> +#include <Swiften/Network/UDPSocket.h> #include <boost/algorithm/string/split.hpp> #include <boost/algorithm/string/classification.hpp> @@ -22,33 +23,42 @@ namespace Swift { -RTPSessionImpl::RTPSessionImpl() - : RTPSession() -{ +bool Sender::SendRTP(const void *data, size_t len) { + send(data, len); + return true; } -RTPSessionImpl::~RTPSessionImpl() -{ +bool Sender::SendRTCP(const void* data, size_t len) { + send(data, len); + return true; } -void RTPSessionImpl::create(boost::shared_ptr<UDPSocket> udpSocket, const HostAddressPort &remotePeer, RTPSession::PayloadType payloadType, int frequency) -{ - this->udpSocket = udpSocket; - this->udpSocket->onDataRead.connect(boost::bind(&RTPSessionImpl::handleDataRead, this, _1)); +bool Sender::ComesFromThisSender (const jrtplib::RTPAddress* address) { + return RTPSessionImpl::nativeAddressToJRTPAddress(udpSocket->getLocalAddress()).IsSameAddress(address); +} - this->payloadType = payloadType; - this->frequency = frequency; - nativeAddressToJRTPAddress(remotePeer, jRTPRemotePeer); +void Sender::send(const void* data, size_t len) { + unsigned char *uint8Data = (unsigned char*)data; + udpSocket->send(SafeByteArray(uint8Data, uint8Data + len)); +} +RTPSessionImpl::RTPSessionImpl(boost::shared_ptr<UDPSocket> udpSocket, const RTPPayloadType &payloadType) + : udpSocket(udpSocket), payloadType(payloadType), jRTPRemotePeer(nativeAddressToJRTPAddress(udpSocket->getRemoteAddress())), sender(udpSocket) +{ 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); + sessparams.SetOwnTimestampUnit(1.0 / payloadType.getClockrate()); checkError(session.Create(sessparams, &transparams, jrtplib::RTPTransmitter::ExternalProto)); packetInjecter = static_cast<jrtplib::RTPExternalTransmissionInfo*>(session.GetTransmissionInfo())->GetPacketInjector(); + + udpSocket->onDataRead.connect(boost::bind(&RTPSessionImpl::handleDataRead, this, _1)); +} + +RTPSessionImpl::~RTPSessionImpl() +{ } void RTPSessionImpl::poll() @@ -73,7 +83,7 @@ void RTPSessionImpl::checkIncomingPackets() void RTPSessionImpl::sendPacket(const SafeByteArray& data, int timestampinc, bool marker) { - checkError(session.SendPacket((void*)(&data[0]), data.size(), payloadType, marker, timestampinc)); + checkError(session.SendPacket((void*)(&data[0]), data.size(), payloadType.getID(), marker, timestampinc)); poll(); } @@ -101,7 +111,7 @@ void RTPSessionImpl::handleDataRead(boost::shared_ptr<SafeByteArray> data) injectData(*data); } -void RTPSessionImpl::nativeAddressToJRTPAddress(const HostAddressPort& hostAddressPort, jrtplib::RTPIPv4Address& jRTPAddress) +jrtplib::RTPIPv4Address RTPSessionImpl::nativeAddressToJRTPAddress(const HostAddressPort& hostAddressPort) { // Split address std::vector<std::string> subStrings; @@ -112,8 +122,7 @@ void RTPSessionImpl::nativeAddressToJRTPAddress(const HostAddressPort& hostAddre 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())); + return jrtplib::RTPIPv4Address(ipNumbers, boost::numeric_cast<uint16_t>(hostAddressPort.getPort())); } } diff --git a/Swiften/ScreenSharing/RTPSessionImpl.h b/Swiften/ScreenSharing/RTPSessionImpl.h index 657a34a..9bf08e5 100644 --- a/Swiften/ScreenSharing/RTPSessionImpl.h +++ b/Swiften/ScreenSharing/RTPSessionImpl.h @@ -7,6 +7,7 @@ #pragma once #include <Swiften/ScreenSharing/RTPSession.h> +#include <Swiften/Elements/RTPPayloadType.h> #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wunused-parameter" @@ -16,26 +17,19 @@ #include <rtpipv4address.h> namespace Swift { - // Temporary class - class Sender : public jrtplib::RTPExternalSender - { - public: - Sender() {} + class Sender : public jrtplib::RTPExternalSender { + public: + Sender(boost::shared_ptr<UDPSocket> udpSocket) : udpSocket(udpSocket) {} - virtual bool SendRTP (const void* /*data*/, size_t /*len*/) - { - return true; - } + virtual bool SendRTP(const void* data, size_t len); + virtual bool SendRTCP(const void* data, size_t len); + virtual bool ComesFromThisSender (const jrtplib::RTPAddress* address); - virtual bool SendRTCP (const void* /*data*/, size_t /*len*/) - { - return true; - } + private: + void send(const void* data, size_t len); - virtual bool ComesFromThisSender (const jrtplib::RTPAddress* /*address*/) - { - return false; - } + private: + boost::shared_ptr<UDPSocket> udpSocket; }; class RTPSessionImpl : public RTPSession { @@ -43,30 +37,28 @@ namespace Swift { typedef boost::shared_ptr<RTPSession> ref; public: - RTPSessionImpl(); + RTPSessionImpl(boost::shared_ptr<UDPSocket> udpSocket, const RTPPayloadType& payloadType); virtual ~RTPSessionImpl(); - virtual void create(boost::shared_ptr<UDPSocket> udpSocket, const HostAddressPort &remotePeer, PayloadType payloadType, int frequency); 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); + public: + static jrtplib::RTPIPv4Address nativeAddressToJRTPAddress(const HostAddressPort& hostAddressPort); private: - inline void checkError(int rtperr) const; + void checkError(int rtperr) const; void handleDataRead(boost::shared_ptr<SafeByteArray> data); private: boost::shared_ptr<UDPSocket> udpSocket; - PayloadType payloadType; - int frequency; + RTPPayloadType payloadType; jrtplib::RTPIPv4Address jRTPRemotePeer; - jrtplib::RTPSession session; Sender sender; + jrtplib::RTPSession session; jrtplib::RTPExternalPacketInjecter *packetInjecter; }; } diff --git a/Swiften/ScreenSharing/ScreenSharing.cpp b/Swiften/ScreenSharing/ScreenSharing.cpp index fc7f672..532b73d 100644 --- a/Swiften/ScreenSharing/ScreenSharing.cpp +++ b/Swiften/ScreenSharing/ScreenSharing.cpp @@ -39,26 +39,26 @@ bool ScreenSharing::addBestCandidate(boost::shared_ptr<JingleRawUDPTransportPayl // Find the first ip which is not loopback foreach (const NetworkInterface& interface, interfaces) { if (!interface.isLoopback()) { // exclude loopback - candidate.hostAddressPort = HostAddressPort(interface.getAddresses().front(), listeningPort); + serverSocket = udpSocketFactory->createUDPSocket(); + serverSocket->bind(0); + + candidate.hostAddressPort = HostAddressPort(interface.getAddresses().front(), serverSocket->getLocalAddress().getPort()); candidate.type = JingleRawUDPTransportPayload::Candidate::Host; transport->addCandidate(candidate); - serverSocket = udpSocketFactory->createUDPSocket(); - serverSocket->bind(listeningPort); - return true; } } // else loopback for self sharing if (!interfaces.empty()) { - candidate.hostAddressPort = HostAddressPort(interfaces.front().getAddresses().front(), listeningPort); + serverSocket = udpSocketFactory->createUDPSocket(); + serverSocket->bind(0); + + candidate.hostAddressPort = HostAddressPort(interfaces.front().getAddresses().front(), serverSocket->getLocalAddress().getPort()); candidate.type = JingleRawUDPTransportPayload::Candidate::Host; transport->addCandidate(candidate); - serverSocket = udpSocketFactory->createUDPSocket(); - serverSocket->bind(listeningPort); - return true; } diff --git a/Swiften/ScreenSharing/ScreenSharing.h b/Swiften/ScreenSharing/ScreenSharing.h index 1f6f753..b1756b9 100644 --- a/Swiften/ScreenSharing/ScreenSharing.h +++ b/Swiften/ScreenSharing/ScreenSharing.h @@ -46,8 +46,6 @@ namespace Swift { bool addBestCandidate(boost::shared_ptr<JingleRawUDPTransportPayload> transport); protected: - static const int listeningPort = 28888; - IDGenerator idGenerator; boost::shared_ptr<UDPSocket> serverSocket; boost::shared_ptr<UDPSocket> clientSocket; diff --git a/Swiften/ScreenSharing/ScreenSharingManagerImpl.cpp b/Swiften/ScreenSharing/ScreenSharingManagerImpl.cpp index 4b88581..a747b81 100644 --- a/Swiften/ScreenSharing/ScreenSharingManagerImpl.cpp +++ b/Swiften/ScreenSharing/ScreenSharingManagerImpl.cpp @@ -6,14 +6,19 @@ #include <Swiften/ScreenSharing/ScreenSharingManagerImpl.h> +#include <Swiften/Base/foreach.h> +#include <Swiften/Disco/EntityCapsProvider.h> +#include <Swiften/Elements/Presence.h> +#include <Swiften/Presence/PresenceOracle.h> #include <Swiften/ScreenSharing/IncomingScreenSharingManager.h> #include <Swiften/ScreenSharing/OutgoingScreenSharingManager.h> namespace Swift { ScreenSharingManagerImpl::ScreenSharingManagerImpl(const JID& ownFullJID, JingleSessionManager *jingleSessionManager, IQRouter *iqRouter, - UDPSocketFactory* udpSocketFactory, TimerFactory* timerFactory) - : ownJID(ownFullJID)/*, jingleSM(jingleSessionManager), iqRouter(iqRouter), udpSocketFactory(udpSocketFactory), timerFactory(timerFactory)*/ + UDPSocketFactory* udpSocketFactory, TimerFactory* timerFactory, PresenceOracle* presenceOrable, + EntityCapsProvider* capsProvider) + : ownJID(ownFullJID)/*, jingleSM(jingleSessionManager), iqRouter(iqRouter), udpSocketFactory(udpSocketFactory), timerFactory(timerFactory)*/, capsProvider(capsProvider), presenceOracle(presenceOrable) { incomingSSManager = new IncomingScreenSharingManager(jingleSessionManager, iqRouter, udpSocketFactory); outgoingSSManager = new OutgoingScreenSharingManager(jingleSessionManager, iqRouter, udpSocketFactory, timerFactory); @@ -27,18 +32,38 @@ ScreenSharingManagerImpl::~ScreenSharingManagerImpl() boost::shared_ptr<OutgoingScreenSharing> ScreenSharingManagerImpl::createOutgoingScreenSharing(const JID &to) { - JID receipient = to; - - if (receipient.isBare()) { - //boost::optional<JID> fullJID = highestPriorityJIDSupportingFileTransfer(receipient); - //if (fullJID.is_initialized()) { - // receipient = fullJID.get(); - //} else { - return boost::shared_ptr<OutgoingScreenSharing>(); - //} + JID recipient = to; + + if (recipient.isBare()) { + boost::optional<JID> fullJID = highestPriorityJIDSupportingScreenSharing(recipient); + if (fullJID.is_initialized()) { + recipient = fullJID.get(); + } else { + return boost::shared_ptr<OutgoingScreenSharing>(); + } + } + + return outgoingSSManager->createOutgoingScreenSharing(ownJID, recipient); +} + +boost::optional<JID> ScreenSharingManagerImpl::highestPriorityJIDSupportingScreenSharing(const JID& bareJID) { + int priority = INT_MIN; + JID fullRecipientJID; + + std::vector<Presence::ref> presences = presenceOracle->getAllPresence(bareJID); + foreach (Presence::ref pres, presences) { + if (pres->getPriority() > priority) { + DiscoInfo::ref info = capsProvider->getCaps(pres->getFrom()); // look up caps from the jid + if (info && info->hasFeature(DiscoInfo::JingleFeature) + && info->hasFeature(DiscoInfo::JingleRTPFeature) + && info->hasFeature(DiscoInfo::JingleTransportRawUDPFeature)) { + priority = pres->getPriority(); + fullRecipientJID = pres->getFrom(); + } + } } - return outgoingSSManager->createOutgoingScreenSharing(ownJID, receipient); + return fullRecipientJID.isValid() ? boost::optional<JID>(fullRecipientJID) : boost::optional<JID>(); } } diff --git a/Swiften/ScreenSharing/ScreenSharingManagerImpl.h b/Swiften/ScreenSharing/ScreenSharingManagerImpl.h index 0075630..8e8ea78 100644 --- a/Swiften/ScreenSharing/ScreenSharingManagerImpl.h +++ b/Swiften/ScreenSharing/ScreenSharingManagerImpl.h @@ -16,16 +16,22 @@ namespace Swift { class IQRouter; class UDPSocketFactory; class TimerFactory; + class PresenceOracle; + class EntityCapsProvider; class ScreenSharingManagerImpl : public ScreenSharingManager { public: - ScreenSharingManagerImpl(const JID& ownFullJID, JingleSessionManager* jingleSessionManager, IQRouter *iqRouter, - UDPSocketFactory* udpSocketFactory, TimerFactory* timerFactory); + ScreenSharingManagerImpl(const JID& ownFullJID, JingleSessionManager* jingleSessionManager, IQRouter* iqRouter, + UDPSocketFactory* udpSocketFactory, TimerFactory* timerFactory, PresenceOracle* presenceOrable, + EntityCapsProvider *capsProvider); virtual ~ScreenSharingManagerImpl(); virtual boost::shared_ptr<OutgoingScreenSharing> createOutgoingScreenSharing(const JID& to); private: + boost::optional<JID> highestPriorityJIDSupportingScreenSharing(const JID &bareJID); + + private: IncomingScreenSharingManager* incomingSSManager; OutgoingScreenSharingManager* outgoingSSManager; @@ -35,5 +41,7 @@ namespace Swift { // IQRouter* iqRouter; // BoostUDPSocketFactory* udpSocketFactory; // TimerFactory* timerFactory; + EntityCapsProvider* capsProvider; + PresenceOracle* presenceOracle; }; } |