Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion apps/QmlStreamer/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,11 @@ int main( int argc, char** argv )

try
{
QScopedPointer< deflect::qt::QmlStreamer > streamer(
std::unique_ptr< deflect::qt::QmlStreamer > streamer(
new deflect::qt::QmlStreamer( qmlFile, streamHost.toStdString(),
streamName.toStdString( )));
app.connect( streamer.get(), &deflect::qt::QmlStreamer::streamClosed,
&app, &QCoreApplication::quit );
return app.exec();
}
catch( const std::runtime_error& exception )
Expand Down
2 changes: 1 addition & 1 deletion deflect/Socket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ bool Socket::receive( MessageHeader& messageHeader, QByteArray& message )
{
QMutexLocker locker( &_socketMutex );

if ( !_receiveHeader( messageHeader ))
if( !_receiveHeader( messageHeader ))
return false;

// get the message
Expand Down
8 changes: 7 additions & 1 deletion deflect/Stream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,14 @@ namespace deflect

Stream::Stream( const std::string& name, const std::string& address,
const unsigned short port )
: _impl( new StreamPrivate( this, name, address, port ))
: _impl( new StreamPrivate( name, address, port ))
{
if( isConnected( ))
{
_impl->socket.connect( &_impl->socket, &Socket::disconnected,
[this]() { disconnected(); });
_impl->sendOpen();
}
}

Stream::~Stream()
Expand Down
35 changes: 14 additions & 21 deletions deflect/StreamPrivate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,40 +55,39 @@
namespace deflect
{

StreamPrivate::StreamPrivate( Stream* stream, const std::string &name_,
StreamPrivate::StreamPrivate( const std::string &name_,
const std::string& address,
const unsigned short port )
: name( name_ )
, socket( address, port )
, registeredForEvents( false )
, _parent( stream )
, _sendWorker( 0 )
{
imageSegmenter.setNominalSegmentDimensions( SEGMENT_SIZE, SEGMENT_SIZE );

if( name.empty( ))
throw std::runtime_error( "Invalid Stream name: " + name );

if( socket.isConnected( ))
{
connect( &socket, &Socket::disconnected,
this, &StreamPrivate::_onDisconnected );
const MessageHeader mh( MESSAGE_TYPE_PIXELSTREAM_OPEN, 0, name );
socket.send( mh, QByteArray( ));
}
}

StreamPrivate::~StreamPrivate()
{
delete _sendWorker;
_sendWorker.reset();

if( !socket.isConnected( ))
return;

const MessageHeader mh( MESSAGE_TYPE_QUIT, 0, name );
sendClose();
}

void StreamPrivate::sendOpen()
{
const MessageHeader mh( MESSAGE_TYPE_PIXELSTREAM_OPEN, 0, name );
socket.send( mh, QByteArray( ));
}

registeredForEvents = false;
void StreamPrivate::sendClose()
{
const MessageHeader mh( MESSAGE_TYPE_QUIT, 0, name );
socket.send( mh, QByteArray( ));
}

bool StreamPrivate::send( const ImageWrapper& image )
Expand All @@ -109,7 +108,7 @@ bool StreamPrivate::send( const ImageWrapper& image )
Stream::Future StreamPrivate::asyncSend( const ImageWrapper& image )
{
if( !_sendWorker )
_sendWorker = new StreamSendWorker( *this );
_sendWorker.reset( new StreamSendWorker( *this ));

return _sendWorker->enqueueImage( image );
}
Expand Down Expand Up @@ -150,10 +149,4 @@ bool StreamPrivate::sendSizeHints( const SizeHints& hints )
return socket.send( mh, message );
}

void StreamPrivate::_onDisconnected()
{
if( _parent )
_parent->disconnected();
}

}
24 changes: 11 additions & 13 deletions deflect/StreamPrivate.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,7 @@
#include "Stream.h" // Stream::Future

#include <string>

class QString;
#include <memory>

namespace deflect
{
Expand All @@ -62,10 +61,8 @@ class StreamSendWorker;
/**
* Private implementation for the Stream class.
*/
class StreamPrivate : public QObject
class StreamPrivate
{
Q_OBJECT

public:
/**
* Create a new stream and open a new connection to the deflect::Server.
Expand All @@ -74,17 +71,22 @@ class StreamPrivate : public QObject
* e.g. "192.168.1.83" This method must be called by all Streams sharing a
* common identifier before any of them starts sending images.
*
* @param stream the parent object owning this object
* @param name the unique stream name
* @param address Address of the target Server instance.
* @param port Port of the target Server instance.
*/
StreamPrivate( Stream* stream, const std::string& name,
const std::string& address, const unsigned short port );
StreamPrivate( const std::string& name, const std::string& address,
const unsigned short port );

/** Destructor, close the Stream. */
~StreamPrivate();

/** Send the open message to the server. */
void sendOpen();

/** Send the quit message to the server. */
void sendClose();

/**
* Close the stream.
* @return true on success or if the Stream was not connected
Expand Down Expand Up @@ -124,12 +126,8 @@ class StreamPrivate : public QObject
/** Has a successful event registration reply been received */
bool registeredForEvents;

private slots:
void _onDisconnected();

private:
Stream* _parent;
StreamSendWorker* _sendWorker;
std::unique_ptr< StreamSendWorker > _sendWorker;
};

}
Expand Down
3 changes: 2 additions & 1 deletion deflect/qt/QmlStreamer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ QmlStreamer::QmlStreamer( const QString& qmlFile,
const std::string& streamName )
: _impl( new Impl( qmlFile, streamHost, streamName ))
{
connect( _impl.get(), &Impl::streamClosed,
this, &QmlStreamer::streamClosed );
}

QmlStreamer::~QmlStreamer()
Expand All @@ -66,6 +68,5 @@ QQmlEngine* QmlStreamer::getQmlEngine()
return _impl->getQmlEngine();
}


}
}
8 changes: 7 additions & 1 deletion deflect/qt/QmlStreamer.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,10 @@ namespace qt
* on each update on the given Deflect stream. It automatically register also
* for Deflect events, which can be directly handled in the QML.
*/
class QmlStreamer
class QmlStreamer : public QObject
{
Q_OBJECT

public:
/**
* Construct a new qml streamer by loading the QML, accessible by
Expand All @@ -85,6 +87,10 @@ class QmlStreamer
/** @return the QML engine. */
DEFLECTQT_API QQmlEngine* getQmlEngine();

signals:
/** Emitted when the stream has been closed. */
void streamClosed();

private:
QmlStreamer( const QmlStreamer& ) = delete;
QmlStreamer operator=( const QmlStreamer& ) = delete;
Expand Down
15 changes: 9 additions & 6 deletions deflect/qt/QmlStreamerImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,9 @@ void QmlStreamer::Impl::_render()
qWarning() << "Could not setup Deflect stream";
}

if( !_streaming )
return;

// Polish, synchronize and render the next frame (into our fbo). In this
// example everything happens on the same thread and therefore all three
// steps are performed in succession from here. In a threaded setup the
Expand All @@ -215,12 +218,6 @@ void QmlStreamer::Impl::_render()

_context->functions()->glFlush();

if( !_streaming )
{
QCoreApplication::quit();
return;
}

const QImage image = _fbo->toImage();
if( image.isNull( ))
{
Expand All @@ -233,6 +230,9 @@ void QmlStreamer::Impl::_render()
imageWrapper.compressionPolicy = COMPRESSION_ON;
imageWrapper.compressionQuality = 100;
_streaming = _stream->send( imageWrapper ) && _stream->finishFrame();

if( !_streaming )
emit streamClosed();
}

void QmlStreamer::Impl::_requestUpdate()
Expand Down Expand Up @@ -345,6 +345,9 @@ bool QmlStreamer::Impl::_setupDeflectStream()
if( !_stream->isConnected( ))
return false;

_stream->disconnected.connect(
boost::bind( &QmlStreamer::Impl::streamClosed, this ));

if( !_stream->registerForEvents( ))
return false;

Expand Down
3 changes: 3 additions & 0 deletions deflect/qt/QmlStreamerImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@ private slots:
void _onResized( double, double );
void _onWheeled( double, double, double );

signals:
void streamClosed();

private:
std::string _getDeflectStreamName() const;
bool _setupDeflectStream();
Expand Down
2 changes: 2 additions & 0 deletions doc/Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ Changelog {#Changelog}
## Deflect 0.11

### 0.11.0 (git master)
* [100](https://github.com/BlueBrain/Deflect/pull/100):
QmlStreamer: correcly quit application when stream is closed.
* [95](https://github.com/BlueBrain/Deflect/pull/95):
DesktopStreamer: the list of windows available for streaming is also updated
after a window has been hidden or unhidden.
Expand Down