From 4135c36b08e6daafe371d8f7053eb16d90aa8bae Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Wed, 3 Dec 2014 15:25:59 +0000 Subject: [PATCH 1/2] Change PlaYUVerStream in order to handle different interfaces to read and write streams --- lib/LibAvContextHandle.cpp | 5 ++ lib/PlaYUVerStream.cpp | 112 +++++++++++++++++++++---------------- lib/PlaYUVerStream.h | 8 +++ 3 files changed, 78 insertions(+), 47 deletions(-) diff --git a/lib/LibAvContextHandle.cpp b/lib/LibAvContextHandle.cpp index b29ebe4..a813359 100644 --- a/lib/LibAvContextHandle.cpp +++ b/lib/LibAvContextHandle.cpp @@ -191,6 +191,11 @@ Bool LibAvContextHandle::initAvFormat( char* filename, UInt& width, UInt& height break; } } + if( pixel_format == PlaYUVerFrame::NO_FMT ) + { + closeAvFormat(); + return false; + } /* dump input information to stderr */ av_dump_format( fmt_ctx, 0, src_filename, 0 ); diff --git a/lib/PlaYUVerStream.cpp b/lib/PlaYUVerStream.cpp index 59cb8a1..33605be 100644 --- a/lib/PlaYUVerStream.cpp +++ b/lib/PlaYUVerStream.cpp @@ -41,7 +41,7 @@ PlaYUVerStream::PlaYUVerStream() m_bIsOpened = false; m_bLoadAll = false; m_iErrorStatus = 0; - + m_uiStreamHandler = 0; m_pFile = NULL; m_uiWidth = 0; m_uiHeight = 0; @@ -70,8 +70,6 @@ PlaYUVerStream::~PlaYUVerStream() Bool PlaYUVerStream::open( QString filename, UInt width, UInt height, Int input_format, UInt frame_rate, Bool bInput ) { - Bool avStatus = false; - if( m_bInit ) { close(); @@ -103,11 +101,15 @@ Bool PlaYUVerStream::open( QString filename, UInt width, UInt height, Int input_ } m_cFormatName = PlaYUVerStream::supportedReadFormatsExt().at( m_iFileFormat ).toUpper(); + if( m_iFileFormat == YUVINPUT ) + { + m_uiStreamHandler = YUV_IO; + } + #ifdef USE_FFMPEG if( m_iFileFormat != YUVINPUT ) { - avStatus = m_cLibAvContext->initAvFormat( m_cFilename.toLocal8Bit().data(), m_uiWidth, m_uiHeight, m_iPixelFormat, m_uiFrameRate, m_uiTotalFrameNum ); - m_cCodedName = QString::fromUtf8( m_cLibAvContext->getCodecName() ).toUpper(); + m_uiStreamHandler = FFMPEG; } #endif #if 0 @@ -126,9 +128,21 @@ Bool PlaYUVerStream::open( QString filename, UInt width, UInt height, Int input_ else { m_iFileFormat = YUVOUTPUT; + m_uiStreamHandler = YUV_IO; m_uiFrameBufferSize = 1; } +#ifdef USE_FFMPEG + if( m_uiStreamHandler == FFMPEG ) + { + if( !m_cLibAvContext->initAvFormat( m_cFilename.toLocal8Bit().data(), m_uiWidth, m_uiHeight, m_iPixelFormat, m_uiFrameRate, m_uiTotalFrameNum ) ) + { + throw "Cannot open file using FFmpeg libs"; + } + m_cCodedName = QString::fromUtf8( m_cLibAvContext->getCodecName() ).toUpper(); + } +#endif + if( m_uiWidth <= 0 || m_uiHeight <= 0 || m_iPixelFormat < 0 ) { close(); @@ -136,6 +150,18 @@ Bool PlaYUVerStream::open( QString filename, UInt width, UInt height, Int input_ return m_bInit; } + if( m_uiStreamHandler == YUV_IO ) + { + if( !openFile() ) + { + close(); + throw "[PlaYUVerStream] Cannot open file"; + return m_bInit; + } + m_cFormatName = QString::fromUtf8( "YUV" ); + m_cCodedName = QString::fromUtf8( "Raw Video" ); + } + getMem1D( &m_ppcFrameBuffer, m_uiFrameBufferSize ); for( UInt i = 0; i < m_uiFrameBufferSize; i++ ) { @@ -152,37 +178,21 @@ Bool PlaYUVerStream::open( QString filename, UInt width, UInt height, Int input_ UInt64 frame_bytes_input = m_pcCurrFrame->getBytesPerFrame(); - if( !avStatus ) + if( m_uiStreamHandler == YUV_IO && m_bIsInput ) { - if( !openFile() ) + fseek( m_pFile, 0, SEEK_END ); + UInt64 fileSize = ftell( m_pFile ); +#if 0 + if( fileSize % frame_bytes_input ) { + Int remaining = fileSize % frame_bytes_input; close(); - throw "[PlaYUVerStream] Cannot open file"; + throw "[PlaYUVerStream] Incorrect configuration: failed ( fileSize % frame_bytes_input = " << remaining << " )"; return m_bInit; } - m_cFormatName = QString::fromUtf8( "YUV" ); - m_cCodedName = QString::fromUtf8( "Raw Video" ); - } - - if( !avStatus && m_iFileFormat == YUVINPUT ) - { - if( m_bIsInput ) - { - fseek( m_pFile, 0, SEEK_END ); - UInt64 fileSize = ftell( m_pFile ); -#if 0 - if( fileSize % frame_bytes_input ) - { - Int remaining = fileSize % frame_bytes_input; - close(); - throw "[PlaYUVerStream] Incorrect configuration: failed ( fileSize % frame_bytes_input = " << remaining << " )"; - return m_bInit; - } #endif - m_uiTotalFrameNum = fileSize / frame_bytes_input; - fseek( m_pFile, 0, SEEK_SET ); - } - + m_uiTotalFrameNum = fileSize / frame_bytes_input; + fseek( m_pFile, 0, SEEK_SET ); } if( m_bIsInput && m_uiTotalFrameNum <= 0 ) @@ -200,7 +210,7 @@ Bool PlaYUVerStream::open( QString filename, UInt width, UInt height, Int input_ } m_cStreamInformationString = "[" + m_cFormatName + " / " + m_cCodedName + " / " + PlaYUVerFrame::supportedPixelFormatListNames().at( m_iPixelFormat ) + "] " - + QFileInfo( m_cFilename ).fileName(); + + QFileInfo( m_cFilename ).fileName(); m_iCurrFrameNum = -1; @@ -238,10 +248,12 @@ Void PlaYUVerStream::close() if( !m_bInit ) return; - closeFile(); + if( m_uiStreamHandler == YUV_IO ) + closeFile(); #ifdef USE_FFMPEG - m_cLibAvContext->closeAvFormat(); + if( m_uiStreamHandler == FFMPEG ) + m_cLibAvContext->closeAvFormat(); #endif if( m_ppcFrameBuffer ) @@ -468,7 +480,7 @@ Void PlaYUVerStream::readFrame() } #ifdef USE_FFMPEG - if( m_cLibAvContext->getStatus() ) + if( m_uiStreamHandler == FFMPEG ) { if( !m_cLibAvContext->decodeAvFormat() ) { @@ -477,8 +489,8 @@ Void PlaYUVerStream::readFrame() } m_pcNextFrame->frameFromBuffer( m_cLibAvContext->m_pchFrameBuffer, m_cLibAvContext->m_uiFrameBufferSize ); } - else #endif + if( m_uiStreamHandler == YUV_IO ) { UInt64 frame_bytes_input = m_pcNextFrame->getBytesPerFrame(); UInt64 bytes_read = fread( m_pStreamBuffer, sizeof(Pel), frame_bytes_input, m_pFile ); @@ -497,24 +509,30 @@ Void PlaYUVerStream::readFrame() Void PlaYUVerStream::writeFrame() { - UInt64 frame_bytes_input = m_pcCurrFrame->getBytesPerFrame(); - m_pcCurrFrame->frameToBuffer( m_pStreamBuffer ); - UInt64 bytes_read = fwrite( m_pStreamBuffer, sizeof(Pel), frame_bytes_input, m_pFile ); - if( bytes_read != frame_bytes_input ) + if( m_uiStreamHandler == YUV_IO ) { - m_iErrorStatus = WRITING; + UInt64 frame_bytes_input = m_pcCurrFrame->getBytesPerFrame(); + m_pcCurrFrame->frameToBuffer( m_pStreamBuffer ); + UInt64 bytes_read = fwrite( m_pStreamBuffer, sizeof(Pel), frame_bytes_input, m_pFile ); + if( bytes_read != frame_bytes_input ) + { + m_iErrorStatus = WRITING; + } } return; } Void PlaYUVerStream::writeFrame( PlaYUVerFrame *pcFrame ) { - UInt64 frame_bytes_input = pcFrame->getBytesPerFrame(); - pcFrame->frameToBuffer( m_pStreamBuffer ); - UInt64 bytes_read = fwrite( m_pStreamBuffer, sizeof(Pel), frame_bytes_input, m_pFile ); - if( bytes_read != frame_bytes_input ) + if( m_uiStreamHandler == YUV_IO ) { - m_iErrorStatus = WRITING; + UInt64 frame_bytes_input = pcFrame->getBytesPerFrame(); + pcFrame->frameToBuffer( m_pStreamBuffer ); + UInt64 bytes_read = fwrite( m_pStreamBuffer, sizeof(Pel), frame_bytes_input, m_pFile ); + if( bytes_read != frame_bytes_input ) + { + m_iErrorStatus = WRITING; + } } return; } @@ -604,12 +622,12 @@ Bool PlaYUVerStream::seekInput( UInt64 new_frame_num ) return true; } #ifdef USE_FFMPEG - if( m_cLibAvContext->getStatus() ) + if( m_uiStreamHandler == FFMPEG ) { m_cLibAvContext->seekAvFormat( new_frame_num ); } - else #endif + if( m_uiStreamHandler == YUV_IO ) { UInt64 frame_bytes_input = m_ppcFrameBuffer[0]->getBytesPerFrame(); UInt64 nbytes_seek = frame_bytes_input * new_frame_num; diff --git a/lib/PlaYUVerStream.h b/lib/PlaYUVerStream.h index 505ad2f..a0e35e4 100644 --- a/lib/PlaYUVerStream.h +++ b/lib/PlaYUVerStream.h @@ -47,6 +47,14 @@ private: Bool m_bLoadAll; Int m_iErrorStatus; + enum PlaYUVerStreamHandlers + { + INVALID_HANDLER = -1, + YUV_IO, + FFMPEG, + TOTAL_HANDLERR + }; + UInt m_uiStreamHandler; LibAvContextHandle* m_cLibAvContext; QString m_cFilename; From 7a5df0410e6674a20608575da3ebedfe4a84b429 Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Wed, 3 Dec 2014 18:08:50 +0000 Subject: [PATCH 2/2] Add absolute frame difference module --- modules/AbsoluteFrameDifference.cpp | 77 +++++++++++++++++++++++++++++ modules/AbsoluteFrameDifference.h | 54 ++++++++++++++++++++ modules/CMakeLists.txt | 1 + modules/FrameDifference.cpp | 9 +++- 4 files changed, 139 insertions(+), 2 deletions(-) create mode 100644 modules/AbsoluteFrameDifference.cpp create mode 100644 modules/AbsoluteFrameDifference.h diff --git a/modules/AbsoluteFrameDifference.cpp b/modules/AbsoluteFrameDifference.cpp new file mode 100644 index 0000000..44b4eeb --- /dev/null +++ b/modules/AbsoluteFrameDifference.cpp @@ -0,0 +1,77 @@ +/* This file is a part of plaYUVer project + * Copyright (C) 2014 by Luis Lucas (luisfrlucas@gmail.com) + * Joao Carreira (jfmcarreira@gmail.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/** + * \file AbsoluteFrameDifference.cpp + * \brief Absolute Frame Difference module + */ + +#include "AbsoluteFrameDifference.h" + +namespace plaYUVer +{ + +static PlaYUVerModuleDefinition AbsoluteFrameDifferenceDef = +{ + FRAME_PROCESSING_MODULE, + "Measurements", + "AbsoluteFrameDifference", + "Measure the absolute difference between two images (Y plane), e. g., abs( Y1 - Y2 )", + MODULE_REQUIRES_TWO_FRAMES, + MODULE_REQUIRES_NEW_WINDOW, + APPLY_WHILE_PLAYING, +}; + +AbsoluteFrameDifference::AbsoluteFrameDifference() +{ + m_pcFrameDifference = NULL; + setModuleDefinition( AbsoluteFrameDifferenceDef ); +} + +Void AbsoluteFrameDifference::create( PlaYUVerFrame* Input ) +{ + m_pcFrameDifference = new PlaYUVerFrame( Input->getWidth(), Input->getHeight(), PlaYUVerFrame::GRAY ); +} + +PlaYUVerFrame* AbsoluteFrameDifference::process( PlaYUVerFrame* Input1, PlaYUVerFrame* Input2 ) +{ + Pel* pInput1PelYUV = Input1->getPelBufferYUV()[0][0]; + Pel* pInput2PelYUV = Input2->getPelBufferYUV()[0][0]; + Pel* pOutputPelYUV = m_pcFrameDifference->getPelBufferYUV()[0][0]; + Int aux_pel_1, aux_pel_2; + + for( UInt y = 0; y < m_pcFrameDifference->getHeight(); y++ ) + for( UInt x = 0; x < m_pcFrameDifference->getWidth(); x++ ) + { + aux_pel_1 = *pInput1PelYUV++; + aux_pel_2 = *pInput2PelYUV++; + *pOutputPelYUV++ = abs( aux_pel_1 - aux_pel_2 ); + } + return m_pcFrameDifference; +} + +Void AbsoluteFrameDifference::destroy() +{ + if( m_pcFrameDifference ) + delete m_pcFrameDifference; + m_pcFrameDifference = NULL; +} + +} // NAMESPACE + diff --git a/modules/AbsoluteFrameDifference.h b/modules/AbsoluteFrameDifference.h new file mode 100644 index 0000000..4360790 --- /dev/null +++ b/modules/AbsoluteFrameDifference.h @@ -0,0 +1,54 @@ +/* This file is a part of plaYUVer project + * Copyright (C) 2014 by Luis Lucas (luisfrlucas@gmail.com) + * Joao Carreira (jfmcarreira@gmail.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/** + * \file AbsoluteFrameDifference.h + * \brief Absolute Frame Difference module + */ + +#ifndef __ABSOLUTEFRAMEDIFFERENCE_H__ +#define __ABSOLUTEFRAMEDIFFERENCE_H__ + +#include "PlaYUVerModuleIf.h" + +#include + +namespace plaYUVer +{ + +class AbsoluteFrameDifference: public PlaYUVerModuleIf +{ +private: + PlaYUVerFrame* m_pcFrameDifference; + +public: + AbsoluteFrameDifference(); + virtual ~AbsoluteFrameDifference() + { + } + Void create( PlaYUVerFrame* Input ); + PlaYUVerFrame* process( PlaYUVerFrame* Input1, PlaYUVerFrame* Input2 ); + Void destroy(); + +}; + +} // NAMESPACE + +#endif // __FRAMEDIFFERENCE_H__ + diff --git a/modules/CMakeLists.txt b/modules/CMakeLists.txt index 4f8b6fb..6e37592 100644 --- a/modules/CMakeLists.txt +++ b/modules/CMakeLists.txt @@ -39,6 +39,7 @@ ADD_MODULE( FilterComponentLuma "FilterComponent" ) ADD_MODULE( FilterComponentChromaU "FilterComponent" ) ADD_MODULE( FilterComponentChromaV "FilterComponent" ) ADD_MODULE( FrameDifference "FrameDifference" ) +ADD_MODULE( AbsoluteFrameDifference "AbsoluteFrameDifference" ) ADD_MODULE( MeasurePSNR "MeasurePSNR" ) IF( USE_OPENCV ) ADD_MODULE( DisparityStereoVar "DisparityStereoVar" ) diff --git a/modules/FrameDifference.cpp b/modules/FrameDifference.cpp index cd0abd2..e7aabf4 100644 --- a/modules/FrameDifference.cpp +++ b/modules/FrameDifference.cpp @@ -23,6 +23,7 @@ */ #include "FrameDifference.h" +#include namespace plaYUVer { @@ -32,7 +33,7 @@ static PlaYUVerModuleDefinition FrameDifferenceDef = FRAME_PROCESSING_MODULE, "Measurements", "AbsoluteFrameDifference", - "Measure the difference between two images (Y plane), e. g., abs( Y1 - Y2 )", + "Measure the difference between two images (Y plane), Y1 - Y2, with max absolute diff of 128", MODULE_REQUIRES_TWO_FRAMES, MODULE_REQUIRES_NEW_WINDOW, APPLY_WHILE_PLAYING, @@ -55,13 +56,17 @@ PlaYUVerFrame* FrameDifference::process( PlaYUVerFrame* Input1, PlaYUVerFrame* I Pel* pInput2PelYUV = Input2->getPelBufferYUV()[0][0]; Pel* pOutputPelYUV = m_pcFrameDifference->getPelBufferYUV()[0][0]; Int aux_pel_1, aux_pel_2; + Int diff = 0; for( UInt y = 0; y < m_pcFrameDifference->getHeight(); y++ ) for( UInt x = 0; x < m_pcFrameDifference->getWidth(); x++ ) { aux_pel_1 = *pInput1PelYUV++; aux_pel_2 = *pInput2PelYUV++; - *pOutputPelYUV++ = abs( aux_pel_1 - aux_pel_2 ); + diff = aux_pel_1 - aux_pel_2; + diff = std::min( diff, 127 ); + diff = std::max( diff, -128 ); + *pOutputPelYUV++ = diff; } return m_pcFrameDifference; }