From 74cd14946b11e50a83a42942a91a81dab9769943 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Thu, 13 Aug 2015 17:08:46 +0200 Subject: [PATCH 001/119] jFileAnalysis: clean Fix #214 --- app/jFileAnalysis/jFileAnalysis.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/app/jFileAnalysis/jFileAnalysis.java b/app/jFileAnalysis/jFileAnalysis.java index 7ec53bd9..40c0868b 100644 --- a/app/jFileAnalysis/jFileAnalysis.java +++ b/app/jFileAnalysis/jFileAnalysis.java @@ -1,25 +1,25 @@ import org.avtranscoder.NoDisplayProgress; import org.avtranscoder.InputFile; +import org.avtranscoder.avtranscoder; public class jFileAnalysis { public static void main( String[] args ){ - System.loadLibrary("avutil"); - System.loadLibrary("swscale"); - System.loadLibrary("swresample"); - System.loadLibrary("avcodec"); - System.loadLibrary("avformat"); - System.loadLibrary("avtranscoder"); System.loadLibrary("avtranscoder-java"); System.out.println( "Start input file analyse"); + avtranscoder.preloadCodecsAndFormats(); + InputFile inputFile = new InputFile( args[0] ); NoDisplayProgress progress = new NoDisplayProgress(); inputFile.analyse( progress ); + // Access the properties you want with + // inputFile.getProperties() + System.out.println( "End input file analyse"); - } + } } // How to use From 72f2db50e3aa7163609f4e870bc805d225f7c998 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Thu, 13 Aug 2015 17:14:07 +0200 Subject: [PATCH 002/119] CMake: remove -pg option from debug build * Put profiling instructions for generating profiling information for gprof into the object or executable file. * We don't use gprof to profile. * Fix #212 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6ad9230e..d61f0e19 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,7 +27,7 @@ if(MSVC) set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT") else() - set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall -fPIC -pg -g") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall -fPIC -g") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fPIC -O3") endif() From e67d14053655d36184ff7df6601b207a92872624 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Thu, 13 Aug 2015 17:15:20 +0200 Subject: [PATCH 003/119] CMake: add -Wall option for both release & debug builds * Produce warning messages about a number of things that are legal but dubious. --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d61f0e19..cf85127d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,7 +28,7 @@ if(MSVC) set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT") else() set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall -fPIC -g") - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fPIC -O3") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Wall -fPIC -O3") endif() # CPP flag to create code coverage report From 8ab1d9f19b8d0068335b55729c39bb1b29db48c1 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Thu, 13 Aug 2015 17:41:15 +0200 Subject: [PATCH 004/119] OutputFile: rename setProfile to setupWrapping Issue #206 --- app/pyThumbnail/pythumbnail.py | 2 +- src/AvTranscoder/file/OutputFile.cpp | 2 +- src/AvTranscoder/file/OutputFile.hpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/pyThumbnail/pythumbnail.py b/app/pyThumbnail/pythumbnail.py index a22338d0..ca7eeb64 100644 --- a/app/pyThumbnail/pythumbnail.py +++ b/app/pyThumbnail/pythumbnail.py @@ -75,7 +75,7 @@ formatProfile[ av.avProfileType ] = av.avProfileTypeFormat formatProfile[ av.avProfileFormat ] = "mjpeg" outputFile = av.OutputFile( args.outputFileName ) -outputFile.setProfile( formatProfile ) +outputFile.setupWrapping( formatProfile ) # create input stream videoStreamIndex = inputFile.getProperties().getVideoProperties()[0].getStreamIndex() diff --git a/src/AvTranscoder/file/OutputFile.cpp b/src/AvTranscoder/file/OutputFile.cpp index c318c771..b87bd717 100644 --- a/src/AvTranscoder/file/OutputFile.cpp +++ b/src/AvTranscoder/file/OutputFile.cpp @@ -181,7 +181,7 @@ void OutputFile::addMetadata( const std::string& key, const std::string& value ) _formatContext.addMetaData( key, value ); } -void OutputFile::setProfile( const ProfileLoader::Profile& profile ) +void OutputFile::setupWrapping( const ProfileLoader::Profile& profile ) { LOG_DEBUG( "Set profile of output file with:\n" << profile ) diff --git a/src/AvTranscoder/file/OutputFile.hpp b/src/AvTranscoder/file/OutputFile.hpp index 8a22a138..faa77af7 100644 --- a/src/AvTranscoder/file/OutputFile.hpp +++ b/src/AvTranscoder/file/OutputFile.hpp @@ -77,7 +77,7 @@ class AvExport OutputFile : public IOutputFile * @brief Set the format of the output file * @param profile: the profile of the output format */ - void setProfile( const ProfileLoader::Profile& profile ); + void setupWrapping( const ProfileLoader::Profile& profile ); private: FormatContext _formatContext; From e0b65e73ead59367dd6bebfa2c518c7e16d248cb Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Thu, 13 Aug 2015 17:46:11 +0200 Subject: [PATCH 005/119] InputFile: rename setProfile to setupUnwrapping Fix #206 --- src/AvTranscoder/file/InputFile.cpp | 2 +- src/AvTranscoder/file/InputFile.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/AvTranscoder/file/InputFile.cpp b/src/AvTranscoder/file/InputFile.cpp index 06f5a0fe..479b3312 100644 --- a/src/AvTranscoder/file/InputFile.cpp +++ b/src/AvTranscoder/file/InputFile.cpp @@ -160,7 +160,7 @@ double InputFile::getFps() return fps; } -void InputFile::setProfile( const ProfileLoader::Profile& profile ) +void InputFile::setupUnwrapping( const ProfileLoader::Profile& profile ) { LOG_DEBUG( "Set profile of input file with:\n" << profile ) diff --git a/src/AvTranscoder/file/InputFile.hpp b/src/AvTranscoder/file/InputFile.hpp index cf61937d..156da6b4 100644 --- a/src/AvTranscoder/file/InputFile.hpp +++ b/src/AvTranscoder/file/InputFile.hpp @@ -99,7 +99,7 @@ class AvExport InputFile * @brief Set the format of the input file * @param profile: the profile of the input format */ - virtual void setProfile( const ProfileLoader::Profile& profile ); + virtual void setupUnwrapping( const ProfileLoader::Profile& profile ); public: /** From bc71cee24aef0b46c031fc878fc0d4b0e892b5ff Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Thu, 13 Aug 2015 17:59:31 +0200 Subject: [PATCH 006/119] decoders: call setupDecoder before decoding Fix #216 --- src/AvTranscoder/decoder/AudioDecoder.cpp | 9 +++++++-- src/AvTranscoder/decoder/AudioDecoder.hpp | 2 ++ src/AvTranscoder/decoder/VideoDecoder.cpp | 9 +++++++-- src/AvTranscoder/decoder/VideoDecoder.hpp | 2 ++ 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/AvTranscoder/decoder/AudioDecoder.cpp b/src/AvTranscoder/decoder/AudioDecoder.cpp index 4e12ad32..84f15e92 100644 --- a/src/AvTranscoder/decoder/AudioDecoder.cpp +++ b/src/AvTranscoder/decoder/AudioDecoder.cpp @@ -18,8 +18,9 @@ namespace avtranscoder { AudioDecoder::AudioDecoder( InputStream& inputStream ) - : _inputStream ( &inputStream ) - , _frame ( NULL ) + : _inputStream( &inputStream ) + , _frame( NULL ) + , _isSetup(false) { #if LIBAVCODEC_VERSION_MAJOR > 54 _frame = av_frame_alloc(); @@ -84,6 +85,7 @@ void AudioDecoder::setupDecoder( const ProfileLoader::Profile& profile ) // open decoder _inputStream->getAudioCodec().openCodec(); + _isSetup = true; } bool AudioDecoder::decodeNextFrame( Frame& frameBuffer ) @@ -155,6 +157,9 @@ bool AudioDecoder::decodeNextFrame( Frame& frameBuffer, const size_t subStreamIn bool AudioDecoder::decodeNextFrame() { + if(!_isSetup) + setupDecoder(); + int got_frame = 0; while( ! got_frame ) { diff --git a/src/AvTranscoder/decoder/AudioDecoder.hpp b/src/AvTranscoder/decoder/AudioDecoder.hpp index b9fc3300..73e59000 100644 --- a/src/AvTranscoder/decoder/AudioDecoder.hpp +++ b/src/AvTranscoder/decoder/AudioDecoder.hpp @@ -27,6 +27,8 @@ class AvExport AudioDecoder : public IDecoder private: InputStream* _inputStream; ///< Stream from which we read next frames (no ownership, has link) AVFrame* _frame; ///< Libav object to store decoded data (has ownership) + + bool _isSetup; }; } diff --git a/src/AvTranscoder/decoder/VideoDecoder.cpp b/src/AvTranscoder/decoder/VideoDecoder.cpp index 68503d8b..f6b438c6 100644 --- a/src/AvTranscoder/decoder/VideoDecoder.cpp +++ b/src/AvTranscoder/decoder/VideoDecoder.cpp @@ -17,8 +17,9 @@ namespace avtranscoder { VideoDecoder::VideoDecoder( InputStream& inputStream ) - : _inputStream ( &inputStream ) - , _frame ( NULL ) + : _inputStream( &inputStream ) + , _frame( NULL ) + , _isSetup(false) { #if LIBAVCODEC_VERSION_MAJOR > 54 _frame = av_frame_alloc(); @@ -82,6 +83,7 @@ void VideoDecoder::setupDecoder( const ProfileLoader::Profile& profile ) // open decoder _inputStream->getVideoCodec().openCodec(); + _isSetup = true; } bool VideoDecoder::decodeNextFrame( Frame& frameBuffer ) @@ -109,6 +111,9 @@ bool VideoDecoder::decodeNextFrame( Frame& frameBuffer, const size_t subStreamIn bool VideoDecoder::decodeNextFrame() { + if(!_isSetup) + setupDecoder(); + int got_frame = 0; while( ! got_frame ) { diff --git a/src/AvTranscoder/decoder/VideoDecoder.hpp b/src/AvTranscoder/decoder/VideoDecoder.hpp index 72dfb9cd..e82ed011 100644 --- a/src/AvTranscoder/decoder/VideoDecoder.hpp +++ b/src/AvTranscoder/decoder/VideoDecoder.hpp @@ -29,6 +29,8 @@ class AvExport VideoDecoder : public IDecoder private: InputStream* _inputStream; ///< Stream from which we read next frames (no ownership, has link) AVFrame* _frame; ///< Libav object to store decoded data (has ownership) + + bool _isSetup; }; } From dc791649b4dead050ba4f5820e3d0b9d65441b22 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Thu, 13 Aug 2015 18:02:31 +0200 Subject: [PATCH 007/119] IDecoder: setupDecoder is no more a pure virtual method Avoid to implement an empty function in generators. --- src/AvTranscoder/decoder/AudioGenerator.hpp | 2 -- src/AvTranscoder/decoder/IDecoder.hpp | 2 +- src/AvTranscoder/decoder/VideoGenerator.hpp | 2 -- 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/AvTranscoder/decoder/AudioGenerator.hpp b/src/AvTranscoder/decoder/AudioGenerator.hpp index b9defc01..1590b974 100644 --- a/src/AvTranscoder/decoder/AudioGenerator.hpp +++ b/src/AvTranscoder/decoder/AudioGenerator.hpp @@ -16,8 +16,6 @@ class AvExport AudioGenerator : public IDecoder ~AudioGenerator(); - void setupDecoder( const ProfileLoader::Profile& profile = ProfileLoader::Profile() ) {} - bool decodeNextFrame( Frame& frameBuffer ); bool decodeNextFrame( Frame& frameBuffer, const size_t subStreamIndex ); diff --git a/src/AvTranscoder/decoder/IDecoder.hpp b/src/AvTranscoder/decoder/IDecoder.hpp index bbbf4fa8..9194ccb5 100644 --- a/src/AvTranscoder/decoder/IDecoder.hpp +++ b/src/AvTranscoder/decoder/IDecoder.hpp @@ -18,7 +18,7 @@ class AvExport IDecoder * @param profile: set decoder parameters from the given profile * @note Open the decoder. */ - virtual void setupDecoder( const ProfileLoader::Profile& profile = ProfileLoader::Profile() ) = 0; + virtual void setupDecoder( const ProfileLoader::Profile& profile = ProfileLoader::Profile() ) {} /** * @brief Decode next frame diff --git a/src/AvTranscoder/decoder/VideoGenerator.hpp b/src/AvTranscoder/decoder/VideoGenerator.hpp index ce7cb4fd..2e9b2b40 100644 --- a/src/AvTranscoder/decoder/VideoGenerator.hpp +++ b/src/AvTranscoder/decoder/VideoGenerator.hpp @@ -16,8 +16,6 @@ class AvExport VideoGenerator : public IDecoder ~VideoGenerator(); - void setupDecoder( const ProfileLoader::Profile& profile = ProfileLoader::Profile() ) {} - bool decodeNextFrame( Frame& frameBuffer ); bool decodeNextFrame( Frame& frameBuffer, const size_t subStreamIndex ); From fdc9c53f20d796108903151abc6900fb3cf68167 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Fri, 14 Aug 2015 09:50:31 +0200 Subject: [PATCH 008/119] CMake: fix compilation warnings when build java binding * From swig documentation about java binding: "If you are going to use optimisations turned on with gcc (for example -O2), ensure you also compile with -fno-strict-aliasing. The GCC optimisations have become more aggressive from gcc-4.0 onwards and will result in code that fails with strict aliasing optimisations turned on." * http://www.swig.org/Doc1.3/Java.html --- src/CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 116e6976..a9b2dbab 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -132,6 +132,11 @@ if(SWIG_FOUND) include_directories(${JAVA_INCLUDE_PATH}) include_directories(${JNI_INCLUDE_DIRS}) + # Update compilation flags + if(NOT MSVC) + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fno-strict-aliasing") + endif() + # Swig flags set(CMAKE_SWIG_FLAGS ${CMAKE_SWIG_FLAGS} -package org.avtranscoder) From 99bf0d8853005e40e3bcbec48c4fd9e9fea78778 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Thu, 13 Aug 2015 12:57:23 +0200 Subject: [PATCH 009/119] AudioProperties: compute nbSamples if the info is unknown from ffmpeg --- src/AvTranscoder/mediaProperty/AudioProperties.cpp | 5 ++++- src/AvTranscoder/mediaProperty/AudioProperties.hpp | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/AvTranscoder/mediaProperty/AudioProperties.cpp b/src/AvTranscoder/mediaProperty/AudioProperties.cpp index c67c97b5..5e3f42d5 100644 --- a/src/AvTranscoder/mediaProperty/AudioProperties.cpp +++ b/src/AvTranscoder/mediaProperty/AudioProperties.cpp @@ -167,7 +167,10 @@ size_t AudioProperties::getNbSamples() const { if( ! _formatContext ) throw std::runtime_error( "unknown format context" ); - return _formatContext->streams[_streamIndex]->nb_frames; + size_t nbSamples = _formatContext->streams[_streamIndex]->nb_frames; + if(nbSamples == 0) + nbSamples = getSampleRate() * getChannels() * getDuration(); + return nbSamples; } size_t AudioProperties::getTicksPerFrame() const diff --git a/src/AvTranscoder/mediaProperty/AudioProperties.hpp b/src/AvTranscoder/mediaProperty/AudioProperties.hpp index a53df387..63043b19 100644 --- a/src/AvTranscoder/mediaProperty/AudioProperties.hpp +++ b/src/AvTranscoder/mediaProperty/AudioProperties.hpp @@ -26,7 +26,7 @@ class AvExport AudioProperties : public StreamProperties size_t getSampleRate() const; size_t getChannels() const; size_t getBitRate() const; ///< 0 if unknown - size_t getNbSamples() const; ///< 0 if unknown + size_t getNbSamples() const; size_t getTicksPerFrame() const; From 8d6192ec860c1a68aa927cefadede35774dba268 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Thu, 13 Aug 2015 17:31:58 +0200 Subject: [PATCH 010/119] pyTest: fix test NbSamplesAudioTranscode This test check the number of samples after transcode, between input and output media. The number of channels needs to be the same. --- test/pyTest/testNbSamples.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/test/pyTest/testNbSamples.py b/test/pyTest/testNbSamples.py index b03ed85a..b77c9127 100644 --- a/test/pyTest/testNbSamples.py +++ b/test/pyTest/testNbSamples.py @@ -50,7 +50,14 @@ def testNbSamplesAudioTranscode(): ouputFile = av.OutputFile( outputFileName ) transcoder = av.Transcoder( ouputFile ) - transcoder.add( inputFileName, 0, "wave24b48kmono" ) + # create custom profile + customProfile = av.ProfileMap() + customProfile[av.avProfileIdentificator] = "customProfile" + customProfile[av.avProfileIdentificatorHuman] = "custom profile" + customProfile[av.avProfileType] = av.avProfileTypeAudio + customProfile[av.avProfileCodec] = "pcm_s16le" + + transcoder.add( inputFileName, 0, customProfile ) progress = av.ConsoleProgress() transcoder.process( progress ) From edf15012e253c3afbaa2a297982ac370ef58336e Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Mon, 17 Aug 2015 18:26:27 +0200 Subject: [PATCH 011/119] VideoProperties: compute nbFrames if the info is unknown from ffmpeg Cannot getFps() from nbFrames anymore. So always get fps from a compute with timebase. --- .../mediaProperty/VideoProperties.cpp | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/src/AvTranscoder/mediaProperty/VideoProperties.cpp b/src/AvTranscoder/mediaProperty/VideoProperties.cpp index 47b8df74..f4135fd3 100644 --- a/src/AvTranscoder/mediaProperty/VideoProperties.cpp +++ b/src/AvTranscoder/mediaProperty/VideoProperties.cpp @@ -459,7 +459,10 @@ size_t VideoProperties::getNbFrames() const { if( ! _formatContext ) throw std::runtime_error( "unknown format context" ); - return _formatContext->streams[_streamIndex]->nb_frames; + size_t nbFrames = _formatContext->streams[_streamIndex]->nb_frames; + if( nbFrames == 0 ) + nbFrames = getFps() * getDuration(); + return nbFrames; } size_t VideoProperties::getTicksPerFrame() const @@ -520,16 +523,6 @@ int VideoProperties::getLevel() const float VideoProperties::getFps() const { - const size_t nbFrames = getNbFrames(); - if( nbFrames ) - { - const float duration = getDuration(); - const float epsilon = std::numeric_limits::epsilon(); - if( duration > epsilon ) - return nbFrames / duration; - } - - // if nbFrames of stream is unknwon Rational timeBase = getTimeBase(); float fps = timeBase.den / (double) timeBase.num; if( std::isinf( fps ) ) From c1ce18b5db5dce459a01bbb138665984f40d6c7d Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Mon, 24 Aug 2015 18:06:09 +0200 Subject: [PATCH 012/119] Add reader classes * New source folder 'reader': contains utility classes to read video/audio/... streams. * Add IReader class. * Add VideoReader class. * Update avplay app: use VideoReader class. --- app/avPlay/AvReader.cpp | 85 ----------------------- app/avPlay/AvReader.hpp | 41 ----------- app/avPlay/Reader.hpp | 27 -------- app/avPlay/Window.cpp | 15 ++-- app/avPlay/Window.hpp | 6 +- app/avPlay/main.cpp | 16 ++++- src/AvTranscoder/reader/IReader.hpp | 42 ++++++++++++ src/AvTranscoder/reader/VideoReader.cpp | 91 +++++++++++++++++++++++++ src/AvTranscoder/reader/VideoReader.hpp | 48 +++++++++++++ 9 files changed, 203 insertions(+), 168 deletions(-) delete mode 100644 app/avPlay/AvReader.cpp delete mode 100644 app/avPlay/AvReader.hpp delete mode 100644 app/avPlay/Reader.hpp create mode 100644 src/AvTranscoder/reader/IReader.hpp create mode 100644 src/AvTranscoder/reader/VideoReader.cpp create mode 100644 src/AvTranscoder/reader/VideoReader.hpp diff --git a/app/avPlay/AvReader.cpp b/app/avPlay/AvReader.cpp deleted file mode 100644 index 3febbebe..00000000 --- a/app/avPlay/AvReader.cpp +++ /dev/null @@ -1,85 +0,0 @@ -#include "AvReader.hpp" - -#include -#include - -AvReader::AvReader( const std::string& filename ) - : _inputFile( filename ) - , _inputVideo( NULL ) - , _sourceImage( NULL ) - , _imageToDisplay( NULL ) - , _videoTransform() - , _videoStream( 0 ) -{ - avtranscoder::NoDisplayProgress p; - _inputFile.analyse( p ); - _videoStream = _inputFile.getProperties().getVideoProperties().at(0).getStreamId(); - _inputFile.activateStream( _videoStream ); - - _inputVideo = new avtranscoder::VideoDecoder( _inputFile.getStream( _videoStream ) ); - _inputVideo->setupDecoder(); - - _sourceImage = new avtranscoder::VideoFrame( _inputFile.getStream( _videoStream ).getVideoCodec().getVideoFrameDesc() ); - - avtranscoder::VideoFrameDesc videoFrameDescToDisplay( _sourceImage->desc().getWidth(), _sourceImage->desc().getHeight(), "rgb24" ); - _imageToDisplay = new avtranscoder::VideoFrame( videoFrameDescToDisplay ); -} - -AvReader::~AvReader() -{ - delete _inputVideo; - delete _sourceImage; - delete _imageToDisplay; -} - -size_t AvReader::getWidth() -{ - return _inputFile.getProperties().getVideoProperties().at(0).getWidth(); -}; - -size_t AvReader::getHeight() -{ - return _inputFile.getProperties().getVideoProperties().at(0).getHeight(); -} - -size_t AvReader::getComponents() -{ - return _inputFile.getProperties().getVideoProperties().at(0).getPixelProperties().getNbComponents(); -} - -size_t AvReader::getBitDepth() -{ - return _inputFile.getProperties().getVideoProperties().at(0).getPixelProperties().getBitsPerPixel(); -} - -AVPixelFormat AvReader::getPixelFormat() -{ - return _inputFile.getProperties().getVideoProperties().at(0).getPixelProperties().getAVPixelFormat(); -} - -const char* AvReader::readNextFrame() -{ - ++_currentFrame; - _inputVideo->decodeNextFrame( *_sourceImage ); - _videoTransform.convert( *_sourceImage, *_imageToDisplay ); - return (const char*)_imageToDisplay->getData(); -} - -const char* AvReader::readPrevFrame() -{ - --_currentFrame; - return readFrameAt( _currentFrame ); -} - -const char* AvReader::readFrameAt( const size_t frame ) -{ - // /std::cout << "seek at " << frame << std::endl; - _inputFile.seekAtFrame( frame ); - _inputVideo->flushDecoder(); - return readNextFrame(); -} - -void AvReader::printMetadatas() -{ - std::cout << _inputFile << std::endl; -} diff --git a/app/avPlay/AvReader.hpp b/app/avPlay/AvReader.hpp deleted file mode 100644 index 7b326912..00000000 --- a/app/avPlay/AvReader.hpp +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef _AVPLAYER_AVREADER_ -#define _AVPLAYER_AVREADER_ - -#include -#include -#include -#include - -#include "Reader.hpp" - -class AvReader : public Reader -{ -public: - AvReader( const std::string& filename ); - ~AvReader(); - - size_t getWidth(); - size_t getHeight(); - size_t getComponents(); - size_t getBitDepth(); - AVPixelFormat getPixelFormat(); - - const char* readNextFrame(); - const char* readPrevFrame(); - const char* readFrameAt( const size_t frame ); - - void printMetadatas(); - -private: - avtranscoder::InputFile _inputFile; - - avtranscoder::VideoDecoder* _inputVideo; - - avtranscoder::VideoFrame* _sourceImage; - avtranscoder::VideoFrame* _imageToDisplay; - - avtranscoder::VideoTransform _videoTransform; - size_t _videoStream; -}; - -#endif diff --git a/app/avPlay/Reader.hpp b/app/avPlay/Reader.hpp deleted file mode 100644 index 418e18dc..00000000 --- a/app/avPlay/Reader.hpp +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef _AVPLAYER_READER_ -#define _AVPLAYER_READER_ - -class Reader -{ -public: - Reader() - : _currentFrame( 0 ) - {} - - virtual size_t getWidth() = 0; - virtual size_t getHeight() = 0; - virtual size_t getComponents() = 0; - virtual size_t getBitDepth() = 0; - - virtual const char* readNextFrame() = 0; - virtual const char* readPrevFrame() = 0; - virtual const char* readFrameAt( const size_t frame ) = 0; - - virtual void printMetadatas() = 0; - -protected: - - size_t _currentFrame; -}; - -#endif diff --git a/app/avPlay/Window.cpp b/app/avPlay/Window.cpp index 63d81d48..886c8bd3 100644 --- a/app/avPlay/Window.cpp +++ b/app/avPlay/Window.cpp @@ -14,7 +14,7 @@ #include #include -Reader* Window::_reader = NULL; +avtranscoder::VideoReader* Window::_reader = NULL; size_t Window::_width = 0; size_t Window::_height = 0; @@ -94,7 +94,7 @@ void loadNewTexture( const char* data, GLint internalFormat, size_t width, size_ loadNewTexture( _imageProperties ); } -Window::Window( Reader& reader ) +Window::Window( avtranscoder::VideoReader& reader ) { _reader = &reader; _width = _reader->getWidth(); @@ -220,11 +220,6 @@ void Window::keyboard( unsigned char k, int x, int y ) case 'a': showAlphaChannelTexture(); break; - - case 'm': - _reader->printMetadatas(); - break; - case 'H': if( shift ) { @@ -398,8 +393,7 @@ void Window::displayHelp() { static const std::string kViewerHelp = "Av Player Viewer Help\n" \ - "i : information about image (dimensions, bit depth, channels)\n"\ - "m : full metadatas of media\n"\ + "i : information about image (dimensions, bit depth, channels) + video stream\n"\ "z : zoom view to 1:1\n"\ "h, F1 : print help\n" \ "SHIFT + V : flip\n" \ @@ -425,6 +419,9 @@ void Window::displayInformations() case GL_FLOAT : textureType += "32 float"; break; } std::cout << textureType << " " << _width << "x" << _height << std::endl; + + // stream info + _reader->printInfo(); } void Window::move( float x, float y ) diff --git a/app/avPlay/Window.hpp b/app/avPlay/Window.hpp index 78e6e807..c7c45e01 100644 --- a/app/avPlay/Window.hpp +++ b/app/avPlay/Window.hpp @@ -3,12 +3,12 @@ #include -#include "Reader.hpp" +#include class Window { public: - Window( Reader& reader ); + Window( avtranscoder::VideoReader& reader ); void launch(); @@ -43,7 +43,7 @@ class Window static void loopPlaying( int value ); - static Reader* _reader; + static avtranscoder::VideoReader* _reader; static size_t _width; static size_t _height; diff --git a/app/avPlay/main.cpp b/app/avPlay/main.cpp index eb09cd05..f9336f16 100644 --- a/app/avPlay/main.cpp +++ b/app/avPlay/main.cpp @@ -1,6 +1,6 @@ #include +#include -#include "AvReader.hpp" #include "Window.hpp" @@ -8,7 +8,17 @@ int main( int argc, char** argv ) { avtranscoder::preloadCodecsAndFormats(); - AvReader avReader( argv[1] ); - Window window( avReader ); + if(argc < 2) + { + std::cout << "avplay can play the given video media file." << std::endl; + std::cout << "Provide the filename and the streamIndex (0 by default)" << std::endl; + return( -1 ); + } + + const std::string filename(argv[1]); + const size_t streamIndex = argc > 2 ? atoi(argv[2]) : 0; + + avtranscoder::VideoReader reader( filename, streamIndex ); + Window window( reader ); window.launch(); } \ No newline at end of file diff --git a/src/AvTranscoder/reader/IReader.hpp b/src/AvTranscoder/reader/IReader.hpp new file mode 100644 index 00000000..417a8f16 --- /dev/null +++ b/src/AvTranscoder/reader/IReader.hpp @@ -0,0 +1,42 @@ +#ifndef _AV_TRANSCODER_IREADER_HPP +#define _AV_TRANSCODER_IREADER_HPP + +#include + +namespace avtranscoder +{ + +class AvExport IReader +{ +public: + IReader() + : _currentFrame( 0 ) + {} + + /** + * @return Get next frame after decoding + */ + virtual const char* readNextFrame() = 0; + + /** + * @return Get previous frame after decoding + */ + virtual const char* readPrevFrame() = 0; + + /** + * @return Get indicated frame after decoding + */ + virtual const char* readFrameAt( const size_t frame ) = 0; + + /** + * @brief Print info of the stream read. + */ + virtual void printInfo() = 0; + +protected: + size_t _currentFrame; +}; + +} + +#endif diff --git a/src/AvTranscoder/reader/VideoReader.cpp b/src/AvTranscoder/reader/VideoReader.cpp new file mode 100644 index 00000000..c3194c49 --- /dev/null +++ b/src/AvTranscoder/reader/VideoReader.cpp @@ -0,0 +1,91 @@ +#include "VideoReader.hpp" + +#include +#include + +namespace avtranscoder +{ + +VideoReader::VideoReader( const std::string& filename, const size_t videoStreamIndex ) + : _inputFile( filename ) + , _videoProperties( NULL ) + , _videoDecoder( NULL ) + , _sourceImage( NULL ) + , _imageToDisplay( NULL ) + , _videoTransform() + , _videoStreamIndex( videoStreamIndex ) +{ + avtranscoder::NoDisplayProgress p; + _inputFile.analyse( p ); + _videoProperties = &static_cast(_inputFile.getProperties().getStreamPropertiesWithIndex(_videoStreamIndex)); + _inputFile.activateStream( _videoStreamIndex ); + + _videoDecoder = new avtranscoder::VideoDecoder( _inputFile.getStream( _videoStreamIndex ) ); + _videoDecoder->setupDecoder(); + + _sourceImage = new avtranscoder::VideoFrame( _inputFile.getStream( _videoStreamIndex ).getVideoCodec().getVideoFrameDesc() ); + + avtranscoder::VideoFrameDesc videoFrameDescToDisplay( _sourceImage->desc().getWidth(), _sourceImage->desc().getHeight(), "rgb24" ); + _imageToDisplay = new avtranscoder::VideoFrame( videoFrameDescToDisplay ); +} + +VideoReader::~VideoReader() +{ + delete _videoDecoder; + delete _sourceImage; + delete _imageToDisplay; +} + +size_t VideoReader::getWidth() +{ + return _videoProperties->getWidth(); +}; + +size_t VideoReader::getHeight() +{ + return _videoProperties->getHeight(); +} + +size_t VideoReader::getComponents() +{ + return _videoProperties->getPixelProperties().getNbComponents(); +} + +size_t VideoReader::getBitDepth() +{ + return _videoProperties->getPixelProperties().getBitsPerPixel(); +} + +AVPixelFormat VideoReader::getPixelFormat() +{ + return _videoProperties->getPixelProperties().getAVPixelFormat(); +} + +const char* VideoReader::readNextFrame() +{ + ++_currentFrame; + _videoDecoder->decodeNextFrame( *_sourceImage ); + _videoTransform.convert( *_sourceImage, *_imageToDisplay ); + return (const char*)_imageToDisplay->getData(); +} + +const char* VideoReader::readPrevFrame() +{ + --_currentFrame; + return readFrameAt( _currentFrame ); +} + +const char* VideoReader::readFrameAt( const size_t frame ) +{ + // /std::cout << "seek at " << frame << std::endl; + _inputFile.seekAtFrame( frame ); + _videoDecoder->flushDecoder(); + return readNextFrame(); +} + +void VideoReader::printInfo() +{ + std::cout << *_videoProperties << std::endl; +} + +} diff --git a/src/AvTranscoder/reader/VideoReader.hpp b/src/AvTranscoder/reader/VideoReader.hpp new file mode 100644 index 00000000..03345e5c --- /dev/null +++ b/src/AvTranscoder/reader/VideoReader.hpp @@ -0,0 +1,48 @@ +#ifndef _AV_TRANSCODER_VIDEOREADER_HPP +#define _AV_TRANSCODER_VIDEOREADER_HPP + +#include "IReader.hpp" + +#include +#include +#include +#include +#include + +namespace avtranscoder +{ + +class AvExport VideoReader : public IReader +{ +public: + VideoReader( const std::string& filename, const size_t videoStreamIndex ); + ~VideoReader(); + + size_t getWidth(); + size_t getHeight(); + size_t getComponents(); + size_t getBitDepth(); + AVPixelFormat getPixelFormat(); + + const char* readNextFrame(); + const char* readPrevFrame(); + const char* readFrameAt( const size_t frame ); + + void printInfo(); + +private: + InputFile _inputFile; + const VideoProperties* _videoProperties; + VideoDecoder* _videoDecoder; + + VideoFrame* _sourceImage; + VideoFrame* _imageToDisplay; + + VideoTransform _videoTransform; + + size_t _videoStreamIndex; +}; + +} + +#endif From a8c986282437126a75a33538a0a48ad09fe30d60 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 25 Aug 2015 11:55:30 +0200 Subject: [PATCH 013/119] VideoReader: refactoring read frame functions * readFrameAt contains the logic. * readNextFrame and readPrevFrame call readFrameAt. --- src/AvTranscoder/reader/VideoReader.cpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/AvTranscoder/reader/VideoReader.cpp b/src/AvTranscoder/reader/VideoReader.cpp index c3194c49..01d468e6 100644 --- a/src/AvTranscoder/reader/VideoReader.cpp +++ b/src/AvTranscoder/reader/VideoReader.cpp @@ -63,24 +63,25 @@ AVPixelFormat VideoReader::getPixelFormat() const char* VideoReader::readNextFrame() { - ++_currentFrame; - _videoDecoder->decodeNextFrame( *_sourceImage ); - _videoTransform.convert( *_sourceImage, *_imageToDisplay ); - return (const char*)_imageToDisplay->getData(); + return readFrameAt( _currentFrame + 1 ); } const char* VideoReader::readPrevFrame() { - --_currentFrame; - return readFrameAt( _currentFrame ); + return readFrameAt( _currentFrame - 1 ); } const char* VideoReader::readFrameAt( const size_t frame ) { - // /std::cout << "seek at " << frame << std::endl; + _currentFrame = frame; + // seek _inputFile.seekAtFrame( frame ); _videoDecoder->flushDecoder(); - return readNextFrame(); + // decode + _videoDecoder->decodeNextFrame( *_sourceImage ); + _videoTransform.convert( *_sourceImage, *_imageToDisplay ); + // return buffer + return (const char*)_imageToDisplay->getData(); } void VideoReader::printInfo() From 7eb37a439a6c6ad1a3ad39d17b7af815eb6ed1de Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 25 Aug 2015 11:56:11 +0200 Subject: [PATCH 014/119] avplay: fix update of display when seek to an other frame --- app/avPlay/Window.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/avPlay/Window.cpp b/app/avPlay/Window.cpp index 886c8bd3..eac7a9a1 100644 --- a/app/avPlay/Window.cpp +++ b/app/avPlay/Window.cpp @@ -531,12 +531,14 @@ void Window::displayNextFrame() { const char* buffer = _reader->readNextFrame(); loadNewTexture( buffer, _reader->getComponents(), _reader->getWidth(), _reader->getHeight(), GL_RGB, GL_UNSIGNED_BYTE ); + display(); } void Window::displayPrevFrame() { const char* buffer = _reader->readPrevFrame(); loadNewTexture( buffer, _reader->getComponents(), _reader->getWidth(), _reader->getHeight(), GL_RGB, GL_UNSIGNED_BYTE ); + display(); } void Window::displayFirstFrame() @@ -548,6 +550,7 @@ void Window::displayAtFrame( const size_t frame ) { const char* buffer = _reader->readFrameAt( frame ); loadNewTexture( buffer, _reader->getComponents(), _reader->getWidth(), _reader->getHeight(), GL_RGB, GL_UNSIGNED_BYTE ); + display(); } void Window::loopPlaying( int value ) From 8c1d9317a109594f453462ea3ac2c6fd6988882d Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 25 Aug 2015 11:56:34 +0200 Subject: [PATCH 015/119] avplay: call displayFirstFrame when launch the app --- app/avPlay/Window.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/avPlay/Window.cpp b/app/avPlay/Window.cpp index eac7a9a1..42932dd9 100644 --- a/app/avPlay/Window.cpp +++ b/app/avPlay/Window.cpp @@ -124,7 +124,7 @@ Window::Window( avtranscoder::VideoReader& reader ) void Window::launch() { - displayNextFrame(); + displayFirstFrame(); glutMainLoop(); } From 9b3d44a411ce442a803f14be19248515f428ec6b Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 25 Aug 2015 12:06:49 +0200 Subject: [PATCH 016/119] reader: add AudioReader class --- src/AvTranscoder/reader/AudioReader.cpp | 67 +++++++++++++++++++++++++ src/AvTranscoder/reader/AudioReader.hpp | 42 ++++++++++++++++ 2 files changed, 109 insertions(+) create mode 100644 src/AvTranscoder/reader/AudioReader.cpp create mode 100644 src/AvTranscoder/reader/AudioReader.hpp diff --git a/src/AvTranscoder/reader/AudioReader.cpp b/src/AvTranscoder/reader/AudioReader.cpp new file mode 100644 index 00000000..e70b6198 --- /dev/null +++ b/src/AvTranscoder/reader/AudioReader.cpp @@ -0,0 +1,67 @@ +#include "AudioReader.hpp" + +#include +#include + +namespace avtranscoder +{ + +AudioReader::AudioReader( const std::string& filename, const size_t audioStreamIndex ) + : _inputFile( filename ) + , _audioProperties( NULL ) + , _audioDecoder( NULL ) + , _sourceFrame( NULL ) + , _dstFrame( NULL ) + , _audioTransform() + , _audioStreamIndex( audioStreamIndex ) +{ + avtranscoder::NoDisplayProgress p; + _inputFile.analyse( p ); + _audioProperties = &static_cast(_inputFile.getProperties().getStreamPropertiesWithIndex(_audioStreamIndex)); + _inputFile.activateStream( _audioStreamIndex ); + + _audioDecoder = new avtranscoder::AudioDecoder( _inputFile.getStream( _audioStreamIndex ) ); + _audioDecoder->setupDecoder(); + + _sourceFrame = new avtranscoder::AudioFrame( _inputFile.getStream( _audioStreamIndex ).getAudioCodec().getAudioFrameDesc() ); + + avtranscoder::AudioFrameDesc dstAudioFrame( _sourceFrame->desc().getSampleRate(), _sourceFrame->desc().getChannels(), _sourceFrame->desc().getSampleFormat() ); + _dstFrame = new avtranscoder::AudioFrame( dstAudioFrame ); +} + +AudioReader::~AudioReader() +{ + delete _audioDecoder; + delete _sourceFrame; + delete _dstFrame; +} + +const char* AudioReader::readNextFrame() +{ + return readFrameAt( _currentFrame + 1 ); +} + +const char* AudioReader::readPrevFrame() +{ + return readFrameAt( _currentFrame - 1 ); +} + +const char* AudioReader::readFrameAt( const size_t frame ) +{ + _currentFrame = frame; + // seek + _inputFile.seekAtFrame( frame ); + _audioDecoder->flushDecoder(); + // decode + _audioDecoder->decodeNextFrame( *_sourceFrame ); + _audioTransform.convert( *_sourceFrame, *_dstFrame ); + // return buffer + return (const char*)_dstFrame->getData(); +} + +void AudioReader::printInfo() +{ + std::cout << *_audioProperties << std::endl; +} + +} diff --git a/src/AvTranscoder/reader/AudioReader.hpp b/src/AvTranscoder/reader/AudioReader.hpp new file mode 100644 index 00000000..8ac382dd --- /dev/null +++ b/src/AvTranscoder/reader/AudioReader.hpp @@ -0,0 +1,42 @@ +#ifndef _AV_TRANSCODER_AUDIOREADER_HPP +#define _AV_TRANSCODER_AUDIOREADER_HPP + +#include "IReader.hpp" + +#include +#include +#include +#include +#include + +namespace avtranscoder +{ + +class AvExport AudioReader : public IReader +{ +public: + AudioReader( const std::string& filename, const size_t audioStreamIndex ); + ~AudioReader(); + + const char* readNextFrame(); + const char* readPrevFrame(); + const char* readFrameAt( const size_t frame ); + + void printInfo(); + +private: + InputFile _inputFile; + const AudioProperties* _audioProperties; + AudioDecoder* _audioDecoder; + + AudioFrame* _sourceFrame; + AudioFrame* _dstFrame; + + AudioTransform _audioTransform; + + size_t _audioStreamIndex; +}; + +} + +#endif From 43adf397ae42930ce05db1d731452655a05b1632 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 25 Aug 2015 12:10:03 +0200 Subject: [PATCH 017/119] VideoReader: clean indentation --- src/AvTranscoder/reader/VideoReader.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AvTranscoder/reader/VideoReader.hpp b/src/AvTranscoder/reader/VideoReader.hpp index 03345e5c..4a1a8611 100644 --- a/src/AvTranscoder/reader/VideoReader.hpp +++ b/src/AvTranscoder/reader/VideoReader.hpp @@ -1,5 +1,5 @@ #ifndef _AV_TRANSCODER_VIDEOREADER_HPP -#define _AV_TRANSCODER_VIDEOREADER_HPP +#define _AV_TRANSCODER_VIDEOREADER_HPP #include "IReader.hpp" From 34dd7756e9a2c0ee5d56d26dcd276a0cb24a9ed9 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 25 Aug 2015 12:10:18 +0200 Subject: [PATCH 018/119] avplay: add newline at end of file --- app/avPlay/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/avPlay/main.cpp b/app/avPlay/main.cpp index f9336f16..132dc55f 100644 --- a/app/avPlay/main.cpp +++ b/app/avPlay/main.cpp @@ -21,4 +21,4 @@ int main( int argc, char** argv ) avtranscoder::VideoReader reader( filename, streamIndex ); Window window( reader ); window.launch(); -} \ No newline at end of file +} From e550b237b48d3b5ec2b0971e5034d08481bb4427 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 25 Aug 2015 12:10:47 +0200 Subject: [PATCH 019/119] AudioReader: add getters of sample rate and nb channels --- src/AvTranscoder/reader/AudioReader.cpp | 10 ++++++++++ src/AvTranscoder/reader/AudioReader.hpp | 3 +++ 2 files changed, 13 insertions(+) diff --git a/src/AvTranscoder/reader/AudioReader.cpp b/src/AvTranscoder/reader/AudioReader.cpp index e70b6198..10b774fa 100644 --- a/src/AvTranscoder/reader/AudioReader.cpp +++ b/src/AvTranscoder/reader/AudioReader.cpp @@ -36,6 +36,16 @@ AudioReader::~AudioReader() delete _dstFrame; } +size_t AudioReader::getSampleRate() +{ + return _audioProperties->getSampleRate(); +} + +size_t AudioReader::getChannels() +{ + return _audioProperties->getChannels(); +} + const char* AudioReader::readNextFrame() { return readFrameAt( _currentFrame + 1 ); diff --git a/src/AvTranscoder/reader/AudioReader.hpp b/src/AvTranscoder/reader/AudioReader.hpp index 8ac382dd..2fc33474 100644 --- a/src/AvTranscoder/reader/AudioReader.hpp +++ b/src/AvTranscoder/reader/AudioReader.hpp @@ -18,6 +18,9 @@ class AvExport AudioReader : public IReader AudioReader( const std::string& filename, const size_t audioStreamIndex ); ~AudioReader(); + size_t getSampleRate(); + size_t getChannels(); + const char* readNextFrame(); const char* readPrevFrame(); const char* readFrameAt( const size_t frame ); From 8eace2d995f07cc4934e1e43ae1e3867fae9ee9b Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 25 Aug 2015 14:14:34 +0200 Subject: [PATCH 020/119] AudioReader: add a constructor from an existing InputFile This constructor can improve performances when you create several AudioReader from one InputFile. --- src/AvTranscoder/reader/AudioReader.cpp | 38 ++++++++++++++++++++----- src/AvTranscoder/reader/AudioReader.hpp | 17 ++++++++++- 2 files changed, 47 insertions(+), 8 deletions(-) diff --git a/src/AvTranscoder/reader/AudioReader.cpp b/src/AvTranscoder/reader/AudioReader.cpp index 10b774fa..7b0ad2d0 100644 --- a/src/AvTranscoder/reader/AudioReader.cpp +++ b/src/AvTranscoder/reader/AudioReader.cpp @@ -7,23 +7,44 @@ namespace avtranscoder { AudioReader::AudioReader( const std::string& filename, const size_t audioStreamIndex ) - : _inputFile( filename ) + : _inputFile( NULL ) , _audioProperties( NULL ) , _audioDecoder( NULL ) , _sourceFrame( NULL ) , _dstFrame( NULL ) , _audioTransform() , _audioStreamIndex( audioStreamIndex ) + , _inputFileAllocated( true ) +{ + _inputFile = new InputFile( filename ); + + init(); +} + +AudioReader::AudioReader( InputFile& inputFile, const size_t audioStreamIndex ) + : _inputFile( inputFile ) + , _audioProperties( NULL ) + , _audioDecoder( NULL ) + , _sourceFrame( NULL ) + , _dstFrame( NULL ) + , _audioTransform() + , _audioStreamIndex( audioStreamIndex ) + , _inputFileAllocated( false ) +{ + init(); +} + +void AudioReader::init() { avtranscoder::NoDisplayProgress p; - _inputFile.analyse( p ); - _audioProperties = &static_cast(_inputFile.getProperties().getStreamPropertiesWithIndex(_audioStreamIndex)); - _inputFile.activateStream( _audioStreamIndex ); + _inputFile->analyse( p ); + _audioProperties = &static_cast(_inputFile->getProperties().getStreamPropertiesWithIndex(_audioStreamIndex)); + _inputFile->activateStream( _audioStreamIndex ); - _audioDecoder = new avtranscoder::AudioDecoder( _inputFile.getStream( _audioStreamIndex ) ); + _audioDecoder = new avtranscoder::AudioDecoder( _inputFile->getStream( _audioStreamIndex ) ); _audioDecoder->setupDecoder(); - _sourceFrame = new avtranscoder::AudioFrame( _inputFile.getStream( _audioStreamIndex ).getAudioCodec().getAudioFrameDesc() ); + _sourceFrame = new avtranscoder::AudioFrame( _inputFile->getStream( _audioStreamIndex ).getAudioCodec().getAudioFrameDesc() ); avtranscoder::AudioFrameDesc dstAudioFrame( _sourceFrame->desc().getSampleRate(), _sourceFrame->desc().getChannels(), _sourceFrame->desc().getSampleFormat() ); _dstFrame = new avtranscoder::AudioFrame( dstAudioFrame ); @@ -31,6 +52,9 @@ AudioReader::AudioReader( const std::string& filename, const size_t audioStreamI AudioReader::~AudioReader() { + if( _inputFileAllocated ) + delete _inputFile; + delete _audioDecoder; delete _sourceFrame; delete _dstFrame; @@ -60,7 +84,7 @@ const char* AudioReader::readFrameAt( const size_t frame ) { _currentFrame = frame; // seek - _inputFile.seekAtFrame( frame ); + _inputFile->seekAtFrame( frame ); _audioDecoder->flushDecoder(); // decode _audioDecoder->decodeNextFrame( *_sourceFrame ); diff --git a/src/AvTranscoder/reader/AudioReader.hpp b/src/AvTranscoder/reader/AudioReader.hpp index 2fc33474..bd0589f0 100644 --- a/src/AvTranscoder/reader/AudioReader.hpp +++ b/src/AvTranscoder/reader/AudioReader.hpp @@ -15,7 +15,17 @@ namespace avtranscoder class AvExport AudioReader : public IReader { public: + /** + * @brief Create a new InputFile and prepare to read the audio stream at the given index + */ AudioReader( const std::string& filename, const size_t audioStreamIndex ); + + /** + * @brief Get the existing InputFile and prepare to read the audio stream at the given index + * @note This constructor can improve performances when you create several AudioReader from one InputFile. + */ + AudioReader( InputFile& inputFile, const size_t audioStreamIndex ); + ~AudioReader(); size_t getSampleRate(); @@ -28,7 +38,10 @@ class AvExport AudioReader : public IReader void printInfo(); private: - InputFile _inputFile; + void init(); + +private: + InputFile* _inputFile; const AudioProperties* _audioProperties; AudioDecoder* _audioDecoder; @@ -38,6 +51,8 @@ class AvExport AudioReader : public IReader AudioTransform _audioTransform; size_t _audioStreamIndex; + + bool _inputFileAllocated; }; } From 9d4e43648759f34cb76e9fe1deab9ca5a410d6f0 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 25 Aug 2015 14:58:46 +0200 Subject: [PATCH 021/119] mediaProperty: add print.cpp for functions definition --- src/AvTranscoder/mediaProperty/print.cpp | 151 +++++++++++++++++++++++ src/AvTranscoder/mediaProperty/print.hpp | 144 ++------------------- 2 files changed, 159 insertions(+), 136 deletions(-) create mode 100644 src/AvTranscoder/mediaProperty/print.cpp diff --git a/src/AvTranscoder/mediaProperty/print.cpp b/src/AvTranscoder/mediaProperty/print.cpp new file mode 100644 index 00000000..9ab221ed --- /dev/null +++ b/src/AvTranscoder/mediaProperty/print.cpp @@ -0,0 +1,151 @@ +#include "print.hpp" + +#include +#include +#include + +namespace avtranscoder +{ + +static const size_t keyWidth = 32; +static const std::string separator = "===================="; + +std::ostream& operator<<( std::ostream& flux, const FileProperties& fileProperties ) +{ + flux << std::left; + flux << separator << " Wrapper " << separator << std::endl; + + PropertyVector properties = fileProperties.getPropertiesAsVector(); + for( PropertyVector::iterator it = properties.begin(); it != properties.end(); ++it ) + { + flux << std::setw( keyWidth ) << it->first << ": " << it->second << std::endl; + } + + return flux; +} + +std::ostream& operator<<( std::ostream& flux, const VideoProperties& videoProperties ) +{ + flux << std::left; + flux << separator << " Video stream " << separator << std::endl; + + PropertyVector properties = videoProperties.getPropertiesAsVector(); + for( PropertyVector::iterator it = properties.begin(); it != properties.end(); ++it ) + { + flux << std::setw( keyWidth ) << it->first << ": " << it->second << std::endl; + } + + return flux; +} + +std::ostream& operator<<( std::ostream& flux, const AudioProperties& audioProperties ) +{ + flux << std::left; + flux << separator << " Audio stream " << separator << std::endl; + + PropertyVector properties = audioProperties.getPropertiesAsVector(); + for( PropertyVector::iterator it = properties.begin(); it != properties.end(); ++it ) + { + flux << std::setw( keyWidth ) << it->first << ": " << it->second << std::endl; + } + + return flux; +} + +std::ostream& operator<<( std::ostream& flux, const DataProperties& dataProperties ) +{ + flux << separator << " Data stream " << separator << std::endl; + + PropertyVector properties = dataProperties.getPropertiesAsVector(); + for( PropertyVector::iterator it = properties.begin(); it != properties.end(); ++it ) + { + flux << std::setw( keyWidth ) << it->first << ": " << it->second << std::endl; + } + + return flux; +} + +std::ostream& operator<<( std::ostream& flux, const SubtitleProperties& subtitleProperties ) +{ + flux << separator << " Subtitle stream " << separator << std::endl; + + PropertyVector properties = subtitleProperties.getPropertiesAsVector(); + for( PropertyVector::iterator it = properties.begin(); it != properties.end(); ++it ) + { + flux << std::setw( keyWidth ) << it->first << ": " << it->second << std::endl; + } + + return flux; +} + +std::ostream& operator<<( std::ostream& flux, const AttachementProperties& attachementProperties ) +{ + flux << separator << " Attachement stream " << separator << std::endl; + + PropertyVector properties = attachementProperties.getPropertiesAsVector(); + for( PropertyVector::iterator it = properties.begin(); it != properties.end(); ++it ) + { + flux << std::setw( keyWidth ) << it->first << ": " << it->second << std::endl; + } + + return flux; +} + +std::ostream& operator<<( std::ostream& flux, const UnknownProperties& unknownProperties ) +{ + flux << separator << " Unknown stream " << separator << std::endl; + + PropertyVector properties = unknownProperties.getPropertiesAsVector(); + for( PropertyVector::iterator it = properties.begin(); it != properties.end(); ++it ) + { + flux << std::setw( keyWidth ) << it->first << ": " << it->second << std::endl; + } + + return flux; +} + +std::ostream& operator<<( std::ostream& flux, const InputFile& input ) +{ + // wrapper + flux << input.getProperties(); + + // video streams + for( size_t videoStreamIndex = 0; videoStreamIndex < input.getProperties().getNbVideoStreams(); ++videoStreamIndex ) + { + flux << input.getProperties().getVideoProperties().at( videoStreamIndex ); + } + + // audio streams + for( size_t audioStreamIndex = 0; audioStreamIndex < input.getProperties().getNbAudioStreams(); ++audioStreamIndex ) + { + flux << input.getProperties().getAudioProperties().at( audioStreamIndex ); + } + + // data streams + for( size_t dataStreamIndex = 0; dataStreamIndex < input.getProperties().getNbDataStreams(); ++dataStreamIndex ) + { + flux << input.getProperties().getDataProperties().at( dataStreamIndex ); + } + + // subtitle streams + for( size_t subtitleStreamIndex = 0; subtitleStreamIndex < input.getProperties().getNbSubtitleStreams(); ++subtitleStreamIndex ) + { + flux << input.getProperties().getSubtitleProperties().at( subtitleStreamIndex ); + } + + // attachement streams + for( size_t attachementStreamIndex = 0; attachementStreamIndex < input.getProperties().getNbAttachementStreams(); ++attachementStreamIndex ) + { + flux << input.getProperties().getAttachementProperties().at( attachementStreamIndex ); + } + + // unknown streams + for( size_t unknownStreamIndex = 0; unknownStreamIndex < input.getProperties().getNbUnknownStreams(); ++unknownStreamIndex ) + { + flux << input.getProperties().getUnknownPropertiesProperties().at( unknownStreamIndex ); + } + + return flux; +} + +} diff --git a/src/AvTranscoder/mediaProperty/print.hpp b/src/AvTranscoder/mediaProperty/print.hpp index 05399ec8..0c533211 100644 --- a/src/AvTranscoder/mediaProperty/print.hpp +++ b/src/AvTranscoder/mediaProperty/print.hpp @@ -4,153 +4,25 @@ #include #include -#include -#include -#include namespace avtranscoder { -static const size_t keyWidth = 32; -static const std::string separator = "===================="; +std::ostream& operator<<( std::ostream& flux, const FileProperties& fileProperties ); -std::ostream& operator<<( std::ostream& flux, const FileProperties& fileProperties ) -{ - flux << std::left; - flux << separator << " Wrapper " << separator << std::endl; - - PropertyVector properties = fileProperties.getPropertiesAsVector(); - for( PropertyVector::iterator it = properties.begin(); it != properties.end(); ++it ) - { - flux << std::setw( keyWidth ) << it->first << ": " << it->second << std::endl; - } - - return flux; -} - -std::ostream& operator<<( std::ostream& flux, const VideoProperties& videoProperties ) -{ - flux << std::left; - flux << separator << " Video stream " << separator << std::endl; - - PropertyVector properties = videoProperties.getPropertiesAsVector(); - for( PropertyVector::iterator it = properties.begin(); it != properties.end(); ++it ) - { - flux << std::setw( keyWidth ) << it->first << ": " << it->second << std::endl; - } - - return flux; -} - -std::ostream& operator<<( std::ostream& flux, const AudioProperties& audioProperties ) -{ - flux << std::left; - flux << separator << " Audio stream " << separator << std::endl; - - PropertyVector properties = audioProperties.getPropertiesAsVector(); - for( PropertyVector::iterator it = properties.begin(); it != properties.end(); ++it ) - { - flux << std::setw( keyWidth ) << it->first << ": " << it->second << std::endl; - } - - return flux; -} - -std::ostream& operator<<( std::ostream& flux, const DataProperties& dataProperties ) -{ - flux << separator << " Data stream " << separator << std::endl; - - PropertyVector properties = dataProperties.getPropertiesAsVector(); - for( PropertyVector::iterator it = properties.begin(); it != properties.end(); ++it ) - { - flux << std::setw( keyWidth ) << it->first << ": " << it->second << std::endl; - } - - return flux; -} - -std::ostream& operator<<( std::ostream& flux, const SubtitleProperties& subtitleProperties ) -{ - flux << separator << " Subtitle stream " << separator << std::endl; - - PropertyVector properties = subtitleProperties.getPropertiesAsVector(); - for( PropertyVector::iterator it = properties.begin(); it != properties.end(); ++it ) - { - flux << std::setw( keyWidth ) << it->first << ": " << it->second << std::endl; - } - - return flux; -} - -std::ostream& operator<<( std::ostream& flux, const AttachementProperties& attachementProperties ) -{ - flux << separator << " Attachement stream " << separator << std::endl; - - PropertyVector properties = attachementProperties.getPropertiesAsVector(); - for( PropertyVector::iterator it = properties.begin(); it != properties.end(); ++it ) - { - flux << std::setw( keyWidth ) << it->first << ": " << it->second << std::endl; - } - - return flux; -} +std::ostream& operator<<( std::ostream& flux, const VideoProperties& videoProperties ); -std::ostream& operator<<( std::ostream& flux, const UnknownProperties& unknownProperties ) -{ - flux << separator << " Unknown stream " << separator << std::endl; - - PropertyVector properties = unknownProperties.getPropertiesAsVector(); - for( PropertyVector::iterator it = properties.begin(); it != properties.end(); ++it ) - { - flux << std::setw( keyWidth ) << it->first << ": " << it->second << std::endl; - } +std::ostream& operator<<( std::ostream& flux, const AudioProperties& audioProperties ); - return flux; -} - -std::ostream& operator<<( std::ostream& flux, const InputFile& input ) -{ - // wrapper - flux << input.getProperties(); +std::ostream& operator<<( std::ostream& flux, const DataProperties& dataProperties ); - // video streams - for( size_t videoStreamIndex = 0; videoStreamIndex < input.getProperties().getNbVideoStreams(); ++videoStreamIndex ) - { - flux << input.getProperties().getVideoProperties().at( videoStreamIndex ); - } +std::ostream& operator<<( std::ostream& flux, const SubtitleProperties& subtitleProperties ); - // audio streams - for( size_t audioStreamIndex = 0; audioStreamIndex < input.getProperties().getNbAudioStreams(); ++audioStreamIndex ) - { - flux << input.getProperties().getAudioProperties().at( audioStreamIndex ); - } +std::ostream& operator<<( std::ostream& flux, const AttachementProperties& attachementProperties ); - // data streams - for( size_t dataStreamIndex = 0; dataStreamIndex < input.getProperties().getNbDataStreams(); ++dataStreamIndex ) - { - flux << input.getProperties().getDataProperties().at( dataStreamIndex ); - } +std::ostream& operator<<( std::ostream& flux, const UnknownProperties& unknownProperties ); - // subtitle streams - for( size_t subtitleStreamIndex = 0; subtitleStreamIndex < input.getProperties().getNbSubtitleStreams(); ++subtitleStreamIndex ) - { - flux << input.getProperties().getSubtitleProperties().at( subtitleStreamIndex ); - } - - // attachement streams - for( size_t attachementStreamIndex = 0; attachementStreamIndex < input.getProperties().getNbAttachementStreams(); ++attachementStreamIndex ) - { - flux << input.getProperties().getAttachementProperties().at( attachementStreamIndex ); - } - - // unknown streams - for( size_t unknownStreamIndex = 0; unknownStreamIndex < input.getProperties().getNbUnknownStreams(); ++unknownStreamIndex ) - { - flux << input.getProperties().getUnknownPropertiesProperties().at( unknownStreamIndex ); - } - - return flux; -} +std::ostream& operator<<( std::ostream& flux, const InputFile& input ); } From 6e171b4dfa52e48e072614cf33cfeb1ef360a289 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 25 Aug 2015 15:03:13 +0200 Subject: [PATCH 022/119] readers: generalize code by using based classes in IReader * VideoReader and AudioReader instanciate specific classes (to manage video or audio). * Add IReader.cpp --- src/AvTranscoder/reader/AudioReader.cpp | 71 ++++++++++------------ src/AvTranscoder/reader/AudioReader.hpp | 24 +------- src/AvTranscoder/reader/IReader.cpp | 38 ++++++++++++ src/AvTranscoder/reader/IReader.hpp | 38 ++++++++++-- src/AvTranscoder/reader/VideoReader.cpp | 80 +++++++++++++++---------- src/AvTranscoder/reader/VideoReader.hpp | 17 ++---- 6 files changed, 159 insertions(+), 109 deletions(-) create mode 100644 src/AvTranscoder/reader/IReader.cpp diff --git a/src/AvTranscoder/reader/AudioReader.cpp b/src/AvTranscoder/reader/AudioReader.cpp index 7b0ad2d0..7dbac721 100644 --- a/src/AvTranscoder/reader/AudioReader.cpp +++ b/src/AvTranscoder/reader/AudioReader.cpp @@ -1,5 +1,8 @@ #include "AudioReader.hpp" +#include +#include +#include #include #include @@ -7,67 +10,58 @@ namespace avtranscoder { AudioReader::AudioReader( const std::string& filename, const size_t audioStreamIndex ) - : _inputFile( NULL ) - , _audioProperties( NULL ) - , _audioDecoder( NULL ) - , _sourceFrame( NULL ) - , _dstFrame( NULL ) - , _audioTransform() - , _audioStreamIndex( audioStreamIndex ) - , _inputFileAllocated( true ) + : IReader( filename, audioStreamIndex ) + , _audioStreamProperties(NULL) { - _inputFile = new InputFile( filename ); - init(); } AudioReader::AudioReader( InputFile& inputFile, const size_t audioStreamIndex ) - : _inputFile( inputFile ) - , _audioProperties( NULL ) - , _audioDecoder( NULL ) - , _sourceFrame( NULL ) - , _dstFrame( NULL ) - , _audioTransform() - , _audioStreamIndex( audioStreamIndex ) - , _inputFileAllocated( false ) + : IReader( inputFile, audioStreamIndex ) + , _audioStreamProperties(NULL) { init(); } void AudioReader::init() { + // analyse InputFile avtranscoder::NoDisplayProgress p; _inputFile->analyse( p ); - _audioProperties = &static_cast(_inputFile->getProperties().getStreamPropertiesWithIndex(_audioStreamIndex)); - _inputFile->activateStream( _audioStreamIndex ); - - _audioDecoder = new avtranscoder::AudioDecoder( _inputFile->getStream( _audioStreamIndex ) ); - _audioDecoder->setupDecoder(); - - _sourceFrame = new avtranscoder::AudioFrame( _inputFile->getStream( _audioStreamIndex ).getAudioCodec().getAudioFrameDesc() ); - - avtranscoder::AudioFrameDesc dstAudioFrame( _sourceFrame->desc().getSampleRate(), _sourceFrame->desc().getChannels(), _sourceFrame->desc().getSampleFormat() ); - _dstFrame = new avtranscoder::AudioFrame( dstAudioFrame ); + _streamProperties = &_inputFile->getProperties().getStreamPropertiesWithIndex(_streamIndex); + _audioStreamProperties = static_cast(_streamProperties); + _inputFile->activateStream( _streamIndex ); + + // setup decoder + _decoder = new AudioDecoder( _inputFile->getStream( _streamIndex ) ); + _decoder->setupDecoder(); + + // create src and dst frames + _srcFrame = new AudioFrame( _inputFile->getStream( _streamIndex ).getAudioCodec().getAudioFrameDesc() ); + AudioFrame* srcFrame = static_cast(_srcFrame); + AudioFrameDesc dstAudioFrame( srcFrame->desc().getSampleRate(), srcFrame->desc().getChannels(), srcFrame->desc().getSampleFormat() ); + _dstFrame = new AudioFrame( dstAudioFrame ); + + // create transform + _transform = new AudioTransform(); } AudioReader::~AudioReader() { - if( _inputFileAllocated ) - delete _inputFile; - - delete _audioDecoder; - delete _sourceFrame; + delete _decoder; + delete _srcFrame; delete _dstFrame; + delete _transform; } size_t AudioReader::getSampleRate() { - return _audioProperties->getSampleRate(); + return _audioStreamProperties->getSampleRate(); } size_t AudioReader::getChannels() { - return _audioProperties->getChannels(); + return _audioStreamProperties->getChannels(); } const char* AudioReader::readNextFrame() @@ -85,17 +79,16 @@ const char* AudioReader::readFrameAt( const size_t frame ) _currentFrame = frame; // seek _inputFile->seekAtFrame( frame ); - _audioDecoder->flushDecoder(); // decode - _audioDecoder->decodeNextFrame( *_sourceFrame ); - _audioTransform.convert( *_sourceFrame, *_dstFrame ); + _decoder->decodeNextFrame( *_srcFrame ); + _transform->convert( *_srcFrame, *_dstFrame ); // return buffer return (const char*)_dstFrame->getData(); } void AudioReader::printInfo() { - std::cout << *_audioProperties << std::endl; + std::cout << *_audioStreamProperties << std::endl; } } diff --git a/src/AvTranscoder/reader/AudioReader.hpp b/src/AvTranscoder/reader/AudioReader.hpp index bd0589f0..3adf8dd9 100644 --- a/src/AvTranscoder/reader/AudioReader.hpp +++ b/src/AvTranscoder/reader/AudioReader.hpp @@ -5,9 +5,6 @@ #include #include -#include -#include -#include namespace avtranscoder { @@ -15,15 +12,7 @@ namespace avtranscoder class AvExport AudioReader : public IReader { public: - /** - * @brief Create a new InputFile and prepare to read the audio stream at the given index - */ AudioReader( const std::string& filename, const size_t audioStreamIndex ); - - /** - * @brief Get the existing InputFile and prepare to read the audio stream at the given index - * @note This constructor can improve performances when you create several AudioReader from one InputFile. - */ AudioReader( InputFile& inputFile, const size_t audioStreamIndex ); ~AudioReader(); @@ -41,18 +30,7 @@ class AvExport AudioReader : public IReader void init(); private: - InputFile* _inputFile; - const AudioProperties* _audioProperties; - AudioDecoder* _audioDecoder; - - AudioFrame* _sourceFrame; - AudioFrame* _dstFrame; - - AudioTransform _audioTransform; - - size_t _audioStreamIndex; - - bool _inputFileAllocated; + const AudioProperties* _audioStreamProperties; ///< Properties of the audio stream read (no ownership, has link) }; } diff --git a/src/AvTranscoder/reader/IReader.cpp b/src/AvTranscoder/reader/IReader.cpp new file mode 100644 index 00000000..ffef1367 --- /dev/null +++ b/src/AvTranscoder/reader/IReader.cpp @@ -0,0 +1,38 @@ +#include "IReader.hpp" + +namespace avtranscoder +{ + +IReader::IReader( const std::string& filename, const size_t streamIndex ) + : _inputFile( NULL ) + , _streamProperties( NULL ) + , _decoder( NULL ) + , _srcFrame( NULL ) + , _dstFrame( NULL ) + , _transform( NULL ) + , _streamIndex( streamIndex ) + , _currentFrame( 0 ) + , _inputFileAllocated( true ) +{ + _inputFile = new InputFile( filename ); +} + +IReader::IReader( InputFile& inputFile, const size_t streamIndex ) + : _inputFile( &inputFile ) + , _streamProperties( NULL ) + , _decoder( NULL ) + , _srcFrame( NULL ) + , _dstFrame( NULL ) + , _transform( NULL ) + , _streamIndex( streamIndex ) + , _currentFrame( 0 ) + , _inputFileAllocated( false ) +{} + +IReader::~IReader() +{ + if( _inputFileAllocated ) + delete _inputFile; +} + +} diff --git a/src/AvTranscoder/reader/IReader.hpp b/src/AvTranscoder/reader/IReader.hpp index 417a8f16..1ea01934 100644 --- a/src/AvTranscoder/reader/IReader.hpp +++ b/src/AvTranscoder/reader/IReader.hpp @@ -3,15 +3,33 @@ #include +#include +#include +#include +#include +#include + namespace avtranscoder { +/** + * @brief Based class to read a stream. + */ class AvExport IReader { public: - IReader() - : _currentFrame( 0 ) - {} + /** + * @brief Create a new InputFile and prepare to read the stream at the given index + */ + IReader( const std::string& filename, const size_t streamIndex ); + + /** + * @brief Get the existing InputFile and prepare to read the stream at the given index + * @note This constructor can improve performances when you create several readers from one InputFile. + */ + IReader( InputFile& inputFile, const size_t streamIndex ); + + virtual ~IReader() = 0; /** * @return Get next frame after decoding @@ -34,7 +52,19 @@ class AvExport IReader virtual void printInfo() = 0; protected: - size_t _currentFrame; + InputFile* _inputFile; + const StreamProperties* _streamProperties; + IDecoder* _decoder; + + Frame* _srcFrame; + Frame* _dstFrame; + + ITransform* _transform; + + size_t _streamIndex; + size_t _currentFrame; ///< The current decoded frame. + + bool _inputFileAllocated; ///< Is the InputFile hold by the class or not (depends on the constructor called) }; } diff --git a/src/AvTranscoder/reader/VideoReader.cpp b/src/AvTranscoder/reader/VideoReader.cpp index 01d468e6..3bfd78b2 100644 --- a/src/AvTranscoder/reader/VideoReader.cpp +++ b/src/AvTranscoder/reader/VideoReader.cpp @@ -1,5 +1,8 @@ #include "VideoReader.hpp" +#include +#include +#include #include #include @@ -7,58 +10,73 @@ namespace avtranscoder { VideoReader::VideoReader( const std::string& filename, const size_t videoStreamIndex ) - : _inputFile( filename ) - , _videoProperties( NULL ) - , _videoDecoder( NULL ) - , _sourceImage( NULL ) - , _imageToDisplay( NULL ) - , _videoTransform() - , _videoStreamIndex( videoStreamIndex ) + : IReader( filename, videoStreamIndex ) + , _videoStreamProperties(NULL) { - avtranscoder::NoDisplayProgress p; - _inputFile.analyse( p ); - _videoProperties = &static_cast(_inputFile.getProperties().getStreamPropertiesWithIndex(_videoStreamIndex)); - _inputFile.activateStream( _videoStreamIndex ); - - _videoDecoder = new avtranscoder::VideoDecoder( _inputFile.getStream( _videoStreamIndex ) ); - _videoDecoder->setupDecoder(); + init(); +} - _sourceImage = new avtranscoder::VideoFrame( _inputFile.getStream( _videoStreamIndex ).getVideoCodec().getVideoFrameDesc() ); +VideoReader::VideoReader( InputFile& inputFile, const size_t videoStreamIndex ) + : IReader( inputFile, videoStreamIndex ) + , _videoStreamProperties(NULL) +{ + init(); +} - avtranscoder::VideoFrameDesc videoFrameDescToDisplay( _sourceImage->desc().getWidth(), _sourceImage->desc().getHeight(), "rgb24" ); - _imageToDisplay = new avtranscoder::VideoFrame( videoFrameDescToDisplay ); +void VideoReader::init() +{ + // analyse InputFile + avtranscoder::NoDisplayProgress p; + _inputFile->analyse( p ); + _streamProperties = &_inputFile->getProperties().getStreamPropertiesWithIndex(_streamIndex); + _videoStreamProperties = static_cast(_streamProperties); + _inputFile->activateStream( _streamIndex ); + + // setup decoder + _decoder = new VideoDecoder( _inputFile->getStream( _streamIndex ) ); + _decoder->setupDecoder(); + + // create src and dst frames + _srcFrame = new VideoFrame( _inputFile->getStream( _streamIndex ).getVideoCodec().getVideoFrameDesc() ); + VideoFrame* srcFrame = static_cast(_srcFrame); + VideoFrameDesc videoFrameDescToDisplay( srcFrame->desc().getWidth(), srcFrame->desc().getHeight(), "rgb24" ); + _dstFrame = new VideoFrame( videoFrameDescToDisplay ); + + // create transform + _transform = new VideoTransform(); } VideoReader::~VideoReader() { - delete _videoDecoder; - delete _sourceImage; - delete _imageToDisplay; + delete _decoder; + delete _srcFrame; + delete _dstFrame; + delete _transform; } size_t VideoReader::getWidth() { - return _videoProperties->getWidth(); + return _videoStreamProperties->getWidth(); }; size_t VideoReader::getHeight() { - return _videoProperties->getHeight(); + return _videoStreamProperties->getHeight(); } size_t VideoReader::getComponents() { - return _videoProperties->getPixelProperties().getNbComponents(); + return _videoStreamProperties->getPixelProperties().getNbComponents(); } size_t VideoReader::getBitDepth() { - return _videoProperties->getPixelProperties().getBitsPerPixel(); + return _videoStreamProperties->getPixelProperties().getBitsPerPixel(); } AVPixelFormat VideoReader::getPixelFormat() { - return _videoProperties->getPixelProperties().getAVPixelFormat(); + return _videoStreamProperties->getPixelProperties().getAVPixelFormat(); } const char* VideoReader::readNextFrame() @@ -75,18 +93,18 @@ const char* VideoReader::readFrameAt( const size_t frame ) { _currentFrame = frame; // seek - _inputFile.seekAtFrame( frame ); - _videoDecoder->flushDecoder(); + _inputFile->seekAtFrame( frame ); + static_cast(_decoder)->flushDecoder(); // decode - _videoDecoder->decodeNextFrame( *_sourceImage ); - _videoTransform.convert( *_sourceImage, *_imageToDisplay ); + _decoder->decodeNextFrame( *_srcFrame ); + _transform->convert( *_srcFrame, *_dstFrame ); // return buffer - return (const char*)_imageToDisplay->getData(); + return (const char*)_dstFrame->getData(); } void VideoReader::printInfo() { - std::cout << *_videoProperties << std::endl; + std::cout << *_videoStreamProperties << std::endl; } } diff --git a/src/AvTranscoder/reader/VideoReader.hpp b/src/AvTranscoder/reader/VideoReader.hpp index 4a1a8611..834b99f3 100644 --- a/src/AvTranscoder/reader/VideoReader.hpp +++ b/src/AvTranscoder/reader/VideoReader.hpp @@ -5,9 +5,6 @@ #include #include -#include -#include -#include namespace avtranscoder { @@ -16,6 +13,8 @@ class AvExport VideoReader : public IReader { public: VideoReader( const std::string& filename, const size_t videoStreamIndex ); + VideoReader( InputFile& inputFile, const size_t videoStreamIndex ); + ~VideoReader(); size_t getWidth(); @@ -31,16 +30,10 @@ class AvExport VideoReader : public IReader void printInfo(); private: - InputFile _inputFile; - const VideoProperties* _videoProperties; - VideoDecoder* _videoDecoder; - - VideoFrame* _sourceImage; - VideoFrame* _imageToDisplay; + void init(); - VideoTransform _videoTransform; - - size_t _videoStreamIndex; +private: + const VideoProperties* _videoStreamProperties; ///< Properties of the video stream read (no ownership, has link) }; } From 4f3cdb5a555ce35cc149205b576676afc288b6ca Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 25 Aug 2015 15:10:07 +0200 Subject: [PATCH 023/119] IDecoder: add flushDecoder function * Implement it in AudioDecoder. * It was already done by the VideoDecoder. --- src/AvTranscoder/decoder/AudioDecoder.cpp | 5 +++++ src/AvTranscoder/decoder/AudioDecoder.hpp | 2 ++ src/AvTranscoder/decoder/IDecoder.hpp | 7 +++++++ 3 files changed, 14 insertions(+) diff --git a/src/AvTranscoder/decoder/AudioDecoder.cpp b/src/AvTranscoder/decoder/AudioDecoder.cpp index 4e12ad32..e5c09986 100644 --- a/src/AvTranscoder/decoder/AudioDecoder.cpp +++ b/src/AvTranscoder/decoder/AudioDecoder.cpp @@ -176,4 +176,9 @@ bool AudioDecoder::decodeNextFrame() return true; } +void AudioDecoder::flushDecoder() +{ + avcodec_flush_buffers( &_inputStream->getAudioCodec().getAVCodecContext() ); +} + } diff --git a/src/AvTranscoder/decoder/AudioDecoder.hpp b/src/AvTranscoder/decoder/AudioDecoder.hpp index b9fc3300..f536e698 100644 --- a/src/AvTranscoder/decoder/AudioDecoder.hpp +++ b/src/AvTranscoder/decoder/AudioDecoder.hpp @@ -21,6 +21,8 @@ class AvExport AudioDecoder : public IDecoder bool decodeNextFrame( Frame& frameBuffer ); bool decodeNextFrame( Frame& frameBuffer, const size_t subStreamIndex ); + void flushDecoder(); + private: bool decodeNextFrame(); diff --git a/src/AvTranscoder/decoder/IDecoder.hpp b/src/AvTranscoder/decoder/IDecoder.hpp index bbbf4fa8..e4bbb128 100644 --- a/src/AvTranscoder/decoder/IDecoder.hpp +++ b/src/AvTranscoder/decoder/IDecoder.hpp @@ -41,6 +41,13 @@ class AvExport IDecoder * @param inputFrame: the new next frame */ virtual void setNextFrame( Frame& inputFrame ) {} + + /** + * @brief Reset the internal decoder state / flush internal buffers. + * @note Should be called when seeking or when switching to a different stream. + * @note Not sense for generators. + */ + virtual void flushDecoder() {} }; } From ca3a2596480e851e5a8b0f4d6649feb654900950 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 25 Aug 2015 15:23:18 +0200 Subject: [PATCH 024/119] readers: define read fonctions in based class --- src/AvTranscoder/reader/AudioReader.cpp | 22 ---------------------- src/AvTranscoder/reader/AudioReader.hpp | 4 ---- src/AvTranscoder/reader/IReader.cpp | 22 ++++++++++++++++++++++ src/AvTranscoder/reader/IReader.hpp | 6 +++--- src/AvTranscoder/reader/VideoReader.cpp | 23 ----------------------- src/AvTranscoder/reader/VideoReader.hpp | 4 ---- 6 files changed, 25 insertions(+), 56 deletions(-) diff --git a/src/AvTranscoder/reader/AudioReader.cpp b/src/AvTranscoder/reader/AudioReader.cpp index 7dbac721..2856e0a6 100644 --- a/src/AvTranscoder/reader/AudioReader.cpp +++ b/src/AvTranscoder/reader/AudioReader.cpp @@ -64,28 +64,6 @@ size_t AudioReader::getChannels() return _audioStreamProperties->getChannels(); } -const char* AudioReader::readNextFrame() -{ - return readFrameAt( _currentFrame + 1 ); -} - -const char* AudioReader::readPrevFrame() -{ - return readFrameAt( _currentFrame - 1 ); -} - -const char* AudioReader::readFrameAt( const size_t frame ) -{ - _currentFrame = frame; - // seek - _inputFile->seekAtFrame( frame ); - // decode - _decoder->decodeNextFrame( *_srcFrame ); - _transform->convert( *_srcFrame, *_dstFrame ); - // return buffer - return (const char*)_dstFrame->getData(); -} - void AudioReader::printInfo() { std::cout << *_audioStreamProperties << std::endl; diff --git a/src/AvTranscoder/reader/AudioReader.hpp b/src/AvTranscoder/reader/AudioReader.hpp index 3adf8dd9..a00115b9 100644 --- a/src/AvTranscoder/reader/AudioReader.hpp +++ b/src/AvTranscoder/reader/AudioReader.hpp @@ -20,10 +20,6 @@ class AvExport AudioReader : public IReader size_t getSampleRate(); size_t getChannels(); - const char* readNextFrame(); - const char* readPrevFrame(); - const char* readFrameAt( const size_t frame ); - void printInfo(); private: diff --git a/src/AvTranscoder/reader/IReader.cpp b/src/AvTranscoder/reader/IReader.cpp index ffef1367..5149a0b9 100644 --- a/src/AvTranscoder/reader/IReader.cpp +++ b/src/AvTranscoder/reader/IReader.cpp @@ -35,4 +35,26 @@ IReader::~IReader() delete _inputFile; } +const char* IReader::readNextFrame() +{ + return readFrameAt( _currentFrame + 1 ); +} + +const char* IReader::readPrevFrame() +{ + return readFrameAt( _currentFrame - 1 ); +} + +const char* IReader::readFrameAt( const size_t frame ) +{ + _currentFrame = frame; + // seek + _inputFile->seekAtFrame( frame ); + _decoder->flushDecoder(); + // decode + _decoder->decodeNextFrame( *_srcFrame ); + _transform->convert( *_srcFrame, *_dstFrame ); + // return buffer + return (const char*)_dstFrame->getData(); +} } diff --git a/src/AvTranscoder/reader/IReader.hpp b/src/AvTranscoder/reader/IReader.hpp index 1ea01934..16ace413 100644 --- a/src/AvTranscoder/reader/IReader.hpp +++ b/src/AvTranscoder/reader/IReader.hpp @@ -34,17 +34,17 @@ class AvExport IReader /** * @return Get next frame after decoding */ - virtual const char* readNextFrame() = 0; + const char* readNextFrame(); /** * @return Get previous frame after decoding */ - virtual const char* readPrevFrame() = 0; + const char* readPrevFrame(); /** * @return Get indicated frame after decoding */ - virtual const char* readFrameAt( const size_t frame ) = 0; + const char* readFrameAt( const size_t frame ); /** * @brief Print info of the stream read. diff --git a/src/AvTranscoder/reader/VideoReader.cpp b/src/AvTranscoder/reader/VideoReader.cpp index 3bfd78b2..e2de2bba 100644 --- a/src/AvTranscoder/reader/VideoReader.cpp +++ b/src/AvTranscoder/reader/VideoReader.cpp @@ -79,29 +79,6 @@ AVPixelFormat VideoReader::getPixelFormat() return _videoStreamProperties->getPixelProperties().getAVPixelFormat(); } -const char* VideoReader::readNextFrame() -{ - return readFrameAt( _currentFrame + 1 ); -} - -const char* VideoReader::readPrevFrame() -{ - return readFrameAt( _currentFrame - 1 ); -} - -const char* VideoReader::readFrameAt( const size_t frame ) -{ - _currentFrame = frame; - // seek - _inputFile->seekAtFrame( frame ); - static_cast(_decoder)->flushDecoder(); - // decode - _decoder->decodeNextFrame( *_srcFrame ); - _transform->convert( *_srcFrame, *_dstFrame ); - // return buffer - return (const char*)_dstFrame->getData(); -} - void VideoReader::printInfo() { std::cout << *_videoStreamProperties << std::endl; diff --git a/src/AvTranscoder/reader/VideoReader.hpp b/src/AvTranscoder/reader/VideoReader.hpp index 834b99f3..bca12512 100644 --- a/src/AvTranscoder/reader/VideoReader.hpp +++ b/src/AvTranscoder/reader/VideoReader.hpp @@ -23,10 +23,6 @@ class AvExport VideoReader : public IReader size_t getBitDepth(); AVPixelFormat getPixelFormat(); - const char* readNextFrame(); - const char* readPrevFrame(); - const char* readFrameAt( const size_t frame ); - void printInfo(); private: From 745309aeffae7dcfa5dc026a4d0d2f5bb846702f Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 25 Aug 2015 15:29:07 +0200 Subject: [PATCH 025/119] readers: define printInfo in based class Override this method is sub-classes. --- src/AvTranscoder/mediaProperty/print.cpp | 14 ++++++++++++++ src/AvTranscoder/mediaProperty/print.hpp | 2 ++ src/AvTranscoder/reader/IReader.cpp | 8 ++++++++ src/AvTranscoder/reader/IReader.hpp | 2 +- 4 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/AvTranscoder/mediaProperty/print.cpp b/src/AvTranscoder/mediaProperty/print.cpp index 9ab221ed..dd3aa4f9 100644 --- a/src/AvTranscoder/mediaProperty/print.cpp +++ b/src/AvTranscoder/mediaProperty/print.cpp @@ -24,6 +24,20 @@ std::ostream& operator<<( std::ostream& flux, const FileProperties& fileProperti return flux; } +std::ostream& operator<<( std::ostream& flux, const StreamProperties& streamProperties ) +{ + flux << std::left; + flux << separator << " Stream " << separator << std::endl; + + PropertyVector properties = streamProperties.getPropertiesAsVector(); + for( PropertyVector::iterator it = properties.begin(); it != properties.end(); ++it ) + { + flux << std::setw( keyWidth ) << it->first << ": " << it->second << std::endl; + } + + return flux; +} + std::ostream& operator<<( std::ostream& flux, const VideoProperties& videoProperties ) { flux << std::left; diff --git a/src/AvTranscoder/mediaProperty/print.hpp b/src/AvTranscoder/mediaProperty/print.hpp index 0c533211..d6848813 100644 --- a/src/AvTranscoder/mediaProperty/print.hpp +++ b/src/AvTranscoder/mediaProperty/print.hpp @@ -10,6 +10,8 @@ namespace avtranscoder std::ostream& operator<<( std::ostream& flux, const FileProperties& fileProperties ); +std::ostream& operator<<( std::ostream& flux, const StreamProperties& streamProperties ); + std::ostream& operator<<( std::ostream& flux, const VideoProperties& videoProperties ); std::ostream& operator<<( std::ostream& flux, const AudioProperties& audioProperties ); diff --git a/src/AvTranscoder/reader/IReader.cpp b/src/AvTranscoder/reader/IReader.cpp index 5149a0b9..f7a8cb4a 100644 --- a/src/AvTranscoder/reader/IReader.cpp +++ b/src/AvTranscoder/reader/IReader.cpp @@ -1,5 +1,7 @@ #include "IReader.hpp" +#include + namespace avtranscoder { @@ -57,4 +59,10 @@ const char* IReader::readFrameAt( const size_t frame ) // return buffer return (const char*)_dstFrame->getData(); } + +void IReader::printInfo() +{ + std::cout << *_streamProperties << std::endl; +} + } diff --git a/src/AvTranscoder/reader/IReader.hpp b/src/AvTranscoder/reader/IReader.hpp index 16ace413..b966783f 100644 --- a/src/AvTranscoder/reader/IReader.hpp +++ b/src/AvTranscoder/reader/IReader.hpp @@ -49,7 +49,7 @@ class AvExport IReader /** * @brief Print info of the stream read. */ - virtual void printInfo() = 0; + virtual void printInfo(); protected: InputFile* _inputFile; From c5514379999bea9a3a2bdc5514ab3b3262ac7931 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 25 Aug 2015 15:33:56 +0200 Subject: [PATCH 026/119] IReader: some attributes are private They are not accessible in subclasses. --- src/AvTranscoder/reader/IReader.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/AvTranscoder/reader/IReader.hpp b/src/AvTranscoder/reader/IReader.hpp index b966783f..095e53cc 100644 --- a/src/AvTranscoder/reader/IReader.hpp +++ b/src/AvTranscoder/reader/IReader.hpp @@ -62,6 +62,8 @@ class AvExport IReader ITransform* _transform; size_t _streamIndex; + +private: size_t _currentFrame; ///< The current decoded frame. bool _inputFileAllocated; ///< Is the InputFile hold by the class or not (depends on the constructor called) From 6d3a7a64319850f8dacdb4d15cc43140f991895b Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 25 Aug 2015 15:42:53 +0200 Subject: [PATCH 027/119] SWIG: add reader classes to binding --- src/AvTranscoder/avTranscoder.i | 1 + src/AvTranscoder/reader/reader.i | 11 +++++++++++ 2 files changed, 12 insertions(+) create mode 100644 src/AvTranscoder/reader/reader.i diff --git a/src/AvTranscoder/avTranscoder.i b/src/AvTranscoder/avTranscoder.i index ac5cb1bf..bb39d9c0 100644 --- a/src/AvTranscoder/avTranscoder.i +++ b/src/AvTranscoder/avTranscoder.i @@ -39,3 +39,4 @@ %include "AvTranscoder/file/file.i" %include "AvTranscoder/stat/stat.i" %include "AvTranscoder/transcoder/transcoder.i" +%include "AvTranscoder/reader/reader.i" diff --git a/src/AvTranscoder/reader/reader.i b/src/AvTranscoder/reader/reader.i new file mode 100644 index 00000000..73bf673d --- /dev/null +++ b/src/AvTranscoder/reader/reader.i @@ -0,0 +1,11 @@ +%{ + #include + #include + #include + #include +%} + +%include +%include +%include +%include From 3738364ea695f8b2d078cf7a500e76897fbca0a1 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 25 Aug 2015 15:43:04 +0200 Subject: [PATCH 028/119] IReader: fix indentation --- src/AvTranscoder/reader/IReader.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AvTranscoder/reader/IReader.hpp b/src/AvTranscoder/reader/IReader.hpp index 095e53cc..6a5f366b 100644 --- a/src/AvTranscoder/reader/IReader.hpp +++ b/src/AvTranscoder/reader/IReader.hpp @@ -1,5 +1,5 @@ #ifndef _AV_TRANSCODER_IREADER_HPP -#define _AV_TRANSCODER_IREADER_HPP +#define _AV_TRANSCODER_IREADER_HPP #include From 3c488a8a2512085540f264dc29d5f72337bfe094 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 25 Aug 2015 16:52:16 +0200 Subject: [PATCH 029/119] Video/AudioReader: add method to get properties --- src/AvTranscoder/reader/AudioReader.hpp | 1 + src/AvTranscoder/reader/VideoReader.hpp | 1 + 2 files changed, 2 insertions(+) diff --git a/src/AvTranscoder/reader/AudioReader.hpp b/src/AvTranscoder/reader/AudioReader.hpp index a00115b9..c2c1c32c 100644 --- a/src/AvTranscoder/reader/AudioReader.hpp +++ b/src/AvTranscoder/reader/AudioReader.hpp @@ -19,6 +19,7 @@ class AvExport AudioReader : public IReader size_t getSampleRate(); size_t getChannels(); + const AudioProperties* getAudioProperties() const {return _audioStreamProperties;} void printInfo(); diff --git a/src/AvTranscoder/reader/VideoReader.hpp b/src/AvTranscoder/reader/VideoReader.hpp index bca12512..9cb33b94 100644 --- a/src/AvTranscoder/reader/VideoReader.hpp +++ b/src/AvTranscoder/reader/VideoReader.hpp @@ -22,6 +22,7 @@ class AvExport VideoReader : public IReader size_t getComponents(); size_t getBitDepth(); AVPixelFormat getPixelFormat(); + const VideoProperties* getVideoProperties() const {return _videoStreamProperties;} void printInfo(); From a05d95f7131e98368faec783d14a5f929e61d135 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 25 Aug 2015 16:54:07 +0200 Subject: [PATCH 030/119] IReader: read methods return the Frame object * With the Frame object, we can access the buffer, the size, the number of samples in case of audio frame, etc... * Update avplay app. --- app/avPlay/Window.cpp | 6 +++--- src/AvTranscoder/reader/IReader.cpp | 8 ++++---- src/AvTranscoder/reader/IReader.hpp | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/app/avPlay/Window.cpp b/app/avPlay/Window.cpp index 42932dd9..fd611596 100644 --- a/app/avPlay/Window.cpp +++ b/app/avPlay/Window.cpp @@ -529,14 +529,14 @@ void Window::showAlphaChannelTexture( ) void Window::displayNextFrame() { - const char* buffer = _reader->readNextFrame(); + const char* buffer = (const char*)_reader->readNextFrame()->getData(); loadNewTexture( buffer, _reader->getComponents(), _reader->getWidth(), _reader->getHeight(), GL_RGB, GL_UNSIGNED_BYTE ); display(); } void Window::displayPrevFrame() { - const char* buffer = _reader->readPrevFrame(); + const char* buffer = (const char*)_reader->readPrevFrame()->getData(); loadNewTexture( buffer, _reader->getComponents(), _reader->getWidth(), _reader->getHeight(), GL_RGB, GL_UNSIGNED_BYTE ); display(); } @@ -548,7 +548,7 @@ void Window::displayFirstFrame() void Window::displayAtFrame( const size_t frame ) { - const char* buffer = _reader->readFrameAt( frame ); + const char* buffer = (const char*)_reader->readFrameAt( frame )->getData(); loadNewTexture( buffer, _reader->getComponents(), _reader->getWidth(), _reader->getHeight(), GL_RGB, GL_UNSIGNED_BYTE ); display(); } diff --git a/src/AvTranscoder/reader/IReader.cpp b/src/AvTranscoder/reader/IReader.cpp index f7a8cb4a..3364ca8f 100644 --- a/src/AvTranscoder/reader/IReader.cpp +++ b/src/AvTranscoder/reader/IReader.cpp @@ -37,17 +37,17 @@ IReader::~IReader() delete _inputFile; } -const char* IReader::readNextFrame() +Frame* IReader::readNextFrame() { return readFrameAt( _currentFrame + 1 ); } -const char* IReader::readPrevFrame() +Frame* IReader::readPrevFrame() { return readFrameAt( _currentFrame - 1 ); } -const char* IReader::readFrameAt( const size_t frame ) +Frame* IReader::readFrameAt( const size_t frame ) { _currentFrame = frame; // seek @@ -57,7 +57,7 @@ const char* IReader::readFrameAt( const size_t frame ) _decoder->decodeNextFrame( *_srcFrame ); _transform->convert( *_srcFrame, *_dstFrame ); // return buffer - return (const char*)_dstFrame->getData(); + return _dstFrame; } void IReader::printInfo() diff --git a/src/AvTranscoder/reader/IReader.hpp b/src/AvTranscoder/reader/IReader.hpp index 6a5f366b..cff3dee5 100644 --- a/src/AvTranscoder/reader/IReader.hpp +++ b/src/AvTranscoder/reader/IReader.hpp @@ -34,17 +34,17 @@ class AvExport IReader /** * @return Get next frame after decoding */ - const char* readNextFrame(); + Frame* readNextFrame(); /** * @return Get previous frame after decoding */ - const char* readPrevFrame(); + Frame* readPrevFrame(); /** * @return Get indicated frame after decoding */ - const char* readFrameAt( const size_t frame ); + Frame* readFrameAt( const size_t frame ); /** * @brief Print info of the stream read. From 8f0ec170bc28962f765c5bfdf1cd89d2f5e0cdee Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 25 Aug 2015 17:21:26 +0200 Subject: [PATCH 031/119] file: seek methods return the seek status --- src/AvTranscoder/file/FormatContext.cpp | 8 ++++++-- src/AvTranscoder/file/FormatContext.hpp | 3 ++- src/AvTranscoder/file/InputFile.cpp | 8 ++++---- src/AvTranscoder/file/InputFile.hpp | 7 ++++--- 4 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/AvTranscoder/file/FormatContext.cpp b/src/AvTranscoder/file/FormatContext.cpp index bd8de3f9..6eb8fb97 100644 --- a/src/AvTranscoder/file/FormatContext.cpp +++ b/src/AvTranscoder/file/FormatContext.cpp @@ -142,15 +142,19 @@ AVStream& FormatContext::addAVStream( const AVCodec& avCodec ) return *stream; } -void FormatContext::seek( uint64_t position, const int flag ) +bool FormatContext::seek( uint64_t position, const int flag ) { if( (int)getStartTime() != AV_NOPTS_VALUE ) position += getStartTime(); - if( av_seek_frame( _avFormatContext, -1, position, flag ) < 0 ) + int err = av_seek_frame( _avFormatContext, -1, position, flag ); + if( err < 0 ) { LOG_ERROR( "Error when seek at " << position << " (in AV_TIME_BASE units) in file" ) + LOG_ERROR( getDescriptionFromErrorCode( err ) ) + return false; } + return true; } std::vector