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 ); /**