From 6de2a3172b78dcf23dd7adcc732989e920dc708e Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Thu, 30 Jan 2014 01:43:27 +0000 Subject: [PATCH 01/18] Add function to display the next frame in ImageInterface --- source/ImageInterface.cpp | 12 ++++++++++++ source/ImageInterface.h | 2 ++ 2 files changed, 14 insertions(+) diff --git a/source/ImageInterface.cpp b/source/ImageInterface.cpp index 2b0d869..7891c30 100644 --- a/source/ImageInterface.cpp +++ b/source/ImageInterface.cpp @@ -120,6 +120,18 @@ bool ImageInterface::saveFile( const QString &fileName ) return true; } +bool ImageInterface::nextVideoFrame() +{ + m_currStream.readFrame(); + if( m_currStream.checkErrors( READING ) ) + { + QMessageBox::warning( this, tr( "plaYUVer" ), tr( "Cannot read %1." ).arg( m_cCurrFileName ) ); + return false; + } + m_cViewArea->setImage( QPixmap::fromImage( m_currStream.getFrameQImage() ) ); + return true; +} + Void ImageInterface::normalSize() { m_dScaleFactor = 1.0; diff --git a/source/ImageInterface.h b/source/ImageInterface.h index ef6ae62..8566d7e 100644 --- a/source/ImageInterface.h +++ b/source/ImageInterface.h @@ -68,6 +68,8 @@ public: bool saveAs(); bool saveFile( const QString &fileName ); + bool nextVideoFrame(); + /** * Show the image at its original size */ From 93f61d354999107a235c1d28d4775bbdc4bdc790 Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Thu, 30 Jan 2014 01:43:53 +0000 Subject: [PATCH 02/18] Initial playing test using QTimer --- source/plaYUVerApp.cpp | 30 ++++++++++++++++++++++++++++++ source/plaYUVerApp.h | 5 +++++ 2 files changed, 35 insertions(+) diff --git a/source/plaYUVerApp.cpp b/source/plaYUVerApp.cpp index 23b2b4f..53cbb9b 100644 --- a/source/plaYUVerApp.cpp +++ b/source/plaYUVerApp.cpp @@ -58,6 +58,10 @@ plaYUVerApp::plaYUVerApp() setWindowTitle( tr( "plaYUVerApp" ) ); setWindowIcon( QIcon( ":/images/playuver.png" ) ); setUnifiedTitleAndToolBarOnMac( true ); + + playingTimer = new QTimer( this ); + + playingTimer->start( 1000 ); } Void plaYUVerApp::closeEvent( QCloseEvent *event ) @@ -112,6 +116,7 @@ void plaYUVerApp::open() interfaceChild->close(); } } + play(); } void plaYUVerApp::saveAs() @@ -119,6 +124,28 @@ void plaYUVerApp::saveAs() } +// ----------------------- Playing Functions -------------------- + +void plaYUVerApp::play() +{ + + connect( playingTimer, SIGNAL( timeout() ), this, SLOT( playEvent() ) ); + +} + + +void plaYUVerApp::playEvent() +{ + if( activeImageInterface() ) + { + if( !activeImageInterface()->nextVideoFrame() ) + { + playingTimer->stop(); + } + } + +} + // ----------------------- Zoom Functions ----------------------- void plaYUVerApp::zoomIn() @@ -286,6 +313,9 @@ Void plaYUVerApp::createActions() zoomToFitAct->setShortcut( tr( "Ctrl+F" ) ); connect( zoomToFitAct, SIGNAL( triggered() ), this, SLOT( zoomToFit() ) ); + // ------------ Playing ------------ + + // ------------ Window ------------ tileAct = new QAction( tr( "&Tile" ), this ); diff --git a/source/plaYUVerApp.h b/source/plaYUVerApp.h index f6d1709..56caf93 100644 --- a/source/plaYUVerApp.h +++ b/source/plaYUVerApp.h @@ -54,6 +54,10 @@ private slots: void open(); void saveAs(); + //! Playing functions + void play(); + void playEvent(); + //! View functions void zoomIn(); void zoomOut(); @@ -89,6 +93,7 @@ private: QString m_cLastOpenPath; + QTimer *playingTimer; QMdiArea *mdiArea; QSignalMapper *windowMapper; From f00c91bf430c2b487c55493ce7fad4c9943fad8c Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Thu, 30 Jan 2014 20:06:10 +0000 Subject: [PATCH 03/18] Improve CMakeLists to handle variables and initial support for QT4 --- CMakeLists.txt | 116 ++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 90 insertions(+), 26 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0cc40f5..3d78450 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,8 +12,6 @@ PROJECT( playuver ) SET( PROJECT_NAME playuver ) -SET( CMAKE_BUILD_TYPE Debug ) - # Project directories SET( SRC_DIR source ) SET( INC_DIR source ) @@ -26,20 +24,6 @@ SET( CMAKE_INCLUDE_CURRENT_DIR ON ) # Instruct CMake to run moc automatically when needed. SET( CMAKE_AUTOMOC ON ) - -###################################################################################### -# Dependencies -###################################################################################### -#FIND_PACKAGE( OpenCV REQUIRED ) - - -###################################################################################### -# Qt5 library -###################################################################################### -FIND_PACKAGE( Qt5Core ) -FIND_PACKAGE( Qt5Gui ) -FIND_PACKAGE( Qt5Widgets ) - INCLUDE_DIRECTORIES( ${CMAKE_BINARY_DIR} ${INC_DIR} ) FILE( GLOB SOURCES_FILES ${SRC_DIR}/*.cpp ) @@ -47,16 +31,94 @@ FILE( GLOB HEADERS_FILES ${INC_DIR}/*.h ) FILE( GLOB FORMS_FILES ${UI_DIR}/*.ui ) FILE( GLOB RESOURCES_FILES ${RSC_DIR}/*.qrc ) -INCLUDE_DIRECTORIES( ${Qt5Widgets_INCLUDE_DIRS} ${Qt5Core_INCLUDE_DIRS} ${Qt5Gui_INCLUDE_DIRS}) +###################################################################################### +# Macros +###################################################################################### +macro(ADD_OPTION variable description value) + set(__value ${value}) + set(__condition "") + set(__varname "__value") + foreach(arg ${ARGN}) + if(arg STREQUAL "IF" OR arg STREQUAL "if") + set(__varname "__condition") + else() + list(APPEND ${__varname} ${arg}) + endif() + endforeach() + unset(__varname) + if("${__condition}" STREQUAL "") + set(__condition 2 GREATER 1) + endif() -# QT5_WRAP_CPP( HEADERS_MOC_FILES ${HEADERS_FILES} ) -QT5_WRAP_UI( FORMS_HEADERS_FILES ${FORMS_FILES} ) -QT5_ADD_RESOURCES( RESOURCES_RCC_FILES ${RESOURCES_FILES} ) + if(${__condition}) + if("${__value}" MATCHES ";") + if(${__value}) + option(${variable} "${description}" ON) + else() + option(${variable} "${description}" OFF) + endif() + elseif(DEFINED ${__value}) + if(${__value}) + option(${variable} "${description}" ON) + else() + option(${variable} "${description}" OFF) + endif() + else() + option(${variable} "${description}" ${__value}) + endif() + else() + unset(${variable} CACHE) + endif() + unset(__condition) + unset(__value) +endmacro() -SET( QT_USE_QTOPENGL TRUE ) +###################################################################################### +# Variables +###################################################################################### +ADD_OPTION(CMAKE_BUILD_TYPE "Build type" Debug ) +ADD_OPTION(USE_QT4 "Build with QT4" OFF ) +ADD_OPTION(USE_OPENCV "Add OpenCV support" OFF ) + +###################################################################################### +# Dependencies +###################################################################################### +IF(HAVE_OpenCV) + FIND_PACKAGE( OpenCV REQUIRED ) + #CMAKEDEFINE HAVE_MALLOC_H 1 +ENDIF() + +###################################################################################### +# Qt library +###################################################################################### +IF( USE_QT4 ) + FIND_PACKAGE( Qt4 REQUIRED QtCore QtGui ) + IF( NOT QT4_FOUND) + SET(USE_QT4 FALSE) + ENDIF() + INCLUDE( ${QT_USE_FILE} ) + ADD_DEFINITIONS( ${QT_DEFINITIONS} ) + SET( CURR_QT_LINKER_LIBS ${QT_LIBRARIES} ) +ENDIF() + +IF( NOT USE_QT4 ) + FIND_PACKAGE( Qt5Core REQUIRED ) + FIND_PACKAGE( Qt5Gui REQUIRED ) + FIND_PACKAGE( Qt5Widgets REQUIRED ) + + INCLUDE_DIRECTORIES( ${Qt5Widgets_INCLUDE_DIRS} ${Qt5Core_INCLUDE_DIRS} ${Qt5Gui_INCLUDE_DIRS} ) + # QT5_WRAP_CPP( HEADERS_MOC_FILES ${HEADERS_FILES} ) + QT5_WRAP_UI( FORMS_HEADERS_FILES ${FORMS_FILES} ) + QT5_ADD_RESOURCES( RESOURCES_RCC_FILES ${RESOURCES_FILES} ) + + # Add compiler flags for building executables (-fPIE) + SET( CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} ${Qt5Core_EXECUTABLE_COMPILE_FLAGS} ) + + SET( CURR_QT_LINKER_LIBS ${Qt5Core_LIBRARIES} ${Qt5Gui_LIBRARIES} ${Qt5Widgets_LIBRARIES} ) + + SET( CURR_QT_MODULES Core Gui Widgets ) +ENDIF() -# Add compiler flags for building executables (-fPIE) -SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Core_EXECUTABLE_COMPILE_FLAGS}" ) ###################################################################################### # External Libs @@ -72,8 +134,10 @@ SET( LIST_EXTERNAL_LIBS Scode ) # Target App ###################################################################################### ADD_EXECUTABLE( ${PROJECT_NAME} ${SOURCES_FILES} ${HEADERS_MOC_FILES} ${FORMS_HEADERS_FILES} ${RESOURCES_RCC_FILES} ) -TARGET_LINK_LIBRARIES( ${PROJECT_NAME} ${LIST_EXTERNAL_LIBS} ${Qt5Core_LIBRARIES} ${Qt5Gui_LIBRARIES} ${Qt5Widgets_LIBRARIES} ) -QT5_USE_MODULES( ${PROJECT_NAME} Core Gui Widgets ) - +TARGET_LINK_LIBRARIES( ${PROJECT_NAME} ${LIST_EXTERNAL_LIBS} ${CURR_QT_LINKER_LIBS} ) + +IF( NOT USE_QT4) + QT5_USE_MODULES( ${PROJECT_NAME} ${CURR_QT_MODULES} ) +ENDIF() From 9b980b1eaf618c4511f6a653173612914293d4bc Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Thu, 30 Jan 2014 21:43:54 +0000 Subject: [PATCH 04/18] Add full support to Qt4 in both CMakeLists and source code! config.h is now used --- CMakeLists.txt | 19 +++++++++++++++---- source/ConfigureFormatDialog.cpp | 2 -- source/ConfigureFormatDialog.h | 18 ++++++++++-------- source/ImageInterface.cpp | 6 ------ source/ImageInterface.h | 16 ++++++++-------- source/InputStream.cpp | 1 - source/InputStream.h | 2 ++ source/LibMemAlloc.h | 2 ++ source/TypeDef.h | 12 ++++++++++++ source/plaYUVerApp.cpp | 5 ++++- source/plaYUVerApp.h | 2 ++ source/plaYUVerSettings.cpp | 2 -- source/plaYUVerSettings.h | 10 +++------- 13 files changed, 58 insertions(+), 39 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3d78450..5b36ac8 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -83,9 +83,11 @@ ADD_OPTION(USE_OPENCV "Add OpenCV support" OFF ) ###################################################################################### # Dependencies ###################################################################################### -IF(HAVE_OpenCV) - FIND_PACKAGE( OpenCV REQUIRED ) - #CMAKEDEFINE HAVE_MALLOC_H 1 +IF( USE_OPENCV ) + FIND_PACKAGE( OpenCV QUIET ) + IF( NOT OpenCV_FOUND) + SET(USE_OPENCV FALSE) + ENDIF() ENDIF() ###################################################################################### @@ -98,6 +100,10 @@ IF( USE_QT4 ) ENDIF() INCLUDE( ${QT_USE_FILE} ) ADD_DEFINITIONS( ${QT_DEFINITIONS} ) + + QT4_WRAP_UI( FORMS_HEADERS_FILES ${FORMS_FILES} ) + QT4_ADD_RESOURCES( RESOURCES_RCC_FILES ${RESOURCES_FILES} ) + SET( CURR_QT_LINKER_LIBS ${QT_LIBRARIES} ) ENDIF() @@ -119,7 +125,6 @@ IF( NOT USE_QT4 ) SET( CURR_QT_MODULES Core Gui Widgets ) ENDIF() - ###################################################################################### # External Libs ###################################################################################### @@ -130,6 +135,12 @@ ADD_LIBRARY( Scode ${EXTERNAL_SRC}/scode/viewarea.cpp ${EXTERNAL_SRC}/scode/grid SET( LIST_EXTERNAL_LIBS Scode ) +###################################################################################### +# Create config.h +###################################################################################### +CONFIGURE_FILE( ${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h ) + + ###################################################################################### # Target App ###################################################################################### diff --git a/source/ConfigureFormatDialog.cpp b/source/ConfigureFormatDialog.cpp index fbd6307..9781458 100755 --- a/source/ConfigureFormatDialog.cpp +++ b/source/ConfigureFormatDialog.cpp @@ -21,8 +21,6 @@ * \brief Dialog box to set the sequence resolution */ -#include -#include #include "ConfigureFormatDialog.h" #include "InputStream.h" diff --git a/source/ConfigureFormatDialog.h b/source/ConfigureFormatDialog.h index 641c492..5b1b3ac 100755 --- a/source/ConfigureFormatDialog.h +++ b/source/ConfigureFormatDialog.h @@ -24,15 +24,17 @@ #ifndef __CONFIGURERESOLUTIONDIALOG_H__ #define __CONFIGURERESOLUTIONDIALOG_H__ + +#include "config.h" + +#if( QT_VERSION_PLAYUVER == 5 ) +#include +#elif( QT_VERSION_PLAYUVER == 4 ) +#include +#endif #include -#include -#include -#include -#include -#include -#include -#include -#include + + #include "TypeDef.h" class QPixmap; diff --git a/source/ImageInterface.cpp b/source/ImageInterface.cpp index 7891c30..3427a4a 100644 --- a/source/ImageInterface.cpp +++ b/source/ImageInterface.cpp @@ -21,12 +21,6 @@ * \brief Sub windows handling */ -#include -#include -#include -#include -#include - #include "ConfigureFormatDialog.h" #include "ImageInterface.h" #include "viewarea.h" diff --git a/source/ImageInterface.h b/source/ImageInterface.h index 8566d7e..8ab247f 100644 --- a/source/ImageInterface.h +++ b/source/ImageInterface.h @@ -24,14 +24,14 @@ #ifndef __IMAGEINTERFACE_H__ #define __IMAGEINTERFACE_H__ -#include -#include -#include -#include -#include -//#include -//#include -//#include + +#include "config.h" + +#if( QT_VERSION_PLAYUVER == 5 ) +#include +#elif( QT_VERSION_PLAYUVER == 4 ) +#include +#endif #include "TypeDef.h" diff --git a/source/InputStream.cpp b/source/InputStream.cpp index dcb92bc..42594c3 100755 --- a/source/InputStream.cpp +++ b/source/InputStream.cpp @@ -23,7 +23,6 @@ #include -#include #include #include "InputStream.h" diff --git a/source/InputStream.h b/source/InputStream.h index a85ac10..8fe5e1f 100755 --- a/source/InputStream.h +++ b/source/InputStream.h @@ -24,6 +24,8 @@ #ifndef __INPUTSTREAM_H__ #define __INPUTSTREAM_H__ +#include "config.h" + #include #include diff --git a/source/LibMemAlloc.h b/source/LibMemAlloc.h index e131e3d..62512d0 100644 --- a/source/LibMemAlloc.h +++ b/source/LibMemAlloc.h @@ -24,6 +24,8 @@ #ifndef __LIBMEMALLOC_H__ #define __LIBMEMALLOC_H__ +#include "config.h" + #include #include #include "TypeDef.h" diff --git a/source/TypeDef.h b/source/TypeDef.h index 05b046d..94959e6 100644 --- a/source/TypeDef.h +++ b/source/TypeDef.h @@ -24,6 +24,8 @@ #ifndef __TYPEDEF_H__ #define __TYPEDEF_H__ +#include "config.h" + // ==================================================================================================================== // Basic type redefinition // ==================================================================================================================== @@ -91,4 +93,14 @@ typedef UChar Pel; ///< 8-bit pixel type #define xFree( ptr ) free ( ptr ) #endif + +// ==================================================================================================================== +// Qt functions +// ==================================================================================================================== + +#if( QT_VERSION_PLAYUVER == 4 ) +#define QStringLiteral QString::fromUtf8 +#endif + + #endif // __TYPEDEF_H__ diff --git a/source/plaYUVerApp.cpp b/source/plaYUVerApp.cpp index 53cbb9b..3a8d35f 100644 --- a/source/plaYUVerApp.cpp +++ b/source/plaYUVerApp.cpp @@ -21,8 +21,11 @@ * \brief Main definition of the plaYUVerApp app */ +#if( QT_VERSION_PLAYUVER == 5 ) #include -#include +#elif( QT_VERSION_PLAYUVER == 4 ) +#include +#endif #include #include "TypeDef.h" diff --git a/source/plaYUVerApp.h b/source/plaYUVerApp.h index 56caf93..944ef16 100644 --- a/source/plaYUVerApp.h +++ b/source/plaYUVerApp.h @@ -24,6 +24,8 @@ #ifndef __PLAYUVERAPP_H__ #define __PLAYUVERAPP_H__ +#include "config.h" + #include #include "TypeDef.h" diff --git a/source/plaYUVerSettings.cpp b/source/plaYUVerSettings.cpp index aa923c3..a61c23c 100755 --- a/source/plaYUVerSettings.cpp +++ b/source/plaYUVerSettings.cpp @@ -21,8 +21,6 @@ * \brief plaYUVer app settings */ -#include - #include "plaYUVerSettings.h" namespace plaYUVer diff --git a/source/plaYUVerSettings.h b/source/plaYUVerSettings.h index ed9f091..c389864 100755 --- a/source/plaYUVerSettings.h +++ b/source/plaYUVerSettings.h @@ -24,14 +24,10 @@ #ifndef __PLAYUVERSETTINGS_H__ #define __PLAYUVERSETTINGS_H__ -#include -#include -#include -#include -#include -#include +#include "config.h" + +#include -#include #include "gridmanager.h" namespace plaYUVer From 7a6f7d744f6f2e3caf442673f1e197c9234e4eb9 Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Thu, 30 Jan 2014 21:44:49 +0000 Subject: [PATCH 05/18] Add file config.h.in --- config.h.in | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 config.h.in diff --git a/config.h.in b/config.h.in new file mode 100644 index 0000000..36cc292 --- /dev/null +++ b/config.h.in @@ -0,0 +1,19 @@ +/* Input config.h file */ + +#ifndef __CONFIG_PLAYUVER_H__ +#define __CONFIG_PLAYUVER_H__ + + +/* QT definition */ +#cmakedefine USE_QT4 + +#ifndef USE_QT4 + #define QT_VERSION_PLAYUVER 5 +#else + #define QT_VERSION_PLAYUVER 4 +#endif + +#cmakedefine USE_OPENCV + + +#endif // __CONFIG_PLAYUVER_H__ \ No newline at end of file From fbbed36820914dde736cc86d50682648db9c0a5a Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Fri, 31 Jan 2014 01:33:07 +0000 Subject: [PATCH 06/18] Minor changes in CMakeLists.txt --- CMakeLists.txt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5b36ac8..1377429 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -87,6 +87,8 @@ IF( USE_OPENCV ) FIND_PACKAGE( OpenCV QUIET ) IF( NOT OpenCV_FOUND) SET(USE_OPENCV FALSE) + ELSE() + SET( LINKER_LIBS ${LINKER_LIBS} ${OpenCV_LIBRARIES} ) ENDIF() ENDIF() @@ -104,7 +106,7 @@ IF( USE_QT4 ) QT4_WRAP_UI( FORMS_HEADERS_FILES ${FORMS_FILES} ) QT4_ADD_RESOURCES( RESOURCES_RCC_FILES ${RESOURCES_FILES} ) - SET( CURR_QT_LINKER_LIBS ${QT_LIBRARIES} ) + SET( LINKER_LIBS ${LINKER_LIBS} ${QT_LIBRARIES} ) ENDIF() IF( NOT USE_QT4 ) @@ -120,7 +122,7 @@ IF( NOT USE_QT4 ) # Add compiler flags for building executables (-fPIE) SET( CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} ${Qt5Core_EXECUTABLE_COMPILE_FLAGS} ) - SET( CURR_QT_LINKER_LIBS ${Qt5Core_LIBRARIES} ${Qt5Gui_LIBRARIES} ${Qt5Widgets_LIBRARIES} ) + SET( LINKER_LIBS ${LINKER_LIBS} ${Qt5Core_LIBRARIES} ${Qt5Gui_LIBRARIES} ${Qt5Widgets_LIBRARIES} ) SET( CURR_QT_MODULES Core Gui Widgets ) ENDIF() @@ -132,9 +134,7 @@ ENDIF() INCLUDE_DIRECTORIES( ${EXTERNAL_SRC}/scode ) ADD_LIBRARY( Scode ${EXTERNAL_SRC}/scode/viewarea.cpp ${EXTERNAL_SRC}/scode/gridmanager.cpp ${EXTERNAL_SRC}/scode/scosettings.cpp ) - -SET( LIST_EXTERNAL_LIBS Scode ) - +SET( LINKER_LIBS ${LINKER_LIBS} Scode ) ###################################################################################### # Create config.h ###################################################################################### @@ -145,7 +145,7 @@ CONFIGURE_FILE( ${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_D # Target App ###################################################################################### ADD_EXECUTABLE( ${PROJECT_NAME} ${SOURCES_FILES} ${HEADERS_MOC_FILES} ${FORMS_HEADERS_FILES} ${RESOURCES_RCC_FILES} ) -TARGET_LINK_LIBRARIES( ${PROJECT_NAME} ${LIST_EXTERNAL_LIBS} ${CURR_QT_LINKER_LIBS} ) +TARGET_LINK_LIBRARIES( ${PROJECT_NAME} ${LINKER_LIBS} ) IF( NOT USE_QT4) QT5_USE_MODULES( ${PROJECT_NAME} ${CURR_QT_MODULES} ) From 4280017fa0764c6c2428a5e1f2e9232a2496e296 Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Fri, 31 Jan 2014 01:33:31 +0000 Subject: [PATCH 07/18] Add support to save the current frame --- source/ImageInterface.cpp | 37 +++++++++++++++++++++++---------- source/ImageInterface.h | 2 -- source/InputStream.cpp | 43 +++++++++++++++++++++++++++++++++++++++ source/InputStream.h | 13 ++++++++++++ source/plaYUVerApp.cpp | 21 +++++++++---------- source/plaYUVerApp.h | 3 +-- 6 files changed, 93 insertions(+), 26 deletions(-) diff --git a/source/ImageInterface.cpp b/source/ImageInterface.cpp index 3427a4a..ce86ae4 100644 --- a/source/ImageInterface.cpp +++ b/source/ImageInterface.cpp @@ -96,22 +96,37 @@ bool ImageInterface::loadFile( const QString &fileName ) bool ImageInterface::save() { + QString supported = tr("Supported Files"); + QString formats = InputStream::supportedWriteFormats(); + formats.prepend(" ("); + formats.append(")"); + supported.append(formats); // supported=="Supported Files (*.pbm *.jpg...)" -} + QStringList filter; + filter << supported + << InputStream::supportedWriteFormatsList() + << tr( "All Files (*)" ); -bool ImageInterface::saveAs() -{ - QString fileName = QFileDialog::getSaveFileName( this, tr( "Save As" ), m_cCurrFileName ); - if( fileName.isEmpty() ) - return false; + QString fileName = QFileDialog::getSaveFileName( this, tr( "Save As" ), + m_cCurrFileName, filter.join(";;") ); - return saveFile( fileName ); -} + if ( fileName.isEmpty() ) + return false; -bool ImageInterface::saveFile( const QString &fileName ) -{ + QApplication::setOverrideCursor( Qt::WaitCursor ); - return true; + if ( !m_currStream.writeFrame( fileName ) ) + { + QApplication::restoreOverrideCursor(); + QMessageBox::warning( this, tr( "SCode" ), + tr( "Cannot save file %1" ) + .arg( fileName )); + return false; + } + + QApplication::restoreOverrideCursor(); + + return true; } bool ImageInterface::nextVideoFrame() diff --git a/source/ImageInterface.h b/source/ImageInterface.h index 8ab247f..6404d54 100644 --- a/source/ImageInterface.h +++ b/source/ImageInterface.h @@ -65,8 +65,6 @@ public: bool loadFile( const QString &fileName ); bool save(); - bool saveAs(); - bool saveFile( const QString &fileName ); bool nextVideoFrame(); diff --git a/source/InputStream.cpp b/source/InputStream.cpp index 42594c3..1f9492c 100755 --- a/source/InputStream.cpp +++ b/source/InputStream.cpp @@ -70,6 +70,18 @@ QString InputStream::supportedReadFormats() return formats; } +QString InputStream::supportedWriteFormats() +{ + QString formats; + formats = "*.bmp " // Windows Bitmap + "*.jpg " // Joint Photographic Experts Group + "*.jpeg " // Joint Photographic Experts Group + "*.png " // Portable Network Graphics + ; + + return formats; +} + QStringList InputStream::supportedReadFormatsList() { QStringList formats; @@ -78,6 +90,22 @@ QStringList InputStream::supportedReadFormatsList() return formats; } +QStringList InputStream::supportedWriteFormatsList() +{ + QStringList formats; + formats << "Windows Bitmap (*.bmp)" + << "Joint Photographic Experts Group (*.jpg *.jpeg)" + << "Portable Network Graphics (*.png)" + << "Portable Bitmap (*.pbm)" + << "Portable Graymap (*.pgm)" + << "Portable Pixmap (*.ppm)" + << "Tagged Image File Format (*.tiff)" + << "X11 Bitmap (*.xbm)" + << "X11 Pixmap (*.xpm)"; + + return formats; +} + QStringList InputStream::supportedPixelFormatList() { QStringList formats; @@ -288,6 +316,12 @@ Void InputStream::readFrame() return; } +Bool InputStream::writeFrame( const QString& filename ) +{ + getFrameQImage().save(filename); + return true; +} + QImage InputStream::getFrameQImage() { // Create QImage @@ -315,6 +349,15 @@ QImage InputStream::getFrameQImage() return img; } +#ifdef USE_OPENCV +cv::Mat InputStream::getFrameCvMat() +{ + cv::Mat cvMat( m_uiHeight, m_uiWidth, CV_8UC3 ); + + return cvMat; +} +#endif + Void InputStream::seekInput( Int new_frame_num ) { UInt64 frame_bytes_input = m_uiWidth * m_uiHeight * 1.5; diff --git a/source/InputStream.h b/source/InputStream.h index 8fe5e1f..984236e 100755 --- a/source/InputStream.h +++ b/source/InputStream.h @@ -32,6 +32,10 @@ #include #include +#ifdef USE_OPENCV +#include +#endif + #include "TypeDef.h" namespace plaYUVer @@ -67,9 +71,13 @@ public: ~InputStream(); static QString supportedReadFormats(); + static QString supportedWriteFormats(); static QStringList supportedReadFormatsList(); + static QStringList supportedWriteFormatsList(); + static QStringList supportedPixelFormatList(); + enum InputStreamColorSpace { YUV420, @@ -88,7 +96,12 @@ public: Void readFrame(); + Bool writeFrame( const QString& filename ); + QImage getFrameQImage(); +#ifdef USE_OPENCV + cv::Mat getFrameCvMat(); +#endif Void seekInput( Int new_frame_num ); diff --git a/source/plaYUVerApp.cpp b/source/plaYUVerApp.cpp index 3a8d35f..e0140a2 100644 --- a/source/plaYUVerApp.cpp +++ b/source/plaYUVerApp.cpp @@ -122,9 +122,10 @@ void plaYUVerApp::open() play(); } -void plaYUVerApp::saveAs() +void plaYUVerApp::save() { - + if( activeImageInterface() ) + activeImageInterface()->save(); } // ----------------------- Playing Functions -------------------- @@ -136,7 +137,6 @@ void plaYUVerApp::play() } - void plaYUVerApp::playEvent() { if( activeImageInterface() ) @@ -195,7 +195,7 @@ void plaYUVerApp::about() void plaYUVerApp::updateMenus() { Bool hasImageInterface = ( activeImageInterface() != 0 ); - saveAsAct->setEnabled( hasImageInterface ); + saveAct->setEnabled( hasImageInterface ); closeAct->setEnabled( hasImageInterface ); closeAllAct->setEnabled( hasImageInterface ); tileAct->setEnabled( hasImageInterface ); @@ -271,10 +271,10 @@ Void plaYUVerApp::createActions() openAct->setStatusTip( tr( "Open an existing file" ) ); connect( openAct, SIGNAL( triggered() ), this, SLOT( open() ) ); - saveAsAct = new QAction( QIcon( ":/images/saveas.png" ), tr( "Save &As..." ), this ); - saveAsAct->setShortcuts( QKeySequence::SaveAs ); - saveAsAct->setStatusTip( tr( "Save the document under a new name" ) ); - connect( saveAsAct, SIGNAL( triggered() ), this, SLOT( saveAs() ) ); + saveAct = new QAction( QIcon( ":/images/save.png" ), tr( "&Save..." ), this ); + saveAct->setShortcuts( QKeySequence::SaveAs ); + saveAct->setStatusTip( tr( "Save the document under a new name" ) ); + connect( saveAct, SIGNAL( triggered() ), this, SLOT( save() ) ); exitAct = new QAction( tr( "E&xit" ), this ); exitAct->setShortcuts( QKeySequence::Quit ); @@ -318,7 +318,6 @@ Void plaYUVerApp::createActions() // ------------ Playing ------------ - // ------------ Window ------------ tileAct = new QAction( tr( "&Tile" ), this ); @@ -359,7 +358,7 @@ Void plaYUVerApp::createMenus() fileMenu = menuBar()->addMenu( tr( "&File" ) ); fileMenu->addAction( openAct ); fileMenu->addSeparator(); - fileMenu->addAction( saveAsAct ); + fileMenu->addAction( saveAct ); fileMenu->addSeparator(); fileMenu->addAction( closeAct ); fileMenu->addAction( exitAct ); @@ -385,7 +384,7 @@ Void plaYUVerApp::createToolBars() { fileToolBar = addToolBar( tr( "File" ) ); fileToolBar->addAction( openAct ); - fileToolBar->addAction( saveAsAct ); + fileToolBar->addAction( saveAct ); fileToolBar->addAction( closeAct ); viewToolBar = addToolBar( tr( "Zoom" ) ); diff --git a/source/plaYUVerApp.h b/source/plaYUVerApp.h index 944ef16..2d9d0b2 100644 --- a/source/plaYUVerApp.h +++ b/source/plaYUVerApp.h @@ -54,7 +54,7 @@ private slots: //! File functions void open(); - void saveAs(); + void save(); //! Playing functions void play(); @@ -108,7 +108,6 @@ private: QAction *openAct; QAction *saveAct; - QAction *saveAsAct; QAction *exitAct; QAction *closeAct; QAction *closeAllAct; From 8f46cf8a5dd77e058c84416361bcd966b80c6d06 Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Fri, 31 Jan 2014 01:41:07 +0000 Subject: [PATCH 08/18] Resolve some warnings --- source/InputStream.cpp | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/source/InputStream.cpp b/source/InputStream.cpp index 1f9492c..2015194 100755 --- a/source/InputStream.cpp +++ b/source/InputStream.cpp @@ -36,6 +36,12 @@ InputStream::InputStream() m_iStatus = 0; m_pFile = NULL; + m_uiWidth = 0; + m_uiHeight = 0; + m_uiTotalFrameNum = 0; + m_uiCurrFrameNum = 0; + m_iErrorStatus = 0; + m_iPixelFormat = -1; m_pppcInputPel[0] = NULL; m_pppcInputPel[1] = NULL; m_pppcInputPel[2] = NULL; @@ -190,15 +196,6 @@ Void InputStream::init( QString filename, UInt width, UInt height, Int input_for return; } -static inline Pel iClip3Pel( Pel pel_value, Pel min_value, Pel max_value ) -{ - if( pel_value > max_value ) - return max_value; - if( pel_value < min_value ) - return min_value; - return pel_value; -} - static inline void yuvToRgb( int iY, int iU, int iV, int &iR, int &iG, int &iB ) { iR = iY + 1402 * iV / 1000; From 73fbd054880a5e2b224b11fa98dea1f5b28aaa30 Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Fri, 31 Jan 2014 01:54:39 +0000 Subject: [PATCH 09/18] Add function to check if the dialog box to configure the sequence parameters is needed --- source/ImageInterface.cpp | 7 +++++-- source/InputStream.cpp | 13 +++++++++++++ source/InputStream.h | 2 ++ 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/source/ImageInterface.cpp b/source/ImageInterface.cpp index ce86ae4..a8e0e18 100644 --- a/source/ImageInterface.cpp +++ b/source/ImageInterface.cpp @@ -61,9 +61,12 @@ bool ImageInterface::loadFile( const QString &fileName ) { ConfigureFormatDialog formatDialog( this ); - if( formatDialog.exec() == QDialog::Rejected ) + if( m_currStream.needFormatDialog( fileName ) ) { - return false; + if( formatDialog.exec() == QDialog::Rejected ) + { + return false; + } } QApplication::setOverrideCursor( Qt::WaitCursor ); diff --git a/source/InputStream.cpp b/source/InputStream.cpp index 2015194..07d712e 100755 --- a/source/InputStream.cpp +++ b/source/InputStream.cpp @@ -119,6 +119,19 @@ QStringList InputStream::supportedPixelFormatList() return formats; } +Bool InputStream::needFormatDialog( QString filename ) +{ + QString fileExtension = QFileInfo(filename).completeSuffix(); + if( !fileExtension.compare( QString("yuv") ) ) + { + return true; + } + else + { + return false; + } +} + Void InputStream::init( QString filename, UInt width, UInt height, Int input_format ) { diff --git a/source/InputStream.h b/source/InputStream.h index 984236e..9687d23 100755 --- a/source/InputStream.h +++ b/source/InputStream.h @@ -90,6 +90,8 @@ public: YUVFormat = 0, // Use color space. }; + Bool needFormatDialog( QString filename ); + Void init( QString filename, UInt width, UInt height, Int input_format ); Void YUV420toRGB(); From e4c78ae031e3f9e50d094dd0eb7af8d759ccbb58 Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Fri, 31 Jan 2014 18:09:29 +0000 Subject: [PATCH 10/18] Add ffmpeg code into InputStream and create option for it in the cmake configuration --- CMakeLists.txt | 90 ++++++++++++++++-- config.h.in | 4 + source/InputStream.cpp | 209 ++++++++++++++++++++++++++++++++++++----- source/InputStream.h | 22 +++++ 4 files changed, 294 insertions(+), 31 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1377429..79a1f8e 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,12 +19,13 @@ SET( RSC_DIR resources ) SET( UI_DIR ui ) SET( EXTERNAL_SRC external_lib ) +SET(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}") # Find includes in corresponding build directories SET( CMAKE_INCLUDE_CURRENT_DIR ON ) # Instruct CMake to run moc automatically when needed. SET( CMAKE_AUTOMOC ON ) -INCLUDE_DIRECTORIES( ${CMAKE_BINARY_DIR} ${INC_DIR} ) +INCLUDE_DIRECTORIES( ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR} ${INC_DIR} ) FILE( GLOB SOURCES_FILES ${SRC_DIR}/*.cpp ) FILE( GLOB HEADERS_FILES ${INC_DIR}/*.h ) @@ -73,23 +74,87 @@ macro(ADD_OPTION variable description value) unset(__value) endmacro() +# Status report function. +# Automatically align right column and selects text based on condition. +# Usage: +# status() +# status( [ ...]) +# status( THEN ELSE ) +function(status text) + set(status_cond) + set(status_then) + set(status_else) + + set(status_current_name "cond") + foreach(arg ${ARGN}) + if(arg STREQUAL "THEN") + set(status_current_name "then") + elseif(arg STREQUAL "ELSE") + set(status_current_name "else") + else() + list(APPEND status_${status_current_name} ${arg}) + endif() + endforeach() + + if(DEFINED status_cond) + set(status_placeholder_length 32) + string(RANDOM LENGTH ${status_placeholder_length} ALPHABET " " status_placeholder) + string(LENGTH "${text}" status_text_length) + if(status_text_length LESS status_placeholder_length) + string(SUBSTRING "${text}${status_placeholder}" 0 ${status_placeholder_length} status_text) + elseif(DEFINED status_then OR DEFINED status_else) + message(STATUS ${text}) + set(status_text "${status_placeholder}") + else() + set(status_text "${text}") + endif() + + if(DEFINED status_then OR DEFINED status_else) + if(${status_cond}) + string(REPLACE ";" " " status_then "${status_then}") + string(REGEX REPLACE "^[ \t]+" "" status_then "${status_then}") + message(STATUS "${status_text} ${status_then}") + else() + string(REPLACE ";" " " status_else "${status_else}") + string(REGEX REPLACE "^[ \t]+" "" status_else "${status_else}") + message(STATUS "${status_text} ${status_else}") + endif() + else() + string(REPLACE ";" " " status_cond "${status_cond}") + string(REGEX REPLACE "^[ \t]+" "" status_cond "${status_cond}") + message(STATUS "${status_text} ${status_cond}") + endif() + else() + message(STATUS "${text}") + endif() +endfunction() + + ###################################################################################### # Variables ###################################################################################### ADD_OPTION(CMAKE_BUILD_TYPE "Build type" Debug ) ADD_OPTION(USE_QT4 "Build with QT4" OFF ) ADD_OPTION(USE_OPENCV "Add OpenCV support" OFF ) +ADD_OPTION(USE_FFMPEG "Add FFMPEG support" OFF ) ###################################################################################### # Dependencies ###################################################################################### IF( USE_OPENCV ) - FIND_PACKAGE( OpenCV QUIET ) - IF( NOT OpenCV_FOUND) - SET(USE_OPENCV FALSE) - ELSE() - SET( LINKER_LIBS ${LINKER_LIBS} ${OpenCV_LIBRARIES} ) - ENDIF() + FIND_PACKAGE( OpenCV ) + IF( NOT OpenCV_FOUND) + SET(USE_OPENCV FALSE) + ELSE() + SET( LINKER_LIBS ${LINKER_LIBS} ${OpenCV_LIBRARIES} ) + ENDIF() +ENDIF() + +IF( USE_FFMPEG ) + FIND_PACKAGE( FFmpeg ) + IF( NOT FFMPEG_FOUND ) + SET( USE_FFMPEG FALSE ) + ENDIF() ENDIF() ###################################################################################### @@ -144,7 +209,15 @@ CONFIGURE_FILE( ${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_D ###################################################################################### # Target App ###################################################################################### + ADD_EXECUTABLE( ${PROJECT_NAME} ${SOURCES_FILES} ${HEADERS_MOC_FILES} ${FORMS_HEADERS_FILES} ${RESOURCES_RCC_FILES} ) + +IF( USE_FFMPEG ) + INCLUDE_DIRECTORIES(${FFMPEG_INCLUDE_DIR} ${FFMPEG_INCLUDE_DIRS}) +# SET( LINKER_LIBS ${LINKER_LIBS} ${FFMPEG_LIBRARIES} ) + SET( LINKER_LIBS ${LINKER_LIBS} avformat avcodec avutil ) +ENDIF() +message( STATUS ${LINKER_LIBS} ) TARGET_LINK_LIBRARIES( ${PROJECT_NAME} ${LINKER_LIBS} ) IF( NOT USE_QT4) @@ -152,3 +225,6 @@ IF( NOT USE_QT4) ENDIF() +status("Using third-party libraries:") +status(" Use OpenCV:" USE_OPENCV THEN YES ELSE NO) +status(" FFMPEG:" USE_FFMPEG THEN YES ELSE NO) \ No newline at end of file diff --git a/config.h.in b/config.h.in index 36cc292..a4fc011 100644 --- a/config.h.in +++ b/config.h.in @@ -13,7 +13,11 @@ #define QT_VERSION_PLAYUVER 4 #endif +/* OpenCV */ #cmakedefine USE_OPENCV +/* FFMPEG */ +#cmakedefine USE_FFMPEG + #endif // __CONFIG_PLAYUVER_H__ \ No newline at end of file diff --git a/source/InputStream.cpp b/source/InputStream.cpp index 07d712e..212522f 100755 --- a/source/InputStream.cpp +++ b/source/InputStream.cpp @@ -78,14 +78,14 @@ QString InputStream::supportedReadFormats() QString InputStream::supportedWriteFormats() { - QString formats; - formats = "*.bmp " // Windows Bitmap - "*.jpg " // Joint Photographic Experts Group - "*.jpeg " // Joint Photographic Experts Group - "*.png " // Portable Network Graphics - ; + QString formats; + formats = "*.bmp " // Windows Bitmap + "*.jpg "// Joint Photographic Experts Group + "*.jpeg "// Joint Photographic Experts Group + "*.png "// Portable Network Graphics + ; - return formats; + return formats; } QStringList InputStream::supportedReadFormatsList() @@ -98,18 +98,11 @@ QStringList InputStream::supportedReadFormatsList() QStringList InputStream::supportedWriteFormatsList() { - QStringList formats; - formats << "Windows Bitmap (*.bmp)" - << "Joint Photographic Experts Group (*.jpg *.jpeg)" - << "Portable Network Graphics (*.png)" - << "Portable Bitmap (*.pbm)" - << "Portable Graymap (*.pgm)" - << "Portable Pixmap (*.ppm)" - << "Tagged Image File Format (*.tiff)" - << "X11 Bitmap (*.xbm)" - << "X11 Pixmap (*.xpm)"; + QStringList formats; + formats << "Windows Bitmap (*.bmp)" << "Joint Photographic Experts Group (*.jpg *.jpeg)" << "Portable Network Graphics (*.png)" << "Portable Bitmap (*.pbm)" + << "Portable Graymap (*.pgm)" << "Portable Pixmap (*.ppm)" << "Tagged Image File Format (*.tiff)" << "X11 Bitmap (*.xbm)" << "X11 Pixmap (*.xpm)"; - return formats; + return formats; } QStringList InputStream::supportedPixelFormatList() @@ -121,8 +114,8 @@ QStringList InputStream::supportedPixelFormatList() Bool InputStream::needFormatDialog( QString filename ) { - QString fileExtension = QFileInfo(filename).completeSuffix(); - if( !fileExtension.compare( QString("yuv") ) ) + QString fileExtension = QFileInfo( filename ).completeSuffix(); + if( !fileExtension.compare( QString( "yuv" ) ) ) { return true; } @@ -132,6 +125,174 @@ Bool InputStream::needFormatDialog( QString filename ) } } +#ifdef USE_FFMPEG +static int open_codec_context( int *stream_idx, AVFormatContext *fmt_ctx, enum AVMediaType type ) +{ + int ret; + AVStream *st; + AVCodecContext *dec_ctx = NULL; + AVCodec *dec = NULL; + + ret = av_find_best_stream( fmt_ctx, type, -1, -1, NULL, 0 ); + if( ret < 0 ) + { + return ret; + } + else + { + *stream_idx = ret; + st = fmt_ctx->streams[*stream_idx]; + + /* find decoder for the stream */ + dec_ctx = st->codec; + dec = avcodec_find_decoder( dec_ctx->codec_id ); + if( !dec ) + { + printf( "Failed to find %s codec\n", av_get_media_type_string( type ) ); + return ret; + } + + if( ( ret = avcodec_open2( dec_ctx, dec, NULL ) ) < 0 ) + { + printf( "Failed to open %s codec\n", av_get_media_type_string( type ) ); + return ret; + } + } + + return 0; +} + +Void closeAvFormat( LibAvContext avContext ) +{ + if( avContext.video_dec_ctx ) + avcodec_close( avContext.video_dec_ctx ); + + avformat_close_input( &avContext.fmt_ctx ); + + av_free( avContext.frame ); + av_free( avContext.video_dst_data[0] ); +} + +Bool initAvFormat( LibAvContext avContext, QString filename, UInt width, UInt height ) +{ + Bool bRet = true; + int ret = 0; + + avContext.video_stream_idx = -1; + + char *src_filename = filename.toLocal8Bit().data(); + + FILE *video_dst_file = NULL; + + int video_frame_count = 0; + int audio_frame_count = 0; + + /* register all formats and codecs */ + av_register_all(); + + /* open input file, and allocate format context */ + if( avformat_open_input( &avContext.fmt_ctx, src_filename, NULL, NULL ) < 0 ) + { + qDebug( ) << " Could not open source file %s !!!" << filename << endl; + return false; + } + + /* retrieve stream information */ + if( avformat_find_stream_info( avContext.fmt_ctx, NULL ) < 0 ) + { + qDebug( ) << " Could not find stream information !!!" << endl; + return false; + } + + if( open_codec_context( &avContext.video_stream_idx, avContext.fmt_ctx, AVMEDIA_TYPE_VIDEO ) >= 0 ) + { + avContext.video_stream = avContext.fmt_ctx->streams[avContext.video_stream_idx]; + avContext.video_dec_ctx = avContext.video_stream->codec; + + /* allocate image where the decoded image will be put */ + ret = av_image_alloc( avContext.video_dst_data, avContext.video_dst_linesize, avContext.video_dec_ctx->width, avContext.video_dec_ctx->height, + avContext.video_dec_ctx->pix_fmt, 1 ); + if( ret < 0 ) + { + qDebug( ) << " Could not allocate raw video buffer !!!" << endl; + closeAvFormat( avContext ); + return false; + } + avContext.video_dst_bufsize = ret; + } + + /* dump input information to stderr */ + //av_dump_format(fmt_ctx, 0, src_filename, 0); + if( !avContext.video_stream ) + { + qDebug( ) << " Could not find audio or video stream in the input, aborting !!!" << endl; + bRet = false; + closeAvFormat( avContext ); + return false; + } + + avContext.frame = avcodec_alloc_frame(); + if( !avContext.frame ) + { + qDebug( ) << " Could not allocate frame !!!" << endl; + ret = AVERROR( ENOMEM ); + closeAvFormat( avContext ); + return false; + } + + /* initialize packet, set data to NULL, let the demuxer fill it */ + av_init_packet( &avContext.pkt ); + avContext.pkt.data = NULL; + avContext.pkt.size = 0; + + return true; +} + +Bool decodeAvFormat( LibAvContext avContext ) +{ + Int got_frame; + int ret; + /* read frames from the file */ + + if( av_read_frame( avContext.fmt_ctx, &avContext.pkt ) >= 0 ) + { + if( avContext.pkt.stream_index == avContext.video_stream_idx ) + { + /* decode video frame */ + ret = avcodec_decode_video2( avContext.video_dec_ctx, avContext.frame, &got_frame, &avContext.pkt ); + if( ret < 0 ) + { + fprintf( stderr, "Error decoding video frame\n" ); + return false; + } + + if( got_frame ) + { + /* copy decoded frame to destination buffer: + * this is required since rawvideo expects non aligned data */ + av_image_copy( avContext.video_dst_data, avContext.video_dst_linesize, ( const uint8_t ** )( avContext.frame->data ), avContext.frame->linesize, + avContext.video_dec_ctx->pix_fmt, avContext.video_dec_ctx->width, avContext.video_dec_ctx->height ); + + /* write to rawvideo file */ + //fwrite( avContext.video_dst_data[0], 1, avContext.video_dst_bufsize, avContext.video_dst_file ); + } + } + av_free_packet( &avContext.pkt ); + } + +// /* flush cached frames */ +// avContext.pkt.data = NULL; +// avContext.pkt.size = 0; +// do +// { +// decode_packet( &got_frame, 1 ); +// } +// while( got_frame ); + + true; +} +#endif + Void InputStream::init( QString filename, UInt width, UInt height, Int input_format ) { @@ -302,21 +463,21 @@ Void InputStream::readFrame() if( bytes_read != ( m_uiWidth * m_uiHeight ) ) { m_iErrorStatus = READING; - qDebug() << " Reading error !!!" << endl; + qDebug( ) << " Reading error !!!" << endl; return; } bytes_read = fread( &( m_pppcInputPel[1][0][0] ), sizeof(Pel), m_uiWidth * m_uiHeight / 4, m_pFile ); if( bytes_read != ( m_uiWidth * m_uiHeight / 4 ) ) { m_iErrorStatus = READING; - qDebug() << " Reading error !!!" << endl; + qDebug( ) << " Reading error !!!" << endl; return; } bytes_read = fread( &( m_pppcInputPel[2][0][0] ), sizeof(Pel), m_uiWidth * m_uiHeight / 4, m_pFile ); if( bytes_read != ( m_uiWidth * m_uiHeight / 4 ) ) { m_iErrorStatus = READING; - qDebug() << " Reading error !!!" << endl; + qDebug( ) << " Reading error !!!" << endl; return; } YUV420toRGB(); @@ -328,7 +489,7 @@ Void InputStream::readFrame() Bool InputStream::writeFrame( const QString& filename ) { - getFrameQImage().save(filename); + getFrameQImage().save( filename ); return true; } diff --git a/source/InputStream.h b/source/InputStream.h index 9687d23..2dbb23c 100755 --- a/source/InputStream.h +++ b/source/InputStream.h @@ -36,6 +36,13 @@ #include #endif +#ifdef USE_FFMPEG +#include "libavutil/imgutils.h" +#include "libavutil/samplefmt.h" +#include "libavutil/timestamp.h" +#include "libavformat/avformat.h" +#endif + #include "TypeDef.h" namespace plaYUVer @@ -46,6 +53,21 @@ enum InputStream_Errors NO_ERROR = 0, READING = 1, }; +#ifdef USE_FFMPEG +typedef struct __LibAvContext +{ + AVFormatContext *fmt_ctx; + AVCodecContext *video_dec_ctx; + AVStream *video_stream; + Int video_stream_idx; + AVFrame *frame; + AVPacket pkt; + uint8_t *video_dst_data[4]; + int video_dst_linesize[4]; + int video_dst_bufsize; +} LibAvContext; +#endif + class InputStream { private: From 69098efcc790f6318424b9a6a892b64a76533f85 Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Fri, 31 Jan 2014 18:11:16 +0000 Subject: [PATCH 11/18] Add FindFFmpeg.cmake --- FindFFmpeg.cmake | 111 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 FindFFmpeg.cmake diff --git a/FindFFmpeg.cmake b/FindFFmpeg.cmake new file mode 100644 index 0000000..a780f77 --- /dev/null +++ b/FindFFmpeg.cmake @@ -0,0 +1,111 @@ +# - Try to find FFMPEG +# Once done this will define +# +# FFMPEG_FOUND - system has FFMPEG +# FFMPEG_INCLUDE_DIR - the include directories +# FFMPEG_LIBRARY_DIR - the directory containing the libraries +# FFMPEG_LIBRARIES - link these to use FFMPEG +# FFMPEG_SWSCALE_FOUND - FFMPEG also has SWSCALE +# + +SET( FFMPEG_HEADERS avformat.h avcodec.h avutil.h avdevice.h ) +SET( FFMPEG_PATH_SUFFIXES libavformat libavcodec libavutil libavdevice libffmpeg ) +SET( FFMPEG_SWS_HEADERS swscale.h ) +SET( FFMPEG_SWS_PATH_SUFFIXES libswscale ) + +if( WIN32 ) + SET( FFMPEG_LIBRARIES avformat-52.lib avcodec-51.lib avutil-49.lib avdevice-52.lib ) + SET( FFMPEG_SWS_LIBRARIES swscale-0.lib ) + SET( FFMPEG_LIBRARY_DIR $ENV{FFMPEGDIR}\\lib ) + SET( FFMPEG_INCLUDE_PATHS $ENV{FFMPEGDIR}\\include ) + + # check to see if we can find swscale + SET( TMP_ TMP-NOTFOUND ) + FIND_PATH( TMP_ ${FFMPEG_SWS_LIBRARIES} + PATHS ${FFMPEG_LIBRARY_DIR} ) + IF ( TMP_ ) + SET( SWSCALE_FOUND TRUE ) + ENDIF( TMP_ ) +else( WIN32 ) + SET( FFMPEG_LIBRARIES avformat avcodec avutil avdevice ) + SET( FFMPEG_SWS_LIBRARIES swscale ) + INCLUDE(FindPkgConfig) + if ( PKG_CONFIG_FOUND ) + pkg_check_modules( AVFORMAT libavformat ) + pkg_check_modules( AVCODEC libavcodec ) + pkg_check_modules( AVUTIL libavutil ) + pkg_check_modules( AVDEVICE libavdevice ) + pkg_check_modules( SWSCALE libswscale ) + endif ( PKG_CONFIG_FOUND ) + + SET( FFMPEG_LIBRARY_DIR ${AVFORMAT_LIBRARY_DIRS} + ${AVCODEC_LIBRARY_DIRS} + ${AVUTIL_LIBRARY_DIRS} + ${AVDEVICE_LIBRARY_DIRS} ) + SET( FFMPEG_INCLUDE_PATHS ${AVFORMAT_INCLUDE_DIRS} + ${AVCODEC_INCLUDE_DIRS} + ${AVUTIL_INCLUDE_DIRS} + ${AVDEVICE_INCLUDE_DIRS} ) +endif( WIN32 ) + +# add in swscale if found +IF ( SWSCALE_FOUND ) + SET( FFMPEG_LIBRARY_DIR ${FFMPEG_LIBRARY_DIR} + ${SWSCALE_LIBRARY_DIRS} ) + SET( FFMPEG_INCLUDE_PATHS ${FFMPEG_INCLUDE_PATHS} + ${SWSCALE_INCLUDE_DIRS} ) + SET( FFMPEG_HEADERS ${FFMPEG_HEADERS} + ${FFMPEG_SWS_HEADERS} ) + SET( FFMPEG_PATH_SUFFIXES ${FFMPEG_PATH_SUFFIXES} + ${FFMPEG_SWS_PATH_SUFFIXES} ) + SET( FFMPEG_LIBRARIES ${FFMPEG_LIBRARIES} + ${FFMPEG_SWS_LIBRARIES} ) +ENDIF ( SWSCALE_FOUND ) + +# find includes +SET( INC_SUCCESS 0 ) +SET( TMP_ TMP-NOTFOUND ) +SET( FFMPEG_INCLUDE_DIR ${FFMPEG_INCLUDE_PATHS} ) +FOREACH( INC_ ${FFMPEG_HEADERS} ) + message( "checking: " ${INC_} ) + + FIND_PATH( TMP_ ${INC_} + PATHS ${FFMPEG_INCLUDE_PATHS} + PATH_SUFFIXES ${FFMPEG_PATH_SUFFIXES} ) + IF ( TMP_ ) + message( "found: " ${TMP_} ) + MATH( EXPR INC_SUCCESS ${INC_SUCCESS}+1 ) + SET( FFMPEG_INCLUDE_DIR ${FFMPEG_INCLUDE_DIR} ${TMP_} ) + ENDIF ( TMP_ ) + SET( TMP_ TMP-NOTFOUND ) +ENDFOREACH( INC_ ) + +# clear out duplicates +if(NOT "${FFMPEG_INCLUDE_DIR}" MATCHES "") + LIST( REMOVE_DUPLICATES FFMPEG_INCLUDE_DIR ) +endif(NOT "${FFMPEG_INCLUDE_DIR}" MATCHES "") +if(NOT "${FFMPEG_LIBRARY_DIR}" MATCHES "") + LIST( REMOVE_DUPLICATES FFMPEG_LIBRARY_DIR ) +endif(NOT "${FFMPEG_LIBRARY_DIR}" MATCHES "") + +# find the full paths of the libraries +SET( TMP_ TMP-NOTFOUND ) +IF ( NOT WIN32 ) + FOREACH( LIB_ ${FFMPEG_LIBRARIES} ) + FIND_LIBRARY( TMP_ NAMES ${LIB_} PATHS ${FFMPEG_LIBRARY_DIR} ) + IF ( TMP_ ) + SET( FFMPEG_LIBRARIES_FULL ${FFMPEG_LIBRARIES_FULL} ${TMP_} ) + ENDIF ( TMP_ ) + SET( TMP_ TMP-NOTFOUND ) + ENDFOREACH( LIB_ ) + SET ( FFMPEG_LIBRARIES ${FFMPEG_LIBRARIES_FULL} ) +ENDIF( NOT WIN32 ) + +LIST( LENGTH FFMPEG_HEADERS LIST_SIZE_ ) + +SET( FFMPEG_FOUND FALSE ) +SET( FFMPEG_SWSCALE_FOUND FALSE ) +IF ( ${INC_SUCCESS} EQUAL ${LIST_SIZE_} ) + SET( FFMPEG_FOUND TRUE ) + SET( FFMPEG_SWSCALE_FOUND ${SWSCALE_FOUND} ) +ENDIF ( ${INC_SUCCESS} EQUAL ${LIST_SIZE_} ) From ca9216e949314dc4f52c9f3af6977e0b28bba321 Mon Sep 17 00:00:00 2001 From: J Carreira Date: Fri, 31 Jan 2014 22:07:34 +0000 Subject: [PATCH 12/18] Improve ffmpeg definition in CMakeLists --- CMakeLists.txt | 7 ++++--- config.h.in | 8 +++++++- source/InputStream.h | 2 ++ 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 79a1f8e..c7c8e93 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -154,6 +154,8 @@ IF( USE_FFMPEG ) FIND_PACKAGE( FFmpeg ) IF( NOT FFMPEG_FOUND ) SET( USE_FFMPEG FALSE ) + ELSE() + SET( CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} -D__STDC_CONSTANT_MACROS ) ENDIF() ENDIF() @@ -214,8 +216,7 @@ ADD_EXECUTABLE( ${PROJECT_NAME} ${SOURCES_FILES} ${HEADERS_MOC_FILES} ${FORMS_HE IF( USE_FFMPEG ) INCLUDE_DIRECTORIES(${FFMPEG_INCLUDE_DIR} ${FFMPEG_INCLUDE_DIRS}) -# SET( LINKER_LIBS ${LINKER_LIBS} ${FFMPEG_LIBRARIES} ) - SET( LINKER_LIBS ${LINKER_LIBS} avformat avcodec avutil ) + SET( LINKER_LIBS ${LINKER_LIBS} ${FFMPEG_LIBRARIES} ) ENDIF() message( STATUS ${LINKER_LIBS} ) TARGET_LINK_LIBRARIES( ${PROJECT_NAME} ${LINKER_LIBS} ) @@ -227,4 +228,4 @@ ENDIF() status("Using third-party libraries:") status(" Use OpenCV:" USE_OPENCV THEN YES ELSE NO) -status(" FFMPEG:" USE_FFMPEG THEN YES ELSE NO) \ No newline at end of file +status(" FFMPEG:" USE_FFMPEG THEN YES ELSE NO) diff --git a/config.h.in b/config.h.in index a4fc011..d2aea32 100644 --- a/config.h.in +++ b/config.h.in @@ -19,5 +19,11 @@ /* FFMPEG */ #cmakedefine USE_FFMPEG +#ifdef USE_FFMPEG + #ifndef __STDC_CONSTANT_MACROS + //#define __STDC_CONSTANT_MACROS + #define smprintf _snprintf + #endif +#endif -#endif // __CONFIG_PLAYUVER_H__ \ No newline at end of file +#endif // __CONFIG_PLAYUVER_H__ diff --git a/source/InputStream.h b/source/InputStream.h index 2dbb23c..bfb5258 100755 --- a/source/InputStream.h +++ b/source/InputStream.h @@ -37,10 +37,12 @@ #endif #ifdef USE_FFMPEG +extern "C" { #include "libavutil/imgutils.h" #include "libavutil/samplefmt.h" #include "libavutil/timestamp.h" #include "libavformat/avformat.h" +} #endif #include "TypeDef.h" From cd10e35e45eed167091233b0dfe96d15596decf0 Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Sat, 1 Feb 2014 13:06:33 +0000 Subject: [PATCH 13/18] Source format --- source/plaYUVerApp.h | 2 +- source/plaYUVerSettings.cpp | 2 +- source/plaYUVerSettings.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/source/plaYUVerApp.h b/source/plaYUVerApp.h index 2d9d0b2..224df2a 100644 --- a/source/plaYUVerApp.h +++ b/source/plaYUVerApp.h @@ -127,6 +127,6 @@ private: QAction *aboutQtAct; }; -} // NAMESPACE +} // NAMESPACE #endif // __PLAYUVERAPP_H__ diff --git a/source/plaYUVerSettings.cpp b/source/plaYUVerSettings.cpp index a61c23c..4872e7f 100755 --- a/source/plaYUVerSettings.cpp +++ b/source/plaYUVerSettings.cpp @@ -314,4 +314,4 @@ void PlaYUVerSettings::setImgVDec( QString str ) m_settings.setValue( "MMPdec/imgV", str ); } -} // NAMESPACE +} // NAMESPACE diff --git a/source/plaYUVerSettings.h b/source/plaYUVerSettings.h index c389864..3fc5a81 100755 --- a/source/plaYUVerSettings.h +++ b/source/plaYUVerSettings.h @@ -125,6 +125,6 @@ private: QSettings m_settings; }; -} // NAMESPACE +} // NAMESPACE #endif // __PLAYUVERSETTINGS_H__ From b1f0d47e82561d54b4ca643d147e42d1712de4bd Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Sat, 1 Feb 2014 13:07:04 +0000 Subject: [PATCH 14/18] Format ImageInterface.h --- source/ImageInterface.h | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/source/ImageInterface.h b/source/ImageInterface.h index 6404d54..e74dd1f 100644 --- a/source/ImageInterface.h +++ b/source/ImageInterface.h @@ -24,7 +24,6 @@ #ifndef __IMAGEINTERFACE_H__ #define __IMAGEINTERFACE_H__ - #include "config.h" #if( QT_VERSION_PLAYUVER == 5 ) @@ -33,7 +32,6 @@ #include #endif - #include "TypeDef.h" #include "InputStream.h" #include "viewarea.h" @@ -54,11 +52,9 @@ private: InputStream m_currStream; - QString m_cCurrFileName; Double m_dScaleFactor; - public: ImageInterface( QWidget * parent = 0 ); ~ImageInterface(); @@ -112,7 +108,6 @@ public: * QMdiArea only have a function that arranges @b all the child windows. */ //static void cascader( QList &widgets, const QRect &domain ); - QString userFriendlyCurrentFile(); QString strippedName( const QString &fullFileName ); QString currentFile() @@ -127,6 +122,6 @@ private slots: }; -} // NAMESPACE +} // NAMESPACE #endif // __IMAGEINTERFACE_H__ From 4230166d9ffaa6447c2737a2b409d06e039a8e7e Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Sat, 1 Feb 2014 13:07:42 +0000 Subject: [PATCH 15/18] Add support for FFMPEG! currently only supports YUV420p and still needs resolution input. Add support in ImageInterface.cpp to only show dialog box when it is necessary --- source/ImageInterface.cpp | 50 +++++++------- source/InputStream.cpp | 134 ++++++++++++++++++++++++-------------- source/InputStream.h | 40 ++++++++---- 3 files changed, 136 insertions(+), 88 deletions(-) diff --git a/source/ImageInterface.cpp b/source/ImageInterface.cpp index a8e0e18..40821db 100644 --- a/source/ImageInterface.cpp +++ b/source/ImageInterface.cpp @@ -67,12 +67,15 @@ bool ImageInterface::loadFile( const QString &fileName ) { return false; } + m_currStream.init( fileName, formatDialog.getResolution().width(), formatDialog.getResolution().height(), formatDialog.getPixelFormat() ); + } + else + { + m_currStream.init( fileName, 0, 0, 0 ); } QApplication::setOverrideCursor( Qt::WaitCursor ); - m_currStream.init( fileName, formatDialog.getResolution().width(), formatDialog.getResolution().height(), formatDialog.getPixelFormat() ); - if( m_currStream.getStatus() == 0 ) { return false; @@ -99,37 +102,32 @@ bool ImageInterface::loadFile( const QString &fileName ) bool ImageInterface::save() { - QString supported = tr("Supported Files"); - QString formats = InputStream::supportedWriteFormats(); - formats.prepend(" ("); - formats.append(")"); - supported.append(formats); // supported=="Supported Files (*.pbm *.jpg...)" + QString supported = tr( "Supported Files" ); + QString formats = InputStream::supportedWriteFormats(); + formats.prepend( " (" ); + formats.append( ")" ); + supported.append( formats ); // supported=="Supported Files (*.pbm *.jpg...)" - QStringList filter; - filter << supported - << InputStream::supportedWriteFormatsList() - << tr( "All Files (*)" ); + QStringList filter; + filter << supported << InputStream::supportedWriteFormatsList() << tr( "All Files (*)" ); - QString fileName = QFileDialog::getSaveFileName( this, tr( "Save As" ), - m_cCurrFileName, filter.join(";;") ); + QString fileName = QFileDialog::getSaveFileName( this, tr( "Save As" ), m_cCurrFileName, filter.join( ";;" ) ); - if ( fileName.isEmpty() ) - return false; + if( fileName.isEmpty() ) + return false; - QApplication::setOverrideCursor( Qt::WaitCursor ); - - if ( !m_currStream.writeFrame( fileName ) ) - { - QApplication::restoreOverrideCursor(); - QMessageBox::warning( this, tr( "SCode" ), - tr( "Cannot save file %1" ) - .arg( fileName )); - return false; - } + QApplication::setOverrideCursor( Qt::WaitCursor ); + if( !m_currStream.writeFrame( fileName ) ) + { QApplication::restoreOverrideCursor(); + QMessageBox::warning( this, tr( "SCode" ), tr( "Cannot save file %1" ).arg( fileName ) ); + return false; + } - return true; + QApplication::restoreOverrideCursor(); + + return true; } bool ImageInterface::nextVideoFrame() diff --git a/source/InputStream.cpp b/source/InputStream.cpp index 212522f..1679439 100755 --- a/source/InputStream.cpp +++ b/source/InputStream.cpp @@ -65,6 +65,10 @@ InputStream::~InputStream() if( m_pppcRGBPel ) free_mem3Dpel( m_pppcRGBPel ); +#ifdef USE_FFMPEG + m_cLibAvContext.closeAvFormat(); +#endif + m_iStatus = 0; } @@ -72,7 +76,8 @@ QString InputStream::supportedReadFormats() { QString formats; formats = "*.yuv " // Raw video - ; + "*.avi"// Audio video interleaved + ; return formats; } @@ -91,7 +96,9 @@ QString InputStream::supportedWriteFormats() QStringList InputStream::supportedReadFormatsList() { QStringList formats; - formats << "Raw video (*.yuv)"; + formats << "Raw video (*.yuv)" // Raw video + << "Audio video interleaved (*.avi)" // Audio video interleaved + ; return formats; } @@ -99,8 +106,10 @@ QStringList InputStream::supportedReadFormatsList() QStringList InputStream::supportedWriteFormatsList() { QStringList formats; - formats << "Windows Bitmap (*.bmp)" << "Joint Photographic Experts Group (*.jpg *.jpeg)" << "Portable Network Graphics (*.png)" << "Portable Bitmap (*.pbm)" - << "Portable Graymap (*.pgm)" << "Portable Pixmap (*.ppm)" << "Tagged Image File Format (*.tiff)" << "X11 Bitmap (*.xbm)" << "X11 Pixmap (*.xpm)"; + formats << "Windows Bitmap (*.bmp)" // Windows Bitmap + << "Joint Photographic Experts Group (*.jpg *.jpeg)" // Joint Photographic Experts Group + << "Portable Network Graphics (*.png)" // Portable Network Graphics + ; return formats; } @@ -114,6 +123,7 @@ QStringList InputStream::supportedPixelFormatList() Bool InputStream::needFormatDialog( QString filename ) { + return true; QString fileExtension = QFileInfo( filename ).completeSuffix(); if( !fileExtension.compare( QString( "yuv" ) ) ) { @@ -162,104 +172,111 @@ static int open_codec_context( int *stream_idx, AVFormatContext *fmt_ctx, enum A return 0; } -Void closeAvFormat( LibAvContext avContext ) +Void LibAvContextHandle::closeAvFormat() { - if( avContext.video_dec_ctx ) - avcodec_close( avContext.video_dec_ctx ); + if( video_dec_ctx ) + avcodec_close( video_dec_ctx ); - avformat_close_input( &avContext.fmt_ctx ); + avformat_close_input( &fmt_ctx ); - av_free( avContext.frame ); - av_free( avContext.video_dst_data[0] ); + av_free( frame ); + av_free( video_dst_data[0] ); } -Bool initAvFormat( LibAvContext avContext, QString filename, UInt width, UInt height ) +Bool LibAvContextHandle::initAvFormat( QString filename, UInt width, UInt height ) { Bool bRet = true; int ret = 0; - avContext.video_stream_idx = -1; + fmt_ctx = NULL; + video_dec_ctx = NULL; + video_stream = NULL; + video_dst_data[0] = NULL; + video_dst_data[1] = NULL; + video_dst_data[2] = NULL; + video_dst_data[3] = NULL; + video_stream_idx = -1; + frame = NULL; + m_bHasStream = false; char *src_filename = filename.toLocal8Bit().data(); FILE *video_dst_file = NULL; - int video_frame_count = 0; - int audio_frame_count = 0; - /* register all formats and codecs */ av_register_all(); /* open input file, and allocate format context */ - if( avformat_open_input( &avContext.fmt_ctx, src_filename, NULL, NULL ) < 0 ) + if( avformat_open_input( &fmt_ctx, src_filename, NULL, NULL ) < 0 ) { qDebug( ) << " Could not open source file %s !!!" << filename << endl; return false; } /* retrieve stream information */ - if( avformat_find_stream_info( avContext.fmt_ctx, NULL ) < 0 ) + if( avformat_find_stream_info( fmt_ctx, NULL ) < 0 ) { qDebug( ) << " Could not find stream information !!!" << endl; return false; } - if( open_codec_context( &avContext.video_stream_idx, avContext.fmt_ctx, AVMEDIA_TYPE_VIDEO ) >= 0 ) + if( open_codec_context( &video_stream_idx, fmt_ctx, AVMEDIA_TYPE_VIDEO ) >= 0 ) { - avContext.video_stream = avContext.fmt_ctx->streams[avContext.video_stream_idx]; - avContext.video_dec_ctx = avContext.video_stream->codec; + video_stream = fmt_ctx->streams[video_stream_idx]; + video_dec_ctx = video_stream->codec; /* allocate image where the decoded image will be put */ - ret = av_image_alloc( avContext.video_dst_data, avContext.video_dst_linesize, avContext.video_dec_ctx->width, avContext.video_dec_ctx->height, - avContext.video_dec_ctx->pix_fmt, 1 ); + ret = av_image_alloc( video_dst_data, video_dst_linesize, video_dec_ctx->width, video_dec_ctx->height, video_dec_ctx->pix_fmt, 1 ); if( ret < 0 ) { qDebug( ) << " Could not allocate raw video buffer !!!" << endl; - closeAvFormat( avContext ); + closeAvFormat(); return false; } - avContext.video_dst_bufsize = ret; + video_dst_bufsize = ret; } /* dump input information to stderr */ - //av_dump_format(fmt_ctx, 0, src_filename, 0); - if( !avContext.video_stream ) + av_dump_format( fmt_ctx, 0, src_filename, 0 ); + if( !video_stream ) { qDebug( ) << " Could not find audio or video stream in the input, aborting !!!" << endl; bRet = false; - closeAvFormat( avContext ); + closeAvFormat(); return false; } - avContext.frame = avcodec_alloc_frame(); - if( !avContext.frame ) + frame = avcodec_alloc_frame(); + if( !frame ) { qDebug( ) << " Could not allocate frame !!!" << endl; ret = AVERROR( ENOMEM ); - closeAvFormat( avContext ); + closeAvFormat(); return false; } /* initialize packet, set data to NULL, let the demuxer fill it */ - av_init_packet( &avContext.pkt ); - avContext.pkt.data = NULL; - avContext.pkt.size = 0; + av_init_packet( &pkt ); + pkt.data = NULL; + pkt.size = 0; + + m_bHasStream = true; return true; } -Bool decodeAvFormat( LibAvContext avContext ) +Bool LibAvContextHandle::decodeAvFormat() { Int got_frame; int ret; /* read frames from the file */ - if( av_read_frame( avContext.fmt_ctx, &avContext.pkt ) >= 0 ) + if( av_read_frame( fmt_ctx, &pkt ) >= 0 ) { - if( avContext.pkt.stream_index == avContext.video_stream_idx ) + if( pkt.stream_index == video_stream_idx ) { /* decode video frame */ - ret = avcodec_decode_video2( avContext.video_dec_ctx, avContext.frame, &got_frame, &avContext.pkt ); + ret = avcodec_decode_video2( video_dec_ctx, frame, &got_frame, &pkt ); if( ret < 0 ) { fprintf( stderr, "Error decoding video frame\n" ); @@ -270,19 +287,19 @@ Bool decodeAvFormat( LibAvContext avContext ) { /* copy decoded frame to destination buffer: * this is required since rawvideo expects non aligned data */ - av_image_copy( avContext.video_dst_data, avContext.video_dst_linesize, ( const uint8_t ** )( avContext.frame->data ), avContext.frame->linesize, - avContext.video_dec_ctx->pix_fmt, avContext.video_dec_ctx->width, avContext.video_dec_ctx->height ); + 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 ); /* write to rawvideo file */ - //fwrite( avContext.video_dst_data[0], 1, avContext.video_dst_bufsize, avContext.video_dst_file ); + //fwrite( video_dst_data[0], 1, video_dst_bufsize, video_dst_file ); } } - av_free_packet( &avContext.pkt ); + av_free_packet( &pkt ); } // /* flush cached frames */ -// avContext.pkt.data = NULL; -// avContext.pkt.size = 0; +// pkt.data = NULL; +// pkt.size = 0; // do // { // decode_packet( &got_frame, 1 ); @@ -296,7 +313,17 @@ Bool decodeAvFormat( LibAvContext avContext ) Void InputStream::init( QString filename, UInt width, UInt height, Int input_format ) { - if( width <= 0 || height <= 0 ) + m_uiWidth = width; + m_uiHeight = height; + + m_iFileFormat = YUVFormat; + m_iPixelFormat = input_format; + +#ifdef USE_FFMPEG + Bool avStatus = m_cLibAvContext.initAvFormat( filename, width, height ); +#endif + + if( m_uiWidth <= 0 || m_uiHeight <= 0 ) { //Error return; @@ -310,12 +337,6 @@ Void InputStream::init( QString filename, UInt width, UInt height, Int input_for return; } - m_uiWidth = width; - m_uiHeight = height; - - m_iFileFormat = YUVFormat; - m_iPixelFormat = input_format; - UInt64 frame_bytes_input = m_uiWidth * m_uiHeight * 1.5; UInt64 alloc_memory; @@ -456,6 +477,19 @@ Void InputStream::readFrame() } UInt64 frame_bytes_input = m_uiWidth * m_uiHeight * 1.5; +#ifdef USE_FFMPEG + if( m_cLibAvContext.getStatus() ) + { + m_cLibAvContext.decodeAvFormat(); + //fwrite( video_dst_data[0], 1, video_dst_bufsize, video_dst_file ); + memcpy( &( m_pppcInputPel[0][0][0] ), m_cLibAvContext.video_dst_data[0], m_uiWidth * m_uiHeight * sizeof(uint8_t) ); + memcpy( &( m_pppcInputPel[1][0][0] ), m_cLibAvContext.video_dst_data[1], m_uiWidth * m_uiHeight * sizeof(uint8_t) / 4 ); + memcpy( &( m_pppcInputPel[2][0][0] ), m_cLibAvContext.video_dst_data[2], m_uiWidth * m_uiHeight * sizeof(uint8_t) / 4 ); + YUV420toRGB(); + return; + } +#endif + switch( m_iPixelFormat ) { case YUV420: diff --git a/source/InputStream.h b/source/InputStream.h index bfb5258..f7813ac 100755 --- a/source/InputStream.h +++ b/source/InputStream.h @@ -37,7 +37,8 @@ #endif #ifdef USE_FFMPEG -extern "C" { +extern "C" +{ #include "libavutil/imgutils.h" #include "libavutil/samplefmt.h" #include "libavutil/timestamp.h" @@ -56,18 +57,32 @@ enum InputStream_Errors }; #ifdef USE_FFMPEG -typedef struct __LibAvContext +class LibAvContextHandle { +public: + Bool initAvFormat( QString filename, UInt width, UInt height ); + Void closeAvFormat(); + Bool decodeAvFormat(); + + Bool getStatus() + { + return m_bHasStream; + } + + uint8_t *video_dst_data[4]; + int video_dst_linesize[4]; + int video_dst_bufsize; + +private: AVFormatContext *fmt_ctx; AVCodecContext *video_dec_ctx; AVStream *video_stream; Int video_stream_idx; AVFrame *frame; AVPacket pkt; - uint8_t *video_dst_data[4]; - int video_dst_linesize[4]; - int video_dst_bufsize; -} LibAvContext; + + Bool m_bHasStream; +}; #endif class InputStream @@ -77,6 +92,10 @@ private: Int m_iStatus; Int m_iErrorStatus; +#ifdef USE_FFMPEG + LibAvContextHandle m_cLibAvContext; +#endif + QString m_cFilename; FILE* m_pFile; /**< The input file pointer >*/ Int m_iFileFormat; @@ -101,17 +120,14 @@ public: static QStringList supportedPixelFormatList(); - enum InputStreamColorSpace { - YUV420, - YUV400, + YUV420, YUV400, }; enum InputStreamFormats { - INVALID = -1, - YUVFormat = 0, // Use color space. + INVALID = -1, YUVFormat = 0, // Use color space. }; Bool needFormatDialog( QString filename ); @@ -171,6 +187,6 @@ public: }; -} // NAMESPACE +} // NAMESPACE #endif // __INPUTSTREAM_H__ From dae8b84c6cdf3b4ae4f8af1f3f5d47961349b5ee Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Sat, 1 Feb 2014 13:11:04 +0000 Subject: [PATCH 16/18] Clean CMakeLists after support of FFMPEG --- CMakeLists.txt | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c7c8e93..b5b6db0 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -156,6 +156,8 @@ IF( USE_FFMPEG ) SET( USE_FFMPEG FALSE ) ELSE() SET( CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS} -D__STDC_CONSTANT_MACROS ) + INCLUDE_DIRECTORIES(${FFMPEG_INCLUDE_DIR} ${FFMPEG_INCLUDE_DIRS}) + SET( LINKER_LIBS ${LINKER_LIBS} ${FFMPEG_LIBRARIES} ) ENDIF() ENDIF() @@ -214,11 +216,6 @@ CONFIGURE_FILE( ${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_D ADD_EXECUTABLE( ${PROJECT_NAME} ${SOURCES_FILES} ${HEADERS_MOC_FILES} ${FORMS_HEADERS_FILES} ${RESOURCES_RCC_FILES} ) -IF( USE_FFMPEG ) - INCLUDE_DIRECTORIES(${FFMPEG_INCLUDE_DIR} ${FFMPEG_INCLUDE_DIRS}) - SET( LINKER_LIBS ${LINKER_LIBS} ${FFMPEG_LIBRARIES} ) -ENDIF() -message( STATUS ${LINKER_LIBS} ) TARGET_LINK_LIBRARIES( ${PROJECT_NAME} ${LINKER_LIBS} ) IF( NOT USE_QT4) From 3ea4aad26f3ad33587e623747952c2afe0ab063a Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Sat, 1 Feb 2014 20:15:21 +0000 Subject: [PATCH 17/18] Add file to include functions for libav interface! Rename ImageInterface. --- source/InputStream.cpp | 175 -------------- source/InputStream.h | 39 +--- source/LibAvContextHandle.cpp | 213 ++++++++++++++++++ source/LibAvContextHandle.h | 77 +++++++ ...ImageInterface.cpp => SubWindowHandle.cpp} | 34 +-- .../{ImageInterface.h => SubWindowHandle.h} | 6 +- source/plaYUVerApp.cpp | 18 +- source/plaYUVerApp.h | 8 +- 8 files changed, 324 insertions(+), 246 deletions(-) create mode 100755 source/LibAvContextHandle.cpp create mode 100755 source/LibAvContextHandle.h rename source/{ImageInterface.cpp => SubWindowHandle.cpp} (87%) rename source/{ImageInterface.h => SubWindowHandle.h} (96%) diff --git a/source/InputStream.cpp b/source/InputStream.cpp index 1679439..f7bbfcc 100755 --- a/source/InputStream.cpp +++ b/source/InputStream.cpp @@ -135,181 +135,6 @@ Bool InputStream::needFormatDialog( QString filename ) } } -#ifdef USE_FFMPEG -static int open_codec_context( int *stream_idx, AVFormatContext *fmt_ctx, enum AVMediaType type ) -{ - int ret; - AVStream *st; - AVCodecContext *dec_ctx = NULL; - AVCodec *dec = NULL; - - ret = av_find_best_stream( fmt_ctx, type, -1, -1, NULL, 0 ); - if( ret < 0 ) - { - return ret; - } - else - { - *stream_idx = ret; - st = fmt_ctx->streams[*stream_idx]; - - /* find decoder for the stream */ - dec_ctx = st->codec; - dec = avcodec_find_decoder( dec_ctx->codec_id ); - if( !dec ) - { - printf( "Failed to find %s codec\n", av_get_media_type_string( type ) ); - return ret; - } - - if( ( ret = avcodec_open2( dec_ctx, dec, NULL ) ) < 0 ) - { - printf( "Failed to open %s codec\n", av_get_media_type_string( type ) ); - return ret; - } - } - - return 0; -} - -Void LibAvContextHandle::closeAvFormat() -{ - if( video_dec_ctx ) - avcodec_close( video_dec_ctx ); - - avformat_close_input( &fmt_ctx ); - - av_free( frame ); - av_free( video_dst_data[0] ); -} - -Bool LibAvContextHandle::initAvFormat( QString filename, UInt width, UInt height ) -{ - Bool bRet = true; - int ret = 0; - - fmt_ctx = NULL; - video_dec_ctx = NULL; - video_stream = NULL; - video_dst_data[0] = NULL; - video_dst_data[1] = NULL; - video_dst_data[2] = NULL; - video_dst_data[3] = NULL; - video_stream_idx = -1; - frame = NULL; - m_bHasStream = false; - - char *src_filename = filename.toLocal8Bit().data(); - - FILE *video_dst_file = NULL; - - /* register all formats and codecs */ - av_register_all(); - - /* open input file, and allocate format context */ - if( avformat_open_input( &fmt_ctx, src_filename, NULL, NULL ) < 0 ) - { - qDebug( ) << " Could not open source file %s !!!" << filename << endl; - return false; - } - - /* retrieve stream information */ - if( avformat_find_stream_info( fmt_ctx, NULL ) < 0 ) - { - qDebug( ) << " Could not find stream information !!!" << endl; - return false; - } - - if( open_codec_context( &video_stream_idx, fmt_ctx, AVMEDIA_TYPE_VIDEO ) >= 0 ) - { - video_stream = fmt_ctx->streams[video_stream_idx]; - video_dec_ctx = video_stream->codec; - - /* allocate image where the decoded image will be put */ - ret = av_image_alloc( video_dst_data, video_dst_linesize, video_dec_ctx->width, video_dec_ctx->height, video_dec_ctx->pix_fmt, 1 ); - if( ret < 0 ) - { - qDebug( ) << " Could not allocate raw video buffer !!!" << endl; - closeAvFormat(); - return false; - } - video_dst_bufsize = ret; - } - - /* dump input information to stderr */ - av_dump_format( fmt_ctx, 0, src_filename, 0 ); - if( !video_stream ) - { - qDebug( ) << " Could not find audio or video stream in the input, aborting !!!" << endl; - bRet = false; - closeAvFormat(); - return false; - } - - frame = avcodec_alloc_frame(); - if( !frame ) - { - qDebug( ) << " Could not allocate frame !!!" << endl; - ret = AVERROR( ENOMEM ); - closeAvFormat(); - return false; - } - - /* initialize packet, set data to NULL, let the demuxer fill it */ - av_init_packet( &pkt ); - pkt.data = NULL; - pkt.size = 0; - - m_bHasStream = true; - - return true; -} - -Bool LibAvContextHandle::decodeAvFormat() -{ - Int got_frame; - int ret; - /* read frames from the file */ - - if( av_read_frame( fmt_ctx, &pkt ) >= 0 ) - { - if( pkt.stream_index == video_stream_idx ) - { - /* decode video frame */ - 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 ) - { - /* 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 ); - - /* write to rawvideo file */ - //fwrite( video_dst_data[0], 1, video_dst_bufsize, video_dst_file ); - } - } - av_free_packet( &pkt ); - } - -// /* flush cached frames */ -// pkt.data = NULL; -// pkt.size = 0; -// do -// { -// decode_packet( &got_frame, 1 ); -// } -// while( got_frame ); - - true; -} -#endif - Void InputStream::init( QString filename, UInt width, UInt height, Int input_format ) { diff --git a/source/InputStream.h b/source/InputStream.h index f7813ac..9248a77 100755 --- a/source/InputStream.h +++ b/source/InputStream.h @@ -36,17 +36,8 @@ #include #endif -#ifdef USE_FFMPEG -extern "C" -{ -#include "libavutil/imgutils.h" -#include "libavutil/samplefmt.h" -#include "libavutil/timestamp.h" -#include "libavformat/avformat.h" -} -#endif - #include "TypeDef.h" +#include "LibAvContextHandle.h" namespace plaYUVer { @@ -56,34 +47,6 @@ enum InputStream_Errors NO_ERROR = 0, READING = 1, }; -#ifdef USE_FFMPEG -class LibAvContextHandle -{ -public: - Bool initAvFormat( QString filename, UInt width, UInt height ); - Void closeAvFormat(); - Bool decodeAvFormat(); - - Bool getStatus() - { - return m_bHasStream; - } - - uint8_t *video_dst_data[4]; - int video_dst_linesize[4]; - int video_dst_bufsize; - -private: - AVFormatContext *fmt_ctx; - AVCodecContext *video_dec_ctx; - AVStream *video_stream; - Int video_stream_idx; - AVFrame *frame; - AVPacket pkt; - - Bool m_bHasStream; -}; -#endif class InputStream { diff --git a/source/LibAvContextHandle.cpp b/source/LibAvContextHandle.cpp new file mode 100755 index 0000000..e08404c --- /dev/null +++ b/source/LibAvContextHandle.cpp @@ -0,0 +1,213 @@ +/* This file is a part of plaYUVer project + * Copyright (C) 2014 by plaYUVer developers + * + * 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 LibAvContextHandle.cpp + * \brief Interface with libav libs + */ + +#include "LibAvContextHandle.h" + +#ifdef USE_FFMPEG + +#include + +#include + +#include "InputStream.h" +#include "LibMemAlloc.h" + +namespace plaYUVer +{ + +static int open_codec_context( int *stream_idx, AVFormatContext *fmt_ctx, enum AVMediaType type ) +{ + int ret; + AVStream *st; + AVCodecContext *dec_ctx = NULL; + AVCodec *dec = NULL; + + ret = av_find_best_stream( fmt_ctx, type, -1, -1, NULL, 0 ); + if( ret < 0 ) + { + return ret; + } + else + { + *stream_idx = ret; + st = fmt_ctx->streams[*stream_idx]; + + /* find decoder for the stream */ + dec_ctx = st->codec; + dec = avcodec_find_decoder( dec_ctx->codec_id ); + if( !dec ) + { + printf( "Failed to find %s codec\n", av_get_media_type_string( type ) ); + return ret; + } + + if( ( ret = avcodec_open2( dec_ctx, dec, NULL ) ) < 0 ) + { + printf( "Failed to open %s codec\n", av_get_media_type_string( type ) ); + return ret; + } + } + + return 0; +} + +Void LibAvContextHandle::closeAvFormat() +{ + if( video_dec_ctx ) + avcodec_close( video_dec_ctx ); + + avformat_close_input( &fmt_ctx ); + + av_free( frame ); + av_free( video_dst_data[0] ); +} + +Bool LibAvContextHandle::initAvFormat( QString filename, UInt width, UInt height ) +{ + Bool bRet = true; + int ret = 0; + + fmt_ctx = NULL; + video_dec_ctx = NULL; + video_stream = NULL; + video_dst_data[0] = NULL; + video_dst_data[1] = NULL; + video_dst_data[2] = NULL; + video_dst_data[3] = NULL; + video_stream_idx = -1; + frame = NULL; + m_bHasStream = false; + + char *src_filename = filename.toLocal8Bit().data(); + + FILE *video_dst_file = NULL; + + /* register all formats and codecs */ + av_register_all(); + + /* open input file, and allocate format context */ + if( avformat_open_input( &fmt_ctx, src_filename, NULL, NULL ) < 0 ) + { + qDebug( ) << " Could not open source file %s !!!" << filename << endl; + return false; + } + + /* retrieve stream information */ + if( avformat_find_stream_info( fmt_ctx, NULL ) < 0 ) + { + qDebug( ) << " Could not find stream information !!!" << endl; + return false; + } + + if( open_codec_context( &video_stream_idx, fmt_ctx, AVMEDIA_TYPE_VIDEO ) >= 0 ) + { + video_stream = fmt_ctx->streams[video_stream_idx]; + video_dec_ctx = video_stream->codec; + + /* allocate image where the decoded image will be put */ + ret = av_image_alloc( video_dst_data, video_dst_linesize, video_dec_ctx->width, video_dec_ctx->height, video_dec_ctx->pix_fmt, 1 ); + if( ret < 0 ) + { + qDebug( ) << " Could not allocate raw video buffer !!!" << endl; + closeAvFormat(); + return false; + } + video_dst_bufsize = ret; + } + + /* dump input information to stderr */ + av_dump_format( fmt_ctx, 0, src_filename, 0 ); + if( !video_stream ) + { + qDebug( ) << " Could not find audio or video stream in the input, aborting !!!" << endl; + bRet = false; + closeAvFormat(); + return false; + } + + frame = avcodec_alloc_frame(); + if( !frame ) + { + qDebug( ) << " Could not allocate frame !!!" << endl; + ret = AVERROR( ENOMEM ); + closeAvFormat(); + return false; + } + + /* initialize packet, set data to NULL, let the demuxer fill it */ + av_init_packet( &pkt ); + pkt.data = NULL; + pkt.size = 0; + + m_bHasStream = true; + + return true; +} + +Bool LibAvContextHandle::decodeAvFormat() +{ + Int got_frame; + int ret; + /* read frames from the file */ + + if( av_read_frame( fmt_ctx, &pkt ) >= 0 ) + { + if( pkt.stream_index == video_stream_idx ) + { + /* decode video frame */ + 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 ) + { + /* 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 ); + + /* write to rawvideo file */ + //fwrite( video_dst_data[0], 1, video_dst_bufsize, video_dst_file ); + } + } + av_free_packet( &pkt ); + } + +// /* flush cached frames */ +// pkt.data = NULL; +// pkt.size = 0; +// do +// { +// decode_packet( &got_frame, 1 ); +// } +// while( got_frame ); + + true; +} + +} // NAMESPACE + +#endif diff --git a/source/LibAvContextHandle.h b/source/LibAvContextHandle.h new file mode 100755 index 0000000..7b44c26 --- /dev/null +++ b/source/LibAvContextHandle.h @@ -0,0 +1,77 @@ +/* This file is a part of plaYUVer project + * Copyright (C) 2014 by plaYUVer developers + * + * 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 LibAvContextHandle.h + * \brief Interface with libav libs + */ + +#ifndef __LIBAVCONTEXTHANDLE_H__ +#define __LIBAVCONTEXTHANDLE_H__ + +#include "config.h" + +#ifdef USE_FFMPEG + +#include + +extern "C" +{ +#include "libavutil/imgutils.h" +#include "libavutil/samplefmt.h" +#include "libavutil/timestamp.h" +#include "libavformat/avformat.h" +} + +#include "TypeDef.h" + +namespace plaYUVer +{ + +class LibAvContextHandle +{ +public: + Bool initAvFormat( QString filename, UInt width, UInt height ); + Void closeAvFormat(); + Bool decodeAvFormat(); + + Bool getStatus() + { + return m_bHasStream; + } + + uint8_t *video_dst_data[4]; + int video_dst_linesize[4]; + int video_dst_bufsize; + +private: + AVFormatContext *fmt_ctx; + AVCodecContext *video_dec_ctx; + AVStream *video_stream; + Int video_stream_idx; + AVFrame *frame; + AVPacket pkt; + + Bool m_bHasStream; +}; + +} // NAMESPACE + +#endif + +#endif // __LIBAVCONTEXTHANDLE_H__ diff --git a/source/ImageInterface.cpp b/source/SubWindowHandle.cpp similarity index 87% rename from source/ImageInterface.cpp rename to source/SubWindowHandle.cpp index 40821db..19ade75 100644 --- a/source/ImageInterface.cpp +++ b/source/SubWindowHandle.cpp @@ -22,13 +22,13 @@ */ #include "ConfigureFormatDialog.h" -#include "ImageInterface.h" +#include "SubWindowHandle.h" #include "viewarea.h" namespace plaYUVer { -ImageInterface::ImageInterface( QWidget * parent ) : +SubWindowHandle::SubWindowHandle( QWidget * parent ) : QMdiSubWindow( parent ) { setParent( parent ); @@ -52,12 +52,12 @@ ImageInterface::ImageInterface( QWidget * parent ) : } -ImageInterface::~ImageInterface() +SubWindowHandle::~SubWindowHandle() { delete m_cViewArea; } -bool ImageInterface::loadFile( const QString &fileName ) +bool SubWindowHandle::loadFile( const QString &fileName ) { ConfigureFormatDialog formatDialog( this ); @@ -100,7 +100,7 @@ bool ImageInterface::loadFile( const QString &fileName ) return true; } -bool ImageInterface::save() +bool SubWindowHandle::save() { QString supported = tr( "Supported Files" ); QString formats = InputStream::supportedWriteFormats(); @@ -130,7 +130,7 @@ bool ImageInterface::save() return true; } -bool ImageInterface::nextVideoFrame() +bool SubWindowHandle::nextVideoFrame() { m_currStream.readFrame(); if( m_currStream.checkErrors( READING ) ) @@ -142,13 +142,13 @@ bool ImageInterface::nextVideoFrame() return true; } -Void ImageInterface::normalSize() +Void SubWindowHandle::normalSize() { m_dScaleFactor = 1.0; m_cViewArea->setZoomFactor( m_dScaleFactor ); } -Void ImageInterface::zoomToFit() +Void SubWindowHandle::zoomToFit() { // Scale to a smaller size that the real to a nicer look QSize niceFit( m_cScrollArea->viewport()->size().width() - 10, m_cScrollArea->viewport()->size().height() - 10 ); @@ -160,7 +160,7 @@ Void ImageInterface::zoomToFit() scaleView( niceFit ); } -Void ImageInterface::scaleView( Double factor ) +Void SubWindowHandle::scaleView( Double factor ) { Q_ASSERT( m_cViewArea->image() ); m_dScaleFactor *= factor; @@ -168,12 +168,12 @@ Void ImageInterface::scaleView( Double factor ) adjustScrollBar( m_dScaleFactor ); } -Void ImageInterface::scaleView( Int width, Int height ) +Void SubWindowHandle::scaleView( Int width, Int height ) { scaleView( QSize( width, height ) ); } -Void ImageInterface::scaleView( const QSize & size ) +Void SubWindowHandle::scaleView( const QSize & size ) { QSize imgViewSize( m_currStream.getWidth(), m_currStream.getHeight() ); QSize newSize = imgViewSize; @@ -193,7 +193,7 @@ Void ImageInterface::scaleView( const QSize & size ) scaleView( hfactor ); } -Void ImageInterface::adjustScrollBar( Double factor ) +Void SubWindowHandle::adjustScrollBar( Double factor ) { QScrollBar *scrollBar = m_cScrollArea->horizontalScrollBar(); scrollBar->setValue( int( factor * scrollBar->value() + ( ( factor - 1 ) * scrollBar->pageStep() / 2 ) ) ); @@ -201,7 +201,7 @@ Void ImageInterface::adjustScrollBar( Double factor ) scrollBar->setValue( int( factor * scrollBar->value() + ( ( factor - 1 ) * scrollBar->pageStep() / 2 ) ) ); } -QSize ImageInterface::sizeHint() const +QSize SubWindowHandle::sizeHint() const { QSize maxSize; // The size of the parent (viewport widget // of the QMdiArea). @@ -214,7 +214,7 @@ QSize ImageInterface::sizeHint() const QSize isize = QSize( m_currStream.getWidth() + 500, m_currStream.getHeight() + 500 ); - // If the ImageInterface needs more space that the avaiable, we'll give + // If the SubWindowHandle 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() ) { @@ -229,17 +229,17 @@ QSize ImageInterface::sizeHint() const return maxSize; } -Void ImageInterface::closeEvent( QCloseEvent *event ) +Void SubWindowHandle::closeEvent( QCloseEvent *event ) { event->accept(); } -QString ImageInterface::userFriendlyCurrentFile() +QString SubWindowHandle::userFriendlyCurrentFile() { return strippedName( m_cCurrFileName ); } -QString ImageInterface::strippedName( const QString &fullFileName ) +QString SubWindowHandle::strippedName( const QString &fullFileName ) { return QFileInfo( fullFileName ).fileName(); } diff --git a/source/ImageInterface.h b/source/SubWindowHandle.h similarity index 96% rename from source/ImageInterface.h rename to source/SubWindowHandle.h index e74dd1f..396f8fb 100644 --- a/source/ImageInterface.h +++ b/source/SubWindowHandle.h @@ -41,7 +41,7 @@ namespace plaYUVer using namespace SCode; -class ImageInterface: public QMdiSubWindow +class SubWindowHandle: public QMdiSubWindow { Q_OBJECT @@ -56,8 +56,8 @@ private: Double m_dScaleFactor; public: - ImageInterface( QWidget * parent = 0 ); - ~ImageInterface(); + SubWindowHandle( QWidget * parent = 0 ); + ~SubWindowHandle(); bool loadFile( const QString &fileName ); bool save(); diff --git a/source/plaYUVerApp.cpp b/source/plaYUVerApp.cpp index e0140a2..1c04cbe 100644 --- a/source/plaYUVerApp.cpp +++ b/source/plaYUVerApp.cpp @@ -30,7 +30,7 @@ #include "TypeDef.h" #include "plaYUVerApp.h" -#include "ImageInterface.h" +#include "SubWindowHandle.h" #include "InputStream.h" namespace plaYUVer @@ -107,7 +107,7 @@ void plaYUVerApp::open() return; } - ImageInterface *interfaceChild = new ImageInterface( this ); //createImageInterface(); + SubWindowHandle *interfaceChild = new SubWindowHandle( this ); //createImageInterface(); if( interfaceChild->loadFile( fileName ) ) { addImageInterface( interfaceChild ); @@ -226,7 +226,7 @@ void plaYUVerApp::updateWindowMenu() for( Int i = 0; i < windows.size(); ++i ) { - ImageInterface *child = qobject_cast( windows.at( i ) ); + SubWindowHandle *child = qobject_cast( windows.at( i ) ); QString text; if( i < 9 ) @@ -245,15 +245,15 @@ void plaYUVerApp::updateWindowMenu() } } -ImageInterface *plaYUVerApp::createImageInterface() +SubWindowHandle *plaYUVerApp::createImageInterface() { - ImageInterface *child = new ImageInterface; + SubWindowHandle *child = new SubWindowHandle; mdiArea->addSubWindow( child ); return child; } -void plaYUVerApp::addImageInterface( ImageInterface *child ) +void plaYUVerApp::addImageInterface( SubWindowHandle *child ) { //connect( child, SIGNAL( areaSelected( QRect ) ), this, SLOT( setSelection( QRect ) ) ); @@ -416,10 +416,10 @@ Void plaYUVerApp::writeSettings() settings.setValue( "size", size() ); } -ImageInterface *plaYUVerApp::activeImageInterface() +SubWindowHandle *plaYUVerApp::activeImageInterface() { if( QMdiSubWindow *activeImageInterface = mdiArea->activeSubWindow() ) - return qobject_cast( activeImageInterface ); + return qobject_cast( activeImageInterface ); return 0; } @@ -428,7 +428,7 @@ QMdiSubWindow *plaYUVerApp::findImageInterface( const QString &fileName ) QString canonicalFilePath = QFileInfo( fileName ).canonicalFilePath(); foreach( QMdiSubWindow * window, mdiArea->subWindowList() ){ - ImageInterface *mdiChild = qobject_cast( window); + SubWindowHandle *mdiChild = qobject_cast( window); if( mdiChild->currentFile() == canonicalFilePath ) return window; } diff --git a/source/plaYUVerApp.h b/source/plaYUVerApp.h index 224df2a..36891a6 100644 --- a/source/plaYUVerApp.h +++ b/source/plaYUVerApp.h @@ -38,7 +38,7 @@ class QSignalMapper; namespace plaYUVer { -class ImageInterface; +class SubWindowHandle; class plaYUVerApp: public QMainWindow { @@ -72,8 +72,8 @@ private slots: void updateWindowMenu(); - ImageInterface *createImageInterface(); - void addImageInterface( ImageInterface *child ); + SubWindowHandle *createImageInterface(); + void addImageInterface( SubWindowHandle *child ); void setActiveImageInterface( QWidget *window ); private: @@ -83,7 +83,7 @@ private: Void createStatusBar(); Void readSettings(); Void writeSettings(); - ImageInterface *activeImageInterface(); + SubWindowHandle *activeImageInterface(); QMdiSubWindow *findImageInterface( const QString &fileName ); /** From 831ea939a52d9623e39787c4eb04f805ff0a4c23 Mon Sep 17 00:00:00 2001 From: Joao Carreira Date: Sat, 1 Feb 2014 20:21:55 +0000 Subject: [PATCH 18/18] Add MACRO to define standard resolutions --- source/ConfigureFormatDialog.h | 29 +++++++++++------------------ 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/source/ConfigureFormatDialog.h b/source/ConfigureFormatDialog.h index 5b1b3ac..9d0dce6 100755 --- a/source/ConfigureFormatDialog.h +++ b/source/ConfigureFormatDialog.h @@ -24,7 +24,6 @@ #ifndef __CONFIGURERESOLUTIONDIALOG_H__ #define __CONFIGURERESOLUTIONDIALOG_H__ - #include "config.h" #if( QT_VERSION_PLAYUVER == 5 ) @@ -34,7 +33,6 @@ #endif #include - #include "TypeDef.h" class QPixmap; @@ -43,7 +41,10 @@ class QColor; namespace plaYUVer { -#define MAX_STANDARD_RESOLUTIONSIZES 10 +#define ADD_STANDARD_RESOLUTION( name, width, height) \ + standardResolutionNames.push_back( QString( name ) ); \ + standardResolutionSizesList.push_back( QSize( width, height ) ) + /** * */ @@ -62,7 +63,7 @@ public: Int getPixelFormat() { - pixelFormatBox->currentIndex(); + return pixelFormatBox->currentIndex(); } private Q_SLOTS: @@ -71,7 +72,6 @@ private Q_SLOTS: private: QStringList standardResolutionNames; QList standardResolutionSizesList; - QSize standardResolutionSizes[MAX_STANDARD_RESOLUTIONSIZES]; QVBoxLayout *MainLayout; QHBoxLayout *headLayout; QLabel *dialogTitleLabel; @@ -98,29 +98,22 @@ private: QSpacerItem *pixelFormatHorizontalSpacer; QComboBox *pixelFormatBox; - QSpacerItem *verticalSpacerConfirmation; QDialogButtonBox *dialogButtonOkCancel; Void setStandardResolutionSizes() { - standardResolutionNames.push_back( QString( "CIF (352x288)" ) ); - standardResolutionSizesList.push_back( QSize( 352, 288 ) ); - - standardResolutionNames.push_back( QString( "VGA (640x480)" ) ); - standardResolutionSizesList.push_back( QSize( 640, 480 ) ); - - standardResolutionNames.push_back( QString( "HD (1024x768)" ) ); - standardResolutionSizesList.push_back( QSize( 1024, 768 ) ); - - standardResolutionNames.push_back( QString( "Full HD (1920x1080)" ) ); - standardResolutionSizesList.push_back( QSize( 1920, 1080 ) ); + ADD_STANDARD_RESOLUTION( "CIF (352x288)", 352, 288 ); + ADD_STANDARD_RESOLUTION( "VGA (640x480)", 640, 480 ); + ADD_STANDARD_RESOLUTION( "XVGA (1024x768)", 1024, 768 ); + ADD_STANDARD_RESOLUTION( "HD (1280x720)", 1280, 720 ); + ADD_STANDARD_RESOLUTION( "Full HD (1920x1080)", 1920, 1080 ); } }; -} // NAMESPACE +} // NAMESPACE #endif // __CONFIGURERESOLUTIONDIALOG_H__