Skip to content

Commit

Permalink
Reduce session loading time by validating contents concurrently
Browse files Browse the repository at this point in the history
  • Loading branch information
Raphael Dumusc committed Jul 18, 2016
1 parent dfd4543 commit d2f39e6
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 46 deletions.
2 changes: 2 additions & 0 deletions doc/Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ Changelog {#Changelog}

# Release 1.2 (git master)

* [64](https://github.com/BlueBrain/Tide/pull/64):
Faster session loading and fix for FFMPEG thread safety issues.
* [63](https://github.com/BlueBrain/Tide/pull/63):
Several corrections and bugfixes for session loading. Due to an error in
[#28](https://github.com/BlueBrain/Tide/pull/28), some sessions saved
Expand Down
23 changes: 23 additions & 0 deletions tide/core/FFMPEGMovie.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,28 @@
#pragma clang diagnostic ignored "-Wdeprecated"
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"

// Solve FFMPEG issue "insufficient thread locking around avcodec_open/close()"
int ffmpegLockManagerCallback( void** mutex, enum AVLockOp op )
{
switch( op )
{
case AV_LOCK_CREATE:
*mutex = static_cast<void*>( new std::mutex( ));
return 0;
case AV_LOCK_OBTAIN:
static_cast<std::mutex*>( *mutex )->lock();
return 0;
case AV_LOCK_RELEASE:
static_cast<std::mutex*>( *mutex )->unlock();
return 0;
case AV_LOCK_DESTROY:
delete static_cast<std::mutex*>( *mutex );
return 0;
default:
return 1;
}
}

FFMPEGMovie::FFMPEGMovie( const QString& uri )
: _avFormatContext( 0 )
, _streamPosition( 0.0 )
Expand Down Expand Up @@ -123,6 +145,7 @@ void FFMPEGMovie::initGlobalState()

if( !initialized )
{
av_lockmgr_register( &ffmpegLockManagerCallback );
av_register_all();
initialized = true;
}
Expand Down
3 changes: 2 additions & 1 deletion tide/core/FFMPEGVideoStream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ FFMPEGVideoStream::~FFMPEGVideoStream()
{
#if USE_NEW_FFMPEG_API
avcodec_free_context( &_videoCodecContext );
#else
avcodec_close( _videoCodecContext );
#endif
}

Expand Down Expand Up @@ -300,7 +302,6 @@ void FFMPEGVideoStream::_openVideoStreamDecoder()
std::stringstream message;
message << "Could not open codec, error code " << ret << ": " <<
_getAvError( ret );

throw std::runtime_error( message.str( ));
}
}
Expand Down
2 changes: 2 additions & 0 deletions tide/master/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ set(TIDEMASTER_LINK_LIBRARIES
PUBLIC
TideCore
Qt5::Widgets
PRIVATE
Qt5::Concurrent
)

list(APPEND TIDEMASTER_PUBLIC_HEADERS
Expand Down
90 changes: 45 additions & 45 deletions tide/master/StateSerializationHelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,61 +105,61 @@ bool _canBeRestored( const CONTENT_TYPE type )
return true;
}

void _validateContents( DisplayGroup& group )
bool _validateContent( const ContentWindowPtr& window )
{
const ContentWindowPtrs& windows = group.getContentWindows();
ContentPtr content = window->getContent();
if( !content )
{
put_flog( LOG_WARN, "Window '%s' does not have a Content!",
window->getID().toString().toLocal8Bit().constData( ));
return false;
}

ContentWindowPtrs validContentWindows;
validContentWindows.reserve( windows.size( ));
if( !_canBeRestored( content->getType( )))
return false;

for( ContentWindowPtr contentWindow : windows )
// Some regular textures were saved as DynamicTexture type before the
// migration to qml2 rendering
if( content->getType() == CONTENT_TYPE_DYNAMIC_TEXTURE )
{
ContentPtr content = contentWindow->getContent();
if( !content )
const QString& uri = content->getURI();
const auto type = ContentFactory::getContentTypeForFile( uri );
if( type == CONTENT_TYPE_TEXTURE )
{
put_flog( LOG_WARN, "Window '%s' does not have a Content!",
contentWindow->getID().toString().toLocal8Bit().constData( ));
continue;
}

if( !_canBeRestored( content->getType( )))
continue;
put_flog( LOG_DEBUG, "Try restoring legacy DynamicTexture as "
"a regular texture: '%s'",
content->getURI().toLocal8Bit().constData( ));

// Some regular textures were saved as DynamicTexture type before the
// migration to qml2 rendering
if( content->getType() == CONTENT_TYPE_DYNAMIC_TEXTURE )
{
const QString& uri = content->getURI();
const auto type = ContentFactory::getContentTypeForFile( uri );
if( type == CONTENT_TYPE_TEXTURE )
{
put_flog( LOG_DEBUG, "Try restoring legacy DynamicTexture as "
"a regular texture: '%s'",
content->getURI().toLocal8Bit().constData( ));

content = ContentFactory::getContent( uri );
contentWindow->setContent( content );
}
content = ContentFactory::getContent( uri );
window->setContent( content );
}
}

// Refresh content information, files can have been modified or removed
// since the state was saved.
if( content->readMetadata( ))
{
put_flog( LOG_DEBUG, "Restoring content: '%s'",
content->getURI().toLocal8Bit().constData( ));
}
else
{
put_flog( LOG_WARN, "'%s' could not be restored!",
content->getURI().toLocal8Bit().constData( ));
const QSize& size = content->getDimensions();
contentWindow->setContent( ContentFactory::getErrorContent( size ));
}
validContentWindows.push_back( contentWindow );
// Refresh content information, files can have been modified or removed
// since the state was saved.
if( content->readMetadata( ))
{
put_flog( LOG_DEBUG, "Restoring content: '%s'",
content->getURI().toLocal8Bit().constData( ));
}
else
{
put_flog( LOG_WARN, "'%s' could not be restored!",
content->getURI().toLocal8Bit().constData( ));
const QSize& size = content->getDimensions();
window->setContent( ContentFactory::getErrorContent( size ));
}
return true;
}

void _validateContents( DisplayGroup& group )
{
typedef QVector<ContentWindowPtr> Windows;
Windows windows = Windows::fromStdVector( group.getContentWindows( ));

QtConcurrent::blockingFilter( windows, _validateContent );

group.setContentWindows( validContentWindows );
group.setContentWindows( windows.toStdVector( ));
}

DisplayGroupConstPtr _load( const QString& filename, DisplayGroupConstPtr targetGroup )
Expand Down

0 comments on commit d2f39e6

Please sign in to comment.