From 974fa27814931e875e0e050ca3b1f69937a69e23 Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Sat, 21 Feb 2015 18:10:08 +0000 Subject: [PATCH 01/39] Add a small program to test the command line interface using boost lib --- CMakeLists.txt | 4 +++ lib/CMakeLists.txt | 6 +++- lib/PlaYUVerCmdParser.cpp | 53 +++++++++++++++++++++++++++++ lib/PlaYUVerCmdParser.h | 42 +++++++++++++++++++++++ tools/CMakeLists.txt | 22 ++++++++++++ tools/main.cpp | 71 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 197 insertions(+), 1 deletion(-) create mode 100644 lib/PlaYUVerCmdParser.cpp create mode 100644 lib/PlaYUVerCmdParser.h create mode 100644 tools/CMakeLists.txt create mode 100644 tools/main.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 7c6557d..0bbb827 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -85,6 +85,9 @@ ENDIF() # Dependencies ###################################################################################### +FIND_PACKAGE(Boost COMPONENTS program_options ) +SET_PACKAGE_PROPERTIES(Boost PROPERTIES URL "http://www.boost.org" DESCRIPTION "Boost library support" TYPE REQUIRED) + OPTION( USE_OPENCV "Add OpenCV support" ON ) IF( USE_OPENCV ) FIND_PACKAGE( OpenCV ) @@ -130,6 +133,7 @@ SET( CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O2" ) ADD_SUBDIRECTORY( lib ) ADD_SUBDIRECTORY( modules ) +ADD_SUBDIRECTORY( tools ) ADD_SUBDIRECTORY( app ) diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 72eb6d6..3af29cd 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -4,6 +4,8 @@ INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}/../ ) +INCLUDE_DIRECTORIES( ${Boost_INCLUDE_DIRS} ) + set(plaYUver_Lib_SRCS # Frame PlaYUVerFrame.cpp @@ -11,6 +13,8 @@ set(plaYUver_Lib_SRCS PlaYUVerFrameStats.cpp # Stream PlaYUVerStream.cpp + # Command Line Parser + PlaYUVerCmdParser.cpp ) IF( USE_FFMPEG ) @@ -38,7 +42,7 @@ CONFIGURE_FILE( PlaYUVerConfig.cmake.in ${CMAKE_BINARY_DIR}/PlaYUVerConfig.cmake ADD_LIBRARY( PlaYUVerLib STATIC ${plaYUver_Lib_SRCS} ) INCLUDE_DIRECTORIES( ${FFMPEG_INCLUDE_DIRS} ${OpenCV_INCLUDE_DIRS} ) -TARGET_LINK_LIBRARIES( PlaYUVerLib ${FFMPEG_LIBRARIES} ${OpenCV_LIBRARIES} ) +TARGET_LINK_LIBRARIES( PlaYUVerLib ${FFMPEG_LIBRARIES} ${OpenCV_LIBRARIES} ${Boost_LIBRARIES} ) INSTALL(FILES ${plaYUver_Lib_HEADERS} DESTINATION include ) # INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/libPlaYUVerLib${CMAKE_STATIC_LIBRARY_SUFFIX} DESTINATION lib ) diff --git a/lib/PlaYUVerCmdParser.cpp b/lib/PlaYUVerCmdParser.cpp new file mode 100644 index 0000000..a261ff4 --- /dev/null +++ b/lib/PlaYUVerCmdParser.cpp @@ -0,0 +1,53 @@ +/* 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 PlaYUVerCmdParser.cpp + * \brief Command parser + */ + +#include "config.h" +#include +#include +#include "PlaYUVerCmdParser.h" + +namespace plaYUVer +{ + +po::options_description PlaYUVerCmdParser::GetCommandOpts() +{ + po::options_description inputOpts( "Input" ); + inputOpts.add_options() + ( "input,i", po::value(), "input file" ) + ( "width,w", po::value(), "width" ) + ( "height,h", po::value(), "height" ); + + po::options_description operationOpts( "Operation" ); + operationOpts.add_options() + ( "module", po::value(), "select a module" ) + ( "quality", po::value(),"select a quality metric" ); + + po::options_description commonOpts( "Common" ); + commonOpts.add_options() + ( "help", "produce help message" ); + commonOpts.add( inputOpts ).add( operationOpts ); + return commonOpts; +} + +} // NAMESPACE diff --git a/lib/PlaYUVerCmdParser.h b/lib/PlaYUVerCmdParser.h new file mode 100644 index 0000000..7d83161 --- /dev/null +++ b/lib/PlaYUVerCmdParser.h @@ -0,0 +1,42 @@ +/* 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 PlaYUVerCmdParser.h + * \brief Command parser + */ + +#include "PlaYUVerDefs.h" +#include +namespace po = boost::program_options; + +namespace plaYUVer +{ + +class PlaYUVerCmdParser +{ +public: + PlaYUVerCmdParser() {} ; + ~PlaYUVerCmdParser() {} ; + + static po::options_description GetCommandOpts(); + +}; + +} // NAMESPACE diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt new file mode 100644 index 0000000..e6dcc56 --- /dev/null +++ b/tools/CMakeLists.txt @@ -0,0 +1,22 @@ +### +### CMakeLists for playuver app component +### + +# This is hard way - please fix +INCLUDE_DIRECTORIES( + ${CMAKE_CURRENT_BINARY_DIR}/../ + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/../ ) + +set(plaYUver_Tools_SRCS +# Main + main.cpp +) + +ADD_EXECUTABLE( ${PROJECT_NAME}Tools ${plaYUver_Tools_SRCS} ) + +TARGET_LINK_LIBRARIES( ${PROJECT_NAME}Tools PlaYUVerLib PlaYUVerModules ) + +INSTALL(TARGETS ${PROJECT_NAME}Tools DESTINATION bin ) + + diff --git a/tools/main.cpp b/tools/main.cpp new file mode 100644 index 0000000..7a659dd --- /dev/null +++ b/tools/main.cpp @@ -0,0 +1,71 @@ +/* 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 main.cpp + * \brief main file + */ + +#include +#include +#include + +using namespace plaYUVer; +using namespace std; + +int main( int argc, char *argv[] ) +{ + + try + { + + po::options_description toolsOpt; + toolsOpt.add( PlaYUVerCmdParser::GetCommandOpts() ); + po::variables_map vm; + po::store( po::parse_command_line( argc, argv, toolsOpt ), vm ); + po::notify( vm ); + + if( vm.count( "help" ) ) + { + cout << toolsOpt << "\n"; + return 0; + } + + if( vm.count( "compression" ) ) + { + cout << "Compression level was set to " << vm["compression"].as() << ".\n"; + } + else + { + cout << "Compression level was not set.\n"; + } + } + catch( exception& e ) + { + cerr << "error: " << e.what() << "\n"; + return 1; + } + catch( ... ) + { + cerr << "Exception of unknown type!\n"; + } + + PlaYUVerFrame pcFrameBuffer = new PlaYUVerFrame( 1024, 768, PlaYUVerFrame::YUV420p ); + return 0; +} From 6feedc95b0861513e13585422c1d68060165aef3 Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Sat, 21 Feb 2015 20:23:59 +0000 Subject: [PATCH 02/39] Add new open stream function --- lib/PlaYUVerStream.cpp | 26 ++++++++++++++++++++++++++ lib/PlaYUVerStream.h | 1 + 2 files changed, 27 insertions(+) diff --git a/lib/PlaYUVerStream.cpp b/lib/PlaYUVerStream.cpp index 7acda98..80b7529 100644 --- a/lib/PlaYUVerStream.cpp +++ b/lib/PlaYUVerStream.cpp @@ -155,6 +155,32 @@ PlaYUVerStream::~PlaYUVerStream() close(); } +Bool PlaYUVerStream::open( std::string filename, std::string resolution, std::string input_format_name, UInt frame_rate, Bool bInput ) +{ + UInt width; + UInt height; + Int input_format = -1; + + sscanf( resolution.c_str(), "%ux%u", &width, &height ); + if( width <= 0 || height <= 0 ) + { + return false; + } + for( UInt i = 0; i < PlaYUVerFrame::supportedPixelFormatListNames().size(); i++ ) + { + if( PlaYUVerFrame::supportedPixelFormatListNames()[i] == input_format_name ) + { + input_format = i; + break; + } + } + if( width > 0 && height > 0 && input_format >= 0 ) + { + return open( filename, width, height, input_format, frame_rate, bInput ); + } + return false; +} + Bool PlaYUVerStream::open( std::string filename, UInt width, UInt height, Int input_format, UInt frame_rate, Bool bInput ) { if( m_bInit ) diff --git a/lib/PlaYUVerStream.h b/lib/PlaYUVerStream.h index 565d005..09245ef 100644 --- a/lib/PlaYUVerStream.h +++ b/lib/PlaYUVerStream.h @@ -115,6 +115,7 @@ public: END_OF_SEQ, }; + Bool open( std::string filename, std::string resolution, std::string input_format, UInt frame_rate, Bool bInput = true ); Bool open( std::string filename, UInt width, UInt height, Int input_format, UInt frame_rate, Bool bInput = true ); Void close(); From 5a98b50e59dac77581090aea87aa925b0154d3df Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Sat, 21 Feb 2015 20:44:35 +0000 Subject: [PATCH 03/39] Use opencv to save images --- lib/PlaYUVerStream.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/lib/PlaYUVerStream.cpp b/lib/PlaYUVerStream.cpp index 80b7529..2d5d1c6 100644 --- a/lib/PlaYUVerStream.cpp +++ b/lib/PlaYUVerStream.cpp @@ -27,11 +27,12 @@ #include #include "LibMemory.h" #include "PlaYUVerStream.h" -#include -#include #ifdef USE_FFMPEG #include "LibAvContextHandle.h" #endif +#ifdef USE_OPENCV +#include +#endif namespace plaYUVer { @@ -555,7 +556,6 @@ Bool PlaYUVerStream::saveFrame( const std::string& filename ) Bool PlaYUVerStream::saveFrame( const std::string& filename, PlaYUVerFrame *saveFrame ) { - QString qtString = QString::fromStdString( filename ); Int iFileFormat = INVALID_HANDLER; std::string fmtExt; @@ -585,12 +585,23 @@ Bool PlaYUVerStream::saveFrame( const std::string& filename, PlaYUVerFrame *save auxFrameStream.close(); return true; } +#if 0 else { saveFrame->fillRGBBuffer(); QImage qimg = QImage( saveFrame->getRGBBuffer(), saveFrame->getWidth(), saveFrame->getHeight(), QImage::Format_RGB32 ); return qimg.save( qtString ); } +#endif +#ifdef USE_OPENCV + else + { + cv::Mat* image; + saveFrame->getCvMat( (Void**)&image ); + return cv::imwrite( filename, *image ); + } + +#endif } return false; } From 64ecfbf016717e38dafa46bd76a44ce4f34db749 Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Sat, 21 Feb 2015 21:34:32 +0000 Subject: [PATCH 04/39] Add function to convert a string to lowercase --- lib/PlaYUVerDefs.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/PlaYUVerDefs.h b/lib/PlaYUVerDefs.h index 26c6516..2976e92 100644 --- a/lib/PlaYUVerDefs.h +++ b/lib/PlaYUVerDefs.h @@ -26,6 +26,7 @@ #define __TYPEDEF_H__ #include +#include namespace plaYUVer { @@ -116,6 +117,13 @@ enum RGBcomponent COLOR_A, }; +inline std::string lowercase( const std::string& in ) +{ + std::string out; + transform( in.begin(), in.end(), std::back_inserter( out ), tolower ); + return out; +} + } // NAMESPACE #endif // __TYPEDEF_H__ From a8ee5c965828ccec05a2f46464634659bf5767a0 Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Sat, 21 Feb 2015 21:34:53 +0000 Subject: [PATCH 05/39] Add interface to measure quality using command line --- lib/PlaYUVerCmdParser.cpp | 60 +++++++++++++++++++++++++++++++++++++-- lib/PlaYUVerCmdParser.h | 17 +++++++++-- lib/PlaYUVerStream.cpp | 3 +- tools/CMakeLists.txt | 5 ++-- tools/main.cpp | 47 ++++++------------------------ 5 files changed, 87 insertions(+), 45 deletions(-) diff --git a/lib/PlaYUVerCmdParser.cpp b/lib/PlaYUVerCmdParser.cpp index a261ff4..c965f41 100644 --- a/lib/PlaYUVerCmdParser.cpp +++ b/lib/PlaYUVerCmdParser.cpp @@ -23,6 +23,8 @@ */ #include "config.h" +#include +#include #include #include #include "PlaYUVerCmdParser.h" @@ -30,11 +32,25 @@ namespace plaYUVer { +PlaYUVerCmdParser::PlaYUVerCmdParser( Int argc, Char *argv[] ) +{ + m_iArgc = argc; + m_apcArgv = argv; + m_ParserOptions.add( GetCommandOpts() ); +} + +PlaYUVerCmdParser::~PlaYUVerCmdParser() +{ + +} + po::options_description PlaYUVerCmdParser::GetCommandOpts() { po::options_description inputOpts( "Input" ); inputOpts.add_options() - ( "input,i", po::value(), "input file" ) + ( "input,i", po::value >(), "input file" ) + ( "size,s", po::value(), "size (WxH)" ) + ( "pel_fmt", po::value(), "pixel format name" ) ( "width,w", po::value(), "width" ) ( "height,h", po::value(), "height" ); @@ -45,9 +61,49 @@ po::options_description PlaYUVerCmdParser::GetCommandOpts() po::options_description commonOpts( "Common" ); commonOpts.add_options() - ( "help", "produce help message" ); + ( "help", "produce help message" ) + ( "version", "show version and exit" ); commonOpts.add( inputOpts ).add( operationOpts ); return commonOpts; } +Void PlaYUVerCmdParser::addOptions( po::options_description opts ) +{ + m_ParserOptions.add( opts ); +} + +Bool PlaYUVerCmdParser::parse() +{ + try + { + po::store( po::command_line_parser( m_iArgc, m_apcArgv ).options( m_ParserOptions ).allow_unregistered().run(), m_cOptionsMap ); + po::notify( m_cOptionsMap ); + + if( m_cOptionsMap.count( "help" ) ) + { + std::cout << m_ParserOptions + << "\n"; + return false; + } + if( m_cOptionsMap.count( "version" ) ) + { + std::cout << "PlaYUVer version " + << PLAYUVER_VERSION_STRING + << "\n"; + return false; + } + } + catch( std::exception& e ) + { + std::cerr << "error: " << e.what() << "\n"; + return false; + } + catch( ... ) + { + std::cerr << "Exception of unknown type!\n"; + } + return true; +} + + } // NAMESPACE diff --git a/lib/PlaYUVerCmdParser.h b/lib/PlaYUVerCmdParser.h index 7d83161..2db28df 100644 --- a/lib/PlaYUVerCmdParser.h +++ b/lib/PlaYUVerCmdParser.h @@ -32,11 +32,24 @@ namespace plaYUVer class PlaYUVerCmdParser { public: - PlaYUVerCmdParser() {} ; - ~PlaYUVerCmdParser() {} ; + PlaYUVerCmdParser( Int argc, Char *argv[] ); + ~PlaYUVerCmdParser(); + + Void addOptions( po::options_description ); + Bool parse(); + + po::variables_map getOptionsMap() + { + return m_cOptionsMap; + } static po::options_description GetCommandOpts(); +private: + Int m_iArgc; + Char** m_apcArgv; + po::options_description m_ParserOptions; + po::variables_map m_cOptionsMap; }; } // NAMESPACE diff --git a/lib/PlaYUVerStream.cpp b/lib/PlaYUVerStream.cpp index 2d5d1c6..0a08f64 100644 --- a/lib/PlaYUVerStream.cpp +++ b/lib/PlaYUVerStream.cpp @@ -167,9 +167,10 @@ Bool PlaYUVerStream::open( std::string filename, std::string resolution, std::st { return false; } + for( UInt i = 0; i < PlaYUVerFrame::supportedPixelFormatListNames().size(); i++ ) { - if( PlaYUVerFrame::supportedPixelFormatListNames()[i] == input_format_name ) + if( lowercase( PlaYUVerFrame::supportedPixelFormatListNames()[i] ) == lowercase( input_format_name ) ) { input_format = i; break; diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index e6dcc56..3e90e92 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -9,8 +9,9 @@ INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_SOURCE_DIR}/../ ) set(plaYUver_Tools_SRCS -# Main - main.cpp + # Main + main.cpp + PlaYUVerTools.cpp ) ADD_EXECUTABLE( ${PROJECT_NAME}Tools ${plaYUver_Tools_SRCS} ) diff --git a/tools/main.cpp b/tools/main.cpp index 7a659dd..df3a9f3 100644 --- a/tools/main.cpp +++ b/tools/main.cpp @@ -1,6 +1,7 @@ /* This file is a part of plaYUVer project - * Copyright (C) 2014 by Luis Lucas (luisfrlucas@gmail.com) - * Joao Carreira (jfmcarreira@gmail.com) + * 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 @@ -22,50 +23,20 @@ * \brief main file */ -#include -#include -#include +#include "PlaYUVerTools.h" using namespace plaYUVer; -using namespace std; int main( int argc, char *argv[] ) { + PlaYUVerTools PlaYUVerToolsApp; - try + if( PlaYUVerToolsApp.Init( argc, argv ) > 1 ) { - - po::options_description toolsOpt; - toolsOpt.add( PlaYUVerCmdParser::GetCommandOpts() ); - po::variables_map vm; - po::store( po::parse_command_line( argc, argv, toolsOpt ), vm ); - po::notify( vm ); - - if( vm.count( "help" ) ) - { - cout << toolsOpt << "\n"; - return 0; - } - - if( vm.count( "compression" ) ) - { - cout << "Compression level was set to " << vm["compression"].as() << ".\n"; - } - else - { - cout << "Compression level was not set.\n"; - } - } - catch( exception& e ) - { - cerr << "error: " << e.what() << "\n"; + printf( "Exiting\n" ); return 1; } - catch( ... ) - { - cerr << "Exception of unknown type!\n"; - } - PlaYUVerFrame pcFrameBuffer = new PlaYUVerFrame( 1024, 768, PlaYUVerFrame::YUV420p ); - return 0; + PlaYUVerToolsApp.Process(); + } From 11bb3dbf969e704a6bb4028e2c7206436e97732a Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Sat, 21 Feb 2015 22:30:23 +0000 Subject: [PATCH 06/39] Add missing file --- tools/PlaYUVerTools.cpp | 171 ++++++++++++++++++++++++++++++++++++++++ tools/PlaYUVerTools.h | 65 +++++++++++++++ 2 files changed, 236 insertions(+) create mode 100644 tools/PlaYUVerTools.cpp create mode 100644 tools/PlaYUVerTools.h diff --git a/tools/PlaYUVerTools.cpp b/tools/PlaYUVerTools.cpp new file mode 100644 index 0000000..6d2e9c6 --- /dev/null +++ b/tools/PlaYUVerTools.cpp @@ -0,0 +1,171 @@ +/* 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 PlaYUVerTools.cpp + * \brief Main definition of the PlaYUVerTools APp + */ + +#include "PlaYUVerTools.h" + +namespace plaYUVer +{ + +PlaYUVerTools::PlaYUVerTools() +{ + m_uiOperation = INVALID_OPERATION; +} + +PlaYUVerTools::~PlaYUVerTools() +{ + for( UInt i = 0; i < m_apcInputStreams.size(); i++ ) + { + m_apcInputStreams[i]->close(); + } + for( UInt i = 0; i < m_apcOutputStreams.size(); i++ ) + { + m_apcOutputStreams[i]->close(); + } +} + +Int PlaYUVerTools::Init( Int argc, Char *argv[] ) +{ + + PlaYUVerCmdParser cCommandLineParser( argc, argv ); + + if( !cCommandLineParser.parse() ) + { + return 1; + } + + if( cCommandLineParser.getOptionsMap().count( "input" ) ) + { + if( !cCommandLineParser.getOptionsMap().count( "size" ) ) + { + printf( "Invalid resolution! " ); + return 2; + } + std::string resolutionString = cCommandLineParser.getOptionsMap()["size"].as(); + std::string fmtString( "yuv420p" ); + if( cCommandLineParser.getOptionsMap().count( "pel_fmt" ) ) + { + fmtString = cCommandLineParser.getOptionsMap()["pel_fmt"].as(); + } + + std::vector inputFileNames = cCommandLineParser.getOptionsMap()["input"].as >(); + + PlaYUVerStream* pcStream; + for( UInt i = 0; i < inputFileNames.size(); i++ ) + { + pcStream = new PlaYUVerStream; + if( !pcStream->open( inputFileNames[i], resolutionString, fmtString, 1 ) ) + { + printf( "Error opening file %s! ", inputFileNames[i].c_str() ); + return 2; + } + m_apcInputStreams.push_back( pcStream ); + } + m_uiNumberOfFrames = MAX_UINT; + UInt currFrameNum; + for( UInt i = 0; i < m_apcInputStreams.size(); i++ ) + { + currFrameNum = m_apcInputStreams[i]->getFrameNum(); + if( currFrameNum < m_uiNumberOfFrames ) + m_uiNumberOfFrames = currFrameNum; + } + } + + if( cCommandLineParser.getOptionsMap().count( "quality" ) ) + { + m_uiOperationIndex = -1; + std::string qualityMetric = cCommandLineParser.getOptionsMap()["quality"].as(); + if( m_apcInputStreams.size() != 2 ) + { + printf( "Invalid number of inputs! " ); + return 2; + } + for( UInt i = 0; i < PlaYUVerFrame::supportedQualityMetricsList().size(); i++ ) + { + if( lowercase( PlaYUVerFrame::supportedQualityMetricsList()[i] ) == lowercase( qualityMetric ) ) + { + m_uiOperationIndex = i; + } + } + if( m_uiOperationIndex == -1 ) + { + printf( "Invalid quality metric! " ); + return 2; + } + m_uiOperation = QUALITY_OPERATION; + } + + if( m_uiOperation == INVALID_OPERATION ) + { + printf( "No operation was selected! " ); + return 2; + } + return 0; +} + +Void PlaYUVerTools::Process() +{ + switch( m_uiOperation ) + { + case QUALITY_OPERATION: + qualityOperation(); + break; + } +} + +Void PlaYUVerTools::qualityOperation() +{ + PlaYUVerFrame* apcCurrFrame[m_apcInputStreams.size()]; + Bool abEOF[m_apcInputStreams.size()]; + Double dQuality; + + for( UInt i = 0; i < m_apcInputStreams.size(); i++ ) + abEOF[i] = false; + + for( UInt frame = 0; frame < m_uiNumberOfFrames; frame++ ) + { + printf( " %3d", frame ); + for( UInt i = 0; i < m_apcInputStreams.size(); i++ ) + apcCurrFrame[i] = m_apcInputStreams[i]->getCurrFrame(); + + for( UInt i = 1; i < m_apcInputStreams.size(); i++ ) + { + printf( " " ); + for( Int component = 0; component < 3; component++ ) + { + dQuality = apcCurrFrame[i]->getQuality( m_uiOperationIndex, apcCurrFrame[0], component ); + printf( " %5.3f", dQuality ); + } + } + printf( "\n" ); + for( UInt i = 0; i < m_apcInputStreams.size(); i++ ) + { + if( !abEOF[i] ) + m_apcInputStreams[i]->readFrame(); + abEOF[i] |= m_apcInputStreams[i]->checkErrors( PlaYUVerStream::LAST_FRAME ); + m_apcInputStreams[i]->setNextFrame(); + } + } +} + +} // NAMESPACE diff --git a/tools/PlaYUVerTools.h b/tools/PlaYUVerTools.h new file mode 100644 index 0000000..ce3b48d --- /dev/null +++ b/tools/PlaYUVerTools.h @@ -0,0 +1,65 @@ +/* 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 PlaYUVerTools.h + * \brief Main definition of the PlaYUVerTools app + */ + +#ifndef __PLAYUVERAPP_H__ +#define __PLAYUVERAPP_H__ + +#include "config.h" +#include "lib/PlaYUVerDefs.h" +#include +#include +#include + +namespace plaYUVer +{ + +class PlaYUVerTools +{ +public: + PlaYUVerTools(); + ~PlaYUVerTools(); + + Int Init( Int argc, Char *argv[] ); + Void Process(); + +private: + UInt m_uiOperation; + Int m_uiOperationIndex; + enum TOOLS_OPERATIONS_LIST + { + INVALID_OPERATION, + QUALITY_OPERATION, + MODULE_OPERATION, + }; + + UInt m_uiNumberOfFrames; + std::vector m_apcInputStreams; + std::vector m_apcOutputStreams; + + Void qualityOperation(); +}; + +} // NAMESPACE + +#endif // __PLAYUVERTOOLS_H__ From cbd3a65ed19475ba723d1ef2f05af7af49d7528d Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Mon, 23 Feb 2015 18:19:59 +0000 Subject: [PATCH 07/39] minor changes in PlaYUVerFrame and Stream --- lib/PlaYUVerFrame.cpp | 2 +- lib/PlaYUVerFrame.h | 2 +- lib/PlaYUVerStream.cpp | 20 +++++++++----------- 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/lib/PlaYUVerFrame.cpp b/lib/PlaYUVerFrame.cpp index 854f8ec..e546cba 100644 --- a/lib/PlaYUVerFrame.cpp +++ b/lib/PlaYUVerFrame.cpp @@ -120,7 +120,7 @@ Int PlaYUVerFrame::getColorSpace() const return m_pcPelFormat->colorSpace; } -Int PlaYUVerFrame::getNumberChannels() const +UInt PlaYUVerFrame::getNumberChannels() const { return m_pcPelFormat->numberChannels; } diff --git a/lib/PlaYUVerFrame.h b/lib/PlaYUVerFrame.h index a3824b1..d0562a4 100644 --- a/lib/PlaYUVerFrame.h +++ b/lib/PlaYUVerFrame.h @@ -102,7 +102,7 @@ public: static UInt64 getBytesPerFrame( UInt, UInt, Int ); Int getColorSpace() const; - Int getNumberChannels() const; + UInt getNumberChannels() const; UInt getChromaWidth() const; UInt getChromaHeight() const; UInt getChromaLength() const; diff --git a/lib/PlaYUVerStream.cpp b/lib/PlaYUVerStream.cpp index 0a08f64..79225a8 100644 --- a/lib/PlaYUVerStream.cpp +++ b/lib/PlaYUVerStream.cpp @@ -162,12 +162,14 @@ Bool PlaYUVerStream::open( std::string filename, std::string resolution, std::st UInt height; Int input_format = -1; - sscanf( resolution.c_str(), "%ux%u", &width, &height ); - if( width <= 0 || height <= 0 ) + if( resolution.size() > 0 ) { - return false; + sscanf( resolution.c_str(), "%ux%u", &width, &height ); + if( width <= 0 || height <= 0 ) + { + return false; + } } - for( UInt i = 0; i < PlaYUVerFrame::supportedPixelFormatListNames().size(); i++ ) { if( lowercase( PlaYUVerFrame::supportedPixelFormatListNames()[i] ) == lowercase( input_format_name ) ) @@ -176,11 +178,7 @@ Bool PlaYUVerStream::open( std::string filename, std::string resolution, std::st break; } } - if( width > 0 && height > 0 && input_format >= 0 ) - { - return open( filename, width, height, input_format, frame_rate, bInput ); - } - return false; + return open( filename, width, height, input_format, frame_rate, bInput ); } Bool PlaYUVerStream::open( std::string filename, UInt width, UInt height, Int input_format, UInt frame_rate, Bool bInput ) @@ -481,7 +479,7 @@ Void PlaYUVerStream::readFrame() if( !m_bInit || !m_bIsInput ) return; - if( m_iCurrFrameNum + 1 >= ( Int64 )m_uiTotalFrameNum ) + if( m_iCurrFrameNum + ( m_uiFrameBufferSize - 1 )>= ( Int64 )m_uiTotalFrameNum ) { m_iErrorStatus = LAST_FRAME; m_pcNextFrame = NULL; @@ -598,7 +596,7 @@ Bool PlaYUVerStream::saveFrame( const std::string& filename, PlaYUVerFrame *save else { cv::Mat* image; - saveFrame->getCvMat( (Void**)&image ); + saveFrame->getCvMat( ( Void** )&image ); return cv::imwrite( filename, *image ); } From 6a6fdab5e52f8f0d09bb97bec52a4b44c61fe281 Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Mon, 23 Feb 2015 18:20:24 +0000 Subject: [PATCH 08/39] Add new command line tools and improve the quality measuring --- lib/PlaYUVerCmdParser.cpp | 4 +- tools/PlaYUVerTools.cpp | 101 +++++++++++++++++++++++++++++--------- tools/PlaYUVerTools.h | 6 ++- tools/main.cpp | 14 +++++- 4 files changed, 95 insertions(+), 30 deletions(-) diff --git a/lib/PlaYUVerCmdParser.cpp b/lib/PlaYUVerCmdParser.cpp index c965f41..d3b7808 100644 --- a/lib/PlaYUVerCmdParser.cpp +++ b/lib/PlaYUVerCmdParser.cpp @@ -49,10 +49,10 @@ po::options_description PlaYUVerCmdParser::GetCommandOpts() po::options_description inputOpts( "Input" ); inputOpts.add_options() ( "input,i", po::value >(), "input file" ) + ( "output,o", po::value >(), "output file" ) ( "size,s", po::value(), "size (WxH)" ) ( "pel_fmt", po::value(), "pixel format name" ) - ( "width,w", po::value(), "width" ) - ( "height,h", po::value(), "height" ); + ( "frames,f", po::value(), "number of frames" ); po::options_description operationOpts( "Operation" ); operationOpts.add_options() diff --git a/tools/PlaYUVerTools.cpp b/tools/PlaYUVerTools.cpp index 6d2e9c6..39d87a9 100644 --- a/tools/PlaYUVerTools.cpp +++ b/tools/PlaYUVerTools.cpp @@ -30,6 +30,7 @@ namespace plaYUVer PlaYUVerTools::PlaYUVerTools() { m_uiOperation = INVALID_OPERATION; + m_uiNumberOfFrames = -1; } PlaYUVerTools::~PlaYUVerTools() @@ -44,7 +45,7 @@ PlaYUVerTools::~PlaYUVerTools() } } -Int PlaYUVerTools::Init( Int argc, Char *argv[] ) +Int PlaYUVerTools::Open( Int argc, Char *argv[] ) { PlaYUVerCmdParser cCommandLineParser( argc, argv ); @@ -54,14 +55,16 @@ Int PlaYUVerTools::Init( Int argc, Char *argv[] ) return 1; } + /** + * Create input streams + */ if( cCommandLineParser.getOptionsMap().count( "input" ) ) { - if( !cCommandLineParser.getOptionsMap().count( "size" ) ) + std::string resolutionString; + if( cCommandLineParser.getOptionsMap().count( "size" ) ) { - printf( "Invalid resolution! " ); - return 2; + resolutionString = cCommandLineParser.getOptionsMap()["size"].as(); } - std::string resolutionString = cCommandLineParser.getOptionsMap()["size"].as(); std::string fmtString( "yuv420p" ); if( cCommandLineParser.getOptionsMap().count( "pel_fmt" ) ) { @@ -82,15 +85,31 @@ Int PlaYUVerTools::Init( Int argc, Char *argv[] ) m_apcInputStreams.push_back( pcStream ); } m_uiNumberOfFrames = MAX_UINT; - UInt currFrameNum; + if( cCommandLineParser.getOptionsMap().count( "frames" ) ) + { + m_uiNumberOfFrames = cCommandLineParser.getOptionsMap()["frames"].as(); + } + + m_uiNumberOfComponents = MAX_UINT; for( UInt i = 0; i < m_apcInputStreams.size(); i++ ) { - currFrameNum = m_apcInputStreams[i]->getFrameNum(); - if( currFrameNum < m_uiNumberOfFrames ) - m_uiNumberOfFrames = currFrameNum; + if( m_apcInputStreams[i]->getFrameNum() < m_uiNumberOfFrames ) + m_uiNumberOfFrames = m_apcInputStreams[i]->getFrameNum(); + if( m_apcInputStreams[i]->getCurrFrame()->getNumberChannels() < m_uiNumberOfComponents ) + m_uiNumberOfComponents = m_apcInputStreams[i]->getCurrFrame()->getNumberChannels(); } } + /** + * Create output streams + */ + if( cCommandLineParser.getOptionsMap().count( "output" ) ) + { + + } + /** + * Check Quality operation + */ if( cCommandLineParser.getOptionsMap().count( "quality" ) ) { m_uiOperationIndex = -1; @@ -115,6 +134,14 @@ Int PlaYUVerTools::Init( Int argc, Char *argv[] ) m_uiOperation = QUALITY_OPERATION; } + /** + * Check Module operation + */ + if( cCommandLineParser.getOptionsMap().count( "module" ) ) + { + + } + if( m_uiOperation == INVALID_OPERATION ) { printf( "No operation was selected! " ); @@ -123,49 +150,75 @@ Int PlaYUVerTools::Init( Int argc, Char *argv[] ) return 0; } -Void PlaYUVerTools::Process() +Int PlaYUVerTools::Process() { switch( m_uiOperation ) { case QUALITY_OPERATION: + printf( " Measuring Quality using %s ... \n", PlaYUVerFrame::supportedQualityMetricsList()[m_uiOperationIndex].c_str() ); qualityOperation(); break; } + return 0; +} + +Int PlaYUVerTools::Close() +{ +// Finish + return 0; } Void PlaYUVerTools::qualityOperation() { PlaYUVerFrame* apcCurrFrame[m_apcInputStreams.size()]; Bool abEOF[m_apcInputStreams.size()]; + Double adAverageQuality[m_apcInputStreams.size() - 1][m_uiNumberOfComponents]; Double dQuality; - for( UInt i = 0; i < m_apcInputStreams.size(); i++ ) - abEOF[i] = false; - + for( UInt s = 0; s < m_apcInputStreams.size(); s++ ) + { + abEOF[s] = false; + for( UInt c = 0; c < m_uiNumberOfComponents; c++ ) + { + adAverageQuality[s][c] = 0; + } + } for( UInt frame = 0; frame < m_uiNumberOfFrames; frame++ ) { printf( " %3d", frame ); - for( UInt i = 0; i < m_apcInputStreams.size(); i++ ) - apcCurrFrame[i] = m_apcInputStreams[i]->getCurrFrame(); + for( UInt s = 0; s < m_apcInputStreams.size(); s++ ) + apcCurrFrame[s] = m_apcInputStreams[s]->getCurrFrame(); - for( UInt i = 1; i < m_apcInputStreams.size(); i++ ) + for( UInt s = 1; s < m_apcInputStreams.size(); s++ ) { printf( " " ); - for( Int component = 0; component < 3; component++ ) + for( UInt c = 0; c < m_uiNumberOfComponents; c++ ) { - dQuality = apcCurrFrame[i]->getQuality( m_uiOperationIndex, apcCurrFrame[0], component ); - printf( " %5.3f", dQuality ); + dQuality = apcCurrFrame[s]->getQuality( m_uiOperationIndex, apcCurrFrame[0], c ); + adAverageQuality[s - 1][c] = ( adAverageQuality[s - 1][c] * Double( frame ) + dQuality ) / Double( frame + 1 ); + printf( " %5.3f", dQuality ); } } printf( "\n" ); - for( UInt i = 0; i < m_apcInputStreams.size(); i++ ) + for( UInt s = 0; s < m_apcInputStreams.size(); s++ ) { - if( !abEOF[i] ) - m_apcInputStreams[i]->readFrame(); - abEOF[i] |= m_apcInputStreams[i]->checkErrors( PlaYUVerStream::LAST_FRAME ); - m_apcInputStreams[i]->setNextFrame(); + m_apcInputStreams[s]->setNextFrame(); + if( !abEOF[s] ) + { + m_apcInputStreams[s]->readFrame(); + abEOF[s] = m_apcInputStreams[s]->checkErrors( PlaYUVerStream::LAST_FRAME ); + } } } + printf( "\n Mean Values: \n " ); + for( UInt s = 0; s < m_apcInputStreams.size() - 1; s++ ) + { + for( UInt c = 0; c < m_uiNumberOfComponents; c++ ) + { + printf( " %5.3f", adAverageQuality[s][c] ); + } + } + printf( "\n"); } } // NAMESPACE diff --git a/tools/PlaYUVerTools.h b/tools/PlaYUVerTools.h index ce3b48d..5e6f4a3 100644 --- a/tools/PlaYUVerTools.h +++ b/tools/PlaYUVerTools.h @@ -40,8 +40,9 @@ public: PlaYUVerTools(); ~PlaYUVerTools(); - Int Init( Int argc, Char *argv[] ); - Void Process(); + Int Open( Int argc, Char *argv[] ); + Int Process(); + Int Close(); private: UInt m_uiOperation; @@ -54,6 +55,7 @@ private: }; UInt m_uiNumberOfFrames; + UInt m_uiNumberOfComponents; std::vector m_apcInputStreams; std::vector m_apcOutputStreams; diff --git a/tools/main.cpp b/tools/main.cpp index df3a9f3..910ddc6 100644 --- a/tools/main.cpp +++ b/tools/main.cpp @@ -31,12 +31,22 @@ int main( int argc, char *argv[] ) { PlaYUVerTools PlaYUVerToolsApp; - if( PlaYUVerToolsApp.Init( argc, argv ) > 1 ) + if( PlaYUVerToolsApp.Open( argc, argv ) > 1 ) { printf( "Exiting\n" ); return 1; } - PlaYUVerToolsApp.Process(); + if( PlaYUVerToolsApp.Process() > 1 ) + { + printf( "Exiting\n" ); + return 1; + } + + if( PlaYUVerToolsApp.Close() > 1 ) + { + printf( "Exiting\n" ); + return 1; + } } From 1f12968b90351d9ce1c12547b2549ade81af5ec4 Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Mon, 23 Feb 2015 18:37:10 +0000 Subject: [PATCH 09/39] Improve generic command line interface --- lib/PlaYUVerCmdParser.cpp | 65 +++++++++++++++++++++++++++++---------- lib/PlaYUVerCmdParser.h | 2 ++ 2 files changed, 51 insertions(+), 16 deletions(-) diff --git a/lib/PlaYUVerCmdParser.cpp b/lib/PlaYUVerCmdParser.cpp index d3b7808..3701c20 100644 --- a/lib/PlaYUVerCmdParser.cpp +++ b/lib/PlaYUVerCmdParser.cpp @@ -28,6 +28,7 @@ #include #include #include "PlaYUVerCmdParser.h" +#include "PlaYUVerFrame.h" namespace plaYUVer { @@ -47,27 +48,29 @@ PlaYUVerCmdParser::~PlaYUVerCmdParser() po::options_description PlaYUVerCmdParser::GetCommandOpts() { po::options_description inputOpts( "Input" ); - inputOpts.add_options() - ( "input,i", po::value >(), "input file" ) - ( "output,o", po::value >(), "output file" ) - ( "size,s", po::value(), "size (WxH)" ) - ( "pel_fmt", po::value(), "pixel format name" ) - ( "frames,f", po::value(), "number of frames" ); + inputOpts.add_options()/**/ + ( "input,i", po::value >(), "input file" ) /**/ + ( "output,o", po::value >(), "output file" ) /**/ + ( "size,s", po::value(), "size (WxH)" ) /**/ + ( "pel_fmt", po::value(), "pixel format" ) /**/ + ( "pel_fmts", "list pixel formats" ) /**/ + ( "frames,f", po::value(), "number of frames" ); po::options_description operationOpts( "Operation" ); - operationOpts.add_options() - ( "module", po::value(), "select a module" ) - ( "quality", po::value(),"select a quality metric" ); + operationOpts.add_options() /**/ + ( "module", po::value(), "select a module" ) /**/ + ( "quality", po::value(), "select a quality metric" ) /**/ + ( "quality_metrics", "list supported quality metrics" ); po::options_description commonOpts( "Common" ); - commonOpts.add_options() - ( "help", "produce help message" ) - ( "version", "show version and exit" ); + commonOpts.add_options()/**/ + ( "help", "produce help message" )/**/ + ( "version", "show version and exit" ); commonOpts.add( inputOpts ).add( operationOpts ); return commonOpts; } -Void PlaYUVerCmdParser::addOptions( po::options_description opts ) +Void PlaYUVerCmdParser::addOptions( po::options_description opts ) { m_ParserOptions.add( opts ); } @@ -88,14 +91,20 @@ Bool PlaYUVerCmdParser::parse() if( m_cOptionsMap.count( "version" ) ) { std::cout << "PlaYUVer version " - << PLAYUVER_VERSION_STRING - << "\n"; + << PLAYUVER_VERSION_STRING + << "\n"; + return false; + } + if( checkListingOpts() ) + { return false; } } catch( std::exception& e ) { - std::cerr << "error: " << e.what() << "\n"; + std::cerr << "error: " + << e.what() + << "\n"; return false; } catch( ... ) @@ -105,5 +114,29 @@ Bool PlaYUVerCmdParser::parse() return true; } +Bool PlaYUVerCmdParser::checkListingOpts() +{ + Bool bRet = false; + if( m_cOptionsMap.count( "pel_fmts" ) ) + { + printf( "PlaYUVer supported pixel formats: \n" ); + for( UInt i = 0; i < PlaYUVerFrame::supportedPixelFormatListNames().size(); i++ ) + { + printf( " %s\n", PlaYUVerFrame::supportedPixelFormatListNames()[i].c_str() ); + } + bRet |= true; + } + + if( m_cOptionsMap.count( "quality_metrics" ) ) + { + printf( "PlaYUVer supported quality metrics: \n" ); + for( UInt i = 0; i < PlaYUVerFrame::supportedQualityMetricsList().size(); i++ ) + { + printf( " %s\n", PlaYUVerFrame::supportedQualityMetricsList()[i].c_str() ); + } + bRet |= true; + } + return bRet; +} } // NAMESPACE diff --git a/lib/PlaYUVerCmdParser.h b/lib/PlaYUVerCmdParser.h index 2db28df..6831788 100644 --- a/lib/PlaYUVerCmdParser.h +++ b/lib/PlaYUVerCmdParser.h @@ -50,6 +50,8 @@ private: Char** m_apcArgv; po::options_description m_ParserOptions; po::variables_map m_cOptionsMap; + + Bool checkListingOpts(); }; } // NAMESPACE From 7c608e9d38299a4a0253b88af107805e81fd31eb Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Mon, 23 Feb 2015 21:38:12 +0000 Subject: [PATCH 10/39] Reorganize functions --- lib/PlaYUVerCmdParser.cpp | 12 +++++-- lib/PlaYUVerCmdParser.h | 3 +- tools/PlaYUVerTools.cpp | 74 +++++++++++++++++++++------------------ tools/PlaYUVerTools.h | 10 +++++- tools/main.cpp | 8 ++++- 5 files changed, 67 insertions(+), 40 deletions(-) diff --git a/lib/PlaYUVerCmdParser.cpp b/lib/PlaYUVerCmdParser.cpp index 3701c20..7a9ef94 100644 --- a/lib/PlaYUVerCmdParser.cpp +++ b/lib/PlaYUVerCmdParser.cpp @@ -33,10 +33,10 @@ namespace plaYUVer { -PlaYUVerCmdParser::PlaYUVerCmdParser( Int argc, Char *argv[] ) +PlaYUVerCmdParser::PlaYUVerCmdParser() { - m_iArgc = argc; - m_apcArgv = argv; + m_iArgc = 0; + m_apcArgv = NULL; m_ParserOptions.add( GetCommandOpts() ); } @@ -45,6 +45,12 @@ PlaYUVerCmdParser::~PlaYUVerCmdParser() } +Void PlaYUVerCmdParser::Config( Int argc, Char *argv[] ) +{ + m_iArgc = argc; + m_apcArgv = argv; +} + po::options_description PlaYUVerCmdParser::GetCommandOpts() { po::options_description inputOpts( "Input" ); diff --git a/lib/PlaYUVerCmdParser.h b/lib/PlaYUVerCmdParser.h index 6831788..6dbee30 100644 --- a/lib/PlaYUVerCmdParser.h +++ b/lib/PlaYUVerCmdParser.h @@ -32,9 +32,10 @@ namespace plaYUVer class PlaYUVerCmdParser { public: - PlaYUVerCmdParser( Int argc, Char *argv[] ); + PlaYUVerCmdParser(); ~PlaYUVerCmdParser(); + Void Config( Int argc, Char *argv[] ); Void addOptions( po::options_description ); Bool parse(); diff --git a/tools/PlaYUVerTools.cpp b/tools/PlaYUVerTools.cpp index 39d87a9..116c47e 100644 --- a/tools/PlaYUVerTools.cpp +++ b/tools/PlaYUVerTools.cpp @@ -45,33 +45,25 @@ PlaYUVerTools::~PlaYUVerTools() } } -Int PlaYUVerTools::Open( Int argc, Char *argv[] ) +Int PlaYUVerTools::openInputs() { - - PlaYUVerCmdParser cCommandLineParser( argc, argv ); - - if( !cCommandLineParser.parse() ) - { - return 1; - } - /** * Create input streams */ - if( cCommandLineParser.getOptionsMap().count( "input" ) ) + if( m_cCommandLineParser.getOptionsMap().count( "input" ) ) { std::string resolutionString; - if( cCommandLineParser.getOptionsMap().count( "size" ) ) + if( m_cCommandLineParser.getOptionsMap().count( "size" ) ) { - resolutionString = cCommandLineParser.getOptionsMap()["size"].as(); + resolutionString = m_cCommandLineParser.getOptionsMap()["size"].as(); } std::string fmtString( "yuv420p" ); - if( cCommandLineParser.getOptionsMap().count( "pel_fmt" ) ) + if( m_cCommandLineParser.getOptionsMap().count( "pel_fmt" ) ) { - fmtString = cCommandLineParser.getOptionsMap()["pel_fmt"].as(); + fmtString = m_cCommandLineParser.getOptionsMap()["pel_fmt"].as(); } - std::vector inputFileNames = cCommandLineParser.getOptionsMap()["input"].as >(); + std::vector inputFileNames = m_cCommandLineParser.getOptionsMap()["input"].as >(); PlaYUVerStream* pcStream; for( UInt i = 0; i < inputFileNames.size(); i++ ) @@ -85,9 +77,9 @@ Int PlaYUVerTools::Open( Int argc, Char *argv[] ) m_apcInputStreams.push_back( pcStream ); } m_uiNumberOfFrames = MAX_UINT; - if( cCommandLineParser.getOptionsMap().count( "frames" ) ) + if( m_cCommandLineParser.getOptionsMap().count( "frames" ) ) { - m_uiNumberOfFrames = cCommandLineParser.getOptionsMap()["frames"].as(); + m_uiNumberOfFrames = m_cCommandLineParser.getOptionsMap()["frames"].as(); } m_uiNumberOfComponents = MAX_UINT; @@ -99,21 +91,38 @@ Int PlaYUVerTools::Open( Int argc, Char *argv[] ) m_uiNumberOfComponents = m_apcInputStreams[i]->getCurrFrame()->getNumberChannels(); } } + return 0; +} - /** - * Create output streams - */ - if( cCommandLineParser.getOptionsMap().count( "output" ) ) +Int PlaYUVerTools::openOutputs() +{ + if( m_cCommandLineParser.getOptionsMap().count( "output" ) ) { } + return 0; +} + +Int PlaYUVerTools::Open( Int argc, Char *argv[] ) +{ + m_cCommandLineParser.Config( argc, argv ); + if( !m_cCommandLineParser.parse() ) + { + return 1; + } + + if( openInputs() > 0 || openOutputs() > 0 ) + { + return 2; + } + /** * Check Quality operation */ - if( cCommandLineParser.getOptionsMap().count( "quality" ) ) + if( m_cCommandLineParser.getOptionsMap().count( "quality" ) ) { m_uiOperationIndex = -1; - std::string qualityMetric = cCommandLineParser.getOptionsMap()["quality"].as(); + std::string qualityMetric = m_cCommandLineParser.getOptionsMap()["quality"].as(); if( m_apcInputStreams.size() != 2 ) { printf( "Invalid number of inputs! " ); @@ -132,12 +141,13 @@ Int PlaYUVerTools::Open( Int argc, Char *argv[] ) return 2; } m_uiOperation = QUALITY_OPERATION; + m_fpProcess = &PlaYUVerTools::QualityOperation; } /** * Check Module operation */ - if( cCommandLineParser.getOptionsMap().count( "module" ) ) + if( m_cCommandLineParser.getOptionsMap().count( "module" ) ) { } @@ -152,14 +162,7 @@ Int PlaYUVerTools::Open( Int argc, Char *argv[] ) Int PlaYUVerTools::Process() { - switch( m_uiOperation ) - { - case QUALITY_OPERATION: - printf( " Measuring Quality using %s ... \n", PlaYUVerFrame::supportedQualityMetricsList()[m_uiOperationIndex].c_str() ); - qualityOperation(); - break; - } - return 0; + return (this->*m_fpProcess)(); } Int PlaYUVerTools::Close() @@ -168,13 +171,15 @@ Int PlaYUVerTools::Close() return 0; } -Void PlaYUVerTools::qualityOperation() +Int PlaYUVerTools::QualityOperation() { PlaYUVerFrame* apcCurrFrame[m_apcInputStreams.size()]; Bool abEOF[m_apcInputStreams.size()]; Double adAverageQuality[m_apcInputStreams.size() - 1][m_uiNumberOfComponents]; Double dQuality; + printf( " Measuring Quality using %s ... \n", PlaYUVerFrame::supportedQualityMetricsList()[m_uiOperationIndex].c_str() ); + for( UInt s = 0; s < m_apcInputStreams.size(); s++ ) { abEOF[s] = false; @@ -218,7 +223,8 @@ Void PlaYUVerTools::qualityOperation() printf( " %5.3f", adAverageQuality[s][c] ); } } - printf( "\n"); + printf( "\n" ); + return 0; } } // NAMESPACE diff --git a/tools/PlaYUVerTools.h b/tools/PlaYUVerTools.h index 5e6f4a3..75314f1 100644 --- a/tools/PlaYUVerTools.h +++ b/tools/PlaYUVerTools.h @@ -45,6 +45,8 @@ public: Int Close(); private: + PlaYUVerCmdParser m_cCommandLineParser; + UInt m_uiOperation; Int m_uiOperationIndex; enum TOOLS_OPERATIONS_LIST @@ -59,7 +61,13 @@ private: std::vector m_apcInputStreams; std::vector m_apcOutputStreams; - Void qualityOperation(); + Int openInputs(); + Int openOutputs(); + + typedef Int (PlaYUVerTools::*FpProcess) (); + FpProcess m_fpProcess; + + Int QualityOperation(); }; } // NAMESPACE diff --git a/tools/main.cpp b/tools/main.cpp index 910ddc6..4c31c20 100644 --- a/tools/main.cpp +++ b/tools/main.cpp @@ -29,9 +29,15 @@ using namespace plaYUVer; int main( int argc, char *argv[] ) { + Int iRet = 0; PlaYUVerTools PlaYUVerToolsApp; - if( PlaYUVerToolsApp.Open( argc, argv ) > 1 ) + iRet = PlaYUVerToolsApp.Open( argc, argv ); + if( iRet == 1 ) + { + return 0; + } + if( iRet > 1 ) { printf( "Exiting\n" ); return 1; From 65c19e3e170ed8abffcd7e517ae2d07e0430434c Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Tue, 24 Feb 2015 00:46:45 +0000 Subject: [PATCH 11/39] Fix issues with configuration --- tools/PlaYUVerTools.cpp | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/tools/PlaYUVerTools.cpp b/tools/PlaYUVerTools.cpp index 116c47e..358a558 100644 --- a/tools/PlaYUVerTools.cpp +++ b/tools/PlaYUVerTools.cpp @@ -69,12 +69,20 @@ Int PlaYUVerTools::openInputs() for( UInt i = 0; i < inputFileNames.size(); i++ ) { pcStream = new PlaYUVerStream; - if( !pcStream->open( inputFileNames[i], resolutionString, fmtString, 1 ) ) + try { - printf( "Error opening file %s! ", inputFileNames[i].c_str() ); - return 2; + if( !pcStream->open( inputFileNames[i], resolutionString, fmtString, 1 ) ) + { + printf( "Cannot open input stream %s! ", inputFileNames[i].c_str() ); + return 2; + } + m_apcInputStreams.push_back( pcStream ); + } + catch( const char *msg ) + { + printf( "Cannot open input stream %s with the following error: \n%s", inputFileNames[i].c_str(), msg ); + return false; } - m_apcInputStreams.push_back( pcStream ); } m_uiNumberOfFrames = MAX_UINT; if( m_cCommandLineParser.getOptionsMap().count( "frames" ) ) @@ -111,7 +119,7 @@ Int PlaYUVerTools::Open( Int argc, Char *argv[] ) return 1; } - if( openInputs() > 0 || openOutputs() > 0 ) + if( openInputs() > 0 ) { return 2; } @@ -162,7 +170,7 @@ Int PlaYUVerTools::Open( Int argc, Char *argv[] ) Int PlaYUVerTools::Process() { - return (this->*m_fpProcess)(); + return ( this->*m_fpProcess )(); } Int PlaYUVerTools::Close() From 6ff4a53d87e80fc88a96b602588283577fd7da18 Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Tue, 24 Feb 2015 00:47:33 +0000 Subject: [PATCH 12/39] Organize cmake file. Put all qt dependencies in app CMakeLists --- CMakeLists.txt | 64 ++++++++++-------------------------------- app/CMakeLists.txt | 35 +++++++++++++++++++++++ modules/CMakeLists.txt | 2 ++ 3 files changed, 52 insertions(+), 49 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0bbb827..8418ee5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,7 +17,7 @@ SET( PLAYUVER_VERSION_PATCH "0" ) SET( PLAYUVER_VERSION "${PLAYUVER_VERSION_MAJOR}.${PLAYUVER_VERSION_MINOR}.${PLAYUVER_VERSION_PATCH}") ###################################################################################### -# CMake Definitions +# CMake Defin1itions ###################################################################################### SET(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake ) @@ -30,56 +30,17 @@ IF(DEFINED CMAKE_BUILD_TYPE AND CMAKE_VERSION VERSION_GREATER "2.8") ENDIF() SET( CMAKE_CXX_FLAGS "" ) +cmake_policy(SET CMP0043 NEW) ###################################################################################### # Variables ###################################################################################### +OPTION( PLAYUVER_BUILD_APP "Build GUI Application" ON ) +OPTION( PLAYUVER_BUILD_TOOLS "Build Command Line Application" ON ) + OPTION( USE_FERVOR "Add Fervor support" OFF ) -OPTION( PLAYUVER_LONGVERSIONNAME "Use long version name in deb" OFF ) -OPTION( PLAYUVER_WERROR "Warnings as errors" OFF ) -OPTION( PLAYUVER_THREADED_MODULES "Use threads for modules" OFF ) -OPTION( USE_QT4 "Build with QT4" OFF ) - -##################################################################################### -# Qt library -###################################################################################### - -IF( USE_QT4 ) - SET( DEPENDENCIES_STRING "${DEPENDENCIES_STRING}QT4" ) - FIND_PACKAGE( Qt4 REQUIRED COMPONENTS QtCore QtGui QtDBus QtNetwork QtWebKit ) - - SET( USE_QTDBUS TRUE ) - - IF( NOT QT4_FOUND ) - SET(USE_QT4 FALSE) - ELSE() - INCLUDE( ${QT_USE_FILE} ) - ADD_DEFINITIONS( ${QT_DEFINITIONS} ) - SET( QT_LINKER_LIBS ${QT_LIBRARIES} ) - ENDIF() -ENDIF() - -IF( NOT USE_QT4 ) - - SET( DEPENDENCIES_STRING "${DEPENDENCIES_STRING}QT5" ) - - FIND_PACKAGE( Qt5 REQUIRED COMPONENTS Core Gui Widgets PrintSupport ) - FIND_PACKAGE( Qt5DBus ) - - - LIST(APPEND QT_LINKER_LIBS Qt5::Core Qt5::Gui Qt5::Widgets Qt5::PrintSupport ) - LIST(APPEND QT_MODULES Core Gui Widgets ) - IF( ${Qt5DBus_FOUND} ) - SET( USE_QTDBUS ${Qt5DBus_FOUND} ) - LIST(APPEND QT_LINKER_LIBS Qt5::DBus ) - LIST(APPEND QT_MODULES DBus ) - ENDIF() - - INCLUDE_DIRECTORIES( ${Qt5Core_INCLUDE_DIRS} ${Qt5Gui_INCLUDE_DIRS} ${Qt5Widgets_INCLUDE_DIRS} ${Qt5DBus_INCLUDE_DIRS}) - SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Core_EXECUTABLE_COMPILE_FLAGS}" ) - -ENDIF() +OPTION( USE_WERROR "Warnings as errors" OFF ) ###################################################################################### # Dependencies @@ -133,9 +94,14 @@ SET( CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O2" ) ADD_SUBDIRECTORY( lib ) ADD_SUBDIRECTORY( modules ) -ADD_SUBDIRECTORY( tools ) -ADD_SUBDIRECTORY( app ) +IF( PLAYUVER_BUILD_TOOLS ) + ADD_SUBDIRECTORY( tools ) +ENDIF() + +IF( PLAYUVER_BUILD_APP ) + ADD_SUBDIRECTORY( app ) +ENDIF() @@ -146,8 +112,8 @@ MESSAGE("") MESSAGE( STATUS "${PROJECT_NAME} INFORMATION" ) MESSAGE( STATUS "Version: " "${PLAYUVER_VERSION}" ) MESSAGE( STATUS "Configuration:" ) -MESSAGE( STATUS " Build type:" "${CMAKE_BUILD_TYPE}" ) -MESSAGE( STATUS " Build flags:" "${CMAKE_CXX_FLAGS}" ) +MESSAGE( STATUS " Build type: " "${CMAKE_BUILD_TYPE}" ) +MESSAGE( STATUS " Build flags:" "${CMAKE_CXX_FLAGS}" ) FEATURE_SUMMARY(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES) diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index f7eabd8..be5c85a 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -10,6 +10,41 @@ INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_BINARY_DIR}/../ ${CMAKE_CURRENT_SOURCE_DIR}/../modules ${CMAKE_CURRENT_BINARY_DIR}/../modules ) +##################################################################################### +# Qt library +###################################################################################### + +OPTION( USE_QT4 "Build with QT4" OFF ) + +IF( USE_QT4 ) + + FIND_PACKAGE( Qt4 REQUIRED COMPONENTS QtCore QtGui QtDBus QtNetwork QtWebKit ) + SET( USE_QTDBUS TRUE ) + IF( NOT QT4_FOUND ) + SET(USE_QT4 FALSE) + ELSE() + INCLUDE( ${QT_USE_FILE} ) + ADD_DEFINITIONS( ${QT_DEFINITIONS} ) + SET( QT_LINKER_LIBS ${QT_LIBRARIES} ) + ENDIF() +ENDIF() + +IF( NOT USE_QT4 ) + FIND_PACKAGE( Qt5 REQUIRED COMPONENTS Core Gui Widgets PrintSupport ) + FIND_PACKAGE( Qt5DBus ) + LIST(APPEND QT_LINKER_LIBS Qt5::Core Qt5::Gui Qt5::Widgets Qt5::PrintSupport ) + LIST(APPEND QT_MODULES Core Gui Widgets ) + IF( ${Qt5DBus_FOUND} ) + SET( USE_QTDBUS ${Qt5DBus_FOUND} ) + LIST(APPEND QT_LINKER_LIBS Qt5::DBus ) + LIST(APPEND QT_MODULES DBus ) + ENDIF() + + #INCLUDE_DIRECTORIES( ${Qt5Core_INCLUDE_DIRS} ${Qt5Gui_INCLUDE_DIRS} ${Qt5Widgets_INCLUDE_DIRS} ${Qt5DBus_INCLUDE_DIRS}) + #SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Core_EXECUTABLE_COMPILE_FLAGS}" ) + +ENDIF() + set(plaYUver_App_SRCS # Main main.cpp diff --git a/modules/CMakeLists.txt b/modules/CMakeLists.txt index 703d107..d420f11 100644 --- a/modules/CMakeLists.txt +++ b/modules/CMakeLists.txt @@ -2,6 +2,8 @@ ### CMakeLists for playuver modules component ### +OPTION( MODULE_THREADED_MODULES "Use threads for modules" OFF ) + INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_SOURCE_DIR}/../ ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ) set(plaYUver_Mod_SRCS From e924a06a9eeedd83606cdb50f722374c9622537b Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Tue, 24 Feb 2015 01:45:54 +0000 Subject: [PATCH 13/39] Add class to handle command line args in the Tools App --- lib/PlaYUVerCmdParser.cpp | 12 ++++++---- tools/CMakeLists.txt | 2 +- tools/CommandLineHandle.cpp | 41 +++++++++++++++++++++++++++++++++ tools/CommandLineHandle.h | 46 +++++++++++++++++++++++++++++++++++++ tools/PlaYUVerTools.cpp | 6 ++--- tools/PlaYUVerTools.h | 12 +++++----- 6 files changed, 105 insertions(+), 14 deletions(-) create mode 100644 tools/CommandLineHandle.cpp create mode 100644 tools/CommandLineHandle.h diff --git a/lib/PlaYUVerCmdParser.cpp b/lib/PlaYUVerCmdParser.cpp index 7a9ef94..ae9c4f8 100644 --- a/lib/PlaYUVerCmdParser.cpp +++ b/lib/PlaYUVerCmdParser.cpp @@ -62,17 +62,21 @@ po::options_description PlaYUVerCmdParser::GetCommandOpts() ( "pel_fmts", "list pixel formats" ) /**/ ( "frames,f", po::value(), "number of frames" ); - po::options_description operationOpts( "Operation" ); - operationOpts.add_options() /**/ - ( "module", po::value(), "select a module" ) /**/ + po::options_description qualityOpts( "Quality" ); + qualityOpts.add_options() /**/ ( "quality", po::value(), "select a quality metric" ) /**/ ( "quality_metrics", "list supported quality metrics" ); + po::options_description moduleOpts( "Module" ); + moduleOpts.add_options() /**/ + ( "module", po::value(), "select a module" ) /**/ + ( "module_list", "list supported modules" ); + po::options_description commonOpts( "Common" ); commonOpts.add_options()/**/ ( "help", "produce help message" )/**/ ( "version", "show version and exit" ); - commonOpts.add( inputOpts ).add( operationOpts ); + commonOpts.add( inputOpts ).add( qualityOpts ).add( moduleOpts ); return commonOpts; } diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 3e90e92..f45ce07 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -9,9 +9,9 @@ INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_SOURCE_DIR}/../ ) set(plaYUver_Tools_SRCS - # Main main.cpp PlaYUVerTools.cpp + CommandLineHandle.cpp ) ADD_EXECUTABLE( ${PROJECT_NAME}Tools ${plaYUver_Tools_SRCS} ) diff --git a/tools/CommandLineHandle.cpp b/tools/CommandLineHandle.cpp new file mode 100644 index 0000000..be0f49d --- /dev/null +++ b/tools/CommandLineHandle.cpp @@ -0,0 +1,41 @@ +/* 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 CommandLineHandle.cpp + * \brief Handle for command line + */ + +#include "CommandLineHandle.h" + +namespace plaYUVer +{ + +CommandLineHandle::CommandLineHandle() +{ + +} + +CommandLineHandle::~CommandLineHandle() +{ + +} + + +} // NAMESPACE diff --git a/tools/CommandLineHandle.h b/tools/CommandLineHandle.h new file mode 100644 index 0000000..b4a6ad6 --- /dev/null +++ b/tools/CommandLineHandle.h @@ -0,0 +1,46 @@ +/* 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 CommandLineHandle.h + * \brief Handle for command line + */ + +#ifndef __COMMANDLINEHANDLE_H__ +#define __COMMANDLINEHANDLE_H__ + +#include "config.h" +#include "lib/PlaYUVerDefs.h" +#include "lib/PlaYUVerCmdParser.h" + +namespace plaYUVer +{ + +class CommandLineHandle: public PlaYUVerCmdParser +{ +public: + CommandLineHandle(); + ~CommandLineHandle(); + + +}; + +} // NAMESPACE + +#endif // __COMMANDLINEHANDLE_H__ diff --git a/tools/PlaYUVerTools.cpp b/tools/PlaYUVerTools.cpp index 358a558..1216b2d 100644 --- a/tools/PlaYUVerTools.cpp +++ b/tools/PlaYUVerTools.cpp @@ -52,7 +52,7 @@ Int PlaYUVerTools::openInputs() */ if( m_cCommandLineParser.getOptionsMap().count( "input" ) ) { - std::string resolutionString; + std::string resolutionString(""); if( m_cCommandLineParser.getOptionsMap().count( "size" ) ) { resolutionString = m_cCommandLineParser.getOptionsMap()["size"].as(); @@ -80,8 +80,8 @@ Int PlaYUVerTools::openInputs() } catch( const char *msg ) { - printf( "Cannot open input stream %s with the following error: \n%s", inputFileNames[i].c_str(), msg ); - return false; + printf( "Cannot open input stream %s with the following error: \n%s\n", inputFileNames[i].c_str(), msg ); + return 2; } } m_uiNumberOfFrames = MAX_UINT; diff --git a/tools/PlaYUVerTools.h b/tools/PlaYUVerTools.h index 75314f1..4d1464b 100644 --- a/tools/PlaYUVerTools.h +++ b/tools/PlaYUVerTools.h @@ -22,14 +22,14 @@ * \brief Main definition of the PlaYUVerTools app */ -#ifndef __PLAYUVERAPP_H__ -#define __PLAYUVERAPP_H__ +#ifndef __PLAYUVERTOOLS_H__ +#define __PLAYUVERTOOLS_H__ #include "config.h" #include "lib/PlaYUVerDefs.h" -#include -#include -#include +#include "lib/PlaYUVerFrame.h" +#include "lib/PlaYUVerStream.h" +#include "CommandLineHandle.h" namespace plaYUVer { @@ -45,7 +45,7 @@ public: Int Close(); private: - PlaYUVerCmdParser m_cCommandLineParser; + CommandLineHandle m_cCommandLineParser; UInt m_uiOperation; Int m_uiOperationIndex; From 40aa4f95f35af36dffe85f899e5aee44d252ab4f Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Tue, 24 Feb 2015 01:53:54 +0000 Subject: [PATCH 14/39] Seperate command opts by app --- lib/PlaYUVerCmdParser.cpp | 22 +--------------------- tools/CommandLineHandle.cpp | 35 +++++++++++++++++++++++++++++++++++ tools/CommandLineHandle.h | 1 + tools/PlaYUVerTools.cpp | 8 +++++--- 4 files changed, 42 insertions(+), 24 deletions(-) diff --git a/lib/PlaYUVerCmdParser.cpp b/lib/PlaYUVerCmdParser.cpp index ae9c4f8..0d9c1c8 100644 --- a/lib/PlaYUVerCmdParser.cpp +++ b/lib/PlaYUVerCmdParser.cpp @@ -62,21 +62,11 @@ po::options_description PlaYUVerCmdParser::GetCommandOpts() ( "pel_fmts", "list pixel formats" ) /**/ ( "frames,f", po::value(), "number of frames" ); - po::options_description qualityOpts( "Quality" ); - qualityOpts.add_options() /**/ - ( "quality", po::value(), "select a quality metric" ) /**/ - ( "quality_metrics", "list supported quality metrics" ); - - po::options_description moduleOpts( "Module" ); - moduleOpts.add_options() /**/ - ( "module", po::value(), "select a module" ) /**/ - ( "module_list", "list supported modules" ); - po::options_description commonOpts( "Common" ); commonOpts.add_options()/**/ ( "help", "produce help message" )/**/ ( "version", "show version and exit" ); - commonOpts.add( inputOpts ).add( qualityOpts ).add( moduleOpts ); + commonOpts.add( inputOpts ); return commonOpts; } @@ -136,16 +126,6 @@ Bool PlaYUVerCmdParser::checkListingOpts() } bRet |= true; } - - if( m_cOptionsMap.count( "quality_metrics" ) ) - { - printf( "PlaYUVer supported quality metrics: \n" ); - for( UInt i = 0; i < PlaYUVerFrame::supportedQualityMetricsList().size(); i++ ) - { - printf( " %s\n", PlaYUVerFrame::supportedQualityMetricsList()[i].c_str() ); - } - bRet |= true; - } return bRet; } diff --git a/tools/CommandLineHandle.cpp b/tools/CommandLineHandle.cpp index be0f49d..418f083 100644 --- a/tools/CommandLineHandle.cpp +++ b/tools/CommandLineHandle.cpp @@ -23,6 +23,7 @@ */ #include "CommandLineHandle.h" +#include "lib/PlaYUVerFrame.h" namespace plaYUVer { @@ -37,5 +38,39 @@ CommandLineHandle::~CommandLineHandle() } +Int CommandLineHandle::ParseToolsArgs() +{ + Int iRet = 0; + + po::options_description qualityOpts( "Quality" ); + qualityOpts.add_options() /**/ + ( "quality", po::value(), "select a quality metric" ) /**/ + ( "quality_metrics", "list supported quality metrics" ); + + po::options_description moduleOpts( "Module" ); + moduleOpts.add_options() /**/ + ( "module", po::value(), "select a module" ) /**/ + ( "module_list", "list supported modules" ); + + addOptions( qualityOpts ); + addOptions( moduleOpts ); + + if( !parse() ) + { + iRet = 1; + } + + if( getOptionsMap().count( "quality_metrics" ) ) + { + printf( "PlaYUVer supported quality metrics: \n" ); + for( UInt i = 0; i < PlaYUVerFrame::supportedQualityMetricsList().size(); i++ ) + { + printf( " %s\n", PlaYUVerFrame::supportedQualityMetricsList()[i].c_str() ); + } + iRet = 1; + } + + return iRet; +} } // NAMESPACE diff --git a/tools/CommandLineHandle.h b/tools/CommandLineHandle.h index b4a6ad6..1d8565a 100644 --- a/tools/CommandLineHandle.h +++ b/tools/CommandLineHandle.h @@ -38,6 +38,7 @@ public: CommandLineHandle(); ~CommandLineHandle(); + Int ParseToolsArgs(); }; diff --git a/tools/PlaYUVerTools.cpp b/tools/PlaYUVerTools.cpp index 1216b2d..23d9636 100644 --- a/tools/PlaYUVerTools.cpp +++ b/tools/PlaYUVerTools.cpp @@ -113,10 +113,12 @@ Int PlaYUVerTools::openOutputs() Int PlaYUVerTools::Open( Int argc, Char *argv[] ) { + Int iRet = 0; + m_cCommandLineParser.Config( argc, argv ); - if( !m_cCommandLineParser.parse() ) + if( ( iRet = m_cCommandLineParser.ParseToolsArgs() ) > 0 ) { - return 1; + return iRet; } if( openInputs() > 0 ) @@ -165,7 +167,7 @@ Int PlaYUVerTools::Open( Int argc, Char *argv[] ) printf( "No operation was selected! " ); return 2; } - return 0; + return iRet; } Int PlaYUVerTools::Process() From db4b6fa1a10b464f15f88a20c680a3128ec5da83 Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Tue, 24 Feb 2015 02:11:18 +0000 Subject: [PATCH 15/39] Remove spaces from modules names --- modules/FilterComponent.cpp | 10 +++++----- modules/LumaAverage.cpp | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/FilterComponent.cpp b/modules/FilterComponent.cpp index a030bdf..6102704 100644 --- a/modules/FilterComponent.cpp +++ b/modules/FilterComponent.cpp @@ -60,7 +60,7 @@ FilterComponentLuma::FilterComponentLuma() /* Module Definition */ m_iModuleType = FRAME_PROCESSING_MODULE; // Apply module to the frames or to the whole sequence. // Currently only support for frame - m_pchModuleCategory = "Filter Component"; // Category (sub-menu) + m_pchModuleCategory = "FilterComponent"; // Category (sub-menu) m_pchModuleName = "Luma"; // Name m_pchModuleTooltip = "Filter Y matrix of YUV frame"; // Description m_uiNumberOfFrames = MODULE_REQUIRES_ONE_FRAME; // Number of Frames required (ONE_FRAME, TWO_FRAMES, THREE_FRAMES) @@ -83,8 +83,8 @@ FilterComponentChromaU::FilterComponentChromaU() { /* Module Definition */ m_iModuleType = FRAME_PROCESSING_MODULE; - m_pchModuleCategory = "Filter Component"; - m_pchModuleName = "Chroma U"; + m_pchModuleCategory = "FilterComponent"; + m_pchModuleName = "ChromaU"; m_pchModuleTooltip = "Filter U matrix of YUV frame"; m_uiNumberOfFrames = MODULE_REQUIRES_ONE_FRAME; m_uiModuleRequirements = MODULE_REQUIRES_NOTHING; @@ -105,8 +105,8 @@ FilterComponentChromaV::FilterComponentChromaV() { /* Module Definition */ m_iModuleType = FRAME_PROCESSING_MODULE; - m_pchModuleCategory = "Filter Component"; - m_pchModuleName = "Chroma V"; + m_pchModuleCategory = "FilterComponent"; + m_pchModuleName = "ChromaV"; m_pchModuleTooltip = "Filter V matrix of YUV frame"; m_uiNumberOfFrames = MODULE_REQUIRES_ONE_FRAME; m_uiModuleRequirements = MODULE_REQUIRES_NOTHING; diff --git a/modules/LumaAverage.cpp b/modules/LumaAverage.cpp index 9d8cd6a..c32a79d 100644 --- a/modules/LumaAverage.cpp +++ b/modules/LumaAverage.cpp @@ -32,7 +32,7 @@ LumaAverage::LumaAverage() /* Module Definition */ m_iModuleType = FRAME_MEASUREMENT_MODULE; m_pchModuleCategory = "Measurements"; - m_pchModuleName = "Luma Average"; + m_pchModuleName = "LumaAverage"; m_pchModuleTooltip = "Measure the average of luma component"; m_uiNumberOfFrames = MODULE_REQUIRES_ONE_FRAME; m_uiModuleRequirements = MODULE_REQUIRES_SIDEBAR; From c3ec5268db166e42c9d8e44b74fc7c7d15c1daf7 Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Tue, 24 Feb 2015 03:00:06 +0000 Subject: [PATCH 16/39] Add support for module operation (only measurement modules are supported) --- tools/CommandLineHandle.cpp | 56 ++++++++++++++++++- tools/CommandLineHandle.h | 3 +- tools/PlaYUVerTools.cpp | 106 +++++++++++++++++++++++++++++++++--- tools/PlaYUVerTools.h | 8 ++- 4 files changed, 163 insertions(+), 10 deletions(-) diff --git a/tools/CommandLineHandle.cpp b/tools/CommandLineHandle.cpp index 418f083..18ac1e1 100644 --- a/tools/CommandLineHandle.cpp +++ b/tools/CommandLineHandle.cpp @@ -22,8 +22,11 @@ * \brief Handle for command line */ +#include #include "CommandLineHandle.h" #include "lib/PlaYUVerFrame.h" +#include "modules/PlaYUVerModuleIf.h" +#include "modules/PlaYUVerModuleFactory.h" namespace plaYUVer { @@ -38,7 +41,7 @@ CommandLineHandle::~CommandLineHandle() } -Int CommandLineHandle::ParseToolsArgs() +Int CommandLineHandle::parseToolsArgs() { Int iRet = 0; @@ -70,7 +73,58 @@ Int CommandLineHandle::ParseToolsArgs() iRet = 1; } + if( getOptionsMap().count( "module_list" ) ) + { + listModules(); + iRet = 1; + } + return iRet; } +Void CommandLineHandle::listModules() +{ + PlaYUVerModuleIf* pcCurrModuleIf; + PlaYUVerModuleFactoryMap& PlaYUVerModuleFactoryMap = PlaYUVerModuleFactory::Get()->getMap(); + PlaYUVerModuleFactoryMap::iterator it = PlaYUVerModuleFactoryMap.begin(); + + printf( "PlaYUVer available modules: \n" ); + //printf( " " ); + printf( " [Name] " ); + printf( " [Type] " ); + printf( " [Description]" ); + printf( " \n" ); + + Char ModuleNameString[40]; + + for( UInt i = 0; it != PlaYUVerModuleFactoryMap.end(); ++it, i++ ) + { + ModuleNameString[0] = '\0'; + + pcCurrModuleIf = it->second(); + + printf( " " ); + if( pcCurrModuleIf->m_pchModuleCategory ) + { + strcat( ModuleNameString, pcCurrModuleIf->m_pchModuleCategory ); + strcat( ModuleNameString, "/" ); + } + strcat( ModuleNameString, pcCurrModuleIf->m_pchModuleName ); + printf( "%-40s", ModuleNameString ); + switch( pcCurrModuleIf->m_iModuleType ) + { + case FRAME_PROCESSING_MODULE: + printf( " Processing " ); + break; + case FRAME_MEASUREMENT_MODULE: + printf( " Measurement " ); + break; + } + printf( " %s", pcCurrModuleIf->m_pchModuleTooltip ); + printf( "\n" ); + pcCurrModuleIf->Delete(); + } + +} + } // NAMESPACE diff --git a/tools/CommandLineHandle.h b/tools/CommandLineHandle.h index 1d8565a..1fa6a35 100644 --- a/tools/CommandLineHandle.h +++ b/tools/CommandLineHandle.h @@ -38,7 +38,8 @@ public: CommandLineHandle(); ~CommandLineHandle(); - Int ParseToolsArgs(); + Int parseToolsArgs(); + Void listModules(); }; diff --git a/tools/PlaYUVerTools.cpp b/tools/PlaYUVerTools.cpp index 23d9636..ab461a0 100644 --- a/tools/PlaYUVerTools.cpp +++ b/tools/PlaYUVerTools.cpp @@ -23,6 +23,8 @@ */ #include "PlaYUVerTools.h" +#include "modules/PlaYUVerModuleIf.h" +#include "modules/PlaYUVerModuleFactory.h" namespace plaYUVer { @@ -31,6 +33,10 @@ PlaYUVerTools::PlaYUVerTools() { m_uiOperation = INVALID_OPERATION; m_uiNumberOfFrames = -1; + + m_uiQualityMetric = -1; + + m_pcCurrModuleIf = NULL; } PlaYUVerTools::~PlaYUVerTools() @@ -52,7 +58,7 @@ Int PlaYUVerTools::openInputs() */ if( m_cCommandLineParser.getOptionsMap().count( "input" ) ) { - std::string resolutionString(""); + std::string resolutionString( "" ); if( m_cCommandLineParser.getOptionsMap().count( "size" ) ) { resolutionString = m_cCommandLineParser.getOptionsMap()["size"].as(); @@ -116,7 +122,7 @@ Int PlaYUVerTools::Open( Int argc, Char *argv[] ) Int iRet = 0; m_cCommandLineParser.Config( argc, argv ); - if( ( iRet = m_cCommandLineParser.ParseToolsArgs() ) > 0 ) + if( ( iRet = m_cCommandLineParser.parseToolsArgs() ) > 0 ) { return iRet; } @@ -131,7 +137,6 @@ Int PlaYUVerTools::Open( Int argc, Char *argv[] ) */ if( m_cCommandLineParser.getOptionsMap().count( "quality" ) ) { - m_uiOperationIndex = -1; std::string qualityMetric = m_cCommandLineParser.getOptionsMap()["quality"].as(); if( m_apcInputStreams.size() != 2 ) { @@ -142,16 +147,17 @@ Int PlaYUVerTools::Open( Int argc, Char *argv[] ) { if( lowercase( PlaYUVerFrame::supportedQualityMetricsList()[i] ) == lowercase( qualityMetric ) ) { - m_uiOperationIndex = i; + m_uiQualityMetric = i; } } - if( m_uiOperationIndex == -1 ) + if( m_uiQualityMetric == -1 ) { printf( "Invalid quality metric! " ); return 2; } m_uiOperation = QUALITY_OPERATION; m_fpProcess = &PlaYUVerTools::QualityOperation; + printf( "PlaYUVer Quality\n" ); } /** @@ -159,7 +165,30 @@ Int PlaYUVerTools::Open( Int argc, Char *argv[] ) */ if( m_cCommandLineParser.getOptionsMap().count( "module" ) ) { + std::string moduleName = m_cCommandLineParser.getOptionsMap()["module"].as(); + PlaYUVerModuleFactoryMap& PlaYUVerModuleFactoryMap = PlaYUVerModuleFactory::Get()->getMap(); + PlaYUVerModuleFactoryMap::iterator it = PlaYUVerModuleFactoryMap.begin(); + for( UInt i = 0; it != PlaYUVerModuleFactoryMap.end(); ++it, i++ ) + { + if( strcmp( it->first, moduleName.c_str() ) == 0 ) + { + m_pcCurrModuleIf = it->second(); + break; + } + } + + if( m_apcInputStreams.size() != m_pcCurrModuleIf->m_uiNumberOfFrames ) + { + printf( "Invalid number of inputs! " ); + return 2; + } + + m_pcCurrModuleIf->create( m_apcInputStreams[0]->getCurrFrame() ); + + m_uiOperation = MODULE_OPERATION; + m_fpProcess = &PlaYUVerTools::ModuleOperation; + printf( "PlaYUVer Module\n" ); } if( m_uiOperation == INVALID_OPERATION ) @@ -188,7 +217,7 @@ Int PlaYUVerTools::QualityOperation() Double adAverageQuality[m_apcInputStreams.size() - 1][m_uiNumberOfComponents]; Double dQuality; - printf( " Measuring Quality using %s ... \n", PlaYUVerFrame::supportedQualityMetricsList()[m_uiOperationIndex].c_str() ); + printf( " Measuring Quality using %s ... \n", PlaYUVerFrame::supportedQualityMetricsList()[m_uiQualityMetric].c_str() ); for( UInt s = 0; s < m_apcInputStreams.size(); s++ ) { @@ -209,7 +238,7 @@ Int PlaYUVerTools::QualityOperation() printf( " " ); for( UInt c = 0; c < m_uiNumberOfComponents; c++ ) { - dQuality = apcCurrFrame[s]->getQuality( m_uiOperationIndex, apcCurrFrame[0], c ); + dQuality = apcCurrFrame[s]->getQuality( m_uiQualityMetric, apcCurrFrame[0], c ); adAverageQuality[s - 1][c] = ( adAverageQuality[s - 1][c] * Double( frame ) + dQuality ) / Double( frame + 1 ); printf( " %5.3f", dQuality ); } @@ -237,4 +266,67 @@ Int PlaYUVerTools::QualityOperation() return 0; } +Int PlaYUVerTools::ModuleOperation() +{ + printf( " Applying Module %s/%s ... \n", m_pcCurrModuleIf->m_pchModuleCategory, m_pcCurrModuleIf->m_pchModuleName ); + + PlaYUVerFrame* pcProcessedFrame = NULL; + Double dMeasurementResult = 0.0; + Double dAveragedMeasurementResult = 0; + Bool abEOF[m_apcInputStreams.size()]; + + for( UInt s = 0; s < m_apcInputStreams.size(); s++ ) + { + abEOF[s] = false; + } + + for( UInt frame = 0; frame < m_uiNumberOfFrames; frame++ ) + { + + if( m_pcCurrModuleIf->m_iModuleType == FRAME_PROCESSING_MODULE ) + { + switch( m_pcCurrModuleIf->m_uiNumberOfFrames ) + { + case MODULE_REQUIRES_ONE_FRAME: + pcProcessedFrame = m_pcCurrModuleIf->process( m_apcInputStreams[0]->getCurrFrame() ); + break; + case MODULE_REQUIRES_TWO_FRAMES: + pcProcessedFrame = m_pcCurrModuleIf->process( m_apcInputStreams[0]->getCurrFrame(), m_apcInputStreams[1]->getCurrFrame() ); + break; + } + } + else if( m_pcCurrModuleIf->m_iModuleType == FRAME_MEASUREMENT_MODULE ) + { + switch( m_pcCurrModuleIf->m_uiNumberOfFrames ) + { + case MODULE_REQUIRES_ONE_FRAME: + dMeasurementResult = m_pcCurrModuleIf->measure( m_apcInputStreams[0]->getCurrFrame() ); + break; + case MODULE_REQUIRES_TWO_FRAMES: + dMeasurementResult = m_pcCurrModuleIf->measure( m_apcInputStreams[0]->getCurrFrame(), m_apcInputStreams[1]->getCurrFrame() ); + break; + } + printf( " %3d %8.3f \n", frame, dMeasurementResult ); + dAveragedMeasurementResult = ( dAveragedMeasurementResult * Double( frame ) + dMeasurementResult ) / Double( frame + 1 ); + } + + for( UInt s = 0; s < m_apcInputStreams.size(); s++ ) + { + m_apcInputStreams[s]->setNextFrame(); + if( !abEOF[s] ) + { + m_apcInputStreams[s]->readFrame(); + abEOF[s] = m_apcInputStreams[s]->checkErrors( PlaYUVerStream::LAST_FRAME ); + } + } + } + + if( m_pcCurrModuleIf->m_iModuleType == FRAME_MEASUREMENT_MODULE ) + { + printf( "\n Mean Value: \n %8.3f\n", dAveragedMeasurementResult ); + } + + return 0; +} + } // NAMESPACE diff --git a/tools/PlaYUVerTools.h b/tools/PlaYUVerTools.h index 4d1464b..6082ad7 100644 --- a/tools/PlaYUVerTools.h +++ b/tools/PlaYUVerTools.h @@ -34,6 +34,8 @@ namespace plaYUVer { +class PlaYUVerModuleIf; + class PlaYUVerTools { public: @@ -48,7 +50,6 @@ private: CommandLineHandle m_cCommandLineParser; UInt m_uiOperation; - Int m_uiOperationIndex; enum TOOLS_OPERATIONS_LIST { INVALID_OPERATION, @@ -67,7 +68,12 @@ private: typedef Int (PlaYUVerTools::*FpProcess) (); FpProcess m_fpProcess; + + Int m_uiQualityMetric; Int QualityOperation(); + + PlaYUVerModuleIf* m_pcCurrModuleIf; + Int ModuleOperation(); }; } // NAMESPACE From c86a5faf70703ce3c4736591a3a5d78bc1bbcc0b Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Tue, 24 Feb 2015 03:16:45 +0000 Subject: [PATCH 17/39] Fix module list --- tools/CommandLineHandle.cpp | 65 ++++++++++++++++++++++--------------- tools/PlaYUVerTools.cpp | 1 + 2 files changed, 40 insertions(+), 26 deletions(-) diff --git a/tools/CommandLineHandle.cpp b/tools/CommandLineHandle.cpp index 18ac1e1..0c60759 100644 --- a/tools/CommandLineHandle.cpp +++ b/tools/CommandLineHandle.cpp @@ -52,8 +52,9 @@ Int CommandLineHandle::parseToolsArgs() po::options_description moduleOpts( "Module" ); moduleOpts.add_options() /**/ - ( "module", po::value(), "select a module" ) /**/ - ( "module_list", "list supported modules" ); + ( "module", po::value(), "select a module (use internal name)" ) /**/ + ( "module_list", "list supported modules" ) /**/ + ( "module_list_full", "detailed list supported modules" ); addOptions( qualityOpts ); addOptions( moduleOpts ); @@ -73,7 +74,7 @@ Int CommandLineHandle::parseToolsArgs() iRet = 1; } - if( getOptionsMap().count( "module_list" ) ) + if( getOptionsMap().count( "module_list" ) || getOptionsMap().count( "module_list_full" ) ) { listModules(); iRet = 1; @@ -84,45 +85,57 @@ Int CommandLineHandle::parseToolsArgs() Void CommandLineHandle::listModules() { + Bool bDetailed = false; + + if( getOptionsMap().count( "module_list_full" ) ) + bDetailed = true; + PlaYUVerModuleIf* pcCurrModuleIf; PlaYUVerModuleFactoryMap& PlaYUVerModuleFactoryMap = PlaYUVerModuleFactory::Get()->getMap(); PlaYUVerModuleFactoryMap::iterator it = PlaYUVerModuleFactoryMap.begin(); printf( "PlaYUVer available modules: \n" ); //printf( " " ); - printf( " [Name] " ); - printf( " [Type] " ); - printf( " [Description]" ); + printf( " [Internal Name] " ); + if( bDetailed ) + { + printf( " [Full Name] " ); + printf( " [Type] " ); + printf( " [Description]" ); + } printf( " \n" ); Char ModuleNameString[40]; for( UInt i = 0; it != PlaYUVerModuleFactoryMap.end(); ++it, i++ ) { - ModuleNameString[0] = '\0'; - - pcCurrModuleIf = it->second(); - printf( " " ); - if( pcCurrModuleIf->m_pchModuleCategory ) + printf( "%-30s", it->first ); + if( bDetailed ) { - strcat( ModuleNameString, pcCurrModuleIf->m_pchModuleCategory ); - strcat( ModuleNameString, "/" ); + ModuleNameString[0] = '\0'; + pcCurrModuleIf = it->second(); + + if( pcCurrModuleIf->m_pchModuleCategory ) + { + strcat( ModuleNameString, pcCurrModuleIf->m_pchModuleCategory ); + strcat( ModuleNameString, "/" ); + } + strcat( ModuleNameString, pcCurrModuleIf->m_pchModuleName ); + printf( " %-40s", ModuleNameString ); + switch( pcCurrModuleIf->m_iModuleType ) + { + case FRAME_PROCESSING_MODULE: + printf( " Processing " ); + break; + case FRAME_MEASUREMENT_MODULE: + printf( " Measurement " ); + break; + } + printf( " %s", pcCurrModuleIf->m_pchModuleTooltip ); + pcCurrModuleIf->Delete(); } - strcat( ModuleNameString, pcCurrModuleIf->m_pchModuleName ); - printf( "%-40s", ModuleNameString ); - switch( pcCurrModuleIf->m_iModuleType ) - { - case FRAME_PROCESSING_MODULE: - printf( " Processing " ); - break; - case FRAME_MEASUREMENT_MODULE: - printf( " Measurement " ); - break; - } - printf( " %s", pcCurrModuleIf->m_pchModuleTooltip ); printf( "\n" ); - pcCurrModuleIf->Delete(); } } diff --git a/tools/PlaYUVerTools.cpp b/tools/PlaYUVerTools.cpp index ab461a0..4f39716 100644 --- a/tools/PlaYUVerTools.cpp +++ b/tools/PlaYUVerTools.cpp @@ -319,6 +319,7 @@ Int PlaYUVerTools::ModuleOperation() abEOF[s] = m_apcInputStreams[s]->checkErrors( PlaYUVerStream::LAST_FRAME ); } } + } if( m_pcCurrModuleIf->m_iModuleType == FRAME_MEASUREMENT_MODULE ) From 659ce9fb8d3406394adf4d5234a5ceae7454260f Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Tue, 24 Feb 2015 11:03:42 +0000 Subject: [PATCH 18/39] Fix cmake file --- CMakeLists.txt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8418ee5..53a8fa4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -92,6 +92,10 @@ SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall" ) SET( CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g" ) SET( CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O2" ) + +ADD_FEATURE_INFO(PlaYUVerApp PLAYUVER_BUILD_TOOLS "Build Graphical Interface") +ADD_FEATURE_INFO(PlaYUVerTools PLAYUVER_BUILD_APP "Build Command line tool" ) + ADD_SUBDIRECTORY( lib ) ADD_SUBDIRECTORY( modules ) From c3a82f758b9636ae731fc32a023ccaf36484a027 Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Thu, 26 Feb 2015 15:26:18 +0000 Subject: [PATCH 19/39] Avoid using fillRGBBuffer when no necessary --- app/VideoHandle.cpp | 2 -- app/VideoSubWindow.cpp | 1 + lib/PlaYUVerFrame.cpp | 2 +- lib/PlaYUVerFrame.h | 54 +++++++++++++++++++++++++++++++++--------- lib/PlaYUVerStream.cpp | 8 ++++++- lib/PlaYUVerStream.h | 4 +++- 6 files changed, 55 insertions(+), 16 deletions(-) diff --git a/app/VideoHandle.cpp b/app/VideoHandle.cpp index c48200a..99f89e7 100644 --- a/app/VideoHandle.cpp +++ b/app/VideoHandle.cpp @@ -467,7 +467,6 @@ Void VideoHandle::stop() } } emit changed(); - //update(); m_arrayActions[VIDEO_LOCK_ACT]->setVisible( false ); } @@ -496,7 +495,6 @@ Void VideoHandle::playEvent() m_pcCurrentVideoSubWindow->close(); } emit changed(); - //update(); } Void VideoHandle::seekEvent( Int direction ) diff --git a/app/VideoSubWindow.cpp b/app/VideoSubWindow.cpp index caedd80..c245d30 100644 --- a/app/VideoSubWindow.cpp +++ b/app/VideoSubWindow.cpp @@ -459,6 +459,7 @@ Bool VideoSubWindow::playEvent() return true; } m_pCurrStream->readFrame(); + m_pCurrStream->getNextFrame()->fillRGBBuffer(); } return false; } diff --git a/lib/PlaYUVerFrame.cpp b/lib/PlaYUVerFrame.cpp index e546cba..15af2f8 100644 --- a/lib/PlaYUVerFrame.cpp +++ b/lib/PlaYUVerFrame.cpp @@ -163,7 +163,7 @@ Void PlaYUVerFrame::frameFromBuffer( Pel *Buff, UInt64 uiBuffSize ) m_pcPelFormat->frameFromBuffer( Buff, m_pppcInputPel, m_uiWidth, m_uiHeight ); m_bHasRGBPel = false; m_bHasHistogram = false; - fillRGBBuffer(); + //fillRGBBuffer(); } Void PlaYUVerFrame::frameToBuffer( Pel *output_buffer ) diff --git a/lib/PlaYUVerFrame.h b/lib/PlaYUVerFrame.h index d0562a4..c301331 100644 --- a/lib/PlaYUVerFrame.h +++ b/lib/PlaYUVerFrame.h @@ -37,7 +37,7 @@ class PixFcSSE; namespace plaYUVer { -class PlaYUVerFrame : public PlaYUVerFrameStats +class PlaYUVerFrame: public PlaYUVerFrameStats { public: class Pixel @@ -60,14 +60,38 @@ public: PixelComponents[1] = c1; PixelComponents[2] = c2; } - Int ColorSpace() { return m_iColorSpace; } - Pel* Components() { return PixelComponents; } - Pel& Y() { return PixelComponents[0]; } - Pel& Cb() { return PixelComponents[1]; } - Pel& Cr() { return PixelComponents[2]; } - Pel& R() { return PixelComponents[0]; } - Pel& G() { return PixelComponents[1]; } - Pel& B() { return PixelComponents[2]; } + Int ColorSpace() + { + return m_iColorSpace; + } + Pel* Components() + { + return PixelComponents; + } + Pel& Y() + { + return PixelComponents[0]; + } + Pel& Cb() + { + return PixelComponents[1]; + } + Pel& Cr() + { + return PixelComponents[2]; + } + Pel& R() + { + return PixelComponents[0]; + } + Pel& G() + { + return PixelComponents[1]; + } + Pel& B() + { + return PixelComponents[2]; + } }; enum ColorSpace @@ -161,8 +185,16 @@ public: m_bHasRGBPel = false; return m_pppcInputPel; } - UChar* getRGBBuffer() const +// UChar* getRGBBuffer() const +// { +// return m_pcRGB32; +// } + UChar* getRGBBuffer() { + if( !m_bHasRGBPel ) + { + fillRGBBuffer(); + } return m_pcRGB32; } @@ -185,7 +217,7 @@ public: NUMBER_METRICS, }; - static std::vector supportedQualityMetricsList() + static std::vector supportedQualityMetricsList() { std::vector metrics; metrics.push_back( "PSNR" ); diff --git a/lib/PlaYUVerStream.cpp b/lib/PlaYUVerStream.cpp index 79225a8..0021a8e 100644 --- a/lib/PlaYUVerStream.cpp +++ b/lib/PlaYUVerStream.cpp @@ -514,7 +514,7 @@ Void PlaYUVerStream::readFrame() } m_pcNextFrame->frameFromBuffer( m_pStreamBuffer, bytes_read ); } - m_pcNextFrame->fillRGBBuffer(); + //m_pcNextFrame->fillRGBBuffer(); return; } @@ -639,6 +639,12 @@ PlaYUVerFrame* PlaYUVerStream::getCurrFrame() return m_pcCurrFrame; } +PlaYUVerFrame* PlaYUVerStream::getNextFrame() +{ + return m_pcNextFrame; +} + + Bool PlaYUVerStream::seekInput( UInt64 new_frame_num ) { if( !m_bInit || new_frame_num < 0 || new_frame_num >= m_uiTotalFrameNum || ( Int64 )new_frame_num == m_iCurrFrameNum ) diff --git a/lib/PlaYUVerStream.h b/lib/PlaYUVerStream.h index 09245ef..7c26796 100644 --- a/lib/PlaYUVerStream.h +++ b/lib/PlaYUVerStream.h @@ -134,8 +134,10 @@ public: static Bool saveFrame( const std::string& filename, PlaYUVerFrame *saveFrame ); Void setNextFrame(); - PlaYUVerFrame* getCurrFrame(); + PlaYUVerFrame* getCurrFrame( PlaYUVerFrame * ); + PlaYUVerFrame* getCurrFrame(); + PlaYUVerFrame* getNextFrame(); Bool seekInput( UInt64 new_frame_num ); From f4b9f4d4f480d449c18cc45269419738872c906d Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Thu, 26 Feb 2015 15:30:38 +0000 Subject: [PATCH 20/39] Remove cmake_policy_set not compatible with older versions --- CMakeLists.txt | 2 -- 1 file changed, 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e88edcf..7a2eb93 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,8 +30,6 @@ IF(DEFINED CMAKE_BUILD_TYPE AND CMAKE_VERSION VERSION_GREATER "2.8") ENDIF() SET( CMAKE_CXX_FLAGS "" ) -cmake_policy(SET CMP0043 NEW) - ###################################################################################### # Variables ###################################################################################### From fa8e3b49cd851766fd6827519bc6db173a26e44c Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Thu, 26 Feb 2015 16:39:45 +0000 Subject: [PATCH 21/39] Add debugging routines for Fps --- app/VideoHandle.cpp | 3 +++ app/VideoHandle.h | 9 +++++++++ lib/PlaYUVerFramePixelFormats.h | 4 ++-- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/app/VideoHandle.cpp b/app/VideoHandle.cpp index 99f89e7..0446158 100644 --- a/app/VideoHandle.cpp +++ b/app/VideoHandle.cpp @@ -27,6 +27,9 @@ #include "PlaYUVerSubWindowHandle.h" #include "VideoHandle.h" #include "DialogSubWindowSelector.h" +#if( _CONTROL_PLAYING_TIME_ == 1 ) +#include +#endif namespace plaYUVer { diff --git a/app/VideoHandle.h b/app/VideoHandle.h index df11798..3383168 100644 --- a/app/VideoHandle.h +++ b/app/VideoHandle.h @@ -36,6 +36,10 @@ #include "WidgetFrameNumber.h" #include "FramePropertiesSidebar.h" +#define _CONTROL_PLAYING_TIME_ 1 + +class QElapsedTimer; + namespace plaYUVer { @@ -99,6 +103,11 @@ private: QTimer *m_pcPlayingTimer; Bool m_bIsPlaying; +#if( _CONTROL_PLAYING_TIME_ == 1 ) + UInt m_uiNumberPlayedFrames; + Double m_dAverageFps; + QElapsedTimer* m_pcPlayControlTimer; +#endif UInt64 getMaxFrameNumber(); Void setTimerStatus(); diff --git a/lib/PlaYUVerFramePixelFormats.h b/lib/PlaYUVerFramePixelFormats.h index 82a2bb2..7185131 100644 --- a/lib/PlaYUVerFramePixelFormats.h +++ b/lib/PlaYUVerFramePixelFormats.h @@ -33,7 +33,7 @@ namespace plaYUVer { template -Void yuvToRgb( T iY, T iU, T iV, T &iR, T &iG, T &iB ) +static inline Void yuvToRgb( T iY, T iU, T iV, T &iR, T &iG, T &iB ) { iR = iY + 1402 * iV / 1000; iG = iY - ( 101004 * iU + 209599 * iV ) / 293500; @@ -55,7 +55,7 @@ Void yuvToRgb( T iY, T iU, T iV, T &iR, T &iG, T &iB ) } template -Void rgbToYuv( T iR, T iG, T iB, T &iY, T &iU, T &iV ) +static inline Void rgbToYuv( T iR, T iG, T iB, T &iY, T &iU, T &iV ) { iY = ( 299 * iR + 587 * iG + 114 * iB + 500 ) / 1000; iU = ( 1000 * ( iB - iY ) + 226816 ) / 1772; From a37c5359859300586d7c591b8b3ca8472de3602f Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Thu, 26 Feb 2015 17:24:05 +0000 Subject: [PATCH 22/39] Do not fillRGBBuffer in last frame --- app/VideoSubWindow.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/VideoSubWindow.cpp b/app/VideoSubWindow.cpp index c245d30..c83bd20 100644 --- a/app/VideoSubWindow.cpp +++ b/app/VideoSubWindow.cpp @@ -459,7 +459,8 @@ Bool VideoSubWindow::playEvent() return true; } m_pCurrStream->readFrame(); - m_pCurrStream->getNextFrame()->fillRGBBuffer(); + if( m_pCurrStream->getNextFrame() ) + m_pCurrStream->getNextFrame()->fillRGBBuffer(); } return false; } From c24e71bf5539e27c43b85cdf5bd9bff58497f50f Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Fri, 27 Feb 2015 01:01:04 +0000 Subject: [PATCH 23/39] Minor changes and code format --- app/VideoHandle.cpp | 24 +++++++++++------------- lib/PlaYUVerFrame.cpp | 4 ++-- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/app/VideoHandle.cpp b/app/VideoHandle.cpp index a36636c..4e39229 100644 --- a/app/VideoHandle.cpp +++ b/app/VideoHandle.cpp @@ -327,16 +327,16 @@ Void VideoHandle::moveAllScrollBars( const QPoint offset ) scrollBar = m_pcCurrentVideoSubWindow->horizontalScrollBar(); // Do not move other images, if current image reached maximum or minimum scroll position - if(scrollBar->value()==scrollBar->maximum() && offset.x()>0) - newOffset.setX(0); - if(scrollBar->value()==scrollBar->minimum() && offset.x()<0) - newOffset.setX(0); + if( scrollBar->value() == scrollBar->maximum() && offset.x() > 0 ) + newOffset.setX( 0 ); + if( scrollBar->value() == scrollBar->minimum() && offset.x() < 0 ) + newOffset.setX( 0 ); scrollBar = m_pcCurrentVideoSubWindow->verticalScrollBar(); - if(scrollBar->value()==scrollBar->maximum() && offset.y()>0) - newOffset.setY(0); - if(scrollBar->value()==scrollBar->minimum() && offset.y()<0) - newOffset.setY(0); + if( scrollBar->value() == scrollBar->maximum() && offset.y() > 0 ) + newOffset.setY( 0 ); + if( scrollBar->value() == scrollBar->minimum() && offset.y() < 0 ) + newOffset.setY( 0 ); for( Int i = 0; i < subWindowList.size(); i++ ) { @@ -505,16 +505,14 @@ 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 ); - //statusBar()->showMessage( warningMsg, 2000 ); qDebug( ) << warningMsg; stop(); m_pcCurrentVideoSubWindow->close(); } #if( _CONTROL_PLAYING_TIME_ == 1 ) - m_dAverageFps = Double( m_dAverageFps * m_uiNumberPlayedFrames + m_pcPlayControlTimer->elapsed() ) - / Double( m_uiNumberPlayedFrames + 1 ); - m_uiNumberPlayedFrames++; - m_pcPlayControlTimer->restart(); + m_dAverageFps = Double( m_dAverageFps * m_uiNumberPlayedFrames + m_pcPlayControlTimer->elapsed() ) / Double( m_uiNumberPlayedFrames + 1 ); + m_uiNumberPlayedFrames++; + m_pcPlayControlTimer->restart(); #endif emit changed(); } diff --git a/lib/PlaYUVerFrame.cpp b/lib/PlaYUVerFrame.cpp index 15af2f8..4913562 100644 --- a/lib/PlaYUVerFrame.cpp +++ b/lib/PlaYUVerFrame.cpp @@ -249,14 +249,14 @@ PlaYUVerFrame::Pixel PlaYUVerFrame::ConvertPixel( PlaYUVerFrame::Pixel inputPixe if( eOutputSpace == COLOR_RGB ) { - yuvToRgb( inputPixel.Y(), inputPixel.Cb(), inputPixel.Cr(), outA, outB, outC ); + yuvToRgb( inputPixel.Y(), inputPixel.Cb(), inputPixel.Cr(), outA, outB, outC ); outPixel.R() = outA; outPixel.G() = outB; outPixel.B() = outC; } if( eOutputSpace == COLOR_YUV ) { - rgbToYuv( inputPixel.R(), inputPixel.G(), inputPixel.B(), outA, outB, outC ); + rgbToYuv( inputPixel.R(), inputPixel.G(), inputPixel.B(), outA, outB, outC ); outPixel.Y() = outA; outPixel.Cb() = outB; outPixel.Cr() = outC; From eac8f23798a496870f29ce48bd6ca17c313f9bb2 Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Fri, 27 Feb 2015 01:01:19 +0000 Subject: [PATCH 24/39] Remove template functions --- lib/PlaYUVerFramePixelFormats.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/PlaYUVerFramePixelFormats.h b/lib/PlaYUVerFramePixelFormats.h index 7185131..9b57c5f 100644 --- a/lib/PlaYUVerFramePixelFormats.h +++ b/lib/PlaYUVerFramePixelFormats.h @@ -32,8 +32,7 @@ namespace plaYUVer { -template -static inline Void yuvToRgb( T iY, T iU, T iV, T &iR, T &iG, T &iB ) +static inline Void yuvToRgb( Int iY, Int iU, Int iV, Int &iR, Int &iG, Int &iB ) { iR = iY + 1402 * iV / 1000; iG = iY - ( 101004 * iU + 209599 * iV ) / 293500; @@ -54,8 +53,7 @@ static inline Void yuvToRgb( T iY, T iU, T iV, T &iR, T &iG, T &iB ) iB = 255; } -template -static inline Void rgbToYuv( T iR, T iG, T iB, T &iY, T &iU, T &iV ) +static inline Void rgbToYuv( Int iR, Int iG, Int iB, Int &iY, Int &iU, Int &iV ) { iY = ( 299 * iR + 587 * iG + 114 * iB + 500 ) / 1000; iU = ( 1000 * ( iB - iY ) + 226816 ) / 1772; From 6bc2406e3ad141db47948902212607fcb67d58d1 Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Fri, 27 Feb 2015 13:57:40 +0000 Subject: [PATCH 25/39] Optimize pixel conversion from yuv to rgb --- lib/PlaYUVerFrame.cpp | 2 +- lib/PlaYUVerFramePixelFormats.cpp | 44 +++++++++++++++++++------------ lib/PlaYUVerFramePixelFormats.h | 32 ++++++---------------- 3 files changed, 36 insertions(+), 42 deletions(-) diff --git a/lib/PlaYUVerFrame.cpp b/lib/PlaYUVerFrame.cpp index 4913562..e90a383 100644 --- a/lib/PlaYUVerFrame.cpp +++ b/lib/PlaYUVerFrame.cpp @@ -249,7 +249,7 @@ PlaYUVerFrame::Pixel PlaYUVerFrame::ConvertPixel( PlaYUVerFrame::Pixel inputPixe if( eOutputSpace == COLOR_RGB ) { - yuvToRgb( inputPixel.Y(), inputPixel.Cb(), inputPixel.Cr(), outA, outB, outC ); + YUV2RGB( inputPixel.Y(), inputPixel.Cb(), inputPixel.Cr(), outA, outB, outC ); outPixel.R() = outA; outPixel.G() = outB; outPixel.B() = outC; diff --git a/lib/PlaYUVerFramePixelFormats.cpp b/lib/PlaYUVerFramePixelFormats.cpp index ddce223..df05e68 100644 --- a/lib/PlaYUVerFramePixelFormats.cpp +++ b/lib/PlaYUVerFramePixelFormats.cpp @@ -67,23 +67,34 @@ Void bufferFromFrameYUVProgressive( Pel*** in, Pel *out, UInt width, UInt height Void fillRGBbufferYUV( Pel*** in, UChar* out, UInt width, UInt height, UInt ratioChromaHor, UInt ratioChromaVer ) { - Pel** pY = in[LUMA]; - Pel** pU = in[CHROMA_U]; - Pel** pV = in[CHROMA_V]; + Pel* pY = in[LUMA][0]; + Pel* pU = in[CHROMA_U][0]; + Pel* pV = in[CHROMA_V][0]; Int iY, iU, iV, iR, iG, iB; UInt* buff = ( UInt* )out; - for( UInt y = 0; y < height; y++ ) + pU -= width >> ratioChromaHor; + pV -= width >> ratioChromaHor; + for( UInt y = 0; y < height >> ratioChromaVer; y++ ) { - for( UInt x = 0; x < width; x++ ) + pU += width >> ratioChromaHor; + pV += width >> ratioChromaHor; + for( Int i = 0; i < 1 << ratioChromaVer; i++ ) { - // Pixel (x, y). - iY = pY[y][x]; - iU = pU[y >> ratioChromaVer][x >> ratioChromaHor] - 128; - iV = pV[y >> ratioChromaVer][x >> ratioChromaHor] - 128; - yuvToRgb( iY, iU, iV, iR, iG, iB ); - *buff = pelRgb( iR, iG, iB ); - buff++; + for( UInt x = 0; x < width >> ratioChromaHor; x++ ) + { + iU = *pU++ - 128; + iV = *pV++ - 128; + for( Int j = 0; j < 1 << ratioChromaHor; j++ ) + { + iY = *pY++; + YUV2RGB( iY, iU, iV, iR, iG, iB ); + *buff = PEL_RGB( iR, iG, iB ); + buff++; + } + } + pU -= width >> ratioChromaHor; + pV -= width >> ratioChromaHor; } } } @@ -234,7 +245,7 @@ Void fillRGBbufferGray( Pel*** in, UChar* out, UInt width, UInt height ) for( UInt i = 0; i < height * width; i++ ) { iY = *inPel; - *buff++ = pelRgb( iY, iY, iY ); + *buff++ = PEL_RGB( iY, iY, iY ); inPel++; } } @@ -259,9 +270,9 @@ Void frameFromBufferRGB( Pel *in, Pel*** out, UInt64 size, Pel* pFirst, Pel* pSe { for( UInt i = 0; i < size; i++ ) { - *pFirst++ = *in++; + *pFirst++ = *in++; *pSecond++ = *in++; - *pthird++ = *in++; + *pthird++ = *in++; } } Void bufferFromFrameRGB( Pel ***in, Pel* out, UInt64 size, Pel* pFirst, Pel* pSecond, Pel* pthird ) @@ -285,7 +296,7 @@ Void fillRGBbufferRGB( Pel*** in, UChar* out, UInt width, UInt height ) iR = *pR++; iG = *pG++; iB = *pB++; - *buff++ = pelRgb( iR, iG, iB ); + *buff++ = PEL_RGB( iR, iG, iB ); } } @@ -343,5 +354,4 @@ PlaYUVerFramePelFormat g_PlaYUVerFramePelFormatsList[PLAYUVER_NUMBER_FORMATS] = RGB24, BGR24, }; - } // NAMESPACE diff --git a/lib/PlaYUVerFramePixelFormats.h b/lib/PlaYUVerFramePixelFormats.h index 9b57c5f..b3439ea 100644 --- a/lib/PlaYUVerFramePixelFormats.h +++ b/lib/PlaYUVerFramePixelFormats.h @@ -22,7 +22,6 @@ * \brief Handling the pixel formats definition */ - #ifndef __PLAYUVERFRAMEPIXELFORMATS_H__ #define __PLAYUVERFRAMEPIXELFORMATS_H__ @@ -32,26 +31,13 @@ namespace plaYUVer { -static inline Void yuvToRgb( Int iY, Int iU, Int iV, Int &iR, Int &iG, Int &iB ) -{ - iR = iY + 1402 * iV / 1000; - iG = iY - ( 101004 * iU + 209599 * iV ) / 293500; - iB = iY + 1772 * iU / 1000; +#define CLAMP(X) X = X < 0 ? 0 : X > 255 ? 255 : X; - if( iR < 0 ) - iR = 0; - if( iG < 0 ) - iG = 0; - if( iB < 0 ) - iB = 0; - - if( iR > 255 ) - iR = 255; - if( iG > 255 ) - iG = 255; - if( iB > 255 ) - iB = 255; -} +#define YUV2RGB( iY, iU, iV, iR, iG, iB ) \ + iR = iY + ( ( 1436 * iV ) >> 10 ); \ + iG = iY - ( ( 352 * iU + 731 * iV ) >> 10 ); \ + iB = iY + ( ( 1812 * iU ) >> 10 ); \ + CLAMP(iR) CLAMP(iG) CLAMP(iB) static inline Void rgbToYuv( Int iR, Int iG, Int iB, Int &iY, Int &iU, Int &iV ) { @@ -80,10 +66,8 @@ inline Int pelAlpha( UInt rgb ) // get alpha part of RGBA return rgb >> 24; } -inline UInt pelRgb( Int r, Int g, Int b ) // set RGB value -{ - return ( 0xffu << 24 ) | ( ( r & 0xff ) << 16 ) | ( ( g & 0xff ) << 8 ) | ( b & 0xff ); -} +#define PEL_RGB( r, g, b ) \ + ( 0xffu << 24 ) | ( ( r & 0xff ) << 16 ) | ( ( g & 0xff ) << 8 ) | ( b & 0xff ) struct structPlaYUVerFramePelFormat { From fc8e6be9bc373a487f0e2dd7db827924c9a26047 Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Tue, 3 Mar 2015 00:21:44 +0000 Subject: [PATCH 26/39] Fix if statment --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 083f2f9..f7659a7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -98,11 +98,11 @@ ADD_FEATURE_INFO(PlaYUVerTools PLAYUVER_BUILD_APP "Build Command line too ADD_SUBDIRECTORY( lib ) ADD_SUBDIRECTORY( modules ) -IF( PLAYUVER_BUILD_TOOLS ) +IF( ${PLAYUVER_BUILD_TOOLS} ) ADD_SUBDIRECTORY( tools ) ENDIF() -IF( PLAYUVER_BUILD_APP ) +IF( ${PLAYUVER_BUILD_APP} ) ADD_SUBDIRECTORY( app ) ENDIF() From 5262b4f14fb072f0d9325fb7e8f4ffdb5424fe7b Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Tue, 3 Mar 2015 00:43:26 +0000 Subject: [PATCH 27/39] Add support for QtConcurrent --- app/CMakeLists.txt | 6 +++--- app/VideoSubWindow.cpp | 9 +++++++++ app/VideoSubWindow.h | 7 +++++++ lib/PlaYUVerStream.cpp | 3 +-- 4 files changed, 20 insertions(+), 5 deletions(-) diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index be5c85a..080403a 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -30,10 +30,10 @@ IF( USE_QT4 ) ENDIF() IF( NOT USE_QT4 ) - FIND_PACKAGE( Qt5 REQUIRED COMPONENTS Core Gui Widgets PrintSupport ) + FIND_PACKAGE( Qt5 REQUIRED COMPONENTS Core Gui Widgets PrintSupport Concurrent ) FIND_PACKAGE( Qt5DBus ) - LIST(APPEND QT_LINKER_LIBS Qt5::Core Qt5::Gui Qt5::Widgets Qt5::PrintSupport ) - LIST(APPEND QT_MODULES Core Gui Widgets ) + LIST(APPEND QT_LINKER_LIBS Qt5::Core Qt5::Gui Qt5::Widgets Qt5::PrintSupport Qt5::Concurrent ) + LIST(APPEND QT_MODULES Core Gui Widgets PrintSupport Concurrent ) IF( ${Qt5DBus_FOUND} ) SET( USE_QTDBUS ${Qt5DBus_FOUND} ) LIST(APPEND QT_LINKER_LIBS Qt5::DBus ) diff --git a/app/VideoSubWindow.cpp b/app/VideoSubWindow.cpp index 74a383b..f1c48d2 100644 --- a/app/VideoSubWindow.cpp +++ b/app/VideoSubWindow.cpp @@ -454,16 +454,25 @@ Bool VideoSubWindow::play() return m_bIsPlaying; } +#include "QtConcurrent/qtconcurrentrun.h" + Bool VideoSubWindow::playEvent() { Bool bEndOfSeq = false; if( m_pCurrStream && m_bIsPlaying ) { +#ifndef QT_NO_CONCURRENT + m_cReadResult.waitForFinished(); +#endif bEndOfSeq = m_pCurrStream->setNextFrame(); if( !bEndOfSeq ) { refreshFrame(); +#ifndef QT_NO_CONCURRENT + m_cReadResult = QtConcurrent::run(m_pCurrStream, &PlaYUVerStream::readFrame); +#else m_pCurrStream->readFrame(); +#endif } } return bEndOfSeq; diff --git a/app/VideoSubWindow.h b/app/VideoSubWindow.h index 6000295..a6fe546 100644 --- a/app/VideoSubWindow.h +++ b/app/VideoSubWindow.h @@ -32,6 +32,7 @@ #elif( QT_VERSION_PLAYUVER == 4 ) #include #endif +#include "QFuture" #include "lib/PlaYUVerStream.h" #include "SubWindowHandle.h" #include "ViewArea.h" @@ -83,6 +84,12 @@ private: Bool m_bIsPlaying; Bool m_bIsModule; + /** + * Threads variables + * QtConcurrent + */ + QFuture m_cReadResult; + static Bool guessFormat( QString filename, UInt& rWidth, UInt& rHeight, Int& rInputFormat, UInt& rFrameRate ); /** diff --git a/lib/PlaYUVerStream.cpp b/lib/PlaYUVerStream.cpp index ad364e4..dd87108 100644 --- a/lib/PlaYUVerStream.cpp +++ b/lib/PlaYUVerStream.cpp @@ -481,7 +481,7 @@ Void PlaYUVerStream::readFrame() if( !m_bInit || !m_bIsInput || m_bLoadAll ) return; - if( m_uiCurrFrameFileIdx >= Int64( m_uiTotalFrameNum ) ) + if( m_uiCurrFrameFileIdx >= m_uiTotalFrameNum ) { m_pcNextFrame = NULL; return; @@ -641,7 +641,6 @@ PlaYUVerFrame* PlaYUVerStream::getNextFrame() return m_pcNextFrame; } - Bool PlaYUVerStream::seekInput( UInt64 new_frame_num ) { if( !m_bInit || new_frame_num < 0 || new_frame_num >= m_uiTotalFrameNum || ( Int64 )new_frame_num == m_iCurrFrameNum ) From fd8b649ef078f57c9b9f0c6abe6a5069a25d0bc9 Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Tue, 3 Mar 2015 01:13:13 +0000 Subject: [PATCH 28/39] Fix missing header in modules factory --- modules/CMakeLists.txt | 2 +- modules/PlaYUVerModuleFactory.cpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/CMakeLists.txt b/modules/CMakeLists.txt index d420f11..1dce7dd 100644 --- a/modules/CMakeLists.txt +++ b/modules/CMakeLists.txt @@ -4,7 +4,7 @@ OPTION( MODULE_THREADED_MODULES "Use threads for modules" OFF ) -INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_SOURCE_DIR}/../ ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ) +INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_SOURCE_DIR}/../ ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/../ ) set(plaYUver_Mod_SRCS PlaYUVerModuleFactory.cpp diff --git a/modules/PlaYUVerModuleFactory.cpp b/modules/PlaYUVerModuleFactory.cpp index 48ecf55..3007499 100644 --- a/modules/PlaYUVerModuleFactory.cpp +++ b/modules/PlaYUVerModuleFactory.cpp @@ -22,6 +22,7 @@ * \brief PlaYUVer modules factory */ +#include "config.h" #include #include #include "PlaYUVerModuleFactory.h" From 159b33a74ffb26059d345e00e838f6ef832468da Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Tue, 3 Mar 2015 01:13:36 +0000 Subject: [PATCH 29/39] Add new function to read and fill rgb buffer operation --- lib/PlaYUVerStream.cpp | 8 +++++++- lib/PlaYUVerStream.h | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/PlaYUVerStream.cpp b/lib/PlaYUVerStream.cpp index dd87108..cfdae4d 100644 --- a/lib/PlaYUVerStream.cpp +++ b/lib/PlaYUVerStream.cpp @@ -476,6 +476,13 @@ Void PlaYUVerStream::getDuration( Int* duration_array ) *duration_array++ = secs; } +Void PlaYUVerStream::readFrameFillRGBBuffer() +{ + readFrame(); + m_pcNextFrame->fillRGBBuffer(); + return; +} + Void PlaYUVerStream::readFrame() { if( !m_bInit || !m_bIsInput || m_bLoadAll ) @@ -510,7 +517,6 @@ Void PlaYUVerStream::readFrame() m_pcNextFrame->frameFromBuffer( m_pStreamBuffer, bytes_read ); } m_uiCurrFrameFileIdx++; - m_pcNextFrame->fillRGBBuffer(); return; } diff --git a/lib/PlaYUVerStream.h b/lib/PlaYUVerStream.h index 7b56503..dfe9f82 100644 --- a/lib/PlaYUVerStream.h +++ b/lib/PlaYUVerStream.h @@ -127,6 +127,7 @@ public: Void loadAll(); Void readFrame(); + Void readFrameFillRGBBuffer(); Void writeFrame(); Void writeFrame( PlaYUVerFrame *pcFrame ); From f3ffac6d9fb758528633fcc2a5e6792667c8c1de Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Tue, 3 Mar 2015 01:14:03 +0000 Subject: [PATCH 30/39] Add support to refresh frame in a different thread - currently disable --- app/VideoSubWindow.cpp | 33 ++++++++++++++++++++++++--------- app/VideoSubWindow.h | 7 +++++-- 2 files changed, 29 insertions(+), 11 deletions(-) diff --git a/app/VideoSubWindow.cpp b/app/VideoSubWindow.cpp index f1c48d2..3a50280 100644 --- a/app/VideoSubWindow.cpp +++ b/app/VideoSubWindow.cpp @@ -26,6 +26,7 @@ #include "ModulesHandle.h" #include "SubWindowHandle.h" #include "ConfigureFormatDialog.h" +#include "QtConcurrent/qtconcurrentrun.h" namespace plaYUVer { @@ -399,7 +400,7 @@ Void VideoSubWindow::setCurrFrame( PlaYUVerFrame* pcCurrFrame ) m_cViewArea->setImage( m_pcCurrFrame ); } -Void VideoSubWindow::refreshFrame() +Void VideoSubWindow::refreshFrameOperation() { Bool bSetFrame = false; if( m_pCurrStream ) @@ -422,6 +423,21 @@ Void VideoSubWindow::refreshFrame() } } +Void VideoSubWindow::refreshFrame( Bool bThreaded ) +{ +#ifndef QT_NO_CONCURRENT + m_cRefreshResult.waitForFinished(); + if( bThreaded ) + { + m_cRefreshResult = QtConcurrent::run( this, &VideoSubWindow::refreshFrameOperation ); + } + else +#endif + { + refreshFrameOperation(); + } +} + Bool VideoSubWindow::save( QString filename ) { Bool iRet = false; @@ -454,14 +470,13 @@ Bool VideoSubWindow::play() return m_bIsPlaying; } -#include "QtConcurrent/qtconcurrentrun.h" - 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(); @@ -469,9 +484,9 @@ Bool VideoSubWindow::playEvent() { refreshFrame(); #ifndef QT_NO_CONCURRENT - m_cReadResult = QtConcurrent::run(m_pCurrStream, &PlaYUVerStream::readFrame); + m_cReadResult = QtConcurrent::run( m_pCurrStream, &PlaYUVerStream::readFrameFillRGBBuffer ); #else - m_pCurrStream->readFrame(); + m_pCurrStream->readFrameFillRGBBuffer(); #endif } } @@ -527,7 +542,7 @@ Void VideoSubWindow::normalSize() Void VideoSubWindow::zoomToFit() { - // Scale to a smaller size that the real to a nicer look +// Scale to a smaller size that the real to a nicer look scaleView( getScrollSize() ); } @@ -564,7 +579,7 @@ Void VideoSubWindow::scaleView( const QSize & size, QPoint center ) QSize newSize = imgViewSize; newSize.scale( size, Qt::KeepAspectRatio ); - // Calc the zoom factor +// Calc the zoom factor Double wfactor = 1; Double hfactor = 1; Double factor; @@ -649,8 +664,8 @@ QSize VideoSubWindow::sizeHint( const QSize & maxSize ) const else if( m_pCurrStream ) isize = QSize( m_pCurrStream->getWidth() + 50, m_pCurrStream->getHeight() + 50 ); - // If the VideoSubWindow needs more space that the avaiable, we'll give - // to the subwindow a reasonable size preserving the image aspect ratio. +// If the VideoSubWindow needs more space that the avaiable, we'll give +// to the subwindow a reasonable size preserving the image aspect ratio. if( !( isize.width() < maxSize.width() && isize.height() < maxSize.height() ) ) { isize.scale( maxSize, Qt::KeepAspectRatio ); diff --git a/app/VideoSubWindow.h b/app/VideoSubWindow.h index a6fe546..fd9c2e5 100644 --- a/app/VideoSubWindow.h +++ b/app/VideoSubWindow.h @@ -88,8 +88,12 @@ private: * Threads variables * QtConcurrent */ + QFuture m_cRefreshResult; QFuture m_cReadResult; + Void refreshFrame( Bool bThreaded = false ); + Void refreshFrameOperation(); + static Bool guessFormat( QString filename, UInt& rWidth, UInt& rHeight, Int& rInputFormat, UInt& rFrameRate ); /** @@ -111,7 +115,7 @@ public: Bool loadFile( QString cFilename, Bool bForceDialog = false ); Bool loadFile( PlaYUVerStreamInfo* streamInfo ); - Void loadAll( ); + Void loadAll(); Void reloadFile(); Bool save( QString filename ); @@ -128,7 +132,6 @@ public: Void seekAbsoluteEvent( UInt new_frame_num ); Void seekRelativeEvent( Bool bIsFoward ); - Void refreshFrame(); Void setCurrFrame( PlaYUVerFrame* pcCurrFrame ); PlaYUVerStreamInfo getStreamInfo() From ee8f0c65d480be1e21819eff75db33ee0d3d643a Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Thu, 5 Mar 2015 01:07:28 +0000 Subject: [PATCH 31/39] Fix minor errors when loading images with opencv --- lib/LibOpenCVHandler.cpp | 24 ++++++---- lib/LibOpenCVHandler.h | 2 +- lib/PlaYUVerStream.cpp | 100 ++++++++++++++++++++++++++------------- 3 files changed, 82 insertions(+), 44 deletions(-) diff --git a/lib/LibOpenCVHandler.cpp b/lib/LibOpenCVHandler.cpp index 290bcb4..7d2aa6e 100644 --- a/lib/LibOpenCVHandler.cpp +++ b/lib/LibOpenCVHandler.cpp @@ -83,22 +83,22 @@ std::vector LibOpenCVHandler::supportedSaveFormatsName() return formatsName; } -Bool LibOpenCVHandler::loadFrame( PlaYUVerFrame* pcFrame, std::string filename ) +PlaYUVerFrame* LibOpenCVHandler::loadFrame( std::string filename ) { cv::Mat pcCvFrame = cv::imread( filename ); - + Int cvChannels = pcCvFrame.channels(); std::string pelFormatName; - Int iPelFormat; - switch( pcCvFrame.channels() ) + Int iPelFormat = -1; + switch( cvChannels ) { case 1: pelFormatName = "GRAY"; break; - case 4: - pelFormatName = "RGB8"; + case 3: + pelFormatName = "BRG24"; break; default: - return false; + return NULL; } for( UInt i = 0; i < PlaYUVerFrame::supportedPixelFormatListNames().size(); i++ ) @@ -109,12 +109,18 @@ Bool LibOpenCVHandler::loadFrame( PlaYUVerFrame* pcFrame, std::string filename ) break; } } - return true; + + if( iPelFormat >= 0 ) + { + PlaYUVerFrame* pcFrame = new PlaYUVerFrame( pcCvFrame.cols, pcCvFrame.rows, iPelFormat ); + pcFrame->frameFromBuffer( pcCvFrame.ptr(), pcFrame->getBytesPerFrame() ); + return pcFrame; + } + return NULL; } Bool LibOpenCVHandler::saveFrame( PlaYUVerFrame* pcFrame, std::string filename ) { - Int cvType = CV_8UC3; switch( pcFrame->getNumberChannels() ) { diff --git a/lib/LibOpenCVHandler.h b/lib/LibOpenCVHandler.h index 7acd81e..d24cd76 100644 --- a/lib/LibOpenCVHandler.h +++ b/lib/LibOpenCVHandler.h @@ -51,7 +51,7 @@ public: { } - static Bool loadFrame( PlaYUVerFrame* pcFrame, std::string filename ); + static PlaYUVerFrame* loadFrame( std::string filename ); static Bool saveFrame( PlaYUVerFrame* pcFrame, std::string filename ); private: diff --git a/lib/PlaYUVerStream.cpp b/lib/PlaYUVerStream.cpp index e43c006..bf999db 100644 --- a/lib/PlaYUVerStream.cpp +++ b/lib/PlaYUVerStream.cpp @@ -237,7 +237,7 @@ Bool PlaYUVerStream::open( std::string filename, UInt width, UInt height, Int in m_uiStreamHandler = YUV_IO; } //#ifdef USE_OPENCV -// else if ( m_cFormatName == "png" ) +// else if( m_cFormatName == "png" || m_cFormatName == "jpg" ) // { // m_uiStreamHandler = OPENCV_HANDLER; // } @@ -279,6 +279,19 @@ Bool PlaYUVerStream::open( std::string filename, UInt width, UInt height, Int in } #endif +#ifdef USE_OPENCV + if( m_uiStreamHandler == 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(); + } + } +#endif + if( m_uiWidth <= 0 || m_uiHeight <= 0 || m_iPixelFormat < 0 ) { close(); @@ -286,49 +299,59 @@ Bool PlaYUVerStream::open( std::string filename, UInt width, UInt height, Int in return m_bInit; } - if( m_uiStreamHandler == YUV_IO ) + if( m_uiStreamHandler != OPENCV_HANDLER ) { - if( !openFile() ) + if( m_uiStreamHandler == YUV_IO ) { - close(); - throw "[PlaYUVerStream] Cannot open file"; - return m_bInit; + if( !openFile() ) + { + close(); + throw "[PlaYUVerStream] Cannot open file"; + return m_bInit; + } + m_cFormatName = "YUV"; + m_cCodedName = "Raw Video"; } - m_cFormatName = "YUV"; - m_cCodedName = "Raw Video"; - } - getMem1D( &m_ppcFrameBuffer, m_uiFrameBufferSize ); - for( UInt i = 0; i < m_uiFrameBufferSize; i++ ) - { - m_ppcFrameBuffer[i] = new PlaYUVerFrame( m_uiWidth, m_uiHeight, m_iPixelFormat ); - if( !m_ppcFrameBuffer[i] ) + getMem1D( &m_ppcFrameBuffer, m_uiFrameBufferSize ); + for( UInt i = 0; i < m_uiFrameBufferSize; i++ ) { - close(); - throw "[PlaYUVerStream] Cannot allocated frame buffer"; - return m_bInit; + m_ppcFrameBuffer[i] = new PlaYUVerFrame( m_uiWidth, m_uiHeight, m_iPixelFormat ); + if( !m_ppcFrameBuffer[i] ) + { + close(); + throw "[PlaYUVerStream] Cannot allocated frame buffer"; + return m_bInit; + } } - } - m_uiFrameBufferIndex = 0; - m_pcCurrFrame = m_ppcFrameBuffer[m_uiFrameBufferIndex]; + m_uiFrameBufferIndex = 0; + m_pcCurrFrame = m_ppcFrameBuffer[m_uiFrameBufferIndex]; - UInt64 frame_bytes_input = m_pcCurrFrame->getBytesPerFrame(); + UInt64 frame_bytes_input = m_pcCurrFrame->getBytesPerFrame(); - if( m_uiStreamHandler == YUV_IO && m_bIsInput ) - { - fseek( m_pFile, 0, SEEK_END ); - UInt64 fileSize = ftell( m_pFile ); + if( m_uiStreamHandler == YUV_IO && 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; - } + 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 ); + } + } + else + { + m_pcNextFrame = NULL; + m_uiFrameBufferSize = 0; + m_uiFrameBufferIndex = 0; + m_uiTotalFrameNum = 1; } if( m_bIsInput && m_uiTotalFrameNum <= 0 ) @@ -512,6 +535,11 @@ Void PlaYUVerStream::readFrame() return; } + if( m_uiStreamHandler == OPENCV_HANDLER ) + { + return; + } + #ifdef USE_FFMPEG if( m_uiStreamHandler == FFMPEG ) { @@ -676,6 +704,10 @@ Bool PlaYUVerStream::seekInput( UInt64 new_frame_num ) setNextFrame(); return true; } + if( m_uiStreamHandler == OPENCV_HANDLER ) + { + return true; + } #ifdef USE_FFMPEG if( m_uiStreamHandler == FFMPEG ) { From 2b749e3da0fdad163609e606f337d82f14b45dd8 Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Thu, 5 Mar 2015 16:38:57 +0000 Subject: [PATCH 32/39] Fix opening sequences in YUV420 when odd resolutions --- lib/LibAvContextHandle.cpp | 63 +++++++++++++++++++------- lib/LibMemory.h | 27 ------------ lib/PlaYUVerDefs.h | 2 + lib/PlaYUVerFrame.cpp | 68 +++++++++++++++++++++++----- lib/PlaYUVerFrame.h | 4 +- lib/PlaYUVerFramePixelFormats.cpp | 73 +++++++++++++++++-------------- lib/PlaYUVerFramePixelFormats.h | 7 ++- 7 files changed, 152 insertions(+), 92 deletions(-) diff --git a/lib/LibAvContextHandle.cpp b/lib/LibAvContextHandle.cpp index dd250d9..6e33518 100644 --- a/lib/LibAvContextHandle.cpp +++ b/lib/LibAvContextHandle.cpp @@ -295,31 +295,60 @@ Bool LibAvContextHandle::initAvFormat( const char* filename, UInt& width, UInt& Bool LibAvContextHandle::decodeAvFormat() { Int got_frame; + Int decResult; /* read frames from the file */ while( av_read_frame( fmt_ctx, &pkt ) >= 0 ) { - if( pkt.stream_index == video_stream_idx ) + AVPacket orig_pkt = pkt; + do { - /* decode video frame */ - Int ret = avcodec_decode_video2( video_dec_ctx, frame, &got_frame, &pkt ); - if( ret < 0 ) + if( pkt.stream_index == video_stream_idx ) { - fprintf( stderr, "Error decoding video frame\n" ); - return false; - } + /* decode video frame */ + decResult = avcodec_decode_video2( video_dec_ctx, frame, &got_frame, &pkt ); + if( decResult < 0 ) + { + fprintf( stderr, "Error decoding video frame\n" ); + return false; + } - if( got_frame ) - { - av_image_copy_to_buffer( m_pchFrameBuffer, m_uiFrameBufferSize, frame->data, frame->linesize, video_dec_ctx->pix_fmt, video_dec_ctx->width, - video_dec_ctx->height, 1 ); - - /* copy decoded frame to destination buffer: - * this is required since rawvideo expects non aligned data */ - // av_image_copy( video_dst_data, video_dst_linesize, ( const uint8_t ** )( frame->data ), frame->linesize, video_dec_ctx->pix_fmt, video_dec_ctx->width, - // video_dec_ctx->height ); + if( got_frame ) + { + av_image_copy_to_buffer( m_pchFrameBuffer, m_uiFrameBufferSize, frame->data, frame->linesize, video_dec_ctx->pix_fmt, video_dec_ctx->width, + video_dec_ctx->height, 1 ); + } } + pkt.data += decResult; + pkt.size -= decResult; } - av_free_packet( &pkt ); + while( pkt.size > 0 ); + av_free_packet( &orig_pkt ); + +// /* read frames from the file */ +// while( av_read_frame( fmt_ctx, &pkt ) >= 0 ) +// { +// if( pkt.stream_index == video_stream_idx ) +// { +// /* decode video frame */ +// Int ret = avcodec_decode_video2( video_dec_ctx, frame, &got_frame, &pkt ); +// if( ret < 0 ) +// { +// fprintf( stderr, "Error decoding video frame\n" ); +// return false; +// } +// +// if( got_frame ) +// { +// av_image_copy_to_buffer( m_pchFrameBuffer, m_uiFrameBufferSize, frame->data, frame->linesize, video_dec_ctx->pix_fmt, video_dec_ctx->width, +// video_dec_ctx->height, 1 ); +// +// /* copy decoded frame to destination buffer: +// * this is required since rawvideo expects non aligned data */ +// // av_image_copy( video_dst_data, video_dst_linesize, ( const uint8_t ** )( frame->data ), frame->linesize, video_dec_ctx->pix_fmt, video_dec_ctx->width, +// // video_dec_ctx->height ); +// } +// } +// av_free_packet( &pkt ); if( got_frame ) return true; } diff --git a/lib/LibMemory.h b/lib/LibMemory.h index c245f81..1a631f6 100644 --- a/lib/LibMemory.h +++ b/lib/LibMemory.h @@ -176,33 +176,6 @@ Int getMem5D( T****** array5D, Int dim0, Int dim1, Int dim2, Int dim3, Int dim4 return mem_size; } -template -Int getMem3ImageComponents( T**** array3D, Int dim1, Int dim2, Int ratioDim1Chroma, Int ratioDim2Chroma ) -{ - Int dim0 = 3; - Int i, mem_size = ( dim1 * dim2 + dim1 / ratioDim1Chroma * dim2 / ratioDim2Chroma * 2 ) * sizeof(T); - - mem_size += getMem2D( array3D, dim0, dim1 ); - - if( ( ( *array3D )[0][0] = ( T* )xCallocMem( dim1 * dim2 + dim1 / ratioDim1Chroma * dim2 / ratioDim2Chroma * 2, sizeof(T) ) ) == NULL ) - printf( "getMem3DImageComponents: array1D" ); - - // Luma - for( i = 1; i < dim1; i++ ) - ( *array3D )[0][i] = ( *array3D )[0][i - 1] + dim2; - - // Chroma - ( *array3D )[1][0] = ( *array3D )[0][0] + dim2 * dim1; - for( i = 1; i < dim1 / ratioDim1Chroma; i++ ) - ( *array3D )[1][i] = ( *array3D )[1][i - 1] + dim2 / ratioDim2Chroma; - - ( *array3D )[2][0] = ( *array3D )[1][0] + dim2 / ratioDim2Chroma * dim1 / ratioDim1Chroma; - for( i = 1; i < dim1 / ratioDim1Chroma; i++ ) - ( *array3D )[2][i] = ( *array3D )[2][i - 1] + dim2 / ratioDim2Chroma; - - return mem_size; -} - template Void freeMem1D( T *array1D ) { diff --git a/lib/PlaYUVerDefs.h b/lib/PlaYUVerDefs.h index 2976e92..febe010 100644 --- a/lib/PlaYUVerDefs.h +++ b/lib/PlaYUVerDefs.h @@ -47,6 +47,8 @@ typedef unsigned int UInt; typedef double Double; typedef float Float; +//typedef uint32_t UInt32; + // ==================================================================================================================== // 64-bit integer type // ==================================================================================================================== diff --git a/lib/PlaYUVerFrame.cpp b/lib/PlaYUVerFrame.cpp index 4ae4a00..fef348d 100644 --- a/lib/PlaYUVerFrame.cpp +++ b/lib/PlaYUVerFrame.cpp @@ -75,16 +75,50 @@ PlaYUVerFrame::~PlaYUVerFrame() if( m_pppcInputPel ) freeMem3ImageComponents( m_pppcInputPel ); - if( m_pcRGB32 ) - freeMem1D( m_pcRGB32 ); + if( m_pcARGB32 ) + freeMem1D( m_pcARGB32 ); closePixfc(); } +static Int getMem3ImageComponents( Pel**** array3D, Int dim1, Int dim2, Int ratioDim1Chroma, Int ratioDim2Chroma ) +{ + Int dim0 = 3; + Int i; + UInt64 total_mem_size = 0; + UInt64 mem_size = ( dim1 * dim2 + CHROMA_RESAMPLING( dim1 ) / ratioDim1Chroma * CHROMA_RESAMPLING( dim2 ) / ratioDim2Chroma * 2 ); + + total_mem_size += getMem2D( array3D, dim0, dim1 ); + + if( ( ( *array3D )[0][0] = ( Pel* )xCallocMem( mem_size, sizeof(Pel) ) ) == NULL ) + printf( "getMem3DImageComponents: array1D" ); + + total_mem_size += mem_size * sizeof(Pel); + + // Luma + for( i = 1; i < dim1; i++ ) + ( *array3D )[0][i] = ( *array3D )[0][i - 1] + dim2; + + // Chroma + ( *array3D )[1][0] = ( *array3D )[0][0] + dim2 * dim1; + + dim1 = CHROMARATIO( dim1, ratioDim1Chroma ); + dim2 = CHROMARATIO( dim2, ratioDim2Chroma ); + + for( i = 1; i < dim1; i++ ) + ( *array3D )[1][i] = ( *array3D )[1][i - 1] + dim2; + + ( *array3D )[2][0] = ( *array3D )[1][0] + dim2 * dim1; + for( i = 1; i < dim1; i++ ) + ( *array3D )[2][i] = ( *array3D )[2][i - 1] + dim2; + + return total_mem_size; +} + Void PlaYUVerFrame::init( UInt width, UInt height, Int pel_format ) { m_pppcInputPel = NULL; - m_pcRGB32 = NULL; + m_pcARGB32 = NULL; m_uiWidth = width; m_uiHeight = height; m_iPixelFormat = pel_format; @@ -103,13 +137,13 @@ Void PlaYUVerFrame::init( UInt width, UInt height, Int pel_format ) m_bHasRGBPel = false; if( m_pcPelFormat->colorSpace == COLOR_GRAY ) { - getMem3ImageComponents( &m_pppcInputPel, m_uiHeight, m_uiWidth, 1, 1 ); + getMem3ImageComponents( &m_pppcInputPel, m_uiHeight, m_uiWidth, 1, 1 ); } else { - getMem3ImageComponents( &m_pppcInputPel, m_uiHeight, m_uiWidth, m_pcPelFormat->ratioChromaHeight, m_pcPelFormat->ratioChromaWidth ); + getMem3ImageComponents( &m_pppcInputPel, m_uiHeight, m_uiWidth, m_pcPelFormat->ratioChromaHeight, m_pcPelFormat->ratioChromaWidth ); } - getMem1D( &m_pcRGB32, m_uiHeight * m_uiWidth * 4 ); + getMem1D( &m_pcARGB32, m_uiHeight * m_uiWidth * 4 ); xSetupStatistics( this ); openPixfc(); @@ -136,19 +170,29 @@ UInt64 PlaYUVerFrame::getBytesPerFrame( UInt uiWidth, UInt uiHeight, Int iPixelF UInt64 numberBytes = uiWidth * uiHeight; if( pcPelFormat->numberChannels > 1 ) { - numberBytes += ( pcPelFormat->numberChannels - 1 ) * ( uiWidth * uiHeight ) / ( pcPelFormat->ratioChromaWidth * pcPelFormat->ratioChromaHeight ); + UInt64 numberBytesChroma = ( CHROMA_RESAMPLING( uiWidth ) * CHROMA_RESAMPLING( uiHeight ) ) + / ( pcPelFormat->ratioChromaWidth * pcPelFormat->ratioChromaHeight ); + numberBytes += ( pcPelFormat->numberChannels - 1 ) * numberBytesChroma; } return numberBytes; } UInt PlaYUVerFrame::getChromaWidth() const { - return m_pcPelFormat->ratioChromaWidth > 0 ? m_uiWidth / m_pcPelFormat->ratioChromaWidth : 0; + if( m_pcPelFormat->ratioChromaWidth > 0 ) + { + return m_pcPelFormat->ratioChromaWidth > 1 ? ( m_uiWidth + 1 ) / m_pcPelFormat->ratioChromaWidth : m_uiWidth; + } + return 0; } UInt PlaYUVerFrame::getChromaHeight() const { - return m_pcPelFormat->ratioChromaHeight > 0 ? m_uiHeight / m_pcPelFormat->ratioChromaHeight : 0; + if( m_pcPelFormat->ratioChromaHeight > 0 ) + { + return m_pcPelFormat->ratioChromaHeight > 1 ? ( m_uiHeight + 1 ) / m_pcPelFormat->ratioChromaHeight : m_uiHeight; + } + return 0; } UInt PlaYUVerFrame::getChromaLength() const @@ -175,7 +219,7 @@ Void PlaYUVerFrame::fillRGBBuffer() { if( m_bHasRGBPel ) return; - m_pcPelFormat->fillRGBbuffer( m_pppcInputPel, m_pcRGB32, m_uiWidth, m_uiHeight ); + m_pcPelFormat->fillARGB32buffer( m_pppcInputPel, m_pcARGB32, m_uiWidth, m_uiHeight ); m_bHasRGBPel = true; } @@ -339,7 +383,7 @@ Void PlaYUVerFrame::getCvMat( Void** ppCvFrame ) if( m_pcPelFormat->colorSpace != PlaYUVerFrame::COLOR_GRAY ) { fillRGBBuffer(); - memcpy( pcCvFrame->data, m_pcRGB32, m_uiWidth * m_uiHeight * 4 * sizeof(UChar) ); + memcpy( pcCvFrame->data, m_pcARGB32, m_uiWidth * m_uiHeight * 4 * sizeof(UChar) ); } else { @@ -381,7 +425,7 @@ Void PlaYUVerFrame::fromCvMat( Void* voidFrame ) Pel* pInputPelY = m_pppcInputPel[LUMA][0]; Pel* pInputPelU = m_pppcInputPel[CHROMA_U][0]; Pel* pInputPelV = m_pppcInputPel[CHROMA_V][0]; - Pel* pcRGBPelInterlaced = m_pcRGB32; + Pel* pcRGBPelInterlaced = m_pcARGB32; memcpy( pcRGBPelInterlaced, opencvFrame->data, m_uiWidth * m_uiHeight * 4 * sizeof(Pel) ); UInt* buff = ( UInt* )pcRGBPelInterlaced; for( UInt i = 0; i < m_uiHeight * m_uiWidth; i++ ) diff --git a/lib/PlaYUVerFrame.h b/lib/PlaYUVerFrame.h index c7a2e30..e699ceb 100644 --- a/lib/PlaYUVerFrame.h +++ b/lib/PlaYUVerFrame.h @@ -195,7 +195,7 @@ public: { fillRGBBuffer(); } - return m_pcRGB32; + return m_pcARGB32; } /** @@ -243,7 +243,7 @@ private: Bool m_bHasRGBPel; Pel*** m_pppcInputPel; - UChar* m_pcRGB32; + UChar* m_pcARGB32; Void init( UInt width, UInt height, Int pel_format ); Void openPixfc(); diff --git a/lib/PlaYUVerFramePixelFormats.cpp b/lib/PlaYUVerFramePixelFormats.cpp index d2a25aa..aa316d2 100644 --- a/lib/PlaYUVerFramePixelFormats.cpp +++ b/lib/PlaYUVerFramePixelFormats.cpp @@ -56,37 +56,43 @@ namespace plaYUVer * Progressive and interlaces */ -Void frameFromBufferYUVProgressive( Pel* in, Pel ***out, UInt width, UInt height, UInt ratioChroma ) +Void frameFromBufferYUVProgressive( Pel* in, Pel ***out, UInt width, UInt height, UInt ratioChromaWidth, UInt ratioChromaHeight ) { + UInt64 chromaSize = CHROMASHIFT( width, ratioChromaWidth ) * CHROMASHIFT( height, ratioChromaHeight ); memcpy( &out[LUMA][0][0], in, width * height * sizeof(Pel) ); - memcpy( &out[CHROMA_U][0][0], in + width * height, width * height / ratioChroma * sizeof(Pel) ); - memcpy( &out[CHROMA_V][0][0], in + width * height + width * height / ratioChroma, width * height / ratioChroma * sizeof(Pel) ); + memcpy( &out[CHROMA_U][0][0], in + width * height, chromaSize * sizeof(Pel) ); + memcpy( &out[CHROMA_V][0][0], in + width * height + chromaSize, chromaSize * sizeof(Pel) ); } -Void bufferFromFrameYUVProgressive( Pel*** in, Pel *out, UInt width, UInt height, UInt ratioChroma ) +Void bufferFromFrameYUVProgressive( Pel*** in, Pel *out, UInt width, UInt height, UInt ratioChromaWidth, UInt ratioChromaHeight ) { + UInt64 chromaSize = CHROMASHIFT( width, ratioChromaWidth ) * CHROMASHIFT( height, ratioChromaHeight ); memcpy( out, &in[LUMA][0][0], width * height * sizeof(Pel) ); - memcpy( out + width * height, &in[CHROMA_U][0][0], width * height / ratioChroma * sizeof(Pel) ); - memcpy( out + width * height + width * height / ratioChroma, &in[CHROMA_V][0][0], width * height / ratioChroma * sizeof(Pel) ); + memcpy( out + width * height, &in[CHROMA_U][0][0], chromaSize * sizeof(Pel) ); + memcpy( out + width * height + chromaSize, &in[CHROMA_V][0][0], chromaSize * sizeof(Pel) ); } -Void fillRGBbufferYUV( Pel*** in, UChar* out, UInt width, UInt height, UInt ratioChromaHor, UInt ratioChromaVer ) +Void fillARGB32bufferYUV( Pel*** in, UChar* out, UInt width, UInt height, UInt ratioChromaHor, UInt ratioChromaVer ) { - Pel* pY = in[LUMA][0]; + Pel* pLineY = in[LUMA][0]; Pel* pLineU = in[CHROMA_U][0]; Pel* pLineV = in[CHROMA_V][0]; - UInt uiChromaStride = width >> ratioChromaHor; + UInt uiChromaStride = CHROMASHIFT( width, ratioChromaHor ); + Pel* pY; Pel* pU; Pel* pV; Int iY, iU, iV, iR, iG, iB; - UInt* buff = ( UInt* )out; + UInt* pARGBLine = ( UInt* )out; + UInt* pARGB; for( UInt y = 0; y < height >> ratioChromaVer; y++ ) { for( Int i = 0; i < 1 << ratioChromaVer; i++ ) { + pY = pLineY; pU = pLineU; pV = pLineV; + pARGB = pARGBLine; for( UInt x = 0; x < width >> ratioChromaHor; x++ ) { iU = *pU++; @@ -95,10 +101,11 @@ Void fillRGBbufferYUV( Pel*** in, UChar* out, UInt width, UInt height, UInt rati { iY = *pY++; YUV2RGB( iY, iU, iV, iR, iG, iB ); - *buff = PEL_RGB( iR, iG, iB ); - buff++; + *pARGB++ = PEL_RGB( iR, iG, iB ); } } + pLineY += width; + pARGBLine += width; } pLineU += uiChromaStride; pLineV += uiChromaStride; @@ -111,13 +118,13 @@ Void fillRGBbufferYUV( Pel*** in, UChar* out, UInt width, UInt height, UInt rati Void frameFromBufferYUV420p( Pel *in, Pel*** out, UInt width, UInt height ) { - frameFromBufferYUVProgressive( in, out, width, height, 4 ); + frameFromBufferYUVProgressive( in, out, width, height, 1, 1 ); } Void bufferFromFrameYUV420p( Pel ***in, Pel* out, UInt width, UInt height ) { - bufferFromFrameYUVProgressive( in, out, width, height, 4 ); + bufferFromFrameYUVProgressive( in, out, width, height, 1, 1 ); } -Void fillRGBbufferYUV420p( Pel*** in, UChar* out, UInt width, UInt height ) +Void fillARGB32bufferYUV420p( Pel*** in, UChar* out, UInt width, UInt height ) { #ifdef USE_SSE if( ( width % 16 ) == 0 ) @@ -260,7 +267,7 @@ Void fillRGBbufferYUV420p( Pel*** in, UChar* out, UInt width, UInt height ) else #endif { - fillRGBbufferYUV( in, out, width, height, 1, 1 ); + fillARGB32bufferYUV( in, out, width, height, 1, 1 ); } } @@ -273,7 +280,7 @@ PlaYUVerFramePelFormat yuv420p = 2, frameFromBufferYUV420p, bufferFromFrameYUV420p, - fillRGBbufferYUV420p, + fillARGB32bufferYUV420p, ADD_FFMPEG_PEL_FMT( AV_PIX_FMT_YUV420P ), }; /** @@ -282,15 +289,15 @@ PlaYUVerFramePelFormat yuv420p = Void frameFromBufferYUV444p( Pel *in, Pel*** out, UInt width, UInt height ) { - frameFromBufferYUVProgressive( in, out, width, height, 1 ); + frameFromBufferYUVProgressive( in, out, width, height, 0, 0 ); } Void bufferFromFrameYUV444p( Pel ***in, Pel* out, UInt width, UInt height ) { - bufferFromFrameYUVProgressive( in, out, width, height, 1 ); + bufferFromFrameYUVProgressive( in, out, width, height, 0, 0 ); } -Void fillRGBbufferYUV444p( Pel*** in, UChar* out, UInt width, UInt height ) +Void fillARGB32bufferYUV444p( Pel*** in, UChar* out, UInt width, UInt height ) { - fillRGBbufferYUV( in, out, width, height, 0, 0 ); + fillARGB32bufferYUV( in, out, width, height, 0, 0 ); } PlaYUVerFramePelFormat yuv444p = { @@ -301,7 +308,7 @@ PlaYUVerFramePelFormat yuv444p = 1, frameFromBufferYUV444p, bufferFromFrameYUV444p, - fillRGBbufferYUV444p, + fillARGB32bufferYUV444p, ADD_FFMPEG_PEL_FMT( AV_PIX_FMT_YUV444P ), }; /** @@ -310,15 +317,15 @@ PlaYUVerFramePelFormat yuv444p = Void frameFromBufferYUV422p( Pel *in, Pel*** out, UInt width, UInt height ) { - frameFromBufferYUVProgressive( in, out, width, height, 2 ); + frameFromBufferYUVProgressive( in, out, width, height, 1, 0 ); } Void bufferFromFrameYUV422p( Pel ***in, Pel* out, UInt width, UInt height ) { - bufferFromFrameYUVProgressive( in, out, width, height, 2 ); + bufferFromFrameYUVProgressive( in, out, width, height, 1, 0 ); } -Void fillRGBbufferYUV422( Pel*** in, UChar* out, UInt width, UInt height ) +Void fillARGB32bufferYUV422( Pel*** in, UChar* out, UInt width, UInt height ) { - fillRGBbufferYUV( in, out, width, height, 1, 0 ); + fillARGB32bufferYUV( in, out, width, height, 1, 0 ); } PlaYUVerFramePelFormat yuv422p = { @@ -329,7 +336,7 @@ PlaYUVerFramePelFormat yuv422p = 1, frameFromBufferYUV422p, bufferFromFrameYUV422p, - fillRGBbufferYUV422, + fillARGB32bufferYUV422, ADD_FFMPEG_PEL_FMT( AV_PIX_FMT_YUV422P ), }; /** @@ -371,7 +378,7 @@ PlaYUVerFramePelFormat yuyv422 = 1, frameFromBufferYUYV422, bufferFromFrameYUYV422, - fillRGBbufferYUV422, + fillARGB32bufferYUV422, ADD_FFMPEG_PEL_FMT( AV_PIX_FMT_YUYV422 ), }; /** @@ -386,7 +393,7 @@ Void bufferFromFrameGray( Pel ***in, Pel* out, UInt width, UInt height ) { memcpy( out, &in[LUMA][0][0], width * height * sizeof(Pel) ); } -Void fillRGBbufferGray( Pel*** in, UChar* out, UInt width, UInt height ) +Void fillARGB32bufferGray( Pel*** in, UChar* out, UInt width, UInt height ) { Pel *inPel = in[0][0]; Pel iY; @@ -407,7 +414,7 @@ PlaYUVerFramePelFormat gray = 0, frameFromBufferGray, bufferFromFrameGray, - fillRGBbufferGray, + fillARGB32bufferGray, ADD_FFMPEG_PEL_FMT( AV_PIX_FMT_GRAY8 ), }; /** @@ -433,7 +440,7 @@ Void bufferFromFrameRGB( Pel ***in, Pel* out, UInt64 size, Pel* pFirst, Pel* pSe *out++ = *pthird++; } } -Void fillRGBbufferRGB( Pel*** in, UChar* out, UInt width, UInt height ) +Void fillARGB32bufferRGB( Pel*** in, UChar* out, UInt width, UInt height ) { Pel* pR = in[COLOR_R][0]; Pel* pG = in[COLOR_G][0]; @@ -468,7 +475,7 @@ PlaYUVerFramePelFormat RGB24 = 1, frameFromBufferRGB24, bufferFromFrameRGB24, - fillRGBbufferRGB, + fillARGB32bufferRGB, ADD_FFMPEG_PEL_FMT( AV_PIX_FMT_RGB24 ), }; /** BGR 8 bits per pixel / 3 channels */ @@ -490,7 +497,7 @@ PlaYUVerFramePelFormat BGR24 = 1, frameFromBufferBGR24, bufferFromFrameBGR24, - fillRGBbufferRGB, + fillARGB32bufferRGB, ADD_FFMPEG_PEL_FMT( AV_PIX_FMT_BGR24 ), }; PlaYUVerFramePelFormat g_PlaYUVerFramePelFormatsList[PLAYUVER_NUMBER_FORMATS] = diff --git a/lib/PlaYUVerFramePixelFormats.h b/lib/PlaYUVerFramePixelFormats.h index 0624abe..88ce8de 100644 --- a/lib/PlaYUVerFramePixelFormats.h +++ b/lib/PlaYUVerFramePixelFormats.h @@ -31,6 +31,11 @@ namespace plaYUVer { +#define CHROMA_RESAMPLING( X ) ( ( ( X + 1 ) >> 1 ) << 1 ) + +#define CHROMARATIO( SIZE, RATIO ) ( RATIO > 1 ? ( ( SIZE + 1 ) / RATIO ) : SIZE ) +#define CHROMASHIFT( SIZE, SHIFT ) ( SHIFT > 0 ? ( ( SIZE + 1 ) >> SHIFT ) : SIZE ) + #define CLAMP(X) X = X < 0 ? 0 : X > 255 ? 255 : X; #define YUV2RGB( iY, iU, iV, iR, iG, iB ) \ @@ -78,7 +83,7 @@ struct structPlaYUVerFramePelFormat Int ratioChromaHeight; Void (*frameFromBuffer)( Pel *in, Pel*** out, UInt width, UInt height ); Void (*bufferFromFrame)( Pel ***in, Pel* out, UInt width, UInt height ); - Void (*fillRGBbuffer)( Pel*** in, UChar* out, UInt width, UInt height ); + Void (*fillARGB32buffer)( Pel*** in, UChar* out, UInt width, UInt height ); Int ffmpegPelFormat; }; From 379d13a8ed78594d1cc56a064b15e69ea4beecf2 Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Thu, 5 Mar 2015 22:47:36 +0000 Subject: [PATCH 33/39] Major improvements and generalization of the frame from/to buffer based on ffmpeg enfort --- lib/LibAvContextHandle.cpp | 4 +- lib/PlaYUVerDefs.h | 3 +- lib/PlaYUVerFrame.cpp | 120 ++++++++---- lib/PlaYUVerFrame.h | 2 +- lib/PlaYUVerFramePixelFormats.cpp | 302 ++++++++++-------------------- lib/PlaYUVerFramePixelFormats.h | 100 ++++++++-- 6 files changed, 275 insertions(+), 256 deletions(-) diff --git a/lib/LibAvContextHandle.cpp b/lib/LibAvContextHandle.cpp index 6e33518..0d66a7d 100644 --- a/lib/LibAvContextHandle.cpp +++ b/lib/LibAvContextHandle.cpp @@ -158,7 +158,7 @@ Bool LibAvContextHandle::initAvFormat( const char* filename, UInt& width, UInt& av_dict_set( &format_opts, "video_size", aux_string, 0 ); } - Int ffmpeg_pel_format = g_PlaYUVerFramePelFormatsList[pixel_format].ffmpegPelFormat; + Int ffmpeg_pel_format = g_PlaYUVerPixFmtDescriptorsList[pixel_format].ffmpegPelFormat; if( ffmpeg_pel_format >= 0 ) { av_dict_set( &format_opts, "pixel_format", av_get_pix_fmt_name( AVPixelFormat( ffmpeg_pel_format ) ), 0 ); @@ -247,7 +247,7 @@ Bool LibAvContextHandle::initAvFormat( const char* filename, UInt& width, UInt& pixel_format = PlaYUVerFrame::NO_FMT; for( Int i = 0; i < PLAYUVER_NUMBER_FORMATS; i++ ) { - if( g_PlaYUVerFramePelFormatsList[i].ffmpegPelFormat == pix_fmt ) + if( g_PlaYUVerPixFmtDescriptorsList[i].ffmpegPelFormat == pix_fmt ) { pixel_format = i; break; diff --git a/lib/PlaYUVerDefs.h b/lib/PlaYUVerDefs.h index febe010..cfedd79 100644 --- a/lib/PlaYUVerDefs.h +++ b/lib/PlaYUVerDefs.h @@ -47,7 +47,8 @@ typedef unsigned int UInt; typedef double Double; typedef float Float; -//typedef uint32_t UInt32; +typedef unsigned char UInt8; +typedef unsigned int UInt16; // ==================================================================================================================== // 64-bit integer type diff --git a/lib/PlaYUVerFrame.cpp b/lib/PlaYUVerFrame.cpp index fef348d..552af17 100644 --- a/lib/PlaYUVerFrame.cpp +++ b/lib/PlaYUVerFrame.cpp @@ -47,7 +47,7 @@ std::vector PlaYUVerFrame::supportedPixelFormatListNames() Int numberFormats = PLAYUVER_NUMBER_FORMATS; for( Int i = 0; i < numberFormats; i++ ) { - formatsList.push_back( g_PlaYUVerFramePelFormatsList[i].name ); + formatsList.push_back( g_PlaYUVerPixFmtDescriptorsList[i].name ); } return formatsList; } @@ -81,12 +81,12 @@ PlaYUVerFrame::~PlaYUVerFrame() closePixfc(); } -static Int getMem3ImageComponents( Pel**** array3D, Int dim1, Int dim2, Int ratioDim1Chroma, Int ratioDim2Chroma ) +static Int getMem3ImageComponents( Pel**** array3D, Int dim1, Int dim2, Int log2ChromaHeight, Int log2ChromaWidth ) { Int dim0 = 3; Int i; UInt64 total_mem_size = 0; - UInt64 mem_size = ( dim1 * dim2 + CHROMA_RESAMPLING( dim1 ) / ratioDim1Chroma * CHROMA_RESAMPLING( dim2 ) / ratioDim2Chroma * 2 ); + UInt64 mem_size = ( dim1 * dim2 + CHROMASHIFT( dim1, log2ChromaHeight ) * CHROMASHIFT( dim2, log2ChromaWidth ) * 2 ); total_mem_size += getMem2D( array3D, dim0, dim1 ); @@ -102,8 +102,8 @@ static Int getMem3ImageComponents( Pel**** array3D, Int dim1, Int dim2, Int rati // Chroma ( *array3D )[1][0] = ( *array3D )[0][0] + dim2 * dim1; - dim1 = CHROMARATIO( dim1, ratioDim1Chroma ); - dim2 = CHROMARATIO( dim2, ratioDim2Chroma ); + dim1 = CHROMASHIFT( dim1, log2ChromaHeight ); + dim2 = CHROMASHIFT( dim2, log2ChromaWidth ); for( i = 1; i < dim1; i++ ) ( *array3D )[1][i] = ( *array3D )[1][i - 1] + dim2; @@ -132,7 +132,7 @@ Void PlaYUVerFrame::init( UInt width, UInt height, Int pel_format ) return; } - m_pcPelFormat = &( g_PlaYUVerFramePelFormatsList[pel_format] ); + m_pcPelFormat = &( g_PlaYUVerPixFmtDescriptorsList[pel_format] ); m_bHasRGBPel = false; if( m_pcPelFormat->colorSpace == COLOR_GRAY ) @@ -141,7 +141,7 @@ Void PlaYUVerFrame::init( UInt width, UInt height, Int pel_format ) } else { - getMem3ImageComponents( &m_pppcInputPel, m_uiHeight, m_uiWidth, m_pcPelFormat->ratioChromaHeight, m_pcPelFormat->ratioChromaWidth ); + getMem3ImageComponents( &m_pppcInputPel, m_uiHeight, m_uiWidth, m_pcPelFormat->log2ChromaHeight, m_pcPelFormat->log2ChromaWidth ); } getMem1D( &m_pcARGB32, m_uiHeight * m_uiWidth * 4 ); @@ -166,12 +166,11 @@ UInt64 PlaYUVerFrame::getBytesPerFrame() UInt64 PlaYUVerFrame::getBytesPerFrame( UInt uiWidth, UInt uiHeight, Int iPixelFormat ) { - PlaYUVerFramePelFormat* pcPelFormat = &( g_PlaYUVerFramePelFormatsList[iPixelFormat] ); + PlaYUVerPixFmtDescriptor* pcPelFormat = &( g_PlaYUVerPixFmtDescriptorsList[iPixelFormat] ); UInt64 numberBytes = uiWidth * uiHeight; if( pcPelFormat->numberChannels > 1 ) { - UInt64 numberBytesChroma = ( CHROMA_RESAMPLING( uiWidth ) * CHROMA_RESAMPLING( uiHeight ) ) - / ( pcPelFormat->ratioChromaWidth * pcPelFormat->ratioChromaHeight ); + UInt64 numberBytesChroma = CHROMASHIFT( uiWidth, pcPelFormat->log2ChromaWidth ) * CHROMASHIFT( uiWidth, pcPelFormat->log2ChromaHeight ); numberBytes += ( pcPelFormat->numberChannels - 1 ) * numberBytesChroma; } return numberBytes; @@ -179,20 +178,12 @@ UInt64 PlaYUVerFrame::getBytesPerFrame( UInt uiWidth, UInt uiHeight, Int iPixelF UInt PlaYUVerFrame::getChromaWidth() const { - if( m_pcPelFormat->ratioChromaWidth > 0 ) - { - return m_pcPelFormat->ratioChromaWidth > 1 ? ( m_uiWidth + 1 ) / m_pcPelFormat->ratioChromaWidth : m_uiWidth; - } - return 0; + return CHROMASHIFT( m_uiWidth, m_pcPelFormat->log2ChromaWidth ); } UInt PlaYUVerFrame::getChromaHeight() const { - if( m_pcPelFormat->ratioChromaHeight > 0 ) - { - return m_pcPelFormat->ratioChromaHeight > 1 ? ( m_uiHeight + 1 ) / m_pcPelFormat->ratioChromaHeight : m_uiHeight; - } - return 0; + return CHROMASHIFT( m_uiHeight, m_pcPelFormat->log2ChromaHeight ); } UInt PlaYUVerFrame::getChromaLength() const @@ -204,15 +195,70 @@ Void PlaYUVerFrame::frameFromBuffer( Pel *Buff, UInt64 uiBuffSize ) { if( uiBuffSize != getBytesPerFrame() ) return; - m_pcPelFormat->frameFromBuffer( Buff, m_pppcInputPel, m_uiWidth, m_uiHeight ); + + Pel* ppBuff[MAX_NUMBER_PLANES]; + Pel* pTmpPel, *pTmpBuff; + Int ratioH, ratioW, step; + UInt i, ch; + + ppBuff[0] = Buff; + for( Int i = 1; i < MAX_NUMBER_PLANES; i++ ) + { + ratioW = i > 1 ? m_pcPelFormat->log2ChromaWidth : 0; + ratioH = i > 1 ? m_pcPelFormat->log2ChromaHeight : 0; + ppBuff[i] = ppBuff[i - 1] + CHROMASHIFT( m_uiHeight, ratioH ) * CHROMASHIFT( m_uiWidth, ratioW ); + } + + for( ch = 0; ch < m_pcPelFormat->numberChannels; ch++ ) + { + ratioW = ch > 0 ? m_pcPelFormat->log2ChromaWidth : 0; + ratioH = ch > 0 ? m_pcPelFormat->log2ChromaHeight : 0; + step = m_pcPelFormat->comp[ch].step_minus1 + 1; + + pTmpPel = m_pppcInputPel[ch][0]; + pTmpBuff = ppBuff[m_pcPelFormat->comp[ch].plane] + ( m_pcPelFormat->comp[ch].offset_plus1 - 1 ); + + for( i = 0; i < CHROMASHIFT( m_uiHeight, ratioH ) * CHROMASHIFT( m_uiWidth, ratioW ); i++ ) + { + *pTmpPel++ = *pTmpBuff; + pTmpBuff += step; + } + } + m_bHasRGBPel = false; m_bHasHistogram = false; - //fillRGBBuffer(); } Void PlaYUVerFrame::frameToBuffer( Pel *output_buffer ) { - m_pcPelFormat->bufferFromFrame( m_pppcInputPel, output_buffer, m_uiWidth, m_uiHeight ); + Pel* ppBuff[MAX_NUMBER_PLANES]; + Pel* pTmpPel, *pTmpBuff; + Int ratioH, ratioW, step; + UInt i, ch; + + ppBuff[0] = output_buffer; + for( Int i = 1; i < MAX_NUMBER_PLANES; i++ ) + { + ratioW = i > 1 ? m_pcPelFormat->log2ChromaWidth : 0; + ratioH = i > 1 ? m_pcPelFormat->log2ChromaHeight : 0; + ppBuff[i] = ppBuff[i - 1] + CHROMASHIFT( m_uiHeight, ratioH ) * CHROMASHIFT( m_uiWidth, ratioW ); + } + + for( ch = 0; ch < m_pcPelFormat->numberChannels; ch++ ) + { + ratioW = ch > 0 ? m_pcPelFormat->log2ChromaWidth : 0; + ratioH = ch > 0 ? m_pcPelFormat->log2ChromaHeight : 0; + step = m_pcPelFormat->comp[ch].step_minus1 + 1; + + pTmpPel = m_pppcInputPel[ch][0]; + pTmpBuff = ppBuff[m_pcPelFormat->comp[ch].plane]; + + for( i = 0; i < CHROMASHIFT( m_uiHeight, ratioH ) * CHROMASHIFT( m_uiWidth, ratioW ); i++ ) + { + *pTmpBuff++ = *pTmpPel++; + } + } + } Void PlaYUVerFrame::fillRGBBuffer() @@ -234,21 +280,21 @@ Void PlaYUVerFrame::copyFrom( PlaYUVerFrame* input_frame ) Void PlaYUVerFrame::adjustSelectedAreaDims( UInt& posX, UInt& posY, UInt& areaWidth, UInt& areaHeight, Int pelFormat ) { - PlaYUVerFramePelFormat* pcPelFormat = &( g_PlaYUVerFramePelFormatsList[pelFormat] ); - if( pcPelFormat->ratioChromaWidth ) + PlaYUVerPixFmtDescriptor* pcPelFormat = &( g_PlaYUVerPixFmtDescriptorsList[pelFormat] ); + if( pcPelFormat->log2ChromaWidth ) { - if( posX % pcPelFormat->ratioChromaWidth ) + if( posX % ( 1 << pcPelFormat->log2ChromaWidth ) ) posX--; - if( ( posX + areaWidth ) % pcPelFormat->ratioChromaWidth ) + if( ( posX + areaWidth ) % ( 1 << pcPelFormat->log2ChromaWidth ) ) areaWidth++; } - if( pcPelFormat->ratioChromaHeight ) + if( pcPelFormat->log2ChromaHeight ) { - if( posY % pcPelFormat->ratioChromaHeight ) + if( posY % ( 1 << pcPelFormat->log2ChromaHeight ) ) posY--; - if( ( posY + areaHeight ) % pcPelFormat->ratioChromaHeight ) + if( ( posY + areaHeight ) % ( 1 << pcPelFormat->log2ChromaHeight ) ) areaHeight++; } } @@ -260,11 +306,11 @@ Void PlaYUVerFrame::copyFrom( PlaYUVerFrame* input_frame, UInt xPos, UInt yPos ) Pel ***pInput = input_frame->getPelBufferYUV(); for( UInt ch = 0; ch < m_pcPelFormat->numberChannels; ch++ ) { - Int ratioH = ch > 0 ? m_pcPelFormat->ratioChromaHeight : 1; - Int ratioW = ch > 0 ? m_pcPelFormat->ratioChromaWidth : 1; - for( UInt i = 0; i < m_uiHeight / ratioH; i++ ) + Int ratioH = ch > 0 ? m_pcPelFormat->log2ChromaWidth : 0; + 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; @@ -276,9 +322,9 @@ PlaYUVerFrame::Pixel PlaYUVerFrame::getPixelValue( Int xPos, Int yPos, Int eColo PlaYUVerFrame::Pixel PixelValue( m_pcPelFormat->colorSpace, 0, 0, 0 ); for( UInt ch = 0; ch < m_pcPelFormat->numberChannels; ch++ ) { - Int ratioH = ch > 0 ? m_pcPelFormat->ratioChromaHeight : 1; - Int ratioW = ch > 0 ? m_pcPelFormat->ratioChromaWidth : 1; - PixelValue.Components()[ch] = m_pppcInputPel[ch][yPos / ratioH][xPos / ratioW]; + Int ratioH = ch > 0 ? m_pcPelFormat->log2ChromaWidth : 0; + Int ratioW = ch > 0 ? m_pcPelFormat->log2ChromaHeight : 0; + PixelValue.Components()[ch] = m_pppcInputPel[ch][( yPos >> ratioH )][( xPos >> ratioW )]; } return ConvertPixel( PixelValue, eColorSpace ); } diff --git a/lib/PlaYUVerFrame.h b/lib/PlaYUVerFrame.h index e699ceb..b2163a3 100644 --- a/lib/PlaYUVerFrame.h +++ b/lib/PlaYUVerFrame.h @@ -233,7 +233,7 @@ public: private: - struct structPlaYUVerFramePelFormat* m_pcPelFormat; + struct PlaYUVerPixFmtDescriptor* m_pcPelFormat; UInt m_uiWidth; UInt m_uiHeight; diff --git a/lib/PlaYUVerFramePixelFormats.cpp b/lib/PlaYUVerFramePixelFormats.cpp index aa316d2..703d676 100644 --- a/lib/PlaYUVerFramePixelFormats.cpp +++ b/lib/PlaYUVerFramePixelFormats.cpp @@ -51,26 +51,6 @@ namespace plaYUVer #define ADD_FFMPEG_PEL_FMT( fmt ) 0 #endif -/** - * YUV Formats - * Progressive and interlaces - */ - -Void frameFromBufferYUVProgressive( Pel* in, Pel ***out, UInt width, UInt height, UInt ratioChromaWidth, UInt ratioChromaHeight ) -{ - UInt64 chromaSize = CHROMASHIFT( width, ratioChromaWidth ) * CHROMASHIFT( height, ratioChromaHeight ); - memcpy( &out[LUMA][0][0], in, width * height * sizeof(Pel) ); - memcpy( &out[CHROMA_U][0][0], in + width * height, chromaSize * sizeof(Pel) ); - memcpy( &out[CHROMA_V][0][0], in + width * height + chromaSize, chromaSize * sizeof(Pel) ); -} - -Void bufferFromFrameYUVProgressive( Pel*** in, Pel *out, UInt width, UInt height, UInt ratioChromaWidth, UInt ratioChromaHeight ) -{ - UInt64 chromaSize = CHROMASHIFT( width, ratioChromaWidth ) * CHROMASHIFT( height, ratioChromaHeight ); - memcpy( out, &in[LUMA][0][0], width * height * sizeof(Pel) ); - memcpy( out + width * height, &in[CHROMA_U][0][0], chromaSize * sizeof(Pel) ); - memcpy( out + width * height + chromaSize, &in[CHROMA_V][0][0], chromaSize * sizeof(Pel) ); -} Void fillARGB32bufferYUV( Pel*** in, UChar* out, UInt width, UInt height, UInt ratioChromaHor, UInt ratioChromaVer ) { @@ -112,18 +92,6 @@ Void fillARGB32bufferYUV( Pel*** in, UChar* out, UInt width, UInt height, UInt r } } -/** - * YUV420p 12 bits per pixel - */ - -Void frameFromBufferYUV420p( Pel *in, Pel*** out, UInt width, UInt height ) -{ - frameFromBufferYUVProgressive( in, out, width, height, 1, 1 ); -} -Void bufferFromFrameYUV420p( Pel ***in, Pel* out, UInt width, UInt height ) -{ - bufferFromFrameYUVProgressive( in, out, width, height, 1, 1 ); -} Void fillARGB32bufferYUV420p( Pel*** in, UChar* out, UInt width, UInt height ) { #ifdef USE_SSE @@ -271,128 +239,23 @@ Void fillARGB32bufferYUV420p( Pel*** in, UChar* out, UInt width, UInt height ) } } -PlaYUVerFramePelFormat yuv420p = -{ - "YUV420p", - PlaYUVerFrame::COLOR_YUV, - 3, - 2, - 2, - frameFromBufferYUV420p, - bufferFromFrameYUV420p, - fillARGB32bufferYUV420p, - ADD_FFMPEG_PEL_FMT( AV_PIX_FMT_YUV420P ), }; -/** - * YUV444p 24 bits per pixel - */ -Void frameFromBufferYUV444p( Pel *in, Pel*** out, UInt width, UInt height ) -{ - frameFromBufferYUVProgressive( in, out, width, height, 0, 0 ); -} -Void bufferFromFrameYUV444p( Pel ***in, Pel* out, UInt width, UInt height ) -{ - bufferFromFrameYUVProgressive( in, out, width, height, 0, 0 ); -} Void fillARGB32bufferYUV444p( Pel*** in, UChar* out, UInt width, UInt height ) { fillARGB32bufferYUV( in, out, width, height, 0, 0 ); } -PlaYUVerFramePelFormat yuv444p = -{ - "YUV444p", - PlaYUVerFrame::COLOR_YUV, - 3, - 1, - 1, - frameFromBufferYUV444p, - bufferFromFrameYUV444p, - fillARGB32bufferYUV444p, - ADD_FFMPEG_PEL_FMT( AV_PIX_FMT_YUV444P ), }; -/** - * YUV422p 16 bits per pixel - */ -Void frameFromBufferYUV422p( Pel *in, Pel*** out, UInt width, UInt height ) -{ - frameFromBufferYUVProgressive( in, out, width, height, 1, 0 ); -} -Void bufferFromFrameYUV422p( Pel ***in, Pel* out, UInt width, UInt height ) -{ - bufferFromFrameYUVProgressive( in, out, width, height, 1, 0 ); -} + Void fillARGB32bufferYUV422( Pel*** in, UChar* out, UInt width, UInt height ) { fillARGB32bufferYUV( in, out, width, height, 1, 0 ); } -PlaYUVerFramePelFormat yuv422p = -{ - "YUV422p", - PlaYUVerFrame::COLOR_YUV, - 3, - 2, - 1, - frameFromBufferYUV422p, - bufferFromFrameYUV422p, - fillARGB32bufferYUV422, - ADD_FFMPEG_PEL_FMT( AV_PIX_FMT_YUV422P ), }; -/** - * YUYV422 16 bits per pixel - */ -Void frameFromBufferYUYV422( Pel *in, Pel*** out, UInt width, UInt height ) -{ - Pel* pY = out[LUMA][0]; - Pel* pU = out[CHROMA_U][0]; - Pel* pV = out[CHROMA_V][0]; - for( UInt i = 0; i < width * height / 2; i++ ) - { - *pY++ = *in++; - *pU++ = *in++; - *pY++ = *in++; - *pV++ = *in++; - } -} -Void bufferFromFrameYUYV422( Pel ***in, Pel* out, UInt width, UInt height ) -{ - Pel* pY = in[LUMA][0]; - Pel* pU = in[CHROMA_U][0]; - Pel* pV = in[CHROMA_V][0]; - for( UInt i = 0; i < height * width / 2; i++ ) - { - *out++ = *pY++; - *out++ = *pU++; - *out++ = *pY++; - *out++ = *pV++; - } -} -PlaYUVerFramePelFormat yuyv422 = -{ - "YUYV422", - PlaYUVerFrame::COLOR_YUV, - 3, - 2, - 1, - frameFromBufferYUYV422, - bufferFromFrameYUYV422, - fillARGB32bufferYUV422, - ADD_FFMPEG_PEL_FMT( AV_PIX_FMT_YUYV422 ), }; -/** - * Gray Format - */ -Void frameFromBufferGray( Pel *in, Pel*** out, UInt width, UInt height ) -{ - memcpy( &out[LUMA][0][0], in, width * height * sizeof(Pel) ); -} -Void bufferFromFrameGray( Pel ***in, Pel* out, UInt width, UInt height ) -{ - memcpy( out, &in[LUMA][0][0], width * height * sizeof(Pel) ); -} Void fillARGB32bufferGray( Pel*** in, UChar* out, UInt width, UInt height ) { Pel *inPel = in[0][0]; @@ -405,41 +268,7 @@ Void fillARGB32bufferGray( Pel*** in, UChar* out, UInt width, UInt height ) inPel++; } } -PlaYUVerFramePelFormat gray = -{ - "GRAY", - PlaYUVerFrame::COLOR_GRAY, - 1, - 0, - 0, - frameFromBufferGray, - bufferFromFrameGray, - fillARGB32bufferGray, - ADD_FFMPEG_PEL_FMT( AV_PIX_FMT_GRAY8 ), }; -/** - * RGB formats - * Interlaced - */ - -Void frameFromBufferRGB( Pel *in, Pel*** out, UInt64 size, Pel* pFirst, Pel* pSecond, Pel* pthird ) -{ - for( UInt i = 0; i < size; i++ ) - { - *pFirst++ = *in++; - *pSecond++ = *in++; - *pthird++ = *in++; - } -} -Void bufferFromFrameRGB( Pel ***in, Pel* out, UInt64 size, Pel* pFirst, Pel* pSecond, Pel* pthird ) -{ - for( UInt i = 0; i < size; i++ ) - { - *out++ = *pFirst++; - *out++ = *pSecond++; - *out++ = *pthird++; - } -} Void fillARGB32bufferRGB( Pel*** in, UChar* out, UInt width, UInt height ) { Pel* pR = in[COLOR_R][0]; @@ -456,51 +285,122 @@ Void fillARGB32bufferRGB( Pel*** in, UChar* out, UInt width, UInt height ) } } -/** RGB 8 bits per pixel / 3 channels */ -Void frameFromBufferRGB24( Pel *in, Pel*** out, UInt width, UInt height ) +PlaYUVerPixFmtDescriptor yuv420p = { - frameFromBufferRGB( in, out, width * height, out[COLOR_R][0], out[COLOR_G][0], out[COLOR_B][0] ); -} -Void bufferFromFrameRGB24( Pel ***in, Pel* out, UInt width, UInt height ) -{ - bufferFromFrameRGB( in, out, width * height, in[COLOR_R][0], in[COLOR_G][0], in[COLOR_B][0] ); -} + "YUV420p", + PlaYUVerFrame::COLOR_YUV, + 3, + 3, + 1, + 1, + fillARGB32bufferYUV420p, + ADD_FFMPEG_PEL_FMT( AV_PIX_FMT_YUV420P ), + { + { 0, 0, 1, 0, 7 }, /* Y */ + { 1, 0, 1, 0, 7 }, /* U */ + { 2, 0, 1, 0, 7 }, /* V */ + }, +}; -PlaYUVerFramePelFormat RGB24 = +PlaYUVerPixFmtDescriptor yuv422p = +{ + "YUV422p", + PlaYUVerFrame::COLOR_YUV, + 3, + 3, + 1, + 0, + fillARGB32bufferYUV422, + ADD_FFMPEG_PEL_FMT( AV_PIX_FMT_YUV422P ), + { + { 0, 0, 1, 0, 7 }, /* Y */ + { 1, 0, 1, 0, 7 }, /* U */ + { 2, 0, 1, 0, 7 }, /* V */ + }, +}; + +PlaYUVerPixFmtDescriptor yuv444p = +{ + "YUV444p", + PlaYUVerFrame::COLOR_YUV, + 3, + 3, + 0, + 0, + fillARGB32bufferYUV444p, + ADD_FFMPEG_PEL_FMT( AV_PIX_FMT_YUV444P ), + { + { 0, 0, 1, 0, 7 }, /* Y */ + { 1, 0, 1, 0, 7 }, /* U */ + { 2, 0, 1, 0, 7 }, /* V */ + }, +}; + +PlaYUVerPixFmtDescriptor yuyv422 = +{ + "YUYV422", + PlaYUVerFrame::COLOR_YUV, + 3, + 1, + 1, + 0, + fillARGB32bufferYUV422, + ADD_FFMPEG_PEL_FMT( AV_PIX_FMT_YUYV422 ), + { + { 0, 1, 1, 0, 7 }, /* Y */ + { 0, 3, 2, 0, 7 }, /* U */ + { 0, 3, 4, 0, 7 }, /* V */ + }, +}; + +PlaYUVerPixFmtDescriptor gray = +{ + "GRAY", + PlaYUVerFrame::COLOR_GRAY, + 1, + 1, + 0, + 0, + fillARGB32bufferGray, + ADD_FFMPEG_PEL_FMT( AV_PIX_FMT_GRAY8 ), + { { 0, 0, 1, 0, 7 } }, /* Y */ +}; + +PlaYUVerPixFmtDescriptor RGB24 = { "RGB24", PlaYUVerFrame::COLOR_RGB, 3, 1, - 1, - frameFromBufferRGB24, - bufferFromFrameRGB24, + 0, + 0, fillARGB32bufferRGB, - ADD_FFMPEG_PEL_FMT( AV_PIX_FMT_RGB24 ), }; + ADD_FFMPEG_PEL_FMT( AV_PIX_FMT_RGB24 ), + { + { 0, 2, 1, 0, 7 }, /* R */ + { 0, 2, 2, 0, 7 }, /* G */ + { 0, 2, 3, 0, 7 }, /* B */ + }, +}; -/** BGR 8 bits per pixel / 3 channels */ -Void frameFromBufferBGR24( Pel *in, Pel*** out, UInt width, UInt height ) -{ - frameFromBufferRGB( in, out, width * height, out[COLOR_B][0], out[COLOR_G][0], out[COLOR_R][0] ); -} -Void bufferFromFrameBGR24( Pel ***in, Pel* out, UInt width, UInt height ) -{ - bufferFromFrameRGB( in, out, width * height, in[COLOR_B][0], in[COLOR_G][0], in[COLOR_R][0] ); -} - -PlaYUVerFramePelFormat BGR24 = +PlaYUVerPixFmtDescriptor BGR24 = { "BRG24", PlaYUVerFrame::COLOR_RGB, 3, 1, - 1, - frameFromBufferBGR24, - bufferFromFrameBGR24, + 0, + 0, fillARGB32bufferRGB, - ADD_FFMPEG_PEL_FMT( AV_PIX_FMT_BGR24 ), }; + ADD_FFMPEG_PEL_FMT( AV_PIX_FMT_BGR24 ), + { + { 0, 2, 3, 0, 7 }, /* R */ + { 0, 2, 2, 0, 7 }, /* G */ + { 0, 2, 1, 0, 7 }, /* B */ + }, +}; -PlaYUVerFramePelFormat g_PlaYUVerFramePelFormatsList[PLAYUVER_NUMBER_FORMATS] = +PlaYUVerPixFmtDescriptor g_PlaYUVerPixFmtDescriptorsList[PLAYUVER_NUMBER_FORMATS] = { yuv420p, yuv444p, diff --git a/lib/PlaYUVerFramePixelFormats.h b/lib/PlaYUVerFramePixelFormats.h index 88ce8de..0714eea 100644 --- a/lib/PlaYUVerFramePixelFormats.h +++ b/lib/PlaYUVerFramePixelFormats.h @@ -34,7 +34,8 @@ namespace plaYUVer #define CHROMA_RESAMPLING( X ) ( ( ( X + 1 ) >> 1 ) << 1 ) #define CHROMARATIO( SIZE, RATIO ) ( RATIO > 1 ? ( ( SIZE + 1 ) / RATIO ) : SIZE ) -#define CHROMASHIFT( SIZE, SHIFT ) ( SHIFT > 0 ? ( ( SIZE + 1 ) >> SHIFT ) : SIZE ) + +#define CHROMASHIFT( SIZE, SHIFT ) UInt( -( ( - ( Int( SIZE ) ) ) >> SHIFT ) ) #define CLAMP(X) X = X < 0 ? 0 : X > 255 ? 255 : X; @@ -74,23 +75,94 @@ inline Int pelAlpha( UInt rgb ) // get alpha part of RGBA #define PEL_RGB( r, g, b ) \ ( 0xffu << 24 ) | ( ( r & 0xff ) << 16 ) | ( ( g & 0xff ) << 8 ) | ( b & 0xff ) -struct structPlaYUVerFramePelFormat +typedef struct PlaYUVerComponentDescriptor { - const Char* name; - Int colorSpace; - UInt numberChannels; - Int ratioChromaWidth; - Int ratioChromaHeight; - Void (*frameFromBuffer)( Pel *in, Pel*** out, UInt width, UInt height ); - Void (*bufferFromFrame)( Pel ***in, Pel* out, UInt width, UInt height ); - Void (*fillARGB32buffer)( Pel*** in, UChar* out, UInt width, UInt height ); - Int ffmpegPelFormat; -}; + /** + * Which of the 4 planes contains the component. + */ + UInt16 plane; -typedef struct structPlaYUVerFramePelFormat PlaYUVerFramePelFormat; + /** + * Number of elements between 2 horizontally consecutive pixels minus 1. + * Elements are bits for bitstream formats, bytes otherwise. + */ + UInt16 step_minus1; + + /** + * Number of elements before the component of the first pixel plus 1. + * Elements are bits for bitstream formats, bytes otherwise. + */ + UInt16 offset_plus1; + + /** + * Number of least significant bits that must be shifted away + * to get the value. + */ + UInt16 shift; + + /** + * Number of bits in the component minus 1. + */ + UInt16 depth_minus1; +} PlaYUVerComponentDescriptor; + +/** + * Descriptor that unambiguously describes how the bits of a pixel are + * stored in the up to 4 data planes of an image. It also stores the + * subsampling factors and number of components. + * + * @note This is separate of the colorspace (RGB, YCbCr, YPbPr, JPEG-style YUV + * and all the YUV variants) AVPixFmtDescriptor just stores how values + * are stored not what these values represent. + */ +typedef struct PlaYUVerPixFmtDescriptor +{ + const char *name; + + Int colorSpace; + + UInt8 numberChannels; ///< The number of components each pixel has, (1-4) + + UInt8 numberPlanes; ///< The number of planes that should be read from the file + + /** + * Amount to shift the luma width right to find the chroma width. + * For YV12 this is 1 for example. + * chroma_width = -((-luma_width) >> log2ChromaWidth) + * The note above is needed to ensure rounding up. + * This value only refers to the chroma components. + */ + UInt8 log2ChromaWidth; ///< chroma_width = -((-luma_width )>>log2ChromaWidth) + + /** + * Amount to shift the luma height right to find the chroma height. + * For YV12 this is 1 for example. + * chroma_height= -((-luma_height) >> log2ChromaHeight) + * The note above is needed to ensure rounding up. + * This value only refers to the chroma components. + */ + UInt8 log2ChromaHeight; + + Void (*fillARGB32buffer)( Pel*** in, UChar* out, UInt width, UInt height ); + + Int ffmpegPelFormat; + + /** + * Parameters that describe how pixels are packed. + * If the format has 2 or 4 components, then alpha is last. + * If the format has 1 or 2 components, then luma is 0. + * If the format has 3 or 4 components, + * if the RGB flag is set then 0 is red, 1 is green and 2 is blue; + * otherwise 0 is luma, 1 is chroma-U and 2 is chroma-V. + */ + PlaYUVerComponentDescriptor comp[4]; + +} PlaYUVerPixFmtDescriptor; + +#define MAX_NUMBER_PLANES 3 #define PLAYUVER_NUMBER_FORMATS 7 -extern PlaYUVerFramePelFormat g_PlaYUVerFramePelFormatsList[PLAYUVER_NUMBER_FORMATS]; +extern PlaYUVerPixFmtDescriptor g_PlaYUVerPixFmtDescriptorsList[PLAYUVER_NUMBER_FORMATS]; } // NAMESPACE From 51f95852634654858b6b78ad788e654e5961fbef Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Fri, 6 Mar 2015 00:16:57 +0000 Subject: [PATCH 34/39] Fix bug when calculating BytesPerFrame --- lib/PlaYUVerFrame.cpp | 25 ++++++++++++++++++++++--- lib/PlaYUVerFramePixelFormats.cpp | 25 ++++++++++--------------- lib/PlaYUVerFramePixelFormats.h | 4 ++-- 3 files changed, 34 insertions(+), 20 deletions(-) diff --git a/lib/PlaYUVerFrame.cpp b/lib/PlaYUVerFrame.cpp index 552af17..8296463 100644 --- a/lib/PlaYUVerFrame.cpp +++ b/lib/PlaYUVerFrame.cpp @@ -170,7 +170,7 @@ UInt64 PlaYUVerFrame::getBytesPerFrame( UInt uiWidth, UInt uiHeight, Int iPixelF UInt64 numberBytes = uiWidth * uiHeight; if( pcPelFormat->numberChannels > 1 ) { - UInt64 numberBytesChroma = CHROMASHIFT( uiWidth, pcPelFormat->log2ChromaWidth ) * CHROMASHIFT( uiWidth, pcPelFormat->log2ChromaHeight ); + UInt64 numberBytesChroma = CHROMASHIFT( uiWidth, pcPelFormat->log2ChromaWidth ) * CHROMASHIFT( uiHeight, pcPelFormat->log2ChromaHeight ); numberBytes += ( pcPelFormat->numberChannels - 1 ) * numberBytesChroma; } return numberBytes; @@ -255,7 +255,8 @@ Void PlaYUVerFrame::frameToBuffer( Pel *output_buffer ) for( i = 0; i < CHROMASHIFT( m_uiHeight, ratioH ) * CHROMASHIFT( m_uiWidth, ratioW ); i++ ) { - *pTmpBuff++ = *pTmpPel++; + *pTmpBuff = *pTmpPel++; + pTmpBuff += step; } } @@ -265,7 +266,25 @@ Void PlaYUVerFrame::fillRGBBuffer() { if( m_bHasRGBPel ) return; - m_pcPelFormat->fillARGB32buffer( m_pppcInputPel, m_pcARGB32, m_uiWidth, m_uiHeight ); + if( m_pcPelFormat->colorSpace == COLOR_RGB ) + { + Pel* pR = m_pppcInputPel[COLOR_R][0]; + Pel* pG = m_pppcInputPel[COLOR_G][0]; + Pel* pB = m_pppcInputPel[COLOR_B][0]; + Int iR, iG, iB; + UInt* pARGB = ( UInt* )m_pcARGB32; + for( UInt i = 0; i < m_uiHeight * m_uiWidth; i++ ) + { + iR = *pR++; + iG = *pG++; + iB = *pB++; + *pARGB++ = PEL_RGB( iR, iG, iB ); + } + } + else + { + m_pcPelFormat->fillARGB32buffer( m_pppcInputPel, m_pcARGB32, m_uiWidth, m_uiHeight ); + } m_bHasRGBPel = true; } diff --git a/lib/PlaYUVerFramePixelFormats.cpp b/lib/PlaYUVerFramePixelFormats.cpp index 703d676..b34c96d 100644 --- a/lib/PlaYUVerFramePixelFormats.cpp +++ b/lib/PlaYUVerFramePixelFormats.cpp @@ -239,23 +239,16 @@ Void fillARGB32bufferYUV420p( Pel*** in, UChar* out, UInt width, UInt height ) } } - - Void fillARGB32bufferYUV444p( Pel*** in, UChar* out, UInt width, UInt height ) { fillARGB32bufferYUV( in, out, width, height, 0, 0 ); } - - Void fillARGB32bufferYUV422( Pel*** in, UChar* out, UInt width, UInt height ) { fillARGB32bufferYUV( in, out, width, height, 1, 0 ); } - - - Void fillARGB32bufferGray( Pel*** in, UChar* out, UInt width, UInt height ) { Pel *inPel = in[0][0]; @@ -285,6 +278,7 @@ Void fillARGB32bufferRGB( Pel*** in, UChar* out, UInt width, UInt height ) } } + PlaYUVerPixFmtDescriptor yuv420p = { "YUV420p", @@ -293,13 +287,13 @@ PlaYUVerPixFmtDescriptor yuv420p = 3, 1, 1, - fillARGB32bufferYUV420p, ADD_FFMPEG_PEL_FMT( AV_PIX_FMT_YUV420P ), { { 0, 0, 1, 0, 7 }, /* Y */ { 1, 0, 1, 0, 7 }, /* U */ { 2, 0, 1, 0, 7 }, /* V */ }, + fillARGB32bufferYUV420p, }; PlaYUVerPixFmtDescriptor yuv422p = @@ -310,13 +304,13 @@ PlaYUVerPixFmtDescriptor yuv422p = 3, 1, 0, - fillARGB32bufferYUV422, ADD_FFMPEG_PEL_FMT( AV_PIX_FMT_YUV422P ), { { 0, 0, 1, 0, 7 }, /* Y */ { 1, 0, 1, 0, 7 }, /* U */ { 2, 0, 1, 0, 7 }, /* V */ }, + fillARGB32bufferYUV422, }; PlaYUVerPixFmtDescriptor yuv444p = @@ -327,13 +321,13 @@ PlaYUVerPixFmtDescriptor yuv444p = 3, 0, 0, - fillARGB32bufferYUV444p, ADD_FFMPEG_PEL_FMT( AV_PIX_FMT_YUV444P ), { { 0, 0, 1, 0, 7 }, /* Y */ { 1, 0, 1, 0, 7 }, /* U */ { 2, 0, 1, 0, 7 }, /* V */ }, + fillARGB32bufferYUV444p, }; PlaYUVerPixFmtDescriptor yuyv422 = @@ -344,13 +338,13 @@ PlaYUVerPixFmtDescriptor yuyv422 = 1, 1, 0, - fillARGB32bufferYUV422, ADD_FFMPEG_PEL_FMT( AV_PIX_FMT_YUYV422 ), { { 0, 1, 1, 0, 7 }, /* Y */ { 0, 3, 2, 0, 7 }, /* U */ { 0, 3, 4, 0, 7 }, /* V */ }, + fillARGB32bufferYUV422, }; PlaYUVerPixFmtDescriptor gray = @@ -361,9 +355,9 @@ PlaYUVerPixFmtDescriptor gray = 1, 0, 0, - fillARGB32bufferGray, ADD_FFMPEG_PEL_FMT( AV_PIX_FMT_GRAY8 ), { { 0, 0, 1, 0, 7 } }, /* Y */ + fillARGB32bufferGray, }; PlaYUVerPixFmtDescriptor RGB24 = @@ -374,13 +368,13 @@ PlaYUVerPixFmtDescriptor RGB24 = 1, 0, 0, - fillARGB32bufferRGB, ADD_FFMPEG_PEL_FMT( AV_PIX_FMT_RGB24 ), { { 0, 2, 1, 0, 7 }, /* R */ { 0, 2, 2, 0, 7 }, /* G */ { 0, 2, 3, 0, 7 }, /* B */ }, + fillARGB32bufferRGB, }; PlaYUVerPixFmtDescriptor BGR24 = @@ -391,13 +385,13 @@ PlaYUVerPixFmtDescriptor BGR24 = 1, 0, 0, - fillARGB32bufferRGB, ADD_FFMPEG_PEL_FMT( AV_PIX_FMT_BGR24 ), { { 0, 2, 3, 0, 7 }, /* R */ { 0, 2, 2, 0, 7 }, /* G */ { 0, 2, 1, 0, 7 }, /* B */ }, + fillARGB32bufferRGB, }; PlaYUVerPixFmtDescriptor g_PlaYUVerPixFmtDescriptorsList[PLAYUVER_NUMBER_FORMATS] = @@ -408,6 +402,7 @@ PlaYUVerPixFmtDescriptor g_PlaYUVerPixFmtDescriptorsList[PLAYUVER_NUMBER_FORMATS yuyv422, gray, RGB24, - BGR24, }; + BGR24, +}; } // NAMESPACE diff --git a/lib/PlaYUVerFramePixelFormats.h b/lib/PlaYUVerFramePixelFormats.h index 0714eea..23f958d 100644 --- a/lib/PlaYUVerFramePixelFormats.h +++ b/lib/PlaYUVerFramePixelFormats.h @@ -143,8 +143,6 @@ typedef struct PlaYUVerPixFmtDescriptor */ UInt8 log2ChromaHeight; - Void (*fillARGB32buffer)( Pel*** in, UChar* out, UInt width, UInt height ); - Int ffmpegPelFormat; /** @@ -157,6 +155,8 @@ typedef struct PlaYUVerPixFmtDescriptor */ PlaYUVerComponentDescriptor comp[4]; + Void (*fillARGB32buffer)( Pel*** in, UChar* out, UInt width, UInt height ); + } PlaYUVerPixFmtDescriptor; #define MAX_NUMBER_PLANES 3 From 2bd2e2ce957faa5a5579ad46e820b3e4e10cc941 Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Fri, 6 Mar 2015 00:52:30 +0000 Subject: [PATCH 35/39] Fix save image with opencv problems --- lib/LibOpenCVHandler.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/lib/LibOpenCVHandler.cpp b/lib/LibOpenCVHandler.cpp index 7d2aa6e..18256b4 100644 --- a/lib/LibOpenCVHandler.cpp +++ b/lib/LibOpenCVHandler.cpp @@ -125,7 +125,7 @@ Bool LibOpenCVHandler::saveFrame( PlaYUVerFrame* pcFrame, std::string filename ) switch( pcFrame->getNumberChannels() ) { case 3: - cvType = CV_8UC4; + cvType = CV_8UC3; break; case 1: cvType = CV_8UC1; @@ -134,10 +134,20 @@ Bool LibOpenCVHandler::saveFrame( PlaYUVerFrame* pcFrame, std::string filename ) return false; break; } + cv::Mat pcCvFrame( pcFrame->getHeight(), pcFrame->getWidth(), cvType ); + if( pcFrame->getColorSpace() != PlaYUVerFrame::COLOR_GRAY ) { - memcpy( pcCvFrame.data, pcFrame->getRGBBuffer(), pcFrame->getHeight() * pcFrame->getWidth() * 4 * sizeof(UChar) ); + UChar* pCvPel = pcCvFrame.data; + UChar* pARGB = pcFrame->getRGBBuffer(); + for( UInt i = 0; i < pcFrame->getHeight() * pcFrame->getWidth(); i++ ) + { + *pCvPel++ = *pARGB++; + *pCvPel++ = *pARGB++; + *pCvPel++ = *pARGB++; + pARGB++; + } } else { From 2a43b5262a2be84398cc28d260215f537c36c978 Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Fri, 6 Mar 2015 01:50:59 +0000 Subject: [PATCH 36/39] Try fix detection of number of frames (detected problem within the libavs). Use double for frame rate --- app/VideoHandle.cpp | 2 +- lib/LibAvContextHandle.cpp | 122 ++++++++++++++++++------------------- lib/LibAvContextHandle.h | 8 ++- lib/PlaYUVerStream.cpp | 13 ++-- lib/PlaYUVerStream.h | 6 +- 5 files changed, 76 insertions(+), 75 deletions(-) diff --git a/app/VideoHandle.cpp b/app/VideoHandle.cpp index d6a9a46..7951d6d 100644 --- a/app/VideoHandle.cpp +++ b/app/VideoHandle.cpp @@ -427,7 +427,7 @@ Void VideoHandle::play() if( !m_pcCurrentVideoSubWindow->isPlaying() ) // Not playing { - UInt frameRate; + Double frameRate; UInt timeInterval; if( m_acPlayingSubWindows.size() < 2 ) { diff --git a/lib/LibAvContextHandle.cpp b/lib/LibAvContextHandle.cpp index 0d66a7d..6ef2101 100644 --- a/lib/LibAvContextHandle.cpp +++ b/lib/LibAvContextHandle.cpp @@ -133,7 +133,7 @@ Void LibAvContextHandle::closeAvFormat() m_bHasStream = false; } -Bool LibAvContextHandle::initAvFormat( const char* filename, UInt& width, UInt& height, Int& pixel_format, UInt& frame_rate, UInt64& num_frames ) +Bool LibAvContextHandle::initAvFormat( const char* filename, UInt& width, UInt& height, Int& pixel_format, Double& frame_rate, UInt64& num_frames ) { fmt_ctx = NULL; video_dec_ctx = NULL; @@ -212,9 +212,13 @@ Bool LibAvContextHandle::initAvFormat( const char* filename, UInt& width, UInt& else if( video_stream->codec->time_base.den && video_stream->codec->time_base.num ) fr = 1 / av_q2d( video_stream->codec->time_base ); - frame_rate = ( UInt )fr; + frame_rate = fr; - if( fmt_ctx->duration != AV_NOPTS_VALUE ) + /*if( video_stream->nb_frames ) + { + num_frames = video_stream->nb_frames; + } + else*/ if( fmt_ctx->duration != AV_NOPTS_VALUE ) { Int64 duration = fmt_ctx->duration + 5000; m_uiSecs = duration / AV_TIME_BASE; @@ -292,77 +296,71 @@ Bool LibAvContextHandle::initAvFormat( const char* filename, UInt& width, UInt& return true; } +Bool LibAvContextHandle::decodeVideoPkt() +{ + Int got_frame = 0; + Int decResult; + if( pkt.stream_index == video_stream_idx ) + { + decResult = avcodec_decode_video2( video_dec_ctx, frame, &got_frame, &pkt ); + if( decResult < 0 ) + { + fprintf( stderr, "Error decoding video frame\n" ); + return false; + } + pkt.data += decResult; + pkt.size -= decResult; + } + else + { + pkt.size = 0; + } + Bool bRet = got_frame > 0 ? true : false; + return bRet; +} + Bool LibAvContextHandle::decodeAvFormat() { - Int got_frame; - Int decResult; + Bool bGotFrame = false; + AVPacket orig_pkt = pkt; + + bGotFrame |= decodeVideoPkt(); + /* read frames from the file */ - while( av_read_frame( fmt_ctx, &pkt ) >= 0 ) + while( !bGotFrame && ( av_read_frame( fmt_ctx, &pkt ) >= 0 ) ) { - AVPacket orig_pkt = pkt; + orig_pkt = pkt; do { - if( pkt.stream_index == video_stream_idx ) - { - /* decode video frame */ - decResult = avcodec_decode_video2( video_dec_ctx, frame, &got_frame, &pkt ); - if( decResult < 0 ) - { - fprintf( stderr, "Error decoding video frame\n" ); - return false; - } - - if( got_frame ) - { - av_image_copy_to_buffer( m_pchFrameBuffer, m_uiFrameBufferSize, frame->data, frame->linesize, video_dec_ctx->pix_fmt, video_dec_ctx->width, - video_dec_ctx->height, 1 ); - } - } - pkt.data += decResult; - pkt.size -= decResult; + bGotFrame |= decodeVideoPkt(); + if( bGotFrame ) + break; } while( pkt.size > 0 ); + + if( bGotFrame ) + { + break; + } + } + + /*! Try flush existing packets */ + if( !bGotFrame ) + { + bGotFrame |= decodeVideoPkt(); + } + + if( bGotFrame ) + { + av_image_copy_to_buffer( m_pchFrameBuffer, m_uiFrameBufferSize, frame->data, frame->linesize, video_dec_ctx->pix_fmt, video_dec_ctx->width, + video_dec_ctx->height, 1 ); + av_free_packet( &orig_pkt ); -// /* read frames from the file */ -// while( av_read_frame( fmt_ctx, &pkt ) >= 0 ) -// { -// if( pkt.stream_index == video_stream_idx ) -// { -// /* decode video frame */ -// Int ret = avcodec_decode_video2( video_dec_ctx, frame, &got_frame, &pkt ); -// if( ret < 0 ) -// { -// fprintf( stderr, "Error decoding video frame\n" ); -// return false; -// } -// -// if( got_frame ) -// { -// av_image_copy_to_buffer( m_pchFrameBuffer, m_uiFrameBufferSize, frame->data, frame->linesize, video_dec_ctx->pix_fmt, video_dec_ctx->width, -// video_dec_ctx->height, 1 ); -// -// /* copy decoded frame to destination buffer: -// * this is required since rawvideo expects non aligned data */ -// // av_image_copy( video_dst_data, video_dst_linesize, ( const uint8_t ** )( frame->data ), frame->linesize, video_dec_ctx->pix_fmt, video_dec_ctx->width, -// // video_dec_ctx->height ); -// } -// } -// av_free_packet( &pkt ); - if( got_frame ) - return true; + return true; } - return false; -// /* flush cached frames */ -// pkt.data = NULL; -// pkt.size = 0; -// do -// { -// decode_packet( &got_frame, 1 ); -// } -// while( got_frame ); - return true; + return false; } Void LibAvContextHandle::seekAvFormat( UInt64 frame_num ) diff --git a/lib/LibAvContextHandle.h b/lib/LibAvContextHandle.h index 1a2e977..bf51225 100644 --- a/lib/LibAvContextHandle.h +++ b/lib/LibAvContextHandle.h @@ -66,7 +66,7 @@ public: m_bHasStream( false ) { } - Bool initAvFormat( const char* filename, UInt& width, UInt& height, Int& pixel_format, UInt& frame_rate, UInt64& num_frames ); + Bool initAvFormat( const char* filename, UInt& width, UInt& height, Int& pixel_format, Double& frame_rate, UInt64& num_frames ); Void closeAvFormat(); Bool decodeAvFormat(); @@ -103,8 +103,10 @@ private: Bool m_bHasStream; Char m_acCodecName[20]; - UInt m_uiSecs; - UInt m_uiMicroSec; + UInt64 m_uiSecs; + UInt64 m_uiMicroSec; + + Bool decodeVideoPkt(); }; } // NAMESPACE diff --git a/lib/PlaYUVerStream.cpp b/lib/PlaYUVerStream.cpp index 25514a8..95390cf 100644 --- a/lib/PlaYUVerStream.cpp +++ b/lib/PlaYUVerStream.cpp @@ -148,7 +148,7 @@ PlaYUVerStream::PlaYUVerStream() m_uiTotalFrameNum = 0; m_iCurrFrameNum = -1; m_iPixelFormat = -1; - m_uiFrameRate = 30; + m_dFrameRate = 30; m_iFileFormat = -1; m_pStreamBuffer = NULL; m_cFilename = ""; @@ -205,7 +205,7 @@ Bool PlaYUVerStream::open( std::string filename, UInt width, UInt height, Int in m_uiWidth = width; m_uiHeight = height; m_iPixelFormat = input_format; - m_uiFrameRate = frame_rate; + m_dFrameRate = frame_rate; m_pchFilename = new Char[m_cFilename.size() + 1]; std::copy( m_cFilename.begin(), m_cFilename.end(), m_pchFilename ); @@ -271,7 +271,7 @@ Bool PlaYUVerStream::open( std::string filename, UInt width, UInt height, Int in #ifdef USE_FFMPEG if( m_uiStreamHandler == FFMPEG ) { - if( !m_cLibAvContext->initAvFormat( m_pchFilename, m_uiWidth, m_uiHeight, m_iPixelFormat, m_uiFrameRate, m_uiTotalFrameNum ) ) + if( !m_cLibAvContext->initAvFormat( m_pchFilename, m_uiWidth, m_uiHeight, m_iPixelFormat, m_dFrameRate, m_uiTotalFrameNum ) ) { throw "Cannot open file using FFmpeg libs"; } @@ -442,7 +442,7 @@ Void PlaYUVerStream::getFormat( UInt& rWidth, UInt& rHeight, Int& rInputFormat, rWidth = m_uiWidth; rHeight = m_uiHeight; rInputFormat = m_iPixelFormat; - rFrameRate = m_uiFrameRate; + rFrameRate = m_dFrameRate; } else { @@ -506,7 +506,7 @@ Void PlaYUVerStream::getDuration( Int* duration_array ) else #endif { - secs = m_uiTotalFrameNum / m_uiFrameRate; + secs = m_uiTotalFrameNum / m_dFrameRate; } mins = secs / 60; secs %= 60; @@ -520,7 +520,8 @@ Void PlaYUVerStream::getDuration( Int* duration_array ) Void PlaYUVerStream::readFrameFillRGBBuffer() { readFrame(); - m_pcNextFrame->fillRGBBuffer(); + if( m_pcNextFrame ) + m_pcNextFrame->fillRGBBuffer(); return; } diff --git a/lib/PlaYUVerStream.h b/lib/PlaYUVerStream.h index 6519b0b..0db4a24 100644 --- a/lib/PlaYUVerStream.h +++ b/lib/PlaYUVerStream.h @@ -90,7 +90,7 @@ private: UInt m_uiWidth; UInt m_uiHeight; - UInt m_uiFrameRate; + Double m_dFrameRate; UInt64 m_uiTotalFrameNum; Int64 m_iCurrFrameNum; @@ -181,9 +181,9 @@ public: { return m_iCurrFrameNum; } - UInt getFrameRate() + Double getFrameRate() { - return m_uiFrameRate; + return m_dFrameRate; } Void getDuration( Int* duration_array ); From 5e4af61da6484f3b91f93ccc6aefd104544d0731 Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Mon, 9 Mar 2015 00:08:36 +0000 Subject: [PATCH 37/39] Minor fixes in modules handle --- app/ModulesHandle.cpp | 24 ++++++++++++------------ app/VideoSubWindow.h | 5 +++++ 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/app/ModulesHandle.cpp b/app/ModulesHandle.cpp index d481017..89f512c 100644 --- a/app/ModulesHandle.cpp +++ b/app/ModulesHandle.cpp @@ -164,16 +164,18 @@ Void ModulesHandle::updateMenus() if( pcSubWindow ) { QList apcCurrentModule = pcSubWindow->getModuleArray(); + if( pcSubWindow->getDisplayModule() ) + { + m_arrayActions[APPLY_ALL_ACT]->setEnabled( true ); + m_arrayActions[SWAP_FRAMES_ACT]->setEnabled( true ); + apcCurrentModule.append( pcSubWindow->getDisplayModule() ); + } for( Int i = 0; i < apcCurrentModule.size(); i++ ) { currModuleAction = apcCurrentModule.at( i )->m_pcModuleAction; currModuleAction->setChecked( true ); } - if( apcCurrentModule.size() ) - { - m_arrayActions[APPLY_ALL_ACT]->setEnabled( true ); - m_arrayActions[SWAP_FRAMES_ACT]->setEnabled( true ); - } + } } @@ -194,10 +196,10 @@ Void ModulesHandle::processOpt( Int index ) VideoSubWindow* pcSubWindow = qobject_cast( m_pcMainWindowManager->activeSubWindow() ); if( pcSubWindow ) { - QList apcCurrentModule = pcSubWindow->getModuleArray(); - if( apcCurrentModule.size() > 1 ) + PlaYUVerAppModuleIf* pcCurrentModule = pcSubWindow->getDisplayModule(); + if( pcCurrentModule ) { - PlaYUVerAppModuleIf* pcCurrModule = apcCurrentModule.at( 0 ); + PlaYUVerAppModuleIf* pcCurrModule = pcCurrentModule; switch( index ) { case INVALID_OPT: @@ -304,11 +306,10 @@ Void ModulesHandle::enableModuleIf( PlaYUVerAppModuleIf *pcCurrModuleIf ) pcModuleSubWindow->setWindowName( windowName ); connect( pcModuleSubWindow->getViewArea(), SIGNAL( selectionChanged( QRect ) ), m_appModuleVideo, SLOT( updateSelectionArea( QRect ) ) ); - connect( pcModuleSubWindow, SIGNAL( zoomFactorChanged_SWindow( const double, const QPoint ) ), m_appModuleVideo, SLOT( zoomToFactorAll( double, QPoint ) ) ); + connect( pcModuleSubWindow, SIGNAL( zoomFactorChanged_SWindow( const double, const QPoint ) ), m_appModuleVideo, + SLOT( zoomToFactorAll( double, QPoint ) ) ); connect( pcModuleSubWindow, SIGNAL( scrollBarMoved_SWindow( const QPoint ) ), m_appModuleVideo, SLOT( moveAllScrollBars( const QPoint ) ) ); - - pcCurrModuleIf->m_pcDisplaySubWindow = pcModuleSubWindow; } @@ -468,7 +469,6 @@ Void ModulesHandle::applyAllModuleIf( PlaYUVerAppModuleIf *pcCurrModuleIf ) } supported.append( " )" ); - QStringList filter; filter << supported << formatsList diff --git a/app/VideoSubWindow.h b/app/VideoSubWindow.h index fd9c2e5..eb8ec66 100644 --- a/app/VideoSubWindow.h +++ b/app/VideoSubWindow.h @@ -179,6 +179,11 @@ public: Void disableModule( PlaYUVerAppModuleIf* pcModule = NULL ); Void associateModule( PlaYUVerAppModuleIf* pcModule ); + PlaYUVerAppModuleIf* getDisplayModule() + { + return m_pcCurrentDisplayModule; + } + QList getModuleArray() { return m_apcCurrentModule; From 7bdd4a1215442d42d77100878c283e5f6bec8ba6 Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Mon, 9 Mar 2015 00:09:29 +0000 Subject: [PATCH 38/39] Add support for frame processing modules - needs debug --- tools/PlaYUVerTools.cpp | 55 ++++++++++++++++++++++++++++++++++------- tools/PlaYUVerTools.h | 1 + 2 files changed, 47 insertions(+), 9 deletions(-) diff --git a/tools/PlaYUVerTools.cpp b/tools/PlaYUVerTools.cpp index 1089678..d0ba086 100644 --- a/tools/PlaYUVerTools.cpp +++ b/tools/PlaYUVerTools.cpp @@ -186,6 +186,32 @@ Int PlaYUVerTools::Open( Int argc, Char *argv[] ) m_pcCurrModuleIf->create( m_apcInputStreams[0]->getCurrFrame() ); + if( m_pcCurrModuleIf->m_iModuleType == FRAME_PROCESSING_MODULE ) + { + // Check outputs + std::vector outputFileNames; + if( m_cCommandLineParser.getOptionsMap().count( "output" ) ) + outputFileNames = m_cCommandLineParser.getOptionsMap()["output"].as >(); + + if( outputFileNames.size() == 1 ) + { + PlaYUVerFrame* pcModFrame = applyFrameModule(); + PlaYUVerStream* pcModStream = new PlaYUVerStream; + if( !pcModStream->open( outputFileNames[0], pcModFrame->getWidth(), pcModFrame->getHeight(), pcModFrame->getPelFormat(), 1, false ) ) + { + delete pcModStream; + pcModStream = NULL; + return 2; + } + m_apcOutputStreams.push_back( pcModStream ); + } + else + { + printf( "One output is required! " ); + return 2; + } + } + m_uiOperation = MODULE_OPERATION; m_fpProcess = &PlaYUVerTools::ModuleOperation; printf( "PlaYUVer Module\n" ); @@ -265,6 +291,24 @@ Int PlaYUVerTools::QualityOperation() return 0; } +PlaYUVerFrame* PlaYUVerTools::applyFrameModule() +{ + PlaYUVerFrame* pcProcessedFrame = NULL; + if( m_pcCurrModuleIf->m_iModuleType == FRAME_PROCESSING_MODULE ) + { + switch( m_pcCurrModuleIf->m_uiNumberOfFrames ) + { + case MODULE_REQUIRES_ONE_FRAME: + pcProcessedFrame = m_pcCurrModuleIf->process( m_apcInputStreams[0]->getCurrFrame() ); + break; + case MODULE_REQUIRES_TWO_FRAMES: + pcProcessedFrame = m_pcCurrModuleIf->process( m_apcInputStreams[0]->getCurrFrame(), m_apcInputStreams[1]->getCurrFrame() ); + break; + } + } + return pcProcessedFrame; +} + Int PlaYUVerTools::ModuleOperation() { printf( " Applying Module %s/%s ... \n", m_pcCurrModuleIf->m_pchModuleCategory, m_pcCurrModuleIf->m_pchModuleName ); @@ -284,15 +328,8 @@ Int PlaYUVerTools::ModuleOperation() if( m_pcCurrModuleIf->m_iModuleType == FRAME_PROCESSING_MODULE ) { - switch( m_pcCurrModuleIf->m_uiNumberOfFrames ) - { - case MODULE_REQUIRES_ONE_FRAME: - pcProcessedFrame = m_pcCurrModuleIf->process( m_apcInputStreams[0]->getCurrFrame() ); - break; - case MODULE_REQUIRES_TWO_FRAMES: - pcProcessedFrame = m_pcCurrModuleIf->process( m_apcInputStreams[0]->getCurrFrame(), m_apcInputStreams[1]->getCurrFrame() ); - break; - } + pcProcessedFrame = applyFrameModule(); + m_apcInputStreams[0]->writeFrame( pcProcessedFrame ); } else if( m_pcCurrModuleIf->m_iModuleType == FRAME_MEASUREMENT_MODULE ) { diff --git a/tools/PlaYUVerTools.h b/tools/PlaYUVerTools.h index 6082ad7..905b825 100644 --- a/tools/PlaYUVerTools.h +++ b/tools/PlaYUVerTools.h @@ -73,6 +73,7 @@ private: Int QualityOperation(); PlaYUVerModuleIf* m_pcCurrModuleIf; + PlaYUVerFrame* applyFrameModule(); Int ModuleOperation(); }; From 9c554db5025610e962b801bd049c3220f25aca78 Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Mon, 9 Mar 2015 02:03:16 +0000 Subject: [PATCH 39/39] Fixing include in Qt4 --- app/VideoSubWindow.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/VideoSubWindow.cpp b/app/VideoSubWindow.cpp index 3a50280..237f413 100644 --- a/app/VideoSubWindow.cpp +++ b/app/VideoSubWindow.cpp @@ -26,7 +26,9 @@ #include "ModulesHandle.h" #include "SubWindowHandle.h" #include "ConfigureFormatDialog.h" +#if( QT_VERSION_PLAYUVER == 5 ) #include "QtConcurrent/qtconcurrentrun.h" +#endif namespace plaYUVer {