diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index f5c8397..92a79c5 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -22,7 +22,7 @@ IF( USE_FFMPEG ) ENDIF() IF( USE_OPENCV ) - LIST( APPEND PlaYUVer_Lib_SRCS LibOpenCVHandler.cpp ) + LIST( APPEND PlaYUVer_Lib_SRCS StreamHandlerOpenCV.cpp ) ENDIF() diff --git a/lib/LibOpenCVHandler.cpp b/lib/LibOpenCVHandler.cpp deleted file mode 100644 index 136cf64..0000000 --- a/lib/LibOpenCVHandler.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/* This file is a part of plaYUVer project - * Copyright (C) 2014-2015 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 LibOpenCVHandler.cpp - * \ingroup PlaYUVerLib - * \brief Interface with opencv lib - */ - -#include -#include "LibOpenCVHandler.h" -#include "PlaYUVerFrame.h" -#include "PlaYUVerFramePixelFormats.h" -#include "LibMemory.h" - -namespace plaYUVer -{ - -std::vector LibOpenCVHandler::supportedReadFormats() -{ - INI_REGIST_PLAYUVER_SUPPORTED_FMT; - REGIST_PLAYUVER_SUPPORTED_FMT( "Portable Grayscale Map ", "pgm" ); - REGIST_PLAYUVER_SUPPORTED_FMT( "Portable Network Graphics", "png" ); - REGIST_PLAYUVER_SUPPORTED_FMT( "Joint Photographic Experts Group", "jpg" ); - REGIST_PLAYUVER_SUPPORTED_FMT( "Windows Bitmap", "bmp" ); - END_REGIST_PLAYUVER_SUPPORTED_FMT; -} - -std::vector LibOpenCVHandler::supportedWriteFormats() -{ - INI_REGIST_PLAYUVER_SUPPORTED_FMT; - END_REGIST_PLAYUVER_SUPPORTED_FMT; -} - -std::vector LibOpenCVHandler::supportedSaveFormats() -{ - INI_REGIST_PLAYUVER_SUPPORTED_FMT; - APPEND_PLAYUVER_SUPPORTED_FMT( LibOpenCVHandler, Read ); - END_REGIST_PLAYUVER_SUPPORTED_FMT; -} - -PlaYUVerFrame* LibOpenCVHandler::loadFrame( std::string filename ) -{ - return NULL; -} - -Bool LibOpenCVHandler::saveFrame( PlaYUVerFrame* pcFrame, std::string filename ) -{ - cv::Mat* pcCvFrame = pcFrame->getCvMat(); - return cv::imwrite( filename, *pcCvFrame ); -} - -} // NAMESPACE diff --git a/lib/PlaYUVerFrame.cpp b/lib/PlaYUVerFrame.cpp index b2620c6..4e54296 100644 --- a/lib/PlaYUVerFrame.cpp +++ b/lib/PlaYUVerFrame.cpp @@ -33,7 +33,7 @@ #include "StreamHandlerLibav.h" #endif #ifdef USE_OPENCV -#include "LibOpenCVHandler.h" +#include "StreamHandlerOpenCV.h" #endif #ifdef USE_PIXFC #include "pixfc-sse.h" @@ -74,14 +74,14 @@ std::vector PlaYUVerFrame::supportedPixelFormatListNames( Int color return formatsList; } -PlaYUVerFrame::PlaYUVerFrame( UInt width, UInt height, Int pelFormat, Int bitsPixel ) +PlaYUVerFrame::PlaYUVerFrame( UInt width, UInt height, Int pelFormat, Int bitsPixel, Int endianness ) { - init( width, height, pelFormat, bitsPixel ); + init( width, height, pelFormat, bitsPixel, endianness ); } PlaYUVerFrame::PlaYUVerFrame( PlaYUVerFrame *other, Bool bCopy ) { - init( other->getWidth(), other->getHeight(), other->getPelFormat(), other->getBitsPel() ); + init( other->getWidth(), other->getHeight(), other->getPelFormat(), other->getBitsPel(), other->getEndianness() ); copyFrom( other ); } @@ -105,7 +105,7 @@ PlaYUVerFrame::PlaYUVerFrame( PlaYUVerFrame *other, UInt posX, UInt posY, UInt a areaHeight++; } - init( areaWidth, areaHeight, other->getPelFormat(), other->getBitsPel() ); + init( areaWidth, areaHeight, other->getPelFormat(), other->getBitsPel(), other->getEndianness() ); copyFrom( other, posX, posY ); } @@ -138,10 +138,10 @@ static Int getMem3ImageComponents( Pel**** array3D, Int dim1, Int dim2, Int log2 total_mem_size += getMem2D( array3D, dim0, dim1 ); - if( ( ( *array3D )[0][0] = ( Pel* )xCallocMem( mem_size, sizeof(Pel) ) ) == NULL ) + if( ( ( *array3D )[0][0] = ( Pel* )xCallocMem( mem_size, sizeof( Pel ) ) ) == NULL ) printf( "getMem3DImageComponents: array1D" ); - total_mem_size += mem_size * sizeof(Pel); + total_mem_size += mem_size * sizeof( Pel ); // Luma for( i = 1; i < dim1; i++ ) @@ -163,7 +163,7 @@ static Int getMem3ImageComponents( Pel**** array3D, Int dim1, Int dim2, Int log2 return total_mem_size; } -Void PlaYUVerFrame::init( UInt width, UInt height, Int pel_format, Int bitsPixel ) +Void PlaYUVerFrame::init( UInt width, UInt height, Int pel_format, Int bitsPixel, Int endianness ) { m_bInit = false; m_pppcInputPel = NULL; @@ -173,6 +173,11 @@ Void PlaYUVerFrame::init( UInt width, UInt height, Int pel_format, Int bitsPixel m_iPixelFormat = pel_format; m_iNumberChannels = 3; m_uiBitsPel = bitsPixel > 8 ? bitsPixel : 8; + m_iEndianness = endianness; + if( m_uiBitsPel > 8 && m_iEndianness == -1 ) + { + throw "Invalid endianness type for Bits per Pixel greater than 8"; + } m_uiHalfPelValue = 1 << ( m_uiBitsPel - 1 ); if( m_uiWidth == 0 || m_uiHeight == 0 || m_iPixelFormat == -1 || bitsPixel > 16 ) @@ -364,7 +369,7 @@ Void PlaYUVerFrame::copyFrom( PlaYUVerFrame* input_frame ) return; m_bHasRGBPel = false; m_bHasHistogram = false; - memcpy( *m_pppcInputPel[LUMA], input_frame->getPelBufferYUV()[LUMA][0], getBytesPerFrame() * sizeof(Pel) ); + memcpy( *m_pppcInputPel[LUMA], input_frame->getPelBufferYUV()[LUMA][0], getBytesPerFrame() * sizeof( Pel ) ); } Void PlaYUVerFrame::copyFrom( PlaYUVerFrame* input_frame, UInt xPos, UInt yPos ) @@ -378,18 +383,23 @@ Void PlaYUVerFrame::copyFrom( PlaYUVerFrame* input_frame, UInt xPos, UInt yPos ) Int ratioW = ch > 0 ? m_pcPelFormat->log2ChromaHeight : 0; for( UInt i = 0; i < CHROMASHIFT( m_uiHeight, ratioH ); i++ ) { - memcpy( m_pppcInputPel[ch][i], &( pInput[ch][( yPos >> ratioH ) + i][( xPos >> ratioW )] ), ( m_uiWidth >> ratioW ) * sizeof(Pel) ); + memcpy( m_pppcInputPel[ch][i], &( pInput[ch][( yPos >> ratioH ) + i][( xPos >> ratioW )] ), ( m_uiWidth >> ratioW ) * sizeof( Pel ) ); } } m_bHasRGBPel = false; m_bHasHistogram = false; } -Void PlaYUVerFrame::frameFromBuffer( Byte *Buff, UInt64 uiBuffSize, Int endianess ) +Void PlaYUVerFrame::frameFromBuffer( Byte *Buff, UInt64 uiBuffSize ) { if( uiBuffSize != getBytesPerFrame() ) return; + frameFromBuffer( Buff ); +} + +Void PlaYUVerFrame::frameFromBuffer( Byte *Buff ) +{ Byte* ppBuff[MAX_NUMBER_PLANES]; Byte* pTmpBuff; Pel* pPel; @@ -398,7 +408,7 @@ Void PlaYUVerFrame::frameFromBuffer( Byte *Buff, UInt64 uiBuffSize, Int endianes Int ratioH, ratioW, step; UInt i, ch, b; - if( endianess == 1 ) + if( m_iEndianness == 1 ) { shiftInput = 8; shiftOutput = 0; @@ -913,11 +923,11 @@ Void PlaYUVerFrame::openPixfc() #ifdef USE_PIXFC m_pcPixfc = NULL; PixFcPixelFormat input_format = PixFcYUV420P; - PixFcFlag flags = (PixFcFlag)(PixFcFlag_Default + PixFcFlag_NNbResamplingOnly); + PixFcFlag flags = ( PixFcFlag )( PixFcFlag_Default + PixFcFlag_NNbResamplingOnly ); UInt input_row_size = m_uiWidth; - if (create_pixfc(&m_pcPixfc, input_format, PixFcRGB24, m_uiWidth, m_uiHeight, input_row_size, m_uiWidth * 3, flags ) != 0) + if( create_pixfc( &m_pcPixfc, input_format, PixFcRGB24, m_uiWidth, m_uiHeight, input_row_size, m_uiWidth * 3, flags ) != 0 ) { - fprintf(stderr, "Error creating struct pixfc\n"); + fprintf( stderr, "Error creating struct pixfc\n" ); m_pcPixfc = NULL; return; } @@ -928,7 +938,7 @@ Void PlaYUVerFrame::closePixfc() { #ifdef USE_PIXFC if( m_pcPixfc ) - destroy_pixfc(m_pcPixfc); + destroy_pixfc( m_pcPixfc ); #endif } @@ -937,20 +947,20 @@ Void PlaYUVerFrame::FrametoRGB8Pixfc() #ifdef USE_PIXFC switch( m_iPixelFormat ) { - case YUV420p: - m_pcPixfc->convert(m_pcPixfc, m_pppcInputPel, m_pcRGB32); + case YUV420p: + m_pcPixfc->convert( m_pcPixfc, m_pppcInputPel, m_pcRGB32 ); break; - case YUV422p: + case YUV422p: break; - case YUV444p: - case YUYV422: - m_pcPixfc->convert(m_pcPixfc, m_pppcInputPel, m_pcRGB32); + case YUV444p: + case YUYV422: + m_pcPixfc->convert( m_pcPixfc, m_pppcInputPel, m_pcRGB32 ); break; - case GRAY: + case GRAY: break; - case RGB8: + case RGB8: break; - default: + default: // No action. break; } @@ -1020,7 +1030,7 @@ Void PlaYUVerFrame::fromCvMat( cv::Mat* pcCvFrame ) if( !m_bInit ) { - init( pcCvFrame->cols, pcCvFrame->rows, m_iPixelFormat, 8 ); + init( pcCvFrame->cols, pcCvFrame->rows, m_iPixelFormat, 8, -1 ); } m_bHasRGBPel = false; diff --git a/lib/PlaYUVerFrame.h b/lib/PlaYUVerFrame.h index 7a6946a..b8efb41 100644 --- a/lib/PlaYUVerFrame.h +++ b/lib/PlaYUVerFrame.h @@ -115,7 +115,7 @@ public: * * @note this function might misbehave if the pixel format enum is not correct */ - PlaYUVerFrame( UInt width, UInt height, Int pelFormat = 0, Int bitsPixel = 8 ); + PlaYUVerFrame( UInt width, UInt height, Int pelFormat = 0, Int bitsPixel = 8, Int endianness = -1 ); /** * Creates and new frame with the configuration of an @@ -158,7 +158,10 @@ public: { return m_uiBitsPel; } - + Int getEndianness() const + { + return m_iEndianness; + } Pel*** getPelBufferYUV() const { return m_pppcInputPel; @@ -207,11 +210,12 @@ public: PlaYUVerPixel getPixelValue( Int xPos, Int yPos ); PlaYUVerPixel getPixelValue( Int xPos, Int yPos, PlaYUVerPixel::ColorSpace eColorSpace ); Void setPixelValue( Int xPos, Int yPos, PlaYUVerPixel pixel ); - + Void copyFrom( PlaYUVerFrame* ); Void copyFrom( PlaYUVerFrame*, UInt, UInt ); - Void frameFromBuffer( Byte*, UInt64, Int ); + Void frameFromBuffer( Byte*, UInt64 ); + Void frameFromBuffer( Byte* ); Void frameToBuffer( Byte* ); Void fillRGBBuffer(); @@ -297,6 +301,7 @@ private: Int m_iPixelFormat; //!< Pixel format number (it follows the list of supported pixel formats) Int m_iNumberChannels; //!< Number of channels UInt m_uiBitsPel; //!< Bits per pixel/channel + Int m_iEndianness; //!< Endiannes of bytes UInt m_uiHalfPelValue; //!< Bits per pixel/channel Pel*** m_pppcInputPel; @@ -328,7 +333,7 @@ private: * @param pel_format pixel format index (always use PixelFormats enum) * */ - Void init( UInt width, UInt height, Int pel_format, Int bitsPixel ); + Void init( UInt width, UInt height, Int pel_format, Int bitsPixel, Int endianness ); Void openPixfc(); Void closePixfc(); diff --git a/lib/PlaYUVerStream.cpp b/lib/PlaYUVerStream.cpp index 36d0b45..92bf173 100644 --- a/lib/PlaYUVerStream.cpp +++ b/lib/PlaYUVerStream.cpp @@ -30,12 +30,13 @@ #include "PlaYUVerStream.h" #include "PlaYUVerStreamHandlerIf.h" #include "StreamHandlerRaw.h" +#include "StreamHandlerPortable.h" #ifdef USE_FFMPEG #include "StreamHandlerLibav.h" #endif #ifdef USE_OPENCV -#include "LibOpenCVHandler.h" +#include "StreamHandlerOpenCV.h" #endif namespace plaYUVer @@ -44,8 +45,8 @@ namespace plaYUVer std::vector PlaYUVerStream::supportedReadFormats() { INI_REGIST_PLAYUVER_SUPPORTED_FMT; - REGIST_PLAYUVER_SUPPORTED_FMT( "Raw Video", "yuv" ); - REGIST_PLAYUVER_SUPPORTED_FMT( "Raw Video", "gray" ); + REGIST_PLAYUVER_SUPPORTED_FMT( &PlaYUVerRawHandler::Create, "Raw Video", "yuv" ); + REGIST_PLAYUVER_SUPPORTED_FMT( &PlaYUVerRawHandler::Create, "Raw Video", "gray" ); #ifdef USE_FFMPEG APPEND_PLAYUVER_SUPPORTED_FMT( StreamHandlerLibav, Read ); #endif @@ -58,7 +59,7 @@ std::vector PlaYUVerStream::supportedReadFormats() std::vector PlaYUVerStream::supportedWriteFormats() { INI_REGIST_PLAYUVER_SUPPORTED_FMT; - REGIST_PLAYUVER_SUPPORTED_FMT( "Raw Video", "yuv" ); + REGIST_PLAYUVER_SUPPORTED_FMT( &PlaYUVerRawHandler::Create, "Raw Video", "yuv" ); #ifdef USE_FFMPEG APPEND_PLAYUVER_SUPPORTED_FMT( StreamHandlerLibav, Write ); #endif @@ -73,7 +74,7 @@ std::vector PlaYUVerStream::supportedSaveFormats() APPEND_PLAYUVER_SUPPORTED_FMT( StreamHandlerLibav, Save ); #endif #ifdef USE_OPENCV - APPEND_PLAYUVER_SUPPORTED_FMT( LibOpenCVHandler, Save ); + APPEND_PLAYUVER_SUPPORTED_FMT( StreamHandlerOpenCV, Save ); #endif END_REGIST_PLAYUVER_SUPPORTED_FMT; } @@ -129,18 +130,11 @@ PlaYUVerStream::PlaYUVerStream() m_uiFrameBufferSize = 2; m_uiFrameBufferIndex = 0; m_uiCurrFrameFileIdx = 0; -// #ifdef USE_FFMPEG -// m_cLibAvContext = new StreamHandlerLibav; -// #endif } PlaYUVerStream::~PlaYUVerStream() { close(); -// #ifdef USE_FFMPEG -// if( m_cLibAvContext ) -// delete m_cLibAvContext; -// #endif } std::string PlaYUVerStream::getFormatName() @@ -152,57 +146,6 @@ std::string PlaYUVerStream::getCodecName() return !m_pcStreamHandler ? "" : m_pcStreamHandler->getCodecName(); } -Void PlaYUVerStream::findHandler() -{ - m_iStreamHandler = INVALID_HANDLER; - -// if( m_uiBitsPerPixel != 8 ) -// { -// m_iStreamHandler = YUV_IO; -// return; -// } - - std::string currExt = m_cFilename.substr( m_cFilename.find_last_of( "." ) + 1 ); - currExt = lowercase( currExt ); - - if( m_bIsInput ) - { -#ifdef USE_FFMPEG - std::vector supportedFmts = StreamHandlerLibav::supportedReadFormats(); - for( UInt i = 0; i < supportedFmts.size(); i++ ) - { - if( supportedFmts[i].formatExt == currExt ) - { - //m_cFormatName = uppercase( supportedFmts[i].formatExt ); - m_iStreamHandler = FFMPEG; - return; - } - } -#endif - if( m_iStreamHandler == INVALID_HANDLER ) - m_iStreamHandler = YUV_IO; - } - else - { -#ifdef USE_FFMPEG - std::vector supportedFmts = StreamHandlerLibav::supportedWriteFormats(); - for( UInt i = 0; i < supportedFmts.size(); i++ ) - { - if( supportedFmts[i].formatExt == currExt ) - { -// m_cFormatName = uppercase( supportedFmts[i].formatExt ); - m_iStreamHandler = FFMPEG; - return; - } - } -#endif - if( currExt == "yuv" ) - { - m_iStreamHandler = YUV_IO; - } - } -} - Bool PlaYUVerStream::open( std::string filename, std::string resolution, std::string input_format_name, UInt bitsPel, Int endianness, UInt frame_rate, Bool bInput ) { UInt width; @@ -248,43 +191,55 @@ Bool PlaYUVerStream::open( std::string filename, UInt width, UInt height, Int in std::copy( m_cFilename.begin(), m_cFilename.end(), m_pchFilename ); m_pchFilename[m_cFilename.size()] = '\0'; // don't forget the terminating 0 - findHandler(); - if( m_iStreamHandler == INVALID_HANDLER ) + + m_iStreamHandler = INVALID_HANDLER; + std::string currExt = m_cFilename.substr( m_cFilename.find_last_of( "." ) + 1 ); + currExt = lowercase( currExt ); + + std::vector supportedFmts; + if( m_bIsInput ) { - close(); - throw "Invalid file format"; - return m_bInit; + supportedFmts = supportedReadFormats(); } - - m_uiFrameBufferSize = m_bIsInput ? 2 : 1; - -#ifdef USE_OPENCV - if( m_iStreamHandler == OPENCV_HANDLER ) + else { - m_pcCurrFrame = LibOpenCVHandler::loadFrame( m_cFilename ); - if( m_pcCurrFrame ) + supportedFmts = supportedWriteFormats(); + } + for( UInt i = 0; i < supportedFmts.size(); i++ ) + { + if( supportedFmts[i].formatExt == currExt ) { - m_uiWidth = m_pcCurrFrame->getWidth(); - m_uiHeight = m_pcCurrFrame->getHeight(); - m_iPixelFormat = m_pcCurrFrame->getPelFormat(); + m_pfctCreateHandler = supportedFmts[i].formatFct; + break; } - m_pcNextFrame = NULL; - m_uiFrameBufferSize = 0; - m_uiFrameBufferIndex = 0; - m_uiTotalFrameNum = 1; } -#endif -#ifdef USE_FFMPEG - if( m_iStreamHandler == FFMPEG ) - { - m_pcStreamHandler = new StreamHandlerLibav; - } -#endif - if( m_iStreamHandler == YUV_IO ) - { - m_pcStreamHandler = new PlaYUVerRawHandler; - } +// if( m_iStreamHandler == INVALID_HANDLER ) +// { +// close(); +// throw "Invalid file format"; +// return m_bInit; +// } + + +// #ifdef USE_OPENCV +// if( m_iStreamHandler == OPENCV_HANDLER ) +// { +// m_pcCurrFrame = LibOpenCVHandler::loadFrame( m_cFilename ); +// if( m_pcCurrFrame ) +// { +// m_uiWidth = m_pcCurrFrame->getWidth(); +// m_uiHeight = m_pcCurrFrame->getHeight(); +// m_iPixelFormat = m_pcCurrFrame->getPelFormat(); +// } +// m_pcNextFrame = NULL; +// m_uiFrameBufferSize = 0; +// m_uiFrameBufferIndex = 0; +// m_uiTotalFrameNum = 1; +// } +// #endif + + m_pcStreamHandler = m_pfctCreateHandler(); if( !m_pcStreamHandler ) { @@ -307,12 +262,14 @@ Bool PlaYUVerStream::open( std::string filename, UInt width, UInt height, Int in return m_bInit; } + m_uiFrameBufferSize = m_bIsInput ? 2 : 1; + getMem1D( &m_ppcFrameBuffer, m_uiFrameBufferSize ); for( UInt i = 0; i < m_uiFrameBufferSize; i++ ) { try { - m_ppcFrameBuffer[i] = new PlaYUVerFrame( m_uiWidth, m_uiHeight, m_iPixelFormat, m_uiBitsPerPixel ); + m_ppcFrameBuffer[i] = new PlaYUVerFrame( m_uiWidth, m_uiHeight, m_iPixelFormat, m_uiBitsPerPixel, m_iEndianness ); } catch( const char *msg ) { @@ -338,7 +295,7 @@ Bool PlaYUVerStream::open( std::string filename, UInt width, UInt height, Int in return m_bInit; } - if( !getMem1D( &m_pStreamBuffer, m_pcCurrFrame->getBytesPerFrame() ) ) + if( !m_pcStreamHandler->configureBuffer( m_pcCurrFrame ) ) { close(); throw "[PlaYUVerStream] Cannot allocated memory"; @@ -530,15 +487,12 @@ Void PlaYUVerStream::readFrame() return; } - UInt64 uiByterPerFrame = m_pcNextFrame->getBytesPerFrame(); - - - if( !m_pcStreamHandler->read( m_pStreamBuffer ) ) + if( !m_pcStreamHandler->read( m_pcNextFrame ) ) { throw "[PlaYUVerStream] Cannot read file"; return; } - m_pcNextFrame->frameFromBuffer( m_pStreamBuffer, uiByterPerFrame, m_iEndianness ); + m_uiCurrFrameFileIdx++; return; @@ -551,13 +505,9 @@ Void PlaYUVerStream::writeFrame() Void PlaYUVerStream::writeFrame( PlaYUVerFrame *pcFrame ) { - if( m_iStreamHandler == YUV_IO ) + if( !m_pcStreamHandler->write( pcFrame ) ) { - pcFrame->frameToBuffer( m_pStreamBuffer ); - if( !m_pcStreamHandler->write( m_pStreamBuffer ) ) - { - throw "[PlaYUVerStream] Cannot write into the file"; - } + throw "[PlaYUVerStream] Cannot write into the file"; } return; } @@ -572,7 +522,6 @@ Bool PlaYUVerStream::saveFrame( const std::string& filename, PlaYUVerFrame *save Int iFileFormat = INVALID_HANDLER; std::string fmtExt; -//std::string currExt = QFileInfo( qtString ).suffix().toStdString(); std::string currExt = filename.substr( filename.find_last_of( "." ) + 1 ); std::vector supportedFmts = PlaYUVerStream::supportedSaveFormats(); @@ -607,12 +556,12 @@ Bool PlaYUVerStream::saveFrame( const std::string& filename, PlaYUVerFrame *save return qimg.save( qtString ); } #endif -#ifdef USE_OPENCV - else - { - return LibOpenCVHandler::saveFrame( saveFrame, filename ); - } -#endif +// #ifdef USE_OPENCV +// else +// { +// return LibOpenCVHandler::saveFrame( saveFrame, filename ); +// } +// #endif } return false; } diff --git a/lib/PlaYUVerStream.h b/lib/PlaYUVerStream.h index 5fcd2e1..cac1e19 100644 --- a/lib/PlaYUVerStream.h +++ b/lib/PlaYUVerStream.h @@ -35,7 +35,6 @@ namespace plaYUVer { -class StreamHandlerLibav; class LibOpenCVHandler; class PlaYUVerStreamHandlerIf; @@ -46,10 +45,14 @@ typedef struct UInt uiHeight; } PlaYUVerStdResolution; + +typedef PlaYUVerStreamHandlerIf* (*CreateStreamHandlerFn)( void ); + typedef struct { std::string formatName; std::string formatExt; + CreateStreamHandlerFn formatFct; } PlaYUVerSupportedFormat; #define INI_REGIST_PLAYUVER_SUPPORTED_FMT \ @@ -59,9 +62,10 @@ typedef struct #define END_REGIST_PLAYUVER_SUPPORTED_FMT \ return formatsList; -#define REGIST_PLAYUVER_SUPPORTED_FMT( name, ext ) \ + #define REGIST_PLAYUVER_SUPPORTED_FMT( handler, name, ext ) \ formatElem.formatName = name; \ formatElem.formatExt = lowercase( ext ); \ + formatElem.formatFct = handler; \ formatsList.push_back( formatElem ); #define APPEND_PLAYUVER_SUPPORTED_FMT( class_name, fct ) \ @@ -176,8 +180,8 @@ private: TOTAL_HANDLERR }; Int m_iStreamHandler; + CreateStreamHandlerFn m_pfctCreateHandler; PlaYUVerStreamHandlerIf* m_pcStreamHandler; - StreamHandlerLibav* m_cLibAvContext; std::string m_cFilename; Char* m_pchFilename; @@ -200,8 +204,6 @@ private: UInt m_uiFrameBufferIndex; UInt64 m_uiCurrFrameFileIdx; - Void findHandler(); - }; } // NAMESPACE diff --git a/lib/PlaYUVerStreamHandlerIf.h b/lib/PlaYUVerStreamHandlerIf.h index 02f9f81..ff399a7 100644 --- a/lib/PlaYUVerStreamHandlerIf.h +++ b/lib/PlaYUVerStreamHandlerIf.h @@ -26,13 +26,16 @@ #define __PLAYUVERSTREAMHANDLERIF_H__ #include "PlaYUVerDefs.h" -// #include -// #include -// #include +#include "LibMemory.h" namespace plaYUVer { +#define REGISTER_STREAM_HANDLER(X) \ + public: \ + static PlaYUVerStreamHandlerIf* Create() { return new X(); } \ + void Delete() { delete this; } + /** * \class PlaYUVerStreamHandlerIf * \ingroup PlaYUVerLib PlaYUVerLib_Stream @@ -45,16 +48,21 @@ public: { m_bIsInput = true; } - ~PlaYUVerStreamHandlerIf() + virtual ~PlaYUVerStreamHandlerIf() { } virtual Bool openHandler( std::string strFilename, Bool bInput ) = 0; virtual UInt64 calculateFrameNumber() = 0; virtual Void closeHandler() = 0; - virtual Bool read( Byte* pchBuffer ) = 0; - virtual Bool write( Byte* pchBuffer ) = 0; + virtual Bool read( PlaYUVerFrame* pcFrame ) = 0; + virtual Bool write( PlaYUVerFrame* pcFrame ) = 0; virtual Bool seek( UInt64 iFrameNum ) = 0; + virtual Bool configureBuffer( PlaYUVerFrame* pcFrame ) + { + return getMem1D( &m_pStreamBuffer, pcFrame->getBytesPerFrame() ); + } + virtual Void getFormat( UInt& rWidth, UInt& rHeight, Int& rInputFormat, UInt& rBitsPerPel, Int& rEndianness, Double& rFrameRate ) { return; @@ -71,8 +79,10 @@ public: { return m_strCodecName; } + protected: Bool m_bIsInput; + Byte* m_pStreamBuffer; UInt64 m_uiNBytesPerFrame; std::string m_strFormatName; std::string m_strCodecName; diff --git a/lib/StreamHandlerLibav.cpp b/lib/StreamHandlerLibav.cpp index 95ae08a..7d52311 100644 --- a/lib/StreamHandlerLibav.cpp +++ b/lib/StreamHandlerLibav.cpp @@ -35,16 +35,16 @@ namespace plaYUVer std::vector StreamHandlerLibav::supportedReadFormats() { INI_REGIST_PLAYUVER_SUPPORTED_FMT; - REGIST_PLAYUVER_SUPPORTED_FMT( "Portable Grayscale Map", "pgm" ); - REGIST_PLAYUVER_SUPPORTED_FMT( "Portable Network Graphics", "png" ); - REGIST_PLAYUVER_SUPPORTED_FMT( "Joint Photographic Experts Group", "jpg" ); - REGIST_PLAYUVER_SUPPORTED_FMT( "Windows Bitmap", "bmp" ); - REGIST_PLAYUVER_SUPPORTED_FMT( "Audio video interleaved", "avi" ); - REGIST_PLAYUVER_SUPPORTED_FMT( "Windows media video", "wmv" ); - REGIST_PLAYUVER_SUPPORTED_FMT( "MPEG4", "mp4" ); - REGIST_PLAYUVER_SUPPORTED_FMT( "Matroska Multimedia Container", "mkv" ); - REGIST_PLAYUVER_SUPPORTED_FMT( "H.264 streams", "h264" ); - REGIST_PLAYUVER_SUPPORTED_FMT( "HEVC streams", "hevc" ); + REGIST_PLAYUVER_SUPPORTED_FMT( &StreamHandlerLibav::Create, "Portable Grayscale Map", "pgm" ); + REGIST_PLAYUVER_SUPPORTED_FMT( &StreamHandlerLibav::Create, "Portable Network Graphics", "png" ); + REGIST_PLAYUVER_SUPPORTED_FMT( &StreamHandlerLibav::Create, "Joint Photographic Experts Group", "jpg" ); + REGIST_PLAYUVER_SUPPORTED_FMT( &StreamHandlerLibav::Create, "Windows Bitmap", "bmp" ); + REGIST_PLAYUVER_SUPPORTED_FMT( &StreamHandlerLibav::Create, "Audio video interleaved", "avi" ); + REGIST_PLAYUVER_SUPPORTED_FMT( &StreamHandlerLibav::Create, "Windows media video", "wmv" ); + REGIST_PLAYUVER_SUPPORTED_FMT( &StreamHandlerLibav::Create, "MPEG4", "mp4" ); + REGIST_PLAYUVER_SUPPORTED_FMT( &StreamHandlerLibav::Create, "Matroska Multimedia Container", "mkv" ); + REGIST_PLAYUVER_SUPPORTED_FMT( &StreamHandlerLibav::Create, "H.264 streams", "h264" ); + REGIST_PLAYUVER_SUPPORTED_FMT( &StreamHandlerLibav::Create, "HEVC streams", "hevc" ); END_REGIST_PLAYUVER_SUPPORTED_FMT; } @@ -96,8 +96,6 @@ static int open_codec_context( int *stream_idx, AVFormatContext *m_cFmtCtx, enum return 0; } -// Bool StreamHandlerLibav::initAvFormat( const char* filename, UInt& width, UInt& height, Int& pixel_format, UInt& bits_pel, Int& endianness, Double& frame_rate, -// UInt64& num_frames ) Bool StreamHandlerLibav::openHandler( std::string strFilename, Bool bInput ) { const char* filename = strFilename.c_str(); @@ -331,7 +329,7 @@ Bool StreamHandlerLibav::decodeVideoPkt() return got_frame > 0 ? true : false; } -Bool StreamHandlerLibav::read( Byte* pchBuffer ) +Bool StreamHandlerLibav::read( PlaYUVerFrame* pcFrame ) { Bool bGotFrame = false; AVPacket orig_pkt = pkt; @@ -364,20 +362,22 @@ Bool StreamHandlerLibav::read( Byte* pchBuffer ) if( bGotFrame ) { - av_image_copy_to_buffer( m_pchFrameBuffer, m_uiFrameBufferSize, m_cFrame->data, m_cFrame->linesize, m_cCodecCtx->pix_fmt, m_cCodecCtx->width, - m_cCodecCtx->height, 1 ); - av_image_copy_to_buffer( pchBuffer, m_uiFrameBufferSize, m_cFrame->data, m_cFrame->linesize, m_cCodecCtx->pix_fmt, m_cCodecCtx->width, +// av_image_copy_to_buffer( m_pchFrameBuffer, m_uiFrameBufferSize, m_cFrame->data, m_cFrame->linesize, m_cCodecCtx->pix_fmt, m_cCodecCtx->width, +// m_cCodecCtx->height, 1 ); + av_image_copy_to_buffer( m_pStreamBuffer, m_uiFrameBufferSize, m_cFrame->data, m_cFrame->linesize, m_cCodecCtx->pix_fmt, m_cCodecCtx->width, m_cCodecCtx->height, 1 ); if( orig_pkt.size ) av_free_packet( &orig_pkt ); + pcFrame->frameFromBuffer( m_pStreamBuffer ); + return true; } return false; } -Bool StreamHandlerLibav::write( Byte* pchBuffer ) +Bool StreamHandlerLibav::write( PlaYUVerFrame* pcFrame ) { return false; } diff --git a/lib/StreamHandlerLibav.h b/lib/StreamHandlerLibav.h index 1b48906..4c0de4f 100644 --- a/lib/StreamHandlerLibav.h +++ b/lib/StreamHandlerLibav.h @@ -56,6 +56,8 @@ namespace plaYUVer class StreamHandlerLibav: public PlaYUVerStreamHandlerIf { + REGISTER_STREAM_HANDLER( StreamHandlerLibav ) + public: static std::vector supportedReadFormats(); @@ -65,14 +67,16 @@ public: StreamHandlerLibav() { } + ~StreamHandlerLibav() + { + } Bool openHandler( std::string strFilename, Bool bInput ); -// Bool initAvFormat( const char* filename, UInt& width, UInt& height, Int& pixel_format, UInt& bits_pel, Int& endianness, Double& frame_rate, UInt64& num_frames ); Void closeHandler(); UInt64 calculateFrameNumber(); Bool seek( UInt64 iFrameNum ); - Bool read( Byte* pchBuffer ); - Bool write( Byte* pchBuffer ); + Bool read( PlaYUVerFrame* pcFrame ); + Bool write( PlaYUVerFrame* pcFrame ); Void getFormat( UInt& rWidth, UInt& rHeight, Int& rInputFormat, UInt& rBitsPerPel, Int& rEndianness, Double& rFrameRate ); diff --git a/lib/StreamHandlerOpenCV.cpp b/lib/StreamHandlerOpenCV.cpp new file mode 100644 index 0000000..f793fe5 --- /dev/null +++ b/lib/StreamHandlerOpenCV.cpp @@ -0,0 +1,100 @@ +/* This file is a part of plaYUVer project + * Copyright (C) 2014-2015 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 StreamHandlerOpenCV.cpp + * \ingroup PlaYUVerLib + * \brief Interface with opencv lib + */ + +#include +#include "StreamHandlerOpenCV.h" +#include "PlaYUVerFrame.h" +#include "PlaYUVerFramePixelFormats.h" +#include "LibMemory.h" + +namespace plaYUVer +{ + +std::vector StreamHandlerOpenCV::supportedReadFormats() +{ + INI_REGIST_PLAYUVER_SUPPORTED_FMT; + REGIST_PLAYUVER_SUPPORTED_FMT( &StreamHandlerOpenCV::Create, "Portable Grayscale Map ", "pgm" ); + REGIST_PLAYUVER_SUPPORTED_FMT( &StreamHandlerOpenCV::Create, "Portable Network Graphics", "png" ); + REGIST_PLAYUVER_SUPPORTED_FMT( &StreamHandlerOpenCV::Create, "Joint Photographic Experts Group", "jpg" ); + REGIST_PLAYUVER_SUPPORTED_FMT( &StreamHandlerOpenCV::Create, "Windows Bitmap", "bmp" ); + END_REGIST_PLAYUVER_SUPPORTED_FMT; +} + +std::vector StreamHandlerOpenCV::supportedWriteFormats() +{ + INI_REGIST_PLAYUVER_SUPPORTED_FMT; + END_REGIST_PLAYUVER_SUPPORTED_FMT; +} + +std::vector StreamHandlerOpenCV::supportedSaveFormats() +{ + INI_REGIST_PLAYUVER_SUPPORTED_FMT; +// APPEND_PLAYUVER_SUPPORTED_FMT( StreamHandlerOpenCV, Read ); + END_REGIST_PLAYUVER_SUPPORTED_FMT; +} + +Bool StreamHandlerOpenCV::openHandler( std::string strFilename, Bool bInput ) +{ + m_cFilename = m_cFilename; + return true; +} + +Void StreamHandlerOpenCV::closeHandler() +{ + +} + +Void StreamHandlerOpenCV::getFormat( UInt& rWidth, UInt& rHeight, Int& rInputFormat, UInt& rBitsPerPel, Int& rEndianness, Double& rFrameRate ) +{ +// rWidth = m_uiWidth; +// rHeight = m_uiHeight; +// rInputFormat = m_iPixelFormat; +// rBitsPerPel = m_uiBitsPerPixel; +// rEndianness = m_iEndianness; + rFrameRate = 1; +} + +UInt64 StreamHandlerOpenCV::calculateFrameNumber() +{ + return 1; +} + +Bool StreamHandlerOpenCV::seek( UInt64 iFrameNum ) +{ + return true; +} + +Bool StreamHandlerOpenCV::read( PlaYUVerFrame* pcFrame ) +{ + return false; +} + +Bool StreamHandlerOpenCV::write( PlaYUVerFrame* pcFrame ) +{ + cv::Mat* pcCvFrame = pcFrame->getCvMat(); + return cv::imwrite( m_cFilename.c_str(), *pcCvFrame ); +} + +} // NAMESPACE diff --git a/lib/LibOpenCVHandler.h b/lib/StreamHandlerOpenCV.h similarity index 66% rename from lib/LibOpenCVHandler.h rename to lib/StreamHandlerOpenCV.h index 7a71eb9..cd14dfc 100644 --- a/lib/LibOpenCVHandler.h +++ b/lib/StreamHandlerOpenCV.h @@ -18,13 +18,13 @@ */ /** - * \file LibOpenCVHandler.h + * \file StreamHandlerOpenCV.h * \ingroup PlaYUVerLib * \brief Interface with opencv lib */ -#ifndef __LIBOPENCVHANDLER_H__ -#define __LIBOPENCVHANDLER_H__ +#ifndef __STREAMHANDLEROPENCV_H__ +#define __STREAMHANDLEROPENCV_H__ #include #include @@ -32,29 +32,43 @@ #include #include "PlaYUVerDefs.h" #include "PlaYUVerStream.h" +#include "PlaYUVerStreamHandlerIf.h" namespace plaYUVer { class PlaYUVerFrame; -class LibOpenCVHandler +class StreamHandlerOpenCV: public PlaYUVerStreamHandlerIf { + REGISTER_STREAM_HANDLER( StreamHandlerOpenCV ) + public: static std::vector supportedReadFormats(); static std::vector supportedWriteFormats(); static std::vector supportedSaveFormats(); - LibOpenCVHandler() + StreamHandlerOpenCV() + { + } + ~StreamHandlerOpenCV() { } - static PlaYUVerFrame* loadFrame( std::string filename ); - static Bool saveFrame( PlaYUVerFrame* pcFrame, std::string filename ); + Bool openHandler( std::string strFilename, Bool bInput ); + Void closeHandler(); + UInt64 calculateFrameNumber(); + Bool seek( UInt64 iFrameNum ); + Bool read( PlaYUVerFrame* pcFrame ); + Bool write( PlaYUVerFrame* pcFrame ); + Void getFormat( UInt& rWidth, UInt& rHeight, Int& rInputFormat, UInt& rBitsPerPel, Int& rEndianness, Double& rFrameRate ); + +private: + std::string m_cFilename; }; } // NAMESPACE -#endif // __LIBOPENCVHANDLER_H__ +#endif // __STREAMHANDLEROPENCV_H__ diff --git a/lib/StreamHandlerRaw.h b/lib/StreamHandlerRaw.h index e1d05f4..f4615b4 100644 --- a/lib/StreamHandlerRaw.h +++ b/lib/StreamHandlerRaw.h @@ -38,9 +38,14 @@ namespace plaYUVer */ class PlaYUVerRawHandler: public PlaYUVerStreamHandlerIf { + REGISTER_STREAM_HANDLER( PlaYUVerRawHandler ) + private: FILE* m_pFile; /**< The input file pointer >*/ + public: + PlaYUVerRawHandler() {} + ~PlaYUVerRawHandler() {} Bool openHandler( std::string strFilename, Bool bInput ) { @@ -78,16 +83,18 @@ public: } return false; } - Bool read( Byte* pchBuffer ) + Bool read( PlaYUVerFrame* pcFrame ) { - UInt64 processed_bytes = fread( pchBuffer, sizeof( Byte ), m_uiNBytesPerFrame, m_pFile ); + UInt64 processed_bytes = fread( m_pStreamBuffer, sizeof( Byte ), m_uiNBytesPerFrame, m_pFile ); if( processed_bytes != m_uiNBytesPerFrame ) return false; + pcFrame->frameFromBuffer( m_pStreamBuffer ); return true; } - Bool write( Byte* pchBuffer ) + Bool write( PlaYUVerFrame* pcFrame ) { - UInt64 processed_bytes = fwrite( pchBuffer, sizeof( Byte ), m_uiNBytesPerFrame, m_pFile ); + pcFrame->frameToBuffer( m_pStreamBuffer ); + UInt64 processed_bytes = fwrite( m_pStreamBuffer, sizeof( Byte ), m_uiNBytesPerFrame, m_pFile ); if( processed_bytes != m_uiNBytesPerFrame ) return false; return true;