From 51958a50e31b483aa932aac8d696b229ba66b5cb Mon Sep 17 00:00:00 2001 From: dknn Date: Sat, 14 Jul 2012 10:00:24 +0200 Subject: Fixes to make classes working together diff --git a/Swiften/ScreenSharing/Image.cpp b/Swiften/ScreenSharing/Image.cpp index c3acd69..d807c58 100644 --- a/Swiften/ScreenSharing/Image.cpp +++ b/Swiften/ScreenSharing/Image.cpp @@ -8,7 +8,7 @@ namespace Swift { -Image::Image(int width, int height, uint8_t* rgb24data) +Image::Image(int width, int height, const uint8_t* rgb24data) : width(width), height(height) { int len = width * height * 3; diff --git a/Swiften/ScreenSharing/Image.h b/Swiften/ScreenSharing/Image.h index 5cdf043..0e0151d 100644 --- a/Swiften/ScreenSharing/Image.h +++ b/Swiften/ScreenSharing/Image.h @@ -15,7 +15,7 @@ namespace Swift { public: typedef boost::shared_ptr ref; - Image(int width, int height, uint8_t* rgb24data = 0); + Image(int width, int height, const uint8_t* rgb24data = 0); int width; int height; diff --git a/Swiften/ScreenSharing/IncomingScreenSharing.cpp b/Swiften/ScreenSharing/IncomingScreenSharing.cpp index d5ee56e..2ddfab9 100644 --- a/Swiften/ScreenSharing/IncomingScreenSharing.cpp +++ b/Swiften/ScreenSharing/IncomingScreenSharing.cpp @@ -8,27 +8,37 @@ #include #include +#include #include #include +#include +#include +#include + +#include namespace Swift { IncomingScreenSharing::IncomingScreenSharing(boost::shared_ptr session, UDPSocketFactory* udpSocketFactory, boost::shared_ptr content) : ScreenSharing(session, udpSocketFactory), - initialContent(content) + initialContent(content), parser(0), decoder(0) { onStateChange(ScreenSharing::WaitingForAccept); } IncomingScreenSharing::~IncomingScreenSharing() { + delete rtpSession; + delete parser; + delete decoder; } void IncomingScreenSharing::cancel() { - session->sendTerminate(JinglePayload::Reason::Cancel); - clientSocket->close(); + jingleSession->sendTerminate(JinglePayload::Reason::Cancel); + if (rtpSession) + rtpSession->stop(); onStateChange(ScreenSharing::Canceled); } @@ -36,8 +46,12 @@ void IncomingScreenSharing::accept() { JingleRawUDPTransportPayload::ref transport = boost::make_shared(); addBestCandidate(transport); + JingleRTPDescription::ref desc = initialContent->getDescription(); + if (!desc->getPayloadTypes().empty()) + payloadTypeUsed = desc->getPayloadTypes().front(); + // TODO: create a valid description instead of copying the initator's one - session->sendAccept(getContentID(), initialContent->getDescriptions().front(), transport); + jingleSession->sendAccept(getContentID(), desc, transport); JingleRawUDPTransportPayload::ref initialTransport = initialContent->getTransport(); clientSocket = udpSocketFactory->createUDPSocket(); @@ -46,6 +60,15 @@ void IncomingScreenSharing::accept() SafeByteArray data(1, 0); clientSocket->send(data); + rtpSession = new RTPSessionImpl(clientSocket, payloadTypeUsed); + + if (payloadTypeUsed.getID() == 98 && payloadTypeUsed.getName() == "VP8") { + decoder = new VP8Decoder; + parser = new VP8RTPParser(decoder); + rtpSession->onIncomingPacket.connect(boost::bind(&VP8RTPParser::newPayloadReceived, parser, _1, _2, _3)); + decoder->onNewImageDecoded.connect(boost::bind(&IncomingScreenSharing::hangleNewImageDecoded, this, _1)); + } + onStateChange(ScreenSharing::Connecting); } @@ -54,4 +77,9 @@ JingleContentID IncomingScreenSharing::getContentID() const return JingleContentID(initialContent->getName(), initialContent->getCreator()); } +void IncomingScreenSharing::hangleNewImageDecoded(const Image& image) +{ + onNewImageReceived(image); +} + } diff --git a/Swiften/ScreenSharing/IncomingScreenSharing.h b/Swiften/ScreenSharing/IncomingScreenSharing.h index a9850fd..f6d9b62 100644 --- a/Swiften/ScreenSharing/IncomingScreenSharing.h +++ b/Swiften/ScreenSharing/IncomingScreenSharing.h @@ -8,17 +8,21 @@ #include #include +#include +#include namespace Swift { class JingleContentPayload; + class VP8RTPParser; + class VideoDecoder; + class Image; - class IncomingScreenSharing : public ScreenSharing - { + class IncomingScreenSharing : public ScreenSharing { public: typedef boost::shared_ptr ref; public: - IncomingScreenSharing(boost::shared_ptr session, UDPSocketFactory* udpSocketFactory, + IncomingScreenSharing(boost::shared_ptr jingleSession, UDPSocketFactory* udpSocketFactory, boost::shared_ptr content); virtual ~IncomingScreenSharing(); @@ -26,10 +30,17 @@ namespace Swift { void accept(); + public: + boost::signal onNewImageReceived; + private: JingleContentID getContentID() const; + void hangleNewImageDecoded(const Image& image); private: boost::shared_ptr initialContent; + RTPPayloadType payloadTypeUsed; + VP8RTPParser* parser; + VideoDecoder* decoder; }; } diff --git a/Swiften/ScreenSharing/OutgoingScreenSharing.cpp b/Swiften/ScreenSharing/OutgoingScreenSharing.cpp index da7eb3e..77226c5 100644 --- a/Swiften/ScreenSharing/OutgoingScreenSharing.cpp +++ b/Swiften/ScreenSharing/OutgoingScreenSharing.cpp @@ -6,6 +6,7 @@ #include +#include #include #include #include @@ -14,6 +15,9 @@ #include #include #include +#include +#include +#include #include @@ -21,29 +25,35 @@ namespace Swift { OutgoingScreenSharing::OutgoingScreenSharing(boost::shared_ptr session, UDPSocketFactory* udpSocketFactory, TimerFactory* timerFactory) : ScreenSharing(session, udpSocketFactory), - contentID(JingleContentID(idGenerator.generateID(), JingleContentPayload::InitiatorCreator)), canceled(false), - sessionAccepted(false), socketConnected(false), rtpSession(0), timerFactory(timerFactory) + timerFactory(timerFactory), contentID(JingleContentID(idGenerator.generateID(), JingleContentPayload::InitiatorCreator)), + canceled(false), sessionAccepted(false), socketConnected(false), encoder(0), packetizer(0) { session->onSessionAcceptReceived.connect(boost::bind(&OutgoingScreenSharing::handleSessionAcceptReceived, this, _1, _2, _3)); } OutgoingScreenSharing::~OutgoingScreenSharing() { + delete rtpSession; + delete encoder; + delete packetizer; } void OutgoingScreenSharing::cancel() { canceled = true; - session->sendTerminate(JinglePayload::Reason::Cancel); + jingleSession->sendTerminate(JinglePayload::Reason::Cancel); onStateChange(ScreenSharing::Canceled); } -void OutgoingScreenSharing::start() +void OutgoingScreenSharing::start(unsigned int width, unsigned int height) { //onStateChange(ScreenSharing::WaitingForStart); SWIFT_LOG(debug) << "Screen sharing: start" << std::endl; + this->width = width; + this->height = height; + JingleRTPDescription::ref desc = boost::make_shared(JingleRTPDescription::Video); payloadTypeUsed = RTPPayloadType(98, "VP8", 90000); desc->addPayloadType(payloadTypeUsed); @@ -51,13 +61,18 @@ void OutgoingScreenSharing::start() JingleRawUDPTransportPayload::ref transport = boost::make_shared(); addBestCandidate(transport); - session->sendInitiate(contentID, desc, transport); + jingleSession->sendInitiate(contentID, desc, transport); onStateChange(ScreenSharing::WaitingForAccept); serverSocket->onConnected.connect(boost::bind(&OutgoingScreenSharing::handleSocketConnected, this)); serverSocket->connectToFirstIncoming(); } +void OutgoingScreenSharing::addImage(const Image &image) +{ + encoder->encodeImage(image); +} + void OutgoingScreenSharing::handleSocketConnected() { if (canceled) @@ -92,7 +107,7 @@ void OutgoingScreenSharing::handleConnectionFailed() { SWIFT_LOG(debug) << "Screen sharing: unable to connect" << std::endl; - session->sendTerminate(JinglePayload::Reason::ConnectivityError); + jingleSession->sendTerminate(JinglePayload::Reason::ConnectivityError); canceled = true; onStateChange(ScreenSharing::Failed); @@ -104,6 +119,19 @@ void OutgoingScreenSharing::startRTPSession() // Session accepted and socket connected, we can start the rtp session rtpSession = new RTPSessionImpl(serverSocket, payloadTypeUsed); + + if (payloadTypeUsed.getID() == 98 && payloadTypeUsed.getName() == "VP8") { + packetizer = new VP8RTPPacketizer; + encoder = new VP8Encoder(packetizer, width, height); + packetizer->onNewPayloadReady.connect(boost::bind(&OutgoingScreenSharing::handleNewPayloadReady, this, _1, _2)); + onReady(); + } +} + +void OutgoingScreenSharing::handleNewPayloadReady(const std::vector& data, bool marker) +{ + SafeByteArray sba(data.begin(), data.end()); + rtpSession->sendPacket(sba, 500, marker); } } diff --git a/Swiften/ScreenSharing/OutgoingScreenSharing.h b/Swiften/ScreenSharing/OutgoingScreenSharing.h index c00d11e..cacc715 100644 --- a/Swiften/ScreenSharing/OutgoingScreenSharing.h +++ b/Swiften/ScreenSharing/OutgoingScreenSharing.h @@ -10,41 +10,53 @@ #include #include +#include +#include + namespace Swift { class ConnectivityManager; class JingleDescription; class JingleTransportPayload; class TimerFactory; class Timer; - class RTPSession; + class VideoEncoder; + class VP8RTPPacketizer; + class Image; class OutgoingScreenSharing : public ScreenSharing { public: typedef boost::shared_ptr ref; public: - OutgoingScreenSharing(boost::shared_ptr session, UDPSocketFactory* udpSocketFactory, TimerFactory* timerFactory); + OutgoingScreenSharing(boost::shared_ptr jingleSession, UDPSocketFactory* udpSocketFactory, TimerFactory* timerFactory); virtual ~OutgoingScreenSharing(); virtual void cancel(); - void start(); + void start(unsigned int width, unsigned int height); + void addImage(const Image& image); + + public: + boost::signal onReady; private: void handleSocketConnected(); void handleSessionAcceptReceived(const JingleContentID& /*id*/, boost::shared_ptr /*desc*/, boost::shared_ptr /*transport*/); void handleConnectionFailed(); void startRTPSession(); + void handleNewPayloadReady(const std::vector& data, bool marker); private: + TimerFactory* timerFactory; JingleContentID contentID; bool canceled; bool sessionAccepted; bool socketConnected; - RTPSession* rtpSession; RTPPayloadType payloadTypeUsed; - - TimerFactory* timerFactory; + VideoEncoder* encoder; + VP8RTPPacketizer* packetizer; + unsigned int width; + unsigned int height; boost::shared_ptr connectionTimer; }; } diff --git a/Swiften/ScreenSharing/RTPSessionImpl.cpp b/Swiften/ScreenSharing/RTPSessionImpl.cpp index 62b05d5..94641ff 100644 --- a/Swiften/ScreenSharing/RTPSessionImpl.cpp +++ b/Swiften/ScreenSharing/RTPSessionImpl.cpp @@ -23,6 +23,10 @@ namespace Swift { +Sender::Sender(boost::shared_ptr udpSocket) + : udpSocket(udpSocket) { +} + bool Sender::SendRTP(const void *data, size_t len) { send(data, len); return true; @@ -38,7 +42,7 @@ bool Sender::ComesFromThisSender (const jrtplib::RTPAddress* address) { } void Sender::send(const void* data, size_t len) { - unsigned char *uint8Data = (unsigned char*)data; + uint8_t* uint8Data = (uint8_t*)data; udpSocket->send(SafeByteArray(uint8Data, uint8Data + len)); } @@ -55,6 +59,7 @@ RTPSessionImpl::RTPSessionImpl(boost::shared_ptr udpSocket, const RTP packetInjecter = static_cast(session.GetTransmissionInfo())->GetPacketInjector(); udpSocket->onDataRead.connect(boost::bind(&RTPSessionImpl::handleDataRead, this, _1)); + udpSocket->listen(); } RTPSessionImpl::~RTPSessionImpl() @@ -97,7 +102,7 @@ void RTPSessionImpl::injectData(const SafeByteArray& data) void RTPSessionImpl::stop(int maxWaitMs) { session.BYEDestroy(jrtplib::RTPTime(0, maxWaitMs * 1000), "", 0); - // TODO: shutdown socket + udpSocket->close(); } void RTPSessionImpl::checkError(int rtperr) const diff --git a/Swiften/ScreenSharing/RTPSessionImpl.h b/Swiften/ScreenSharing/RTPSessionImpl.h index 9bf08e5..231ec1e 100644 --- a/Swiften/ScreenSharing/RTPSessionImpl.h +++ b/Swiften/ScreenSharing/RTPSessionImpl.h @@ -19,7 +19,7 @@ namespace Swift { class Sender : public jrtplib::RTPExternalSender { public: - Sender(boost::shared_ptr udpSocket) : udpSocket(udpSocket) {} + Sender(boost::shared_ptr udpSocket); virtual bool SendRTP(const void* data, size_t len); virtual bool SendRTCP(const void* data, size_t len); diff --git a/Swiften/ScreenSharing/ScreenSharing.cpp b/Swiften/ScreenSharing/ScreenSharing.cpp index 532b73d..d5ab921 100644 --- a/Swiften/ScreenSharing/ScreenSharing.cpp +++ b/Swiften/ScreenSharing/ScreenSharing.cpp @@ -6,24 +6,35 @@ #include -#include -#include #include - -#include +#include +#include #include +#include +#include +#include + +#include namespace Swift { ScreenSharing::ScreenSharing(boost::shared_ptr session, UDPSocketFactory* udpSocketFactory) - : session(session), udpSocketFactory(udpSocketFactory) + : rtpSession(0), jingleSession(session), udpSocketFactory(udpSocketFactory) { + session->onSessionTerminateReceived.connect(boost::bind(&ScreenSharing::handleSessionTerminateReceived, this, _1)); } ScreenSharing::~ScreenSharing() { } +void ScreenSharing::stop() +{ + jingleSession->sendTerminate(JinglePayload::Reason::Success); + if (rtpSession) + rtpSession->stop(); +} + bool ScreenSharing::addBestCandidate(boost::shared_ptr transport) { // TODO: NAT traversal @@ -65,4 +76,21 @@ bool ScreenSharing::addBestCandidate(boost::shared_ptr reason) +{ + if (rtpSession) + rtpSession->stop(); + + if (reason.is_initialized() && reason.get().type == JinglePayload::Reason::Cancel) { + onStateChange(ScreenSharing::Canceled); + //onFinished(FileTransferError(FileTransferError::PeerError)); + } else if (reason.is_initialized() && reason.get().type == JinglePayload::Reason::Success) { + onStateChange(ScreenSharing::Finished); + //onFinished(boost::optional()); + } else { + onStateChange(ScreenSharing::Failed); + //onFinished(FileTransferError(FileTransferError::PeerError)); + } +} + } diff --git a/Swiften/ScreenSharing/ScreenSharing.h b/Swiften/ScreenSharing/ScreenSharing.h index b1756b9..5289d3c 100644 --- a/Swiften/ScreenSharing/ScreenSharing.h +++ b/Swiften/ScreenSharing/ScreenSharing.h @@ -8,6 +8,7 @@ #include #include +#include #include @@ -16,6 +17,7 @@ namespace Swift { class JingleRawUDPTransportPayload; class UDPSocketFactory; class UDPSocket; + class RTPSession; class ScreenSharing { public: @@ -34,24 +36,26 @@ namespace Swift { }; public: - ScreenSharing(boost::shared_ptr session, UDPSocketFactory* udpSocketFactory); + ScreenSharing(boost::shared_ptr jingleSession, UDPSocketFactory* udpSocketFactory); virtual ~ScreenSharing(); virtual void cancel() = 0; + void stop(); public: boost::signal onStateChange; protected: bool addBestCandidate(boost::shared_ptr transport); + void handleSessionTerminateReceived(boost::optional reason); protected: IDGenerator idGenerator; boost::shared_ptr serverSocket; boost::shared_ptr clientSocket; + RTPSession* rtpSession; - boost::shared_ptr session; + boost::shared_ptr jingleSession; UDPSocketFactory* udpSocketFactory; - }; } diff --git a/Swiften/ScreenSharing/VP8Encoder.cpp b/Swiften/ScreenSharing/VP8Encoder.cpp index ed4d3de..7a88418 100644 --- a/Swiften/ScreenSharing/VP8Encoder.cpp +++ b/Swiften/ScreenSharing/VP8Encoder.cpp @@ -21,7 +21,7 @@ VP8Encoder::VP8Encoder(VP8RTPPacketizer* packetizer, unsigned int width, unsign // Populate encoder configuration vpx_codec_err_t err = vpx_codec_enc_config_default(codecInterface, &codecConfig, 0); if (err) { - SWIFT_LOG(debug) << "VP8 Encoder: Failed to get config, " << vpx_codec_err_to_string(err) << std::endl; + SWIFT_LOG(error) << "VP8 Encoder: Failed to get config, " << vpx_codec_err_to_string(err) << std::endl; // TODO: exception } @@ -50,29 +50,29 @@ void VP8Encoder::updateCodecConfig() vpx_codec_err_t err = vpx_codec_enc_init(&codecContext, codecInterface, &codecConfig, codecFlags); if (err) { - SWIFT_LOG(debug) << "VP8 Encoder: Failed to initialize encoder, " << vpx_codec_err_to_string(err) << std::endl; + SWIFT_LOG(error) << "VP8 Encoder: Failed to initialize encoder, " << vpx_codec_err_to_string(err) << std::endl; // TODO: exception return; } imageBuffer = vpx_img_alloc(0, VPX_IMG_FMT_YV12, codecConfig.g_w, codecConfig.g_h, 1); if (!imageBuffer) { - SWIFT_LOG(debug) << "VP8 Encoder: Failed to allocate image" << std::endl; + SWIFT_LOG(error) << "VP8 Encoder: Failed to allocate image" << std::endl; // TODO: exception } } -void VP8Encoder::encodeImage(const Image &frame) +void VP8Encoder::encodeImage(const Image& frame) { if (!convertRGB24toYV12inBuffer(frame)) { - SWIFT_LOG(debug) << "VP8 Encoder: Failed to convert frame: Image buffer not initialized" << std::endl; + SWIFT_LOG(error) << "VP8 Encoder: Failed to convert frame: Image buffer not initialized" << std::endl; // TODO: exception ? return; } vpx_codec_err_t err = vpx_codec_encode(&codecContext, imageBuffer, frameNumber, 1, frameFlags, VPX_DL_REALTIME); if (err) { - SWIFT_LOG(debug) << "VP8 Encoder: Failed to encode frame, " << vpx_codec_err_to_string(err) << std::endl; + SWIFT_LOG(error) << "VP8 Encoder: Failed to encode frame, " << vpx_codec_err_to_string(err) << std::endl; // TODO: exception ? return; } @@ -92,7 +92,7 @@ void VP8Encoder::encodeImage(const Image &frame) ++frameNumber; } -bool VP8Encoder::convertRGB24toYV12inBuffer(const Image &frame) +bool VP8Encoder::convertRGB24toYV12inBuffer(const Image& frame) { if (!imageBuffer) return false; @@ -104,7 +104,7 @@ bool VP8Encoder::convertRGB24toYV12inBuffer(const Image &frame) unsigned int width = frame.width; unsigned int height = frame.height; unsigned int len = width * height; - const std::vector &data = frame.data; + const std::vector& data = frame.data; for (unsigned int i = 0; i < len; ++i) { const uint8_t* p = &data[3 * i]; diff --git a/Swiften/ScreenSharing/VP8RTPParser.cpp b/Swiften/ScreenSharing/VP8RTPParser.cpp index 5a725ea..053a50a 100644 --- a/Swiften/ScreenSharing/VP8RTPParser.cpp +++ b/Swiften/ScreenSharing/VP8RTPParser.cpp @@ -10,7 +10,7 @@ namespace Swift { -VP8RTPParser::VP8RTPParser(VP8Decoder* decoder) +VP8RTPParser::VP8RTPParser(VideoDecoder* decoder) : decoder(decoder), firstPacket(true) { } diff --git a/Swiften/ScreenSharing/VP8RTPParser.h b/Swiften/ScreenSharing/VP8RTPParser.h index c88e2a6..1594c66 100644 --- a/Swiften/ScreenSharing/VP8RTPParser.h +++ b/Swiften/ScreenSharing/VP8RTPParser.h @@ -11,11 +11,11 @@ #include namespace Swift { - class VP8Decoder; + class VideoDecoder; class VP8RTPParser { public: - VP8RTPParser(VP8Decoder* decoder); + VP8RTPParser(VideoDecoder* decoder); void newPayloadReceived(const uint8_t* data, size_t len, bool hasMarker); @@ -24,7 +24,7 @@ namespace Swift { static const uint8_t HBit = 1 << 4; static const uint8_t Size0BitShift = 5; - VP8Decoder* decoder; + VideoDecoder* decoder; std::vector buffer; bool firstPacket; -- cgit v0.10.2-6-g49f6