From eb31fc0287d1094192245ff3b2c8ce45135294f0 Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Sat, 23 Sep 2017 02:15:29 +0100 Subject: [PATCH] Merge branch devel --- CMakeLists.txt | 2 +- app/ConfigureFormatDialog.cpp | 3 +- app/HistogramWidget.cpp | 8 +- app/VideoHandle.cpp | 38 +++-- app/VideoHandle.h | 3 +- app/VideoSubWindow.cpp | 59 +++++--- app/VideoSubWindow.h | 1 + lib/PlaYUVerFrame.cpp | 33 +++-- lib/PlaYUVerStream.cpp | 233 ++++++++++++++----------------- lib/PlaYUVerStream.h | 22 +-- lib/PlaYUVerStreamHandlerIf.h | 17 ++- lib/StreamHandlerLibav.cpp | 2 + lib/StreamHandlerOpenCV.cpp | 3 + lib/StreamHandlerPortableMap.cpp | 2 + lib/StreamHandlerRaw.cpp | 4 + tools/PlaYUVerTools.cpp | 6 +- 16 files changed, 231 insertions(+), 205 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a70a9f6..c2a69c2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,7 +21,7 @@ set( PROJECT_NAME "playuver" CACHE INTERNAL "" FORCE ) PROJECT( ${PROJECT_NAME} ) SET( PLAYUVER_VERSION_MAJOR "0" ) SET( PLAYUVER_VERSION_MINOR "14" ) -SET( PLAYUVER_VERSION_PATCH "0" ) +SET( PLAYUVER_VERSION_PATCH "1" ) SET( PLAYUVER_VERSION "${PLAYUVER_VERSION_MAJOR}.${PLAYUVER_VERSION_MINOR}.${PLAYUVER_VERSION_PATCH}" CACHE INTERNAL "" FORCE ) ###################################################################################### diff --git a/app/ConfigureFormatDialog.cpp b/app/ConfigureFormatDialog.cpp index f2d674c..dd8941e 100644 --- a/app/ConfigureFormatDialog.cpp +++ b/app/ConfigureFormatDialog.cpp @@ -347,7 +347,7 @@ ConfigureFormatDialog::ConfigureFormatDialog( QWidget* parent ) : QDialog( paren m_spinBoxFrameRate = new QSpinBox(); m_spinBoxFrameRate->setSuffix( QStringLiteral( " Hz" ) ); m_spinBoxFrameRate->setMinimumWidth( 30 ); - m_spinBoxFrameRate->setRange( 0, 200 ); + m_spinBoxFrameRate->setRange( 0, 1000 ); m_spinBoxFrameRate->setValue( 30 ); framerateFormatLayout->addWidget( framerateFormatLabel ); framerateFormatLayout->addItem( @@ -442,7 +442,6 @@ Int ConfigureFormatDialog::runConfigureFormatDialog( const QString& Filename, if( standardResolutionSizes.at( i ) == QSize( rWidth, rHeight ) ) { m_comboBoxStandardResolution->setCurrentIndex( i ); - qDebug() << "ola"; break; } } diff --git a/app/HistogramWidget.cpp b/app/HistogramWidget.cpp index c2fea98..3c1eed3 100644 --- a/app/HistogramWidget.cpp +++ b/app/HistogramWidget.cpp @@ -896,10 +896,10 @@ Void HistogramWidget::paintEvent( QPaintEvent* ) guidePos = d->colorGuide.blue(); break; - // case HistogramWidget::LumaHistogram: - // guidePos = qMax( qMax( d->colorGuide.red(), d->colorGuide.green() - // ), d->colorGuide.blue() ); - // break; + // case HistogramWidget::LumaHistogram: + // guidePos = qMax( qMax( d->colorGuide.red(), d->colorGuide.green() + // ), d->colorGuide.blue() ); + // break; default: // Alpha. guidePos = -1; diff --git a/app/VideoHandle.cpp b/app/VideoHandle.cpp index 7c06fcd..29ee4ce 100644 --- a/app/VideoHandle.cpp +++ b/app/VideoHandle.cpp @@ -61,13 +61,15 @@ Void VideoHandle::createActions() m_arrayActions.resize( TOTAL_ACT ); m_arrayActions[PLAY_ACT] = new QAction( "Play", this ); m_arrayActions[PLAY_ACT]->setStatusTip( "Play/Pause" ); - m_arrayActions[PLAY_ACT]->setIcon( QIcon( style()->standardIcon( QStyle::SP_MediaPlay ) ) ); + m_arrayActions[PLAY_ACT]->setIcon( + QIcon( m_pcParet->style()->standardIcon( QStyle::SP_MediaPlay ) ) ); m_arrayActions[PLAY_ACT]->setShortcut( Qt::Key_Space ); connect( m_arrayActions[PLAY_ACT], SIGNAL( triggered() ), this, SLOT( play() ) ); m_arrayActions[STOP_ACT] = new QAction( "Stop", this ); m_arrayActions[STOP_ACT]->setStatusTip( "Stop" ); - m_arrayActions[STOP_ACT]->setIcon( QIcon( style()->standardIcon( QStyle::SP_MediaStop ) ) ); + m_arrayActions[STOP_ACT]->setIcon( + QIcon( m_pcParet->style()->standardIcon( QStyle::SP_MediaStop ) ) ); connect( m_arrayActions[STOP_ACT], SIGNAL( triggered() ), this, SLOT( stop() ) ); m_mapperVideoSeek = new QSignalMapper( this ); @@ -76,7 +78,7 @@ Void VideoHandle::createActions() m_arrayActions[VIDEO_BACKWARD_ACT] = new QAction( "Video Backward", this ); m_arrayActions[VIDEO_BACKWARD_ACT]->setStatusTip( "Seek backward" ); m_arrayActions[VIDEO_BACKWARD_ACT]->setIcon( - QIcon( style()->standardIcon( QStyle::SP_MediaSeekBackward ) ) ); + QIcon( m_pcParet->style()->standardIcon( QStyle::SP_MediaSeekBackward ) ) ); m_arrayActions[VIDEO_BACKWARD_ACT]->setShortcut( Qt::Key_Left ); connect( m_arrayActions[VIDEO_BACKWARD_ACT], SIGNAL( triggered() ), m_mapperVideoSeek, SLOT( map() ) ); @@ -85,7 +87,7 @@ Void VideoHandle::createActions() m_arrayActions[VIDEO_FORWARD_ACT] = new QAction( "Video Forward", this ); m_arrayActions[VIDEO_FORWARD_ACT]->setStatusTip( "Seek forward" ); m_arrayActions[VIDEO_FORWARD_ACT]->setIcon( - QIcon( style()->standardIcon( QStyle::SP_MediaSeekForward ) ) ); + QIcon( m_pcParet->style()->standardIcon( QStyle::SP_MediaSeekForward ) ) ); m_arrayActions[VIDEO_FORWARD_ACT]->setShortcut( Qt::Key_Right ); connect( m_arrayActions[VIDEO_FORWARD_ACT], SIGNAL( triggered() ), m_mapperVideoSeek, SLOT( map() ) ); @@ -170,7 +172,7 @@ Void VideoHandle::createActions() QMenu* VideoHandle::createVideoMenu() { - m_pcMenuVideo = new QMenu( "Video", this ); + m_pcMenuVideo = new QMenu( "Video", m_pcParet ); m_pcMenuVideo->addAction( m_arrayActions[PLAY_ACT] ); m_pcMenuVideo->addAction( m_arrayActions[STOP_ACT] ); m_pcMenuVideo->addAction( m_arrayActions[VIDEO_BACKWARD_ACT] ); @@ -185,7 +187,7 @@ QMenu* VideoHandle::createVideoMenu() QMenu* VideoHandle::createImageMenu() { - m_pcMenuImage = new QMenu( "Image", this ); + m_pcMenuImage = new QMenu( "Image", m_pcParet ); m_pcMenuImage->addAction( m_arrayActions[NAVIGATION_TOOL_ACT] ); m_pcMenuImage->addAction( m_arrayActions[SELECTION_TOOL_ACT] ); m_pcMenuImage->addAction( m_arrayActions[BLOCK_SELECTION_TOOL_ACT] ); @@ -201,7 +203,7 @@ QToolBar* VideoHandle::createToolBar() m_toolbarVideo->addAction( m_arrayActions[PLAY_ACT] ); m_toolbarVideo->addAction( m_arrayActions[STOP_ACT] ); - QLabel* pcLockLabel = new QLabel( "PlayingLock", this ); + QLabel* pcLockLabel = new QLabel( "PlayingLock" ); pcLockLabel->setAlignment( Qt::AlignCenter ); m_arrayActions[VIDEO_LOCK_ACT] = m_toolbarVideo->addWidget( pcLockLabel ); m_arrayActions[VIDEO_LOCK_ACT]->setVisible( false ); @@ -218,8 +220,8 @@ QToolBar* VideoHandle::createToolBar() QDockWidget* VideoHandle::createDock() { - m_pcFramePropertiesSideBar = new FramePropertiesDock( this, &m_bIsPlaying ); - m_pcFramePropertiesDock = new QDockWidget( tr( "Frame Information" ), this ); + m_pcFramePropertiesSideBar = new FramePropertiesDock( m_pcParet, &m_bIsPlaying ); + m_pcFramePropertiesDock = new QDockWidget( tr( "Frame Information" ), m_pcParet ); m_pcFramePropertiesDock->setAllowedAreas( Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea ); m_pcFramePropertiesDock->setWidget( m_pcFramePropertiesSideBar ); connect( m_pcFramePropertiesDock, SIGNAL( visibilityChanged( bool ) ), this, SLOT( update() ) ); @@ -263,14 +265,21 @@ Void VideoHandle::updateMenus() m_arrayActions[VIDEO_BACKWARD_ACT]->setEnabled( hasSubWindow ); m_arrayActions[VIDEO_FORWARD_ACT]->setEnabled( hasSubWindow ); m_arrayActions[VIDEO_REPEAT_ACT]->setEnabled( hasSubWindow ); + m_arrayActions[VIDEO_GOTO_ACT]->setEnabled( hasSubWindow ); m_arrayActions[VIDEO_ZOOM_LOCK_ACT]->setEnabled( hasSubWindow ); m_arrayActions[VIDEO_LOCK_SELECTION_ACT]->setEnabled( hasSubWindow ); m_pcFrameSlider->setEnabled( hasSubWindow ); if( !hasSubWindow ) { + disconnect( m_pcFrameSlider, SIGNAL( valueChanged( int ) ), this, + SLOT( seekSliderEvent( int ) ) ); m_pcFrameSlider->setValue( 0 ); m_pcFrameNumInfo->clear(); } + else + { + connect( m_pcFrameSlider, SIGNAL( valueChanged( int ) ), this, SLOT( seekSliderEvent( int ) ) ); + } m_arrayActions[NAVIGATION_TOOL_ACT]->setEnabled( hasSubWindow ); m_arrayActions[SELECTION_TOOL_ACT]->setEnabled( hasSubWindow ); @@ -357,12 +366,13 @@ Void VideoHandle::update() if( m_pcCurrentVideoSubWindow->isPlaying() ) { m_arrayActions[PLAY_ACT]->setText( "Pause" ); - m_arrayActions[PLAY_ACT]->setIcon( style()->standardIcon( QStyle::SP_MediaPause ) ); + m_arrayActions[PLAY_ACT]->setIcon( + m_pcParet->style()->standardIcon( QStyle::SP_MediaPause ) ); } else { m_arrayActions[PLAY_ACT]->setText( "Play" ); - m_arrayActions[PLAY_ACT]->setIcon( style()->standardIcon( QStyle::SP_MediaPlay ) ); + m_arrayActions[PLAY_ACT]->setIcon( m_pcParet->style()->standardIcon( QStyle::SP_MediaPlay ) ); } } else @@ -643,7 +653,7 @@ Void VideoHandle::playEvent() QString warningMsg = "Error while playing " + QFileInfo( m_pcCurrentVideoSubWindow->getCurrentFileName() ).fileName() + " with the following error: \n" + msg; - QMessageBox::warning( this, QApplication::applicationName(), warningMsg ); + QMessageBox::warning( m_pcParet, QApplication::applicationName(), warningMsg ); qDebug() << warningMsg; stop(); m_pcCurrentVideoSubWindow->close(); @@ -683,7 +693,7 @@ Void VideoHandle::seekVideo() if( m_pcCurrentVideoSubWindow->getInputStream() ) { SeekStreamDialog* dialogSeekVideo = - new SeekStreamDialog( m_pcCurrentVideoSubWindow->getInputStream(), this ); + new SeekStreamDialog( m_pcCurrentVideoSubWindow->getInputStream(), m_pcParet ); Int newFrameNum = dialogSeekVideo->runDialog(); if( newFrameNum >= 0 ) { @@ -741,7 +751,7 @@ Void VideoHandle::videoSelectionButtonEvent() } else { - DialogSubWindowSelector dialogWindowsSelection( this, m_pcMainWindowManager, + DialogSubWindowSelector dialogWindowsSelection( m_pcParet, m_pcMainWindowManager, SubWindowAbstract::VIDEO_STREAM_SUBWINDOW ); QStringList cWindowListNames; for( Int i = 0; i < m_acPlayingSubWindows.size(); i++ ) diff --git a/app/VideoHandle.h b/app/VideoHandle.h index 6e8cf7c..2d72e6c 100644 --- a/app/VideoHandle.h +++ b/app/VideoHandle.h @@ -31,6 +31,7 @@ #include #include #include +#include #include #define _CONTROL_PLAYING_TIME_ 0 @@ -48,7 +49,7 @@ class VideoSubWindow; class FramePropertiesDock; class WidgetFrameNumber; -class VideoHandle : public QWidget +class VideoHandle : public QObject { Q_OBJECT public: diff --git a/app/VideoSubWindow.cpp b/app/VideoSubWindow.cpp index 63e201e..9fffa6c 100644 --- a/app/VideoSubWindow.cpp +++ b/app/VideoSubWindow.cpp @@ -689,6 +689,33 @@ Void VideoSubWindow::refreshFrame( Bool bThreaded ) } } +Bool VideoSubWindow::goToNextFrame( Bool bThreaded ) +{ +#ifndef QT_NO_CONCURRENT + m_cRefreshResult.waitForFinished(); + m_cReadResult.waitForFinished(); +#endif + Bool bEndOfSeq = m_pCurrStream->setNextFrame(); + if( !bEndOfSeq ) + { +#ifndef QT_NO_CONCURRENT + m_cRefreshResult.waitForFinished(); + if( bThreaded ) + { + refreshFrame(); + m_cReadResult = + QtConcurrent::run( m_pCurrStream, &PlaYUVerStream::readNextFrameFillRGBBuffer ); + } + else +#endif + { + refreshFrame(); + m_pCurrStream->readNextFrameFillRGBBuffer(); + } + } + return bEndOfSeq; +} + Bool VideoSubWindow::save( QString filename ) { Bool iRet = false; @@ -727,20 +754,7 @@ Bool VideoSubWindow::playEvent() Bool bEndOfSeq = false; if( m_pCurrStream && m_bIsPlaying ) { -#ifndef QT_NO_CONCURRENT - m_cRefreshResult.waitForFinished(); - m_cReadResult.waitForFinished(); -#endif - bEndOfSeq = m_pCurrStream->setNextFrame(); - if( !bEndOfSeq ) - { - refreshFrame( true ); -#ifndef QT_NO_CONCURRENT - m_cReadResult = QtConcurrent::run( m_pCurrStream, &PlaYUVerStream::readFrameFillRGBBuffer ); -#else - m_pCurrStream->readFrameFillRGBBuffer(); -#endif - } + bEndOfSeq = goToNextFrame( true ); } return bEndOfSeq; } @@ -754,22 +768,27 @@ Void VideoSubWindow::pause() Void VideoSubWindow::seekAbsoluteEvent( UInt new_frame_num ) { if( m_pCurrStream ) - { if( m_pCurrStream->seekInput( new_frame_num ) ) - { refreshFrame(); - } - } } Void VideoSubWindow::seekRelativeEvent( Bool bIsFoward ) { + Bool bRefresh = false; if( m_pCurrStream ) { - if( m_pCurrStream->seekInputRelative( bIsFoward ) ) + if( bIsFoward ) { - refreshFrame(); + goToNextFrame( true ); } + else + { + bRefresh = m_pCurrStream->seekInputRelative( bIsFoward ); + } + } + if( bRefresh ) + { + refreshFrame(); } } diff --git a/app/VideoSubWindow.h b/app/VideoSubWindow.h index 7507b31..913ae2c 100644 --- a/app/VideoSubWindow.h +++ b/app/VideoSubWindow.h @@ -101,6 +101,7 @@ private: QFuture m_cReadResult; Void refreshFrameOperation(); + Bool goToNextFrame( Bool bThreaded = false ); static Bool guessFormat( QString filename, UInt& rWidth, diff --git a/lib/PlaYUVerFrame.cpp b/lib/PlaYUVerFrame.cpp index 367f885..2dc4054 100644 --- a/lib/PlaYUVerFrame.cpp +++ b/lib/PlaYUVerFrame.cpp @@ -214,6 +214,24 @@ struct PlaYUVerFramePrivate m_bInit = true; } + + ~PlaYUVerFramePrivate() + { + if( m_puiHistogram ) + { + freeMem1D( m_puiHistogram ); + } + m_puiHistogram = NULL; + m_bHasHistogram = false; + + if( m_pppcInputPel ) + freeImgMemory( m_pppcInputPel ); + m_pppcInputPel = NULL; + + if( m_pcARGB32 ) + freeMem1D( m_pcARGB32 ); + m_pcARGB32 = NULL; + } }; /*! @@ -302,21 +320,6 @@ PlaYUVerFrame::PlaYUVerFrame( const PlaYUVerFrame* other, PlaYUVerFrame::~PlaYUVerFrame() { - if( d->m_puiHistogram ) - { - freeMem1D( d->m_puiHistogram ); - } - d->m_puiHistogram = NULL; - d->m_bHasHistogram = false; - - if( d->m_pppcInputPel ) - freeImgMemory( d->m_pppcInputPel ); - d->m_pppcInputPel = NULL; - - if( d->m_pcARGB32 ) - freeMem1D( d->m_pcARGB32 ); - d->m_pcARGB32 = NULL; - delete d; } diff --git a/lib/PlaYUVerStream.cpp b/lib/PlaYUVerStream.cpp index 1b74083..b368929 100644 --- a/lib/PlaYUVerStream.cpp +++ b/lib/PlaYUVerStream.cpp @@ -42,6 +42,52 @@ #include "StreamHandlerOpenCV.h" #endif +class PlaYUVerStreamBufferPrivate +{ +private: + std::vector m_apcFrameBuffer; + UInt m_uiIndex; + +public: + PlaYUVerStreamBufferPrivate( UInt size, UInt width, UInt height, Int pelFormat, Int bitsPixel ) + { + for( UInt i = 0; i < size; i++ ) + { + PlaYUVerFrame* pFrame = new PlaYUVerFrame( width, height, pelFormat, bitsPixel ); + m_apcFrameBuffer.push_back( pFrame ); + } + m_uiIndex = 0; + } + + ~PlaYUVerStreamBufferPrivate() + { + while( m_apcFrameBuffer.size() > 0 ) + { + delete m_apcFrameBuffer.back(); + m_apcFrameBuffer.pop_back(); + } + } + Void increase( UInt newSize ) + { + for( UInt i = m_apcFrameBuffer.size(); i < newSize; i++ ) + { + PlaYUVerFrame* pFrame = new PlaYUVerFrame( m_apcFrameBuffer.at( 0 ) ); + m_apcFrameBuffer.push_back( pFrame ); + } + } + UInt size() { return m_apcFrameBuffer.size(); } + Void setIndex( UInt i ) { m_uiIndex = i; } + PlaYUVerFrame* frame( Int i ) { return m_apcFrameBuffer.at( i ); } + + PlaYUVerFrame* current() { return m_apcFrameBuffer.at( m_uiIndex ); } + PlaYUVerFrame* next() { return m_apcFrameBuffer.at( nextIndex() ); } + Void setNextFrame() { m_uiIndex = nextIndex(); } + +private: + inline Int nextIndex() { return m_uiIndex + 1 >= m_apcFrameBuffer.size() ? 0 : m_uiIndex + 1; } + inline Int prevIndex() { return m_uiIndex - 1 < 0 ? m_apcFrameBuffer.size() - 1 : m_uiIndex - 1; } +}; + std::vector PlaYUVerStream::supportedReadFormats() { INI_REGIST_PLAYUVER_SUPPORTED_FMT; @@ -138,12 +184,6 @@ PlaYUVerStream::PlaYUVerStream() m_uiTotalFrameNum = 0; m_iCurrFrameNum = -1; m_cFilename = ""; - m_pcCurrFrame = NULL; - m_pcNextFrame = NULL; - m_ppcFrameBuffer = NULL; - m_uiFrameBufferSize = 2; - m_uiFrameBufferIndex = 0; - m_uiCurrFrameFileIdx = 0; } PlaYUVerStream::~PlaYUVerStream() @@ -246,28 +286,21 @@ Bool PlaYUVerStream::open( String filename, return m_bInit; } - m_uiFrameBufferSize = m_bIsInput ? 2 : 1; - - getMem1D( &m_ppcFrameBuffer, m_uiFrameBufferSize ); - for( UInt i = 0; i < m_uiFrameBufferSize; i++ ) + // Keep past, current and future frames + try { - try - { - m_ppcFrameBuffer[i] = - new PlaYUVerFrame( m_pcHandler->m_uiWidth, m_pcHandler->m_uiHeight, - m_pcHandler->m_iPixelFormat, m_pcHandler->m_uiBitsPerPixel ); - } - catch( PlaYUVerFailure& e ) - { - close(); - throw PlaYUVerFailure( "PlaYUVerStream", "Cannot allocated frame buffer" ); - return m_bInit; - } + m_frameBuffer = new PlaYUVerStreamBufferPrivate( + m_bIsInput ? 3 : 1, m_pcHandler->m_uiWidth, m_pcHandler->m_uiHeight, + m_pcHandler->m_iPixelFormat, m_pcHandler->m_uiBitsPerPixel ); + } + catch( PlaYUVerFailure& e ) + { + close(); + throw PlaYUVerFailure( "PlaYUVerStream", "Cannot allocated frame buffer" ); + return m_bInit; } - m_uiFrameBufferIndex = 0; - m_pcCurrFrame = m_ppcFrameBuffer[m_uiFrameBufferIndex]; - m_pcHandler->setBytesPerFrame( m_pcCurrFrame->getBytesPerFrame() ); + m_pcHandler->setBytesPerFrame( m_frameBuffer->current()->getBytesPerFrame() ); if( m_bIsInput ) { @@ -281,7 +314,7 @@ Bool PlaYUVerStream::open( String filename, return m_bInit; } - if( !m_pcHandler->configureBuffer( m_pcCurrFrame ) ) + if( !m_pcHandler->configureBuffer( m_frameBuffer->current() ) ) { close(); throw PlaYUVerFailure( "PlaYUVerStream", "Cannot allocated memory" ); @@ -304,7 +337,7 @@ Bool PlaYUVerStream::reload() { throw PlaYUVerFailure( "PlaYUVerStream", "Cannot open file" ); } - m_pcHandler->setBytesPerFrame( m_pcCurrFrame->getBytesPerFrame() ); + m_pcHandler->setBytesPerFrame( m_frameBuffer->current()->getBytesPerFrame() ); m_uiTotalFrameNum = m_pcHandler->calculateFrameNumber(); if( m_pcHandler->m_uiWidth <= 0 || m_pcHandler->m_uiHeight <= 0 || @@ -331,17 +364,7 @@ Void PlaYUVerStream::close() m_pcHandler->closeHandler(); m_pcHandler->Delete(); - if( m_ppcFrameBuffer ) - { - for( UInt i = 0; i < m_uiFrameBufferSize; i++ ) - { - if( m_ppcFrameBuffer[i] ) - delete m_ppcFrameBuffer[i]; - m_ppcFrameBuffer[i] = NULL; - } - freeMem1D( m_ppcFrameBuffer ); - m_ppcFrameBuffer = NULL; - } + delete m_frameBuffer; m_bLoadAll = false; m_bInit = false; @@ -410,43 +433,23 @@ Void PlaYUVerStream::loadAll() if( m_bLoadAll || !m_bIsInput ) return; - if( m_ppcFrameBuffer ) + try { - for( UInt i = 0; i < m_uiFrameBufferSize; i++ ) - { - if( m_ppcFrameBuffer[i] ) - delete m_ppcFrameBuffer[i]; - m_ppcFrameBuffer[i] = NULL; - } - freeMem1D( m_ppcFrameBuffer ); - m_ppcFrameBuffer = NULL; + m_frameBuffer->increase( m_uiTotalFrameNum ); } - m_uiFrameBufferSize = m_uiTotalFrameNum; - getMem1D( &m_ppcFrameBuffer, m_uiFrameBufferSize ); - for( UInt i = 0; i < m_uiFrameBufferSize; i++ ) + catch( PlaYUVerFailure& e ) { - m_ppcFrameBuffer[i] = - new PlaYUVerFrame( m_pcHandler->m_uiWidth, m_pcHandler->m_uiHeight, - m_pcHandler->m_iPixelFormat, m_pcHandler->m_uiBitsPerPixel ); - if( !m_ppcFrameBuffer[i] ) - { - close(); - } + close(); + throw PlaYUVerFailure( "PlaYUVerStream", "Cannot allocated frame buffer" ); } - m_uiFrameBufferIndex = 0; - m_pcCurrFrame = m_ppcFrameBuffer[m_uiFrameBufferIndex]; - m_iCurrFrameNum = -1; + seekInput( 0 ); - for( UInt i = m_uiFrameBufferIndex + 1; i < m_uiFrameBufferSize; i++ ) + for( UInt i = 2; i < m_frameBuffer->size(); i++ ) { - m_pcNextFrame = m_ppcFrameBuffer[i]; - readFrame(); + readFrame( m_frameBuffer->frame( i ) ); } m_bLoadAll = true; - m_uiFrameBufferIndex = 0; - m_pcNextFrame = m_ppcFrameBuffer[m_uiFrameBufferIndex]; - m_iCurrFrameNum = -1; - setNextFrame(); + m_iCurrFrameNum = 0; } Void PlaYUVerStream::getDuration( Int* duration_array ) @@ -472,38 +475,25 @@ Void PlaYUVerStream::getDuration( Int* duration_array ) // *duration_array++ = secs; } -Void PlaYUVerStream::readFrameFillRGBBuffer() +Bool PlaYUVerStream::readFrame( PlaYUVerFrame* frame ) { - readFrame(); - if( m_pcNextFrame ) - m_pcNextFrame->fillRGBBuffer(); - return; -} + if( !m_bInit || !m_bIsInput || m_pcHandler->m_uiCurrFrameFileIdx >= m_uiTotalFrameNum ) + return false; -Void PlaYUVerStream::readFrame() -{ - if( !m_bInit || !m_bIsInput || m_bLoadAll ) - return; + if( m_bLoadAll ) + return true; - if( m_uiCurrFrameFileIdx >= m_uiTotalFrameNum ) - { - m_pcNextFrame = NULL; - return; - } - - if( !m_pcHandler->read( m_pcNextFrame ) ) + if( !m_pcHandler->read( frame ) ) { throw PlaYUVerFailure( "PlaYUVerStream", "Cannot read file" ); - return; + return false; } - - m_uiCurrFrameFileIdx++; - return; + return true; } Void PlaYUVerStream::writeFrame() { - writeFrame( m_pcCurrFrame ); + writeFrame( m_frameBuffer->current() ); } Void PlaYUVerStream::writeFrame( PlaYUVerFrame* pcFrame ) @@ -517,7 +507,7 @@ Void PlaYUVerStream::writeFrame( PlaYUVerFrame* pcFrame ) Bool PlaYUVerStream::saveFrame( const String& filename ) { - return saveFrame( filename, m_pcCurrFrame ); + return saveFrame( filename, m_frameBuffer->current() ); } Bool PlaYUVerStream::saveFrame( const String& filename, PlaYUVerFrame* saveFrame ) @@ -537,23 +527,11 @@ Bool PlaYUVerStream::saveFrame( const String& filename, PlaYUVerFrame* saveFrame Bool PlaYUVerStream::setNextFrame() { Bool bEndOfSeq = false; - if( m_pcNextFrame ) + + if( m_iCurrFrameNum + 1 < Int( m_uiTotalFrameNum ) ) { - m_pcCurrFrame = m_pcNextFrame; + m_frameBuffer->setNextFrame(); m_iCurrFrameNum++; - if( m_iCurrFrameNum + 1 < Int( m_uiTotalFrameNum ) ) - { - m_uiFrameBufferIndex++; - if( m_uiFrameBufferIndex == m_uiFrameBufferSize ) - { - m_uiFrameBufferIndex = 0; - } - m_pcNextFrame = m_ppcFrameBuffer[m_uiFrameBufferIndex]; - } - else - { - m_pcNextFrame = NULL; - } } else { @@ -562,23 +540,30 @@ Bool PlaYUVerStream::setNextFrame() return bEndOfSeq; } +Void PlaYUVerStream::readNextFrame() +{ + readFrame( m_frameBuffer->next() ); +} + +Void PlaYUVerStream::readNextFrameFillRGBBuffer() +{ + readNextFrame(); + m_frameBuffer->next()->fillRGBBuffer(); + return; +} + PlaYUVerFrame* PlaYUVerStream::getCurrFrame( PlaYUVerFrame* pyuv_image ) { if( pyuv_image == NULL ) - pyuv_image = new PlaYUVerFrame( m_pcCurrFrame ); + pyuv_image = new PlaYUVerFrame( m_frameBuffer->current() ); else - pyuv_image->copyFrom( m_pcCurrFrame ); + pyuv_image->copyFrom( m_frameBuffer->current() ); return pyuv_image; } PlaYUVerFrame* PlaYUVerStream::getCurrFrame() { - return m_pcCurrFrame; -} - -PlaYUVerFrame* PlaYUVerStream::getNextFrame() -{ - return m_pcNextFrame; + return m_frameBuffer->current(); } Bool PlaYUVerStream::seekInputRelative( Bool bIsFoward ) @@ -590,7 +575,7 @@ Bool PlaYUVerStream::seekInputRelative( Bool bIsFoward ) if( bIsFoward ) { bRet = !setNextFrame(); - readFrame(); + readFrame( m_frameBuffer->next() ); } else { @@ -605,29 +590,23 @@ Bool PlaYUVerStream::seekInput( UInt64 new_frame_num ) if( !m_bInit || new_frame_num >= m_uiTotalFrameNum || (Int64)new_frame_num == m_iCurrFrameNum ) return false; - m_iCurrFrameNum = new_frame_num - 1; + m_iCurrFrameNum = new_frame_num; if( m_bLoadAll ) { - m_uiFrameBufferIndex = new_frame_num; - m_pcNextFrame = m_ppcFrameBuffer[m_uiFrameBufferIndex]; - setNextFrame(); + m_frameBuffer->setIndex( m_iCurrFrameNum ); return true; } - if( !m_pcHandler->seek( new_frame_num ) ) + if( !m_pcHandler->seek( m_iCurrFrameNum ) ) { throw PlaYUVerFailure( "PlaYUVerStream", "Cannot write into the file" ); } - m_uiCurrFrameFileIdx = new_frame_num; - - m_uiFrameBufferIndex = 0; - m_pcCurrFrame = m_pcNextFrame = m_ppcFrameBuffer[m_uiFrameBufferIndex]; - - readFrame(); - setNextFrame(); + m_frameBuffer->setIndex( 0 ); + readFrame( m_frameBuffer->current() ); if( m_uiTotalFrameNum > 1 ) - readFrame(); + readFrame( m_frameBuffer->next() ); + return true; } diff --git a/lib/PlaYUVerStream.h b/lib/PlaYUVerStream.h index 6a48e02..f412482 100644 --- a/lib/PlaYUVerStream.h +++ b/lib/PlaYUVerStream.h @@ -29,6 +29,7 @@ class PlaYUVerFrame; class PlaYUVerStreamHandlerIf; +class PlaYUVerStreamBufferPrivate; typedef struct { @@ -133,18 +134,19 @@ public: Void loadAll(); - Void readFrame(); - Void readFrameFillRGBBuffer(); Void writeFrame(); Void writeFrame( PlaYUVerFrame* pcFrame ); Bool saveFrame( const String& filename ); static Bool saveFrame( const String& filename, PlaYUVerFrame* saveFrame ); - Bool setNextFrame(); - PlaYUVerFrame* getCurrFrame(); PlaYUVerFrame* getCurrFrame( PlaYUVerFrame* ); - PlaYUVerFrame* getNextFrame(); + + // continuous read control + Bool setNextFrame(); + Void readNextFrame(); + Void readNextFrameFillRGBBuffer(); + PlaYUVerFrame* getCurrFrame(); Bool seekInputRelative( Bool bIsFoward ); Bool seekInput( UInt64 new_frame_num ); @@ -152,6 +154,9 @@ public: Bool isInit() { return m_bInit; } Void getDuration( Int* duration_array ); +private: + Bool readFrame( PlaYUVerFrame* frame ); + private: Bool m_bInit; CreateStreamHandlerFn m_pfctCreateHandler; @@ -164,12 +169,7 @@ private: Bool m_bLoadAll; - UInt m_uiFrameBufferSize; - PlaYUVerFrame** m_ppcFrameBuffer; - PlaYUVerFrame* m_pcCurrFrame; - PlaYUVerFrame* m_pcNextFrame; - UInt m_uiFrameBufferIndex; - UInt64 m_uiCurrFrameFileIdx; + PlaYUVerStreamBufferPrivate* m_frameBuffer; }; #endif // __PLAYUVERSTREAM_H__ diff --git a/lib/PlaYUVerStreamHandlerIf.h b/lib/PlaYUVerStreamHandlerIf.h index 0a6dfa3..26d8d6e 100644 --- a/lib/PlaYUVerStreamHandlerIf.h +++ b/lib/PlaYUVerStreamHandlerIf.h @@ -45,14 +45,16 @@ class PlaYUVerStreamHandlerIf public: PlaYUVerStreamHandlerIf() + : m_bIsInput( true ) + , m_uiCurrFrameFileIdx( 0 ) + , m_uiWidth( 0 ) + , m_uiHeight( 0 ) + , m_iPixelFormat( -1 ) + , m_uiBitsPerPixel( 8 ) + , m_iEndianness( -1 ) + , m_dFrameRate( 30 ) + , m_pStreamBuffer( NULL ) { - m_bIsInput = true; - m_uiWidth = 0; - m_uiHeight = 0; - m_iPixelFormat = -1; - m_uiBitsPerPixel = 8; - m_iEndianness = -1; - m_dFrameRate = 30; } virtual ~PlaYUVerStreamHandlerIf() {} virtual void Delete() = 0; @@ -71,6 +73,7 @@ public: protected: Bool m_bIsInput; + UInt64 m_uiCurrFrameFileIdx; String m_cFilename; UInt m_uiWidth; UInt m_uiHeight; diff --git a/lib/StreamHandlerLibav.cpp b/lib/StreamHandlerLibav.cpp index 80804a7..c6892b0 100644 --- a/lib/StreamHandlerLibav.cpp +++ b/lib/StreamHandlerLibav.cpp @@ -389,6 +389,7 @@ Bool StreamHandlerLibav::read( PlaYUVerFrame* pcFrame ) #endif pcFrame->frameFromBuffer( m_pStreamBuffer, m_iEndianness ); + m_uiCurrFrameFileIdx++; return true; } return false; @@ -402,5 +403,6 @@ Bool StreamHandlerLibav::write( PlaYUVerFrame* pcFrame ) Bool StreamHandlerLibav::seek( UInt64 iFrameNum ) { av_seek_frame( m_cFmtCtx, m_iStreamIdx, iFrameNum, AVSEEK_FLAG_FRAME ); + m_uiCurrFrameFileIdx = iFrameNum; return true; } diff --git a/lib/StreamHandlerOpenCV.cpp b/lib/StreamHandlerOpenCV.cpp index bc64333..a40d925 100644 --- a/lib/StreamHandlerOpenCV.cpp +++ b/lib/StreamHandlerOpenCV.cpp @@ -129,6 +129,7 @@ UInt64 StreamHandlerOpenCV::calculateFrameNumber() Bool StreamHandlerOpenCV::seek( UInt64 iFrameNum ) { + // m_uiCurrFrameFileIdx = return true; } @@ -147,6 +148,8 @@ Bool StreamHandlerOpenCV::read( PlaYUVerFrame* pcFrame ) Mat cvMat = cv::imread( m_cFilename ); bRet = pcFrame->fromMat( cvMat ); } + if( bRet ) + m_uiCurrFrameFileIdx++; return bRet; } diff --git a/lib/StreamHandlerPortableMap.cpp b/lib/StreamHandlerPortableMap.cpp index 03dacc8..af27be3 100644 --- a/lib/StreamHandlerPortableMap.cpp +++ b/lib/StreamHandlerPortableMap.cpp @@ -113,6 +113,7 @@ UInt64 StreamHandlerPortableMap::calculateFrameNumber() Bool StreamHandlerPortableMap::seek( UInt64 iFrameNum ) { + // m_uiCurrFrameFileIdx = return true; } @@ -122,6 +123,7 @@ Bool StreamHandlerPortableMap::read( PlaYUVerFrame* pcFrame ) if( processed_bytes != m_uiNBytesPerFrame ) return false; pcFrame->frameFromBuffer( m_pStreamBuffer, PLAYUVER_BIG_ENDIAN ); + m_uiCurrFrameFileIdx++; return true; } diff --git a/lib/StreamHandlerRaw.cpp b/lib/StreamHandlerRaw.cpp index bf34390..08b7d1c 100644 --- a/lib/StreamHandlerRaw.cpp +++ b/lib/StreamHandlerRaw.cpp @@ -48,6 +48,8 @@ Void StreamHandlerRaw::closeHandler() { if( m_pFile ) fclose( m_pFile ); + if( m_pStreamBuffer ) + freeMem1D( m_pStreamBuffer ); } Bool StreamHandlerRaw::configureBuffer( PlaYUVerFrame* pcFrame ) @@ -70,6 +72,7 @@ Bool StreamHandlerRaw::seek( UInt64 iFrameNum ) if( m_bIsInput && m_pFile ) { fseek( m_pFile, iFrameNum >= 0 ? iFrameNum * m_uiNBytesPerFrame : 0, SEEK_SET ); + m_uiCurrFrameFileIdx = iFrameNum; return true; } return false; @@ -80,6 +83,7 @@ Bool StreamHandlerRaw::read( PlaYUVerFrame* pcFrame ) UInt64 processed_bytes = fread( m_pStreamBuffer, sizeof( Byte ), m_uiNBytesPerFrame, m_pFile ); if( processed_bytes != m_uiNBytesPerFrame ) return false; + m_uiCurrFrameFileIdx++; pcFrame->frameFromBuffer( m_pStreamBuffer, m_iEndianness ); return true; } diff --git a/tools/PlaYUVerTools.cpp b/tools/PlaYUVerTools.cpp index e768716..896ab4f 100644 --- a/tools/PlaYUVerTools.cpp +++ b/tools/PlaYUVerTools.cpp @@ -419,7 +419,7 @@ Int PlaYUVerTools::RateReductionOperation() abEOF = m_apcInputStreams[0]->setNextFrame(); if( !abEOF ) { - m_apcInputStreams[0]->readFrame(); + m_apcInputStreams[0]->readNextFrame(); } } return 0; @@ -500,7 +500,7 @@ Int PlaYUVerTools::QualityOperation() abEOF[s] = m_apcInputStreams[s]->setNextFrame(); if( !abEOF[s] ) { - m_apcInputStreams[s]->readFrame(); + m_apcInputStreams[s]->readNextFrame(); } } } @@ -584,7 +584,7 @@ Int PlaYUVerTools::ModuleOperation() abEOF[s] = m_apcInputStreams[s]->setNextFrame(); if( !abEOF[s] ) { - m_apcInputStreams[s]->readFrame(); + m_apcInputStreams[s]->readNextFrame(); } } }