diff --git a/CMakeLists.txt b/CMakeLists.txt index 36c8cfc..f13287e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,7 +12,7 @@ include(GitExternal) set(VERSION_MAJOR "0") set(VERSION_MINOR "5") -set(VERSION_PATCH "0") +set(VERSION_PATCH "1") set(VERSION_ABI 1) set(DEFLECT_DESCRIPTION diff --git a/apps/DesktopStreamer/MainWindow.cpp b/apps/DesktopStreamer/MainWindow.cpp index 1e99f76..182ea1e 100644 --- a/apps/DesktopStreamer/MainWindow.cpp +++ b/apps/DesktopStreamer/MainWindow.cpp @@ -188,6 +188,7 @@ void MainWindow::startStreaming() handleStreamingError("Could not connect to host!"); return; } + stream_->registerForEvents(); #ifdef __APPLE__ napSuspender_.suspend(); @@ -268,7 +269,7 @@ void MainWindow::processStreamEvents() { if( !eventsBox_.checkState( )) return; - if( !stream_->isRegisteredForEvents() && !stream_->registerForEvents( )) + if( !stream_->isRegisteredForEvents( )) return; while( stream_->hasEvent( )) diff --git a/apps/SimpleStreamer/main.cpp b/apps/SimpleStreamer/main.cpp index f0e1f15..4b4eaf4 100644 --- a/apps/SimpleStreamer/main.cpp +++ b/apps/SimpleStreamer/main.cpp @@ -118,13 +118,20 @@ void initGLWindow(int argc, char **argv) void initDeflectStream() { // connect to DisplayCluster - deflectStream = new deflect::Stream(deflectStreamName, deflectHostname); - if (!deflectStream->isConnected()) + deflectStream = new deflect::Stream( deflectStreamName, deflectHostname ); + if( !deflectStream->isConnected( )) { std::cerr << "Could not connect to host!" << std::endl; delete deflectStream; exit(1); } + + if( deflectInteraction && !deflectStream->registerForEvents( )) + { + std::cerr << "Could not register for events!" << std::endl; + delete deflectStream; + exit(1); + } } @@ -183,7 +190,7 @@ void display() deflectImage.compressionPolicy = deflectCompressImage ? deflect::COMPRESSION_ON : deflect::COMPRESSION_OFF; deflectImage.compressionQuality = deflectCompressionQuality; deflect::ImageWrapper::swapYAxis((void*)imageData, windowWidth, windowHeight, 4); - bool success = deflectStream->send(deflectImage); + const bool success = deflectStream->send(deflectImage); deflectStream->finishFrame(); // and free the allocated image data @@ -191,43 +198,40 @@ void display() glutSwapBuffers(); - // increment rotation angle according to interaction, or by a constant rate if interaction is not enabled - // note that mouse position is in normalized window coordinates: (0,0) to (1,1) - if(deflectInteraction) + // increment rotation angle according to interaction, or by a constant rate + // if interaction is not enabled. Note that mouse position is in normalized + // window coordinates: (0,0) to (1,1). + if( deflectStream->isRegisteredForEvents( )) { - if (deflectStream->isRegisteredForEvents() || deflectStream->registerForEvents()) + static float mouseX = 0.; + static float mouseY = 0.; + + // Note: there is a risk of missing events since we only process the + // latest state available. For more advanced applications, event + // processing should be done in a separate thread. + while( deflectStream->hasEvent( )) { - static float mouseX = 0.; - static float mouseY = 0.; + const deflect::Event& event = deflectStream->getEvent(); - // Note: there is a risk of missing events since we only process the latest state available. - // For more advanced applications, event processing should be done in a separate thread. - while (deflectStream->hasEvent()) + if( event.type == deflect::Event::EVT_CLOSE ) { - const deflect::Event& event = deflectStream->getEvent(); - - if (event.type == deflect::Event::EVT_CLOSE) - { - std::cout << "Received close..." << std::endl; - exit(0); - } - - const float newMouseX = event.mouseX; - const float newMouseY = event.mouseY; - - if(event.mouseLeft) - { - angleX += (newMouseX - mouseX) * 360.; - angleY += (newMouseY - mouseY) * 360.; - } - else if(event.mouseRight) - { - zoom += (newMouseY - mouseY); - } - - mouseX = newMouseX; - mouseY = newMouseY; + std::cout << "Received close..." << std::endl; + exit(0); } + + const float newMouseX = event.mouseX; + const float newMouseY = event.mouseY; + + if( event.mouseLeft ) + { + angleX += (newMouseX - mouseX) * 360.; + angleY += (newMouseY - mouseY) * 360.; + } + else if( event.mouseRight ) + zoom += (newMouseY - mouseY); + + mouseX = newMouseX; + mouseY = newMouseY; } } else @@ -235,6 +239,7 @@ void display() angleX += 1.; angleY += 1.; } + if(!success) { if (!deflectStream->isConnected()) diff --git a/deflect/PixelStreamBuffer.cpp b/deflect/PixelStreamBuffer.cpp index fed9c68..fd84b6c 100644 --- a/deflect/PixelStreamBuffer.cpp +++ b/deflect/PixelStreamBuffer.cpp @@ -46,7 +46,7 @@ namespace deflect PixelStreamBuffer::PixelStreamBuffer() : lastFrameComplete_(0) - , allowedToSend_(false) + , allowedToSend_(true) { } diff --git a/deflect/PixelStreamDispatcher.cpp b/deflect/PixelStreamDispatcher.cpp index fa6be23..5e1ada8 100644 --- a/deflect/PixelStreamDispatcher.cpp +++ b/deflect/PixelStreamDispatcher.cpp @@ -40,8 +40,6 @@ #include "PixelStreamDispatcher.h" #include "PixelStreamFrame.h" -#define STREAM_WINDOW_DEFAULT_SIZE 100 - namespace deflect { @@ -49,87 +47,85 @@ PixelStreamDispatcher::PixelStreamDispatcher() { } -void PixelStreamDispatcher::addSource(const QString uri, const size_t sourceIndex) +void PixelStreamDispatcher::addSource( const QString uri, + const size_t sourceIndex ) { - streamBuffers_[uri].addSource(sourceIndex); + streamBuffers_[uri].addSource( sourceIndex ); + + if( streamBuffers_[uri].getSourceCount() == 1 ) + emit openPixelStream( uri ); } -void PixelStreamDispatcher::removeSource(const QString uri, const size_t sourceIndex) +void PixelStreamDispatcher::removeSource( const QString uri, + const size_t sourceIndex ) { - if(!streamBuffers_.count(uri)) + if( !streamBuffers_.count( uri )) return; - streamBuffers_[uri].removeSource(sourceIndex); + streamBuffers_[uri].removeSource( sourceIndex ); - if (streamBuffers_[uri].getSourceCount() == 0) - { - deleteStream(uri); - } + if( streamBuffers_[uri].getSourceCount() == 0 ) + deleteStream( uri ); } -void PixelStreamDispatcher::processSegment(const QString uri, const size_t sourceIndex, PixelStreamSegment segment) +void PixelStreamDispatcher::processSegment( const QString uri, + const size_t sourceIndex, + PixelStreamSegment segment ) { - if (streamBuffers_.count(uri)) - streamBuffers_[uri].insertSegment(segment, sourceIndex); + if( streamBuffers_.count( uri )) + streamBuffers_[uri].insertSegment( segment, sourceIndex ); } -void PixelStreamDispatcher::processFrameFinished(const QString uri, const size_t sourceIndex) +void PixelStreamDispatcher::processFrameFinished( const QString uri, + const size_t sourceIndex ) { - if (!streamBuffers_.count(uri)) + if( !streamBuffers_.count( uri )) return; PixelStreamBuffer& buffer = streamBuffers_[uri]; - buffer.finishFrameForSource(sourceIndex); - - // When the first frame is complete, notify that the stream is now open - if (buffer.isFirstCompleteFrame()) - { - QSize size = buffer.getFrameSize(); - emit openPixelStream(uri, size); - buffer.setAllowedToSend(true); - } + buffer.finishFrameForSource( sourceIndex ); - if (buffer.isAllowedToSend()) - sendLatestFrame(uri); + if( buffer.isAllowedToSend( )) + sendLatestFrame( uri ); } -void PixelStreamDispatcher::deleteStream(const QString uri) +void PixelStreamDispatcher::deleteStream( const QString uri ) { - if (streamBuffers_.count(uri)) + if( streamBuffers_.count( uri )) { - streamBuffers_.erase(uri); - emit deletePixelStream(uri); + streamBuffers_.erase( uri ); + emit deletePixelStream( uri ); } } -void PixelStreamDispatcher::requestFrame(const QString uri) +void PixelStreamDispatcher::requestFrame( const QString uri ) { - if (!streamBuffers_.count(uri)) + if( !streamBuffers_.count( uri )) return; PixelStreamBuffer& buffer = streamBuffers_[uri]; - buffer.setAllowedToSend(true); - sendLatestFrame(uri); + buffer.setAllowedToSend( true ); + sendLatestFrame( uri ); } -void PixelStreamDispatcher::sendLatestFrame(const QString uri) +void PixelStreamDispatcher::sendLatestFrame( const QString uri ) { - PixelStreamFramePtr frame(new PixelStreamFrame); + PixelStreamFramePtr frame( new PixelStreamFrame ); frame->uri = uri; PixelStreamBuffer& buffer = streamBuffers_[uri]; - // Only send the lastest frame - while (buffer.hasCompleteFrame()) + // Only send the latest frame + while( buffer.hasCompleteFrame( )) frame->segments = buffer.popFrame(); - if (frame->segments.empty()) + if( frame->segments.empty( )) return; // receiver will request a new frame once this frame was consumed - buffer.setAllowedToSend(false); + buffer.setAllowedToSend( false ); - emit sendFrame(frame); + emit sendFrame( frame ); } } diff --git a/deflect/PixelStreamDispatcher.h b/deflect/PixelStreamDispatcher.h index 9b89e8a..c28b4c2 100644 --- a/deflect/PixelStreamDispatcher.h +++ b/deflect/PixelStreamDispatcher.h @@ -116,9 +116,8 @@ public slots: * Notify that a PixelStream has been opened * * @param uri Identifier for the Stream - * @param size Size in pixels of the stream */ - void openPixelStream(QString uri, QSize size); + void openPixelStream(QString uri); /** * Notify that a pixel stream has been deleted diff --git a/deflect/Stream.h b/deflect/Stream.h index a04c51e..0203f20 100644 --- a/deflect/Stream.h +++ b/deflect/Stream.h @@ -159,11 +159,6 @@ class Stream * After registering, the DisplayCluster master application will send Events * whenever a user is interacting with this Stream's window. * - * Registation is only possible after a window for the stream has been - * created on the DisplayWall. A window is first created when all Streams - * that use the same identifier have sent the first frame and called - * finishFrame(). - * * Events can be retrieved using hasEvent() and getEvent(). * * The current registration status can be checked with diff --git a/doc/RelNotes.md b/doc/RelNotes.md index 67d9863..ad1a23b 100644 --- a/doc/RelNotes.md +++ b/doc/RelNotes.md @@ -22,6 +22,9 @@ if you find any other issue with this release. ## git master +* Streamers can register for events immediately, without waiting for the + DisplayCluster host to have opened a window +* Desktopstreamer supports autodiscovery of DisplayCluster hosts using Zeroconf * Add interaction from the Wall with the DesktopStreamer host (Mac OS X only)