From 0d88e74ba7eec9a1d662e377800a82a844924214 Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Wed, 20 Sep 2017 21:42:45 +0100 Subject: [PATCH] Add new class to handle framebuffer --- app/HistogramWidget.cpp | 8 +- app/VideoSubWindow.cpp | 4 +- lib/PlaYUVerStream.cpp | 282 +++++++++++++++++++++------------------- lib/PlaYUVerStream.h | 23 ++-- tools/PlaYUVerTools.cpp | 6 +- 5 files changed, 170 insertions(+), 153 deletions(-) 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/VideoSubWindow.cpp b/app/VideoSubWindow.cpp index 3d516b6..242aaa3 100644 --- a/app/VideoSubWindow.cpp +++ b/app/VideoSubWindow.cpp @@ -736,9 +736,9 @@ Bool VideoSubWindow::playEvent() { refreshFrame(); #ifndef QT_NO_CONCURRENT - m_cReadResult = QtConcurrent::run( m_pCurrStream, &PlaYUVerStream::readFrameFillRGBBuffer ); + m_cReadResult = QtConcurrent::run( m_pCurrStream, &PlaYUVerStream::readNextFrameFillRGBBuffer ); #else - m_pCurrStream->readFrameFillRGBBuffer(); + m_pCurrStream->readNextFrameFillRGBBuffer(); #endif } } diff --git a/lib/PlaYUVerStream.cpp b/lib/PlaYUVerStream.cpp index 1b74083..0c4924c 100644 --- a/lib/PlaYUVerStream.cpp +++ b/lib/PlaYUVerStream.cpp @@ -42,6 +42,68 @@ #include "StreamHandlerOpenCV.h" #endif +class PlaYUVerStreamBufferPrivate +{ +private: + UInt m_uiSize; + UInt m_uiIndex; + std::vector m_apcFrameBuffer; + +public: + PlaYUVerStreamBufferPrivate( UInt size, UInt width, UInt height, Int pelFormat, Int bitsPixel ) + { + m_uiSize = size; + for( UInt i = 0; i < m_uiSize; i++ ) + { + try + { + PlaYUVerFrame* pFrame = new PlaYUVerFrame( width, height, pelFormat, bitsPixel ); + m_apcFrameBuffer.push_back( pFrame ); + } + catch( PlaYUVerFailure& e ) + { + throw PlaYUVerFailure( "PlaYUVerStream", "Cannot allocated frame buffer" ); + } + } + m_uiIndex = 0; + } + + ~PlaYUVerStreamBufferPrivate() + { + for( UInt i = 0; i < m_apcFrameBuffer.size(); i++ ) + { + delete m_apcFrameBuffer.back(); + m_apcFrameBuffer.pop_back(); + } + } + + UInt size() + { + return m_uiSize; + } + Void setIndex( UInt i ) + { + m_uiSize = 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_uiSize ? 0 : m_uiIndex + 1; + } + inline Int prevIndex() + { + return m_uiIndex - 1 < 0 ? 0 : m_uiIndex + 1; + } +}; + std::vector PlaYUVerStream::supportedReadFormats() { INI_REGIST_PLAYUVER_SUPPORTED_FMT; @@ -138,11 +200,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; } @@ -246,28 +303,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 +331,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 +354,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 +381,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 +450,35 @@ Void PlaYUVerStream::loadAll() if( m_bLoadAll || !m_bIsInput ) return; - 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; - } - m_uiFrameBufferSize = m_uiTotalFrameNum; - getMem1D( &m_ppcFrameBuffer, m_uiFrameBufferSize ); - for( UInt i = 0; i < m_uiFrameBufferSize; i++ ) - { - 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(); - } - } - m_uiFrameBufferIndex = 0; - m_pcCurrFrame = m_ppcFrameBuffer[m_uiFrameBufferIndex]; - m_iCurrFrameNum = -1; + + // Keep past, current and future frames + + PlaYUVerStreamBufferPrivate* aux_frameBuffer; + try + { + aux_frameBuffer = new PlaYUVerStreamBufferPrivate( + m_uiTotalFrameNum, m_pcHandler->m_uiWidth, m_pcHandler->m_uiHeight, + m_pcHandler->m_iPixelFormat, m_pcHandler->m_uiBitsPerPixel ); + } + catch( PlaYUVerFailure& e ) + { + delete aux_frameBuffer; + return; + } + + if( m_frameBuffer ) + { + delete m_frameBuffer; + } + m_frameBuffer = aux_frameBuffer; + 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 +504,26 @@ 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_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 +537,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,48 +557,45 @@ Bool PlaYUVerStream::saveFrame( const String& filename, PlaYUVerFrame* saveFrame Bool PlaYUVerStream::setNextFrame() { Bool bEndOfSeq = false; - if( m_pcNextFrame ) - { - m_pcCurrFrame = m_pcNextFrame; - 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 - { - bEndOfSeq = true; - } + + if( m_iCurrFrameNum + 1 < Int( m_uiTotalFrameNum ) ) + { + m_frameBuffer->setNextFrame(); + m_iCurrFrameNum++; + } + else + { + bEndOfSeq = true; + } 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 ); - else - pyuv_image->copyFrom( m_pcCurrFrame ); + pyuv_image = new PlaYUVerFrame( m_frameBuffer->current() ); + else + 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 +607,7 @@ Bool PlaYUVerStream::seekInputRelative( Bool bIsFoward ) if( bIsFoward ) { bRet = !setNextFrame(); - readFrame(); + readFrame( m_frameBuffer->next() ); } else { @@ -609,9 +626,8 @@ Bool PlaYUVerStream::seekInput( UInt64 new_frame_num ) if( m_bLoadAll ) { - m_uiFrameBufferIndex = new_frame_num; - m_pcNextFrame = m_ppcFrameBuffer[m_uiFrameBufferIndex]; - setNextFrame(); + m_frameBuffer->setIndex( new_frame_num ); + setNextFrame(); return true; } @@ -622,12 +638,10 @@ Bool PlaYUVerStream::seekInput( UInt64 new_frame_num ) m_uiCurrFrameFileIdx = new_frame_num; - m_uiFrameBufferIndex = 0; - m_pcCurrFrame = m_pcNextFrame = m_ppcFrameBuffer[m_uiFrameBufferIndex]; + m_frameBuffer->setIndex( 0 ); + readFrame( m_frameBuffer->current() ); + if( m_uiTotalFrameNum > 1 ) + readFrame( m_frameBuffer->next() ); - readFrame(); - setNextFrame(); - if( m_uiTotalFrameNum > 1 ) - readFrame(); return true; } diff --git a/lib/PlaYUVerStream.h b/lib/PlaYUVerStream.h index 6a48e02..1570ff9 100644 --- a/lib/PlaYUVerStream.h +++ b/lib/PlaYUVerStream.h @@ -29,6 +29,7 @@ class PlaYUVerFrame; class PlaYUVerStreamHandlerIf; +class PlaYUVerStreamBufferPrivate; typedef struct { @@ -133,18 +134,20 @@ 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 +155,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,11 +170,8 @@ private: Bool m_bLoadAll; - UInt m_uiFrameBufferSize; - PlaYUVerFrame** m_ppcFrameBuffer; - PlaYUVerFrame* m_pcCurrFrame; - PlaYUVerFrame* m_pcNextFrame; - UInt m_uiFrameBufferIndex; + PlaYUVerStreamBufferPrivate* m_frameBuffer; + UInt64 m_uiCurrFrameFileIdx; }; diff --git a/tools/PlaYUVerTools.cpp b/tools/PlaYUVerTools.cpp index e768716..269de9c 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(); } } }