From 5768d994fd27b2e30dd01a93f6f994242dbd64e5 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 1 Dec 2015 10:42:07 +0100 Subject: [PATCH 01/46] AudioFrame: improved exception message when cannot get data size --- src/AvTranscoder/frame/AudioFrame.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/AvTranscoder/frame/AudioFrame.cpp b/src/AvTranscoder/frame/AudioFrame.cpp index 77b06332..03391c5a 100644 --- a/src/AvTranscoder/frame/AudioFrame.cpp +++ b/src/AvTranscoder/frame/AudioFrame.cpp @@ -2,6 +2,7 @@ #include #include +#include namespace avtranscoder { @@ -31,9 +32,17 @@ size_t AudioFrameDesc::getDataSize() const if( _sampleFormat == AV_SAMPLE_FMT_NONE ) throw std::runtime_error( "incorrect sample format" ); - size_t size = ( _sampleRate / _fps ) * _channels * av_get_bytes_per_sample( _sampleFormat ); + const size_t size = ( _sampleRate / _fps ) * _channels * av_get_bytes_per_sample( _sampleFormat ); if( size == 0 ) - throw std::runtime_error( "unable to determine audio buffer size" ); + { + std::stringstream msg; + msg << "Unable to determine audio buffer size:" << std::endl; + msg << "sampleRate = " << _sampleRate << std::endl; + msg << "fps = " << _fps << std::endl; + msg << "channels = " << _channels << std::endl; + msg << "bytes per sample = " << av_get_bytes_per_sample( _sampleFormat ) << std::endl; + throw std::runtime_error( msg.str() ); + } return size; } From 427f8e8831b1565a89122c51a2a3f6e6c8a206ab Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 1 Dec 2015 10:44:56 +0100 Subject: [PATCH 02/46] IReader: added default value to streamIndex parameter --- src/AvTranscoder/reader/IReader.hpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/AvTranscoder/reader/IReader.hpp b/src/AvTranscoder/reader/IReader.hpp index f9b3f088..ba509531 100644 --- a/src/AvTranscoder/reader/IReader.hpp +++ b/src/AvTranscoder/reader/IReader.hpp @@ -20,14 +20,15 @@ class AvExport IReader public: /** * @brief Create a new InputFile and prepare to read the stream at the given index + * @param streamIndex by default read the first stream */ - IReader( const std::string& filename, const size_t streamIndex ); + IReader( const std::string& filename, const size_t streamIndex = 0 ); /** * @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 ); + IReader( InputFile& inputFile, const size_t streamIndex = 0 ); virtual ~IReader() = 0; From 4a6e71a216fbee34fe5a3ab387d75a52c98b2249 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 1 Dec 2015 10:48:26 +0100 Subject: [PATCH 03/46] IReader: added channelIndex attribute to be able to extract a part of the next frame when decode --- src/AvTranscoder/reader/IReader.cpp | 14 ++++++++++---- src/AvTranscoder/reader/IReader.hpp | 6 ++++-- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/AvTranscoder/reader/IReader.cpp b/src/AvTranscoder/reader/IReader.cpp index a83608b2..b9a1ad81 100644 --- a/src/AvTranscoder/reader/IReader.cpp +++ b/src/AvTranscoder/reader/IReader.cpp @@ -7,7 +7,7 @@ namespace avtranscoder { -IReader::IReader( const std::string& filename, const size_t streamIndex ) +IReader::IReader( const std::string& filename, const size_t streamIndex, const int channelIndex ) : _inputFile( NULL ) , _streamProperties( NULL ) , _decoder( NULL ) @@ -15,13 +15,14 @@ IReader::IReader( const std::string& filename, const size_t streamIndex ) , _dstFrame( NULL ) , _transform( NULL ) , _streamIndex( streamIndex ) + , _channelIndex( channelIndex ) , _currentFrame( -1 ) , _inputFileAllocated( true ) { _inputFile = new InputFile( filename ); } -IReader::IReader( InputFile& inputFile, const size_t streamIndex ) +IReader::IReader( InputFile& inputFile, const size_t streamIndex, const int channelIndex ) : _inputFile( &inputFile ) , _streamProperties( NULL ) , _decoder( NULL ) @@ -29,6 +30,7 @@ IReader::IReader( InputFile& inputFile, const size_t streamIndex ) , _dstFrame( NULL ) , _transform( NULL ) , _streamIndex( streamIndex ) + , _channelIndex( channelIndex ) , _currentFrame( -1 ) , _inputFileAllocated( false ) {} @@ -56,15 +58,19 @@ Frame* IReader::readFrameAt( const size_t frame ) assert( _srcFrame != NULL ); assert( _dstFrame != NULL ); + // seek if( (int)frame != _currentFrame + 1 ) { - // seek _inputFile->seekAtFrame( frame ); _decoder->flushDecoder(); } _currentFrame = frame; // decode - _decoder->decodeNextFrame( *_srcFrame ); + if( _channelIndex != -1 ) + _decoder->decodeNextFrame( *_srcFrame, _channelIndex ); + else + _decoder->decodeNextFrame( *_srcFrame ); + // transform _transform->convert( *_srcFrame, *_dstFrame ); // return buffer return _dstFrame; diff --git a/src/AvTranscoder/reader/IReader.hpp b/src/AvTranscoder/reader/IReader.hpp index ba509531..992ea8c8 100644 --- a/src/AvTranscoder/reader/IReader.hpp +++ b/src/AvTranscoder/reader/IReader.hpp @@ -21,14 +21,15 @@ class AvExport IReader /** * @brief Create a new InputFile and prepare to read the stream at the given index * @param streamIndex by default read the first stream + * @param channelIndex by default -1 (all channels of the stream) */ - IReader( const std::string& filename, const size_t streamIndex = 0 ); + IReader( const std::string& filename, const size_t streamIndex = 0, const int channelIndex = -1 ); /** * @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 = 0 ); + IReader( InputFile& inputFile, const size_t streamIndex = 0, const int channelIndex = -1 ); virtual ~IReader() = 0; @@ -63,6 +64,7 @@ class AvExport IReader ITransform* _transform; size_t _streamIndex; + int _channelIndex; private: int _currentFrame; ///< The current decoded frame. From 82321ad8c6e62a069d36b8628ee041d6b25546c2 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 1 Dec 2015 11:03:06 +0100 Subject: [PATCH 04/46] VideoReader: added updateOutput method to refactore constructors * The constructors are easier to call. * By default we explicitly copy the input parameters (width, height, pixelFormat) to the output. --- src/AvTranscoder/reader/VideoReader.cpp | 39 +++++++++++++++---------- src/AvTranscoder/reader/VideoReader.hpp | 10 +++++-- 2 files changed, 32 insertions(+), 17 deletions(-) diff --git a/src/AvTranscoder/reader/VideoReader.cpp b/src/AvTranscoder/reader/VideoReader.cpp index 3efa12fc..f81421a9 100644 --- a/src/AvTranscoder/reader/VideoReader.cpp +++ b/src/AvTranscoder/reader/VideoReader.cpp @@ -9,22 +9,22 @@ namespace avtranscoder { -VideoReader::VideoReader( const std::string& filename, const size_t videoStreamIndex, const size_t width, const size_t height, const std::string& pixelFormat ) +VideoReader::VideoReader( const std::string& filename, const size_t videoStreamIndex ) : IReader( filename, videoStreamIndex ) , _videoStreamProperties(NULL) - , _width( width ) - , _height( height ) - , _pixelProperties( pixelFormat ) + , _width( 0 ) + , _height( 0 ) + , _pixelProperties() { init(); } -VideoReader::VideoReader( InputFile& inputFile, const size_t videoStreamIndex, const size_t width, const size_t height, const std::string& pixelFormat ) +VideoReader::VideoReader( InputFile& inputFile, const size_t videoStreamIndex ) : IReader( inputFile, videoStreamIndex ) , _videoStreamProperties(NULL) - , _width( width ) - , _height( height ) - , _pixelProperties( pixelFormat ) + , _width( 0 ) + , _height( 0 ) + , _pixelProperties() { init(); } @@ -42,19 +42,18 @@ void VideoReader::init() _decoder = new VideoDecoder( _inputFile->getStream( _streamIndex ) ); _decoder->setupDecoder(); + // create transform + _transform = new VideoTransform(); + // create src frame _srcFrame = new VideoFrame( _inputFile->getStream( _streamIndex ).getVideoCodec().getVideoFrameDesc() ); VideoFrame* srcFrame = static_cast(_srcFrame); // create dst frame - if( _width == 0 ) - _width = srcFrame->desc().getWidth(); - if( _height == 0 ) - _height = srcFrame->desc().getHeight(); + _width = srcFrame->desc().getWidth(); + _height = srcFrame->desc().getHeight(); + _pixelProperties = PixelProperties( "rgb24" ); VideoFrameDesc videoFrameDescToDisplay( _width, _height, getPixelFormat() ); _dstFrame = new VideoFrame( videoFrameDescToDisplay ); - - // create transform - _transform = new VideoTransform(); } VideoReader::~VideoReader() @@ -65,6 +64,16 @@ VideoReader::~VideoReader() delete _transform; } +void VideoReader::updateOutput(const size_t width, const size_t height, const std::string& pixelFormat) +{ + _width = width; + _height = height; + _pixelProperties = PixelProperties( pixelFormat ); + // update dst frame + delete _dstFrame; + _dstFrame = new VideoFrame( VideoFrameDesc( _width, _height, getPixelFormat() ) ); +} + size_t VideoReader::getWidth() { return _width; diff --git a/src/AvTranscoder/reader/VideoReader.hpp b/src/AvTranscoder/reader/VideoReader.hpp index 02170e72..071253eb 100644 --- a/src/AvTranscoder/reader/VideoReader.hpp +++ b/src/AvTranscoder/reader/VideoReader.hpp @@ -18,12 +18,18 @@ class AvExport VideoReader : public IReader // @param height: if 0, get height of source // @param pixelFormat: rgb24 by default (to display) // - VideoReader( const std::string& filename, const size_t videoStreamIndex, const size_t width = 0, const size_t height = 0, const std::string& pixelFormat = "rgb24" ); - VideoReader( InputFile& inputFile, const size_t videoStreamIndex, const size_t width = 0, const size_t height = 0, const std::string& pixelFormat = "rgb24" ); + VideoReader( const std::string& filename, const size_t videoStreamIndex ); + VideoReader( InputFile& inputFile, const size_t videoStreamIndex ); //@} ~VideoReader(); + /** + * @brief Update width, height and pixelFormat of the output. + * @note Will transform the decoded data when read the stream. + */ + void updateOutput(const size_t width, const size_t height, const std::string& pixelFormat); + //@{ // @brief Output info size_t getWidth(); From 154bd3959c6697d4870d5d9c5183687a79020e6f Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 1 Dec 2015 11:05:33 +0100 Subject: [PATCH 05/46] VideoReader: update getters to const and define them in hpp --- src/AvTranscoder/reader/VideoReader.cpp | 25 ------------------------- src/AvTranscoder/reader/VideoReader.hpp | 10 +++++----- 2 files changed, 5 insertions(+), 30 deletions(-) diff --git a/src/AvTranscoder/reader/VideoReader.cpp b/src/AvTranscoder/reader/VideoReader.cpp index f81421a9..a08f078e 100644 --- a/src/AvTranscoder/reader/VideoReader.cpp +++ b/src/AvTranscoder/reader/VideoReader.cpp @@ -74,31 +74,6 @@ void VideoReader::updateOutput(const size_t width, const size_t height, const st _dstFrame = new VideoFrame( VideoFrameDesc( _width, _height, getPixelFormat() ) ); } -size_t VideoReader::getWidth() -{ - return _width; -}; - -size_t VideoReader::getHeight() -{ - return _height; -} - -size_t VideoReader::getComponents() -{ - return _pixelProperties.getNbComponents(); -} - -size_t VideoReader::getBitDepth() -{ - return _pixelProperties.getBitsPerPixel(); -} - -AVPixelFormat VideoReader::getPixelFormat() -{ - return _pixelProperties.getAVPixelFormat(); -} - void VideoReader::printInfo() { std::cout << *_videoStreamProperties << std::endl; diff --git a/src/AvTranscoder/reader/VideoReader.hpp b/src/AvTranscoder/reader/VideoReader.hpp index 071253eb..b238b5c5 100644 --- a/src/AvTranscoder/reader/VideoReader.hpp +++ b/src/AvTranscoder/reader/VideoReader.hpp @@ -32,11 +32,11 @@ class AvExport VideoReader : public IReader //@{ // @brief Output info - size_t getWidth(); - size_t getHeight(); - size_t getComponents(); - size_t getBitDepth(); - AVPixelFormat getPixelFormat(); + size_t getWidth() const { return _width; } + size_t getHeight() const { return _height; } + size_t getComponents() const { return _pixelProperties.getNbComponents(); } + size_t getBitDepth() const { return _pixelProperties.getBitsPerPixel(); } + AVPixelFormat getPixelFormat() const { return _pixelProperties.getAVPixelFormat(); } //@} // @brief Input info From 79da9948a43162acaa1314f6906e4f53f08f957a Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 1 Dec 2015 11:09:58 +0100 Subject: [PATCH 06/46] VideoReader: update name of getters and attributes Added 'output' when the element concerns output. --- app/avPlay/Window.cpp | 10 ++++----- src/AvTranscoder/reader/VideoReader.cpp | 28 ++++++++++++------------- src/AvTranscoder/reader/VideoReader.hpp | 16 +++++++------- 3 files changed, 27 insertions(+), 27 deletions(-) diff --git a/app/avPlay/Window.cpp b/app/avPlay/Window.cpp index fd611596..bb6d6b30 100644 --- a/app/avPlay/Window.cpp +++ b/app/avPlay/Window.cpp @@ -97,8 +97,8 @@ void loadNewTexture( const char* data, GLint internalFormat, size_t width, size_ Window::Window( avtranscoder::VideoReader& reader ) { _reader = &reader; - _width = _reader->getWidth(); - _height = _reader->getHeight(); + _width = _reader->getOutputWidth(); + _height = _reader->getOutputHeight(); char *argv[2] = { (char*)"", NULL }; int argc = 1; @@ -530,14 +530,14 @@ void Window::showAlphaChannelTexture( ) void Window::displayNextFrame() { const char* buffer = (const char*)_reader->readNextFrame()->getData(); - loadNewTexture( buffer, _reader->getComponents(), _reader->getWidth(), _reader->getHeight(), GL_RGB, GL_UNSIGNED_BYTE ); + loadNewTexture( buffer, _reader->getOutputNbComponents(), _reader->getOutputWidth(), _reader->getOutputHeight(), GL_RGB, GL_UNSIGNED_BYTE ); display(); } void Window::displayPrevFrame() { const char* buffer = (const char*)_reader->readPrevFrame()->getData(); - loadNewTexture( buffer, _reader->getComponents(), _reader->getWidth(), _reader->getHeight(), GL_RGB, GL_UNSIGNED_BYTE ); + loadNewTexture( buffer, _reader->getOutputNbComponents(), _reader->getOutputWidth(), _reader->getOutputHeight(), GL_RGB, GL_UNSIGNED_BYTE ); display(); } @@ -549,7 +549,7 @@ void Window::displayFirstFrame() void Window::displayAtFrame( const size_t frame ) { const char* buffer = (const char*)_reader->readFrameAt( frame )->getData(); - loadNewTexture( buffer, _reader->getComponents(), _reader->getWidth(), _reader->getHeight(), GL_RGB, GL_UNSIGNED_BYTE ); + loadNewTexture( buffer, _reader->getOutputNbComponents(), _reader->getOutputWidth(), _reader->getOutputHeight(), GL_RGB, GL_UNSIGNED_BYTE ); display(); } diff --git a/src/AvTranscoder/reader/VideoReader.cpp b/src/AvTranscoder/reader/VideoReader.cpp index a08f078e..b753b9f2 100644 --- a/src/AvTranscoder/reader/VideoReader.cpp +++ b/src/AvTranscoder/reader/VideoReader.cpp @@ -12,9 +12,9 @@ namespace avtranscoder VideoReader::VideoReader( const std::string& filename, const size_t videoStreamIndex ) : IReader( filename, videoStreamIndex ) , _videoStreamProperties(NULL) - , _width( 0 ) - , _height( 0 ) - , _pixelProperties() + , _outputWidth( 0 ) + , _outputHeight( 0 ) + , _outputPixelProperties() { init(); } @@ -22,9 +22,9 @@ VideoReader::VideoReader( const std::string& filename, const size_t videoStreamI VideoReader::VideoReader( InputFile& inputFile, const size_t videoStreamIndex ) : IReader( inputFile, videoStreamIndex ) , _videoStreamProperties(NULL) - , _width( 0 ) - , _height( 0 ) - , _pixelProperties() + , _outputWidth( 0 ) + , _outputHeight( 0 ) + , _outputPixelProperties() { init(); } @@ -49,10 +49,10 @@ void VideoReader::init() _srcFrame = new VideoFrame( _inputFile->getStream( _streamIndex ).getVideoCodec().getVideoFrameDesc() ); VideoFrame* srcFrame = static_cast(_srcFrame); // create dst frame - _width = srcFrame->desc().getWidth(); - _height = srcFrame->desc().getHeight(); - _pixelProperties = PixelProperties( "rgb24" ); - VideoFrameDesc videoFrameDescToDisplay( _width, _height, getPixelFormat() ); + _outputWidth = srcFrame->desc().getWidth(); + _outputHeight = srcFrame->desc().getHeight(); + _outputPixelProperties = PixelProperties( "rgb24" ); + VideoFrameDesc videoFrameDescToDisplay( _outputWidth, _outputHeight, getOutputPixelFormat() ); _dstFrame = new VideoFrame( videoFrameDescToDisplay ); } @@ -66,12 +66,12 @@ VideoReader::~VideoReader() void VideoReader::updateOutput(const size_t width, const size_t height, const std::string& pixelFormat) { - _width = width; - _height = height; - _pixelProperties = PixelProperties( pixelFormat ); + _outputWidth = width; + _outputHeight = height; + _outputPixelProperties = PixelProperties( pixelFormat ); // update dst frame delete _dstFrame; - _dstFrame = new VideoFrame( VideoFrameDesc( _width, _height, getPixelFormat() ) ); + _dstFrame = new VideoFrame( VideoFrameDesc( _outputWidth, _outputHeight, getOutputPixelFormat() ) ); } void VideoReader::printInfo() diff --git a/src/AvTranscoder/reader/VideoReader.hpp b/src/AvTranscoder/reader/VideoReader.hpp index b238b5c5..b3a409f6 100644 --- a/src/AvTranscoder/reader/VideoReader.hpp +++ b/src/AvTranscoder/reader/VideoReader.hpp @@ -32,11 +32,11 @@ class AvExport VideoReader : public IReader //@{ // @brief Output info - size_t getWidth() const { return _width; } - size_t getHeight() const { return _height; } - size_t getComponents() const { return _pixelProperties.getNbComponents(); } - size_t getBitDepth() const { return _pixelProperties.getBitsPerPixel(); } - AVPixelFormat getPixelFormat() const { return _pixelProperties.getAVPixelFormat(); } + size_t getOutputWidth() const { return _outputWidth; } + size_t getOutputHeight() const { return _outputHeight; } + size_t getOutputNbComponents() const { return _outputPixelProperties.getNbComponents(); } + size_t getOutputBitDepth() const { return _outputPixelProperties.getBitsPerPixel(); } + AVPixelFormat getOutputPixelFormat() const { return _outputPixelProperties.getAVPixelFormat(); } //@} // @brief Input info @@ -52,9 +52,9 @@ class AvExport VideoReader : public IReader //@{ // @brief Output info - size_t _width; - size_t _height; - PixelProperties _pixelProperties; + size_t _outputWidth; + size_t _outputHeight; + PixelProperties _outputPixelProperties; //@} }; From 48bcb463b80a25221a81f8b419d8867425e58feb Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 1 Dec 2015 11:11:42 +0100 Subject: [PATCH 07/46] VideoReader: updated doc of constructors --- src/AvTranscoder/reader/VideoReader.hpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/AvTranscoder/reader/VideoReader.hpp b/src/AvTranscoder/reader/VideoReader.hpp index b3a409f6..1a65b2fd 100644 --- a/src/AvTranscoder/reader/VideoReader.hpp +++ b/src/AvTranscoder/reader/VideoReader.hpp @@ -14,9 +14,8 @@ class AvExport VideoReader : public IReader { public: //@{ - // @param width: if 0, get width of source - // @param height: if 0, get height of source - // @param pixelFormat: rgb24 by default (to display) + // @note Transform the input stream to rgb24 pixel format (to display). + // @see updateOutput // VideoReader( const std::string& filename, const size_t videoStreamIndex ); VideoReader( InputFile& inputFile, const size_t videoStreamIndex ); From f151b827bdf62a280ed2a92ba7112da76ae9675e Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 1 Dec 2015 11:21:53 +0100 Subject: [PATCH 08/46] avplay app: added help --- app/avPlay/main.cpp | 43 +++++++++++++++++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/app/avPlay/main.cpp b/app/avPlay/main.cpp index 132dc55f..a25f70f8 100644 --- a/app/avPlay/main.cpp +++ b/app/avPlay/main.cpp @@ -3,20 +3,55 @@ #include "Window.hpp" +#include + int main( int argc, char** argv ) { - avtranscoder::preloadCodecsAndFormats(); + std::string filename; + size_t streamIndex = 0; + + std::string help; + help += "Usage\n"; + help += "\tavplay filename [streamIndex] [--help]\n"; + help += "Command line options\n"; + help += "\tstreamIndex: index of the stream to read (by default 0)\n"; + help += "\t--help: display this help\n"; + // List command line arguments + std::vector< std::string > arguments; + for( int argument = 1; argument < argc; ++argument ) + { + arguments.push_back( argv[argument] ); + } + for( size_t argument = 0; argument < arguments.size(); ++argument ) + { + if( arguments.at( argument ) == "--help" ) + { + std::cout << help << std::endl; + return 0; + } + // positional arguments + if( argument == 0 ) + { + filename = arguments.at( argument ); + } + else if( argument == 1 ) + { + streamIndex = atoi( arguments.at( argument ).c_str() ); + } + } + + // Check required arguments 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; + std::cout << "Use option --help to display help" << std::endl; return( -1 ); } - const std::string filename(argv[1]); - const size_t streamIndex = argc > 2 ? atoi(argv[2]) : 0; + // Setup avtranscoder + avtranscoder::preloadCodecsAndFormats(); avtranscoder::VideoReader reader( filename, streamIndex ); Window window( reader ); From 2f3a66e6b1bb5953b21b1dbb5cb8b54a514bd861 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 1 Dec 2015 11:28:10 +0100 Subject: [PATCH 09/46] avplay app: added --width / --height options --- app/avPlay/main.cpp | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/app/avPlay/main.cpp b/app/avPlay/main.cpp index a25f70f8..9f0f2437 100644 --- a/app/avPlay/main.cpp +++ b/app/avPlay/main.cpp @@ -10,12 +10,16 @@ int main( int argc, char** argv ) { std::string filename; size_t streamIndex = 0; + size_t width = 0; + size_t height = 0; std::string help; help += "Usage\n"; - help += "\tavplay filename [streamIndex] [--help]\n"; + help += "\tavplay filename [streamIndex] [--width width] [--height height] [--help]\n"; help += "Command line options\n"; - help += "\tstreamIndex: index of the stream to read (by default 0)\n"; + help += "\tstreamIndex: specify the index of the stream to read (by default 0)\n"; + help += "\t--width: specify the output width (by default the same as input)\n"; + help += "\t--height: specify the output height (by default the same as input)\n"; help += "\t--help: display this help\n"; // List command line arguments @@ -31,6 +35,30 @@ int main( int argc, char** argv ) std::cout << help << std::endl; return 0; } + else if( arguments.at( argument ) == "--width" ) + { + try + { + width = atoi( arguments.at( ++argument ).c_str() ); + } + catch(...) + { + std::cout << help << std::endl; + return 0; + } + } + else if( arguments.at( argument ) == "--height" ) + { + try + { + height = atoi( arguments.at( ++argument ).c_str() ); + } + catch(...) + { + std::cout << help << std::endl; + return 0; + } + } // positional arguments if( argument == 0 ) { @@ -54,6 +82,11 @@ int main( int argc, char** argv ) avtranscoder::preloadCodecsAndFormats(); avtranscoder::VideoReader reader( filename, streamIndex ); + if( width == 0 ) + width = reader.getOutputWidth(); + if( height == 0 ) + height = reader.getOutputHeight(); + reader.updateOutput(width, height, "rgb24"); Window window( reader ); window.launch(); } From a07c96f1f83c35c675c3b705c7bbebfadff5e0a9 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 1 Dec 2015 11:28:30 +0100 Subject: [PATCH 10/46] avplay app: set log level to QUIET --- app/avPlay/main.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/app/avPlay/main.cpp b/app/avPlay/main.cpp index 9f0f2437..a7f395df 100644 --- a/app/avPlay/main.cpp +++ b/app/avPlay/main.cpp @@ -80,6 +80,7 @@ int main( int argc, char** argv ) // Setup avtranscoder avtranscoder::preloadCodecsAndFormats(); + avtranscoder::Logger::setLogLevel( AV_LOG_QUIET ); avtranscoder::VideoReader reader( filename, streamIndex ); if( width == 0 ) From fe52243d0d24dbb9936c425e02eb2860945e23ea Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 1 Dec 2015 11:36:46 +0100 Subject: [PATCH 11/46] AudioReader: added updateOutput method to refactore constructors * The constructors are easier to call. * By default we explicitly copy the input parameters (sampleRate, nbChannels) to the output. --- src/AvTranscoder/reader/AudioReader.cpp | 41 +++++++++++++++---------- src/AvTranscoder/reader/AudioReader.hpp | 17 ++++++---- 2 files changed, 35 insertions(+), 23 deletions(-) diff --git a/src/AvTranscoder/reader/AudioReader.cpp b/src/AvTranscoder/reader/AudioReader.cpp index 2c8a081e..f93b1a17 100644 --- a/src/AvTranscoder/reader/AudioReader.cpp +++ b/src/AvTranscoder/reader/AudioReader.cpp @@ -9,22 +9,22 @@ namespace avtranscoder { -AudioReader::AudioReader( const std::string& filename, const size_t audioStreamIndex, const size_t sampleRate, const size_t nbChannels, const std::string& sampleFormat ) +AudioReader::AudioReader( const std::string& filename, const size_t audioStreamIndex ) : IReader( filename, audioStreamIndex ) , _audioStreamProperties(NULL) - , _sampleRate( sampleRate ) - , _nbChannels( nbChannels ) - , _sampleFormat( av_get_sample_fmt( sampleFormat.c_str() ) ) + , _sampleRate( 0 ) + , _nbChannels( 0 ) + , _sampleFormat( AV_SAMPLE_FMT_S16 ) { init(); } -AudioReader::AudioReader( InputFile& inputFile, const size_t audioStreamIndex, const size_t sampleRate, const size_t nbChannels, const std::string& sampleFormat ) +AudioReader::AudioReader( InputFile& inputFile, const size_t audioStreamIndex ) : IReader( inputFile, audioStreamIndex ) , _audioStreamProperties(NULL) - , _sampleRate( sampleRate ) - , _nbChannels( nbChannels ) - , _sampleFormat( av_get_sample_fmt( sampleFormat.c_str() ) ) + , _sampleRate( 0 ) + , _nbChannels( 0 ) + , _sampleFormat( AV_SAMPLE_FMT_S16 ) { init(); } @@ -42,19 +42,16 @@ void AudioReader::init() _decoder = new AudioDecoder( _inputFile->getStream( _streamIndex ) ); _decoder->setupDecoder(); + // create transform + _transform = new AudioTransform(); + // create src frame _srcFrame = new AudioFrame( _inputFile->getStream( _streamIndex ).getAudioCodec().getAudioFrameDesc() ); AudioFrame* srcFrame = static_cast(_srcFrame); // create dst frame - if( _sampleRate == 0 ) - _sampleRate = srcFrame->desc().getSampleRate(); - if( _nbChannels == 0 ) - _nbChannels = srcFrame->desc().getChannels(); - AudioFrameDesc dstAudioFrame( _sampleRate, _nbChannels, _sampleFormat ); - _dstFrame = new AudioFrame( dstAudioFrame ); - - // create transform - _transform = new AudioTransform(); + _sampleRate = srcFrame->desc().getSampleRate(); + _nbChannels = srcFrame->desc().getChannels(); + _dstFrame = new AudioFrame( AudioFrameDesc( _sampleRate, _nbChannels, _sampleFormat ) ); } AudioReader::~AudioReader() @@ -65,6 +62,16 @@ AudioReader::~AudioReader() delete _transform; } +void AudioReader::updateOutput( const size_t sampleRate, const size_t nbChannels, const std::string& sampleFormat ) +{ + _sampleRate = sampleRate; + _nbChannels = nbChannels; + _sampleFormat = av_get_sample_fmt( sampleFormat.c_str() ); + // update dst frame + delete _dstFrame; + _dstFrame = new AudioFrame( AudioFrameDesc( _sampleRate, _nbChannels, _sampleFormat ) ); +} + size_t AudioReader::getSampleRate() { return _sampleRate; diff --git a/src/AvTranscoder/reader/AudioReader.hpp b/src/AvTranscoder/reader/AudioReader.hpp index 9547b983..6fed21e5 100644 --- a/src/AvTranscoder/reader/AudioReader.hpp +++ b/src/AvTranscoder/reader/AudioReader.hpp @@ -13,15 +13,20 @@ class AvExport AudioReader : public IReader { public: //@{ - // @param sampleRate: if 0, get sample rate of source - // @param nbChannels: if 0, get number of channels of source - // @param sampleFormat: pcm_16le by default (to listen) - // - AudioReader( const std::string& filename, const size_t audioStreamIndex, const size_t sampleRate = 0, const size_t nbChannels = 0, const std::string& sampleFormat = "s16" ); - AudioReader( InputFile& inputFile, const size_t audioStreamIndex, const size_t sampleRate = 0, const size_t nbChannels = 0, const std::string& sampleFormat = "s16" ); + // @note Transform the input stream to s16 sample format (to listen). + // @see updateOutput + AudioReader( const std::string& filename, const size_t audioStreamIndex ); + AudioReader( InputFile& inputFile, const size_t audioStreamIndex ); + //@} ~AudioReader(); + /** + * @brief Update sample rate, number of channels and sample format of the output. + * @note Will transform the decoded data when read the stream. + */ + void updateOutput( const size_t sampleRate, const size_t nbChannels, const std::string& sampleFormat ); + //@{ // @brief Output info size_t getSampleRate(); From 8ac68dcad1f1e10fe0d39200387763e541078f39 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 1 Dec 2015 11:37:30 +0100 Subject: [PATCH 12/46] VideoReader: removed unnecessary local variable in init method --- src/AvTranscoder/reader/VideoReader.cpp | 3 +-- src/AvTranscoder/reader/VideoReader.hpp | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/AvTranscoder/reader/VideoReader.cpp b/src/AvTranscoder/reader/VideoReader.cpp index b753b9f2..61f2830f 100644 --- a/src/AvTranscoder/reader/VideoReader.cpp +++ b/src/AvTranscoder/reader/VideoReader.cpp @@ -52,8 +52,7 @@ void VideoReader::init() _outputWidth = srcFrame->desc().getWidth(); _outputHeight = srcFrame->desc().getHeight(); _outputPixelProperties = PixelProperties( "rgb24" ); - VideoFrameDesc videoFrameDescToDisplay( _outputWidth, _outputHeight, getOutputPixelFormat() ); - _dstFrame = new VideoFrame( videoFrameDescToDisplay ); + _dstFrame = new VideoFrame( VideoFrameDesc( _outputWidth, _outputHeight, getOutputPixelFormat() ) ); } VideoReader::~VideoReader() diff --git a/src/AvTranscoder/reader/VideoReader.hpp b/src/AvTranscoder/reader/VideoReader.hpp index 1a65b2fd..ea45ea56 100644 --- a/src/AvTranscoder/reader/VideoReader.hpp +++ b/src/AvTranscoder/reader/VideoReader.hpp @@ -16,7 +16,6 @@ class AvExport VideoReader : public IReader //@{ // @note Transform the input stream to rgb24 pixel format (to display). // @see updateOutput - // VideoReader( const std::string& filename, const size_t videoStreamIndex ); VideoReader( InputFile& inputFile, const size_t videoStreamIndex ); //@} From 3b099bbb7198468bc1b7ac3d5f40de5f127cb3f7 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 1 Dec 2015 11:38:58 +0100 Subject: [PATCH 13/46] AudioReader: update getters to const and define them in hpp --- src/AvTranscoder/reader/AudioReader.cpp | 15 --------------- src/AvTranscoder/reader/AudioReader.hpp | 6 +++--- 2 files changed, 3 insertions(+), 18 deletions(-) diff --git a/src/AvTranscoder/reader/AudioReader.cpp b/src/AvTranscoder/reader/AudioReader.cpp index f93b1a17..a0af8916 100644 --- a/src/AvTranscoder/reader/AudioReader.cpp +++ b/src/AvTranscoder/reader/AudioReader.cpp @@ -72,21 +72,6 @@ void AudioReader::updateOutput( const size_t sampleRate, const size_t nbChannels _dstFrame = new AudioFrame( AudioFrameDesc( _sampleRate, _nbChannels, _sampleFormat ) ); } -size_t AudioReader::getSampleRate() -{ - return _sampleRate; -} - -size_t AudioReader::getChannels() -{ - return _nbChannels; -} - -AVSampleFormat AudioReader::getSampleFormat() -{ - return _sampleFormat; -} - void AudioReader::printInfo() { std::cout << *_audioStreamProperties << std::endl; diff --git a/src/AvTranscoder/reader/AudioReader.hpp b/src/AvTranscoder/reader/AudioReader.hpp index 6fed21e5..e013da14 100644 --- a/src/AvTranscoder/reader/AudioReader.hpp +++ b/src/AvTranscoder/reader/AudioReader.hpp @@ -29,9 +29,9 @@ class AvExport AudioReader : public IReader //@{ // @brief Output info - size_t getSampleRate(); - size_t getChannels(); - AVSampleFormat getSampleFormat(); + size_t getSampleRate() const { return _sampleRate; } + size_t getChannels() const { return _nbChannels; } + AVSampleFormat getSampleFormat() const { return _sampleFormat; } //@} // @brief Input info From dbeebb649c55c53bb7b620e9c15b0149fd06bcba Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 1 Dec 2015 11:41:04 +0100 Subject: [PATCH 14/46] AudioReader: update name of getters and attributes Added 'output' when the element concerns output. --- src/AvTranscoder/reader/AudioReader.cpp | 26 ++++++++++++------------- src/AvTranscoder/reader/AudioReader.hpp | 12 ++++++------ 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/AvTranscoder/reader/AudioReader.cpp b/src/AvTranscoder/reader/AudioReader.cpp index a0af8916..22095674 100644 --- a/src/AvTranscoder/reader/AudioReader.cpp +++ b/src/AvTranscoder/reader/AudioReader.cpp @@ -12,9 +12,9 @@ namespace avtranscoder AudioReader::AudioReader( const std::string& filename, const size_t audioStreamIndex ) : IReader( filename, audioStreamIndex ) , _audioStreamProperties(NULL) - , _sampleRate( 0 ) - , _nbChannels( 0 ) - , _sampleFormat( AV_SAMPLE_FMT_S16 ) + , _outputSampleRate( 0 ) + , _outputNbChannels( 0 ) + , _outputSampleFormat( AV_SAMPLE_FMT_S16 ) { init(); } @@ -22,9 +22,9 @@ AudioReader::AudioReader( const std::string& filename, const size_t audioStreamI AudioReader::AudioReader( InputFile& inputFile, const size_t audioStreamIndex ) : IReader( inputFile, audioStreamIndex ) , _audioStreamProperties(NULL) - , _sampleRate( 0 ) - , _nbChannels( 0 ) - , _sampleFormat( AV_SAMPLE_FMT_S16 ) + , _outputSampleRate( 0 ) + , _outputNbChannels( 0 ) + , _outputSampleFormat( AV_SAMPLE_FMT_S16 ) { init(); } @@ -49,9 +49,9 @@ void AudioReader::init() _srcFrame = new AudioFrame( _inputFile->getStream( _streamIndex ).getAudioCodec().getAudioFrameDesc() ); AudioFrame* srcFrame = static_cast(_srcFrame); // create dst frame - _sampleRate = srcFrame->desc().getSampleRate(); - _nbChannels = srcFrame->desc().getChannels(); - _dstFrame = new AudioFrame( AudioFrameDesc( _sampleRate, _nbChannels, _sampleFormat ) ); + _outputSampleRate = srcFrame->desc().getSampleRate(); + _outputNbChannels = srcFrame->desc().getChannels(); + _dstFrame = new AudioFrame( AudioFrameDesc( _outputSampleRate, _outputNbChannels, _outputSampleFormat ) ); } AudioReader::~AudioReader() @@ -64,12 +64,12 @@ AudioReader::~AudioReader() void AudioReader::updateOutput( const size_t sampleRate, const size_t nbChannels, const std::string& sampleFormat ) { - _sampleRate = sampleRate; - _nbChannels = nbChannels; - _sampleFormat = av_get_sample_fmt( sampleFormat.c_str() ); + _outputSampleRate = sampleRate; + _outputNbChannels = nbChannels; + _outputSampleFormat = av_get_sample_fmt( sampleFormat.c_str() ); // update dst frame delete _dstFrame; - _dstFrame = new AudioFrame( AudioFrameDesc( _sampleRate, _nbChannels, _sampleFormat ) ); + _dstFrame = new AudioFrame( AudioFrameDesc( _outputSampleRate, _outputNbChannels, _outputSampleFormat ) ); } void AudioReader::printInfo() diff --git a/src/AvTranscoder/reader/AudioReader.hpp b/src/AvTranscoder/reader/AudioReader.hpp index e013da14..c04e5dab 100644 --- a/src/AvTranscoder/reader/AudioReader.hpp +++ b/src/AvTranscoder/reader/AudioReader.hpp @@ -29,9 +29,9 @@ class AvExport AudioReader : public IReader //@{ // @brief Output info - size_t getSampleRate() const { return _sampleRate; } - size_t getChannels() const { return _nbChannels; } - AVSampleFormat getSampleFormat() const { return _sampleFormat; } + size_t getOutputSampleRate() const { return _outputSampleRate; } + size_t getOutputChannels() const { return _outputNbChannels; } + AVSampleFormat getOutputSampleFormat() const { return _outputSampleFormat; } //@} // @brief Input info @@ -47,9 +47,9 @@ class AvExport AudioReader : public IReader //@{ // @brief Output info - size_t _sampleRate; - size_t _nbChannels; - AVSampleFormat _sampleFormat; + size_t _outputSampleRate; + size_t _outputNbChannels; + AVSampleFormat _outputSampleFormat; //@} }; From 793b0ae1f1a7347580c4d38b9750086909a992f9 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 1 Dec 2015 11:42:40 +0100 Subject: [PATCH 15/46] Video/AudioReader: added default value to streamIndex parameter --- src/AvTranscoder/reader/AudioReader.hpp | 4 ++-- src/AvTranscoder/reader/VideoReader.hpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/AvTranscoder/reader/AudioReader.hpp b/src/AvTranscoder/reader/AudioReader.hpp index c04e5dab..00dc20db 100644 --- a/src/AvTranscoder/reader/AudioReader.hpp +++ b/src/AvTranscoder/reader/AudioReader.hpp @@ -15,8 +15,8 @@ class AvExport AudioReader : public IReader //@{ // @note Transform the input stream to s16 sample format (to listen). // @see updateOutput - AudioReader( const std::string& filename, const size_t audioStreamIndex ); - AudioReader( InputFile& inputFile, const size_t audioStreamIndex ); + AudioReader( const std::string& filename, const size_t audioStreamIndex = 0 ); + AudioReader( InputFile& inputFile, const size_t audioStreamIndex = 0 ); //@} ~AudioReader(); diff --git a/src/AvTranscoder/reader/VideoReader.hpp b/src/AvTranscoder/reader/VideoReader.hpp index ea45ea56..a7ac0058 100644 --- a/src/AvTranscoder/reader/VideoReader.hpp +++ b/src/AvTranscoder/reader/VideoReader.hpp @@ -16,8 +16,8 @@ class AvExport VideoReader : public IReader //@{ // @note Transform the input stream to rgb24 pixel format (to display). // @see updateOutput - VideoReader( const std::string& filename, const size_t videoStreamIndex ); - VideoReader( InputFile& inputFile, const size_t videoStreamIndex ); + VideoReader( const std::string& filename, const size_t videoStreamIndex = 0 ); + VideoReader( InputFile& inputFile, const size_t videoStreamIndex = 0 ); //@} ~VideoReader(); From 98ad8885ea3197f0cf64c7b8b7bbff5e34e46b7a Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 1 Dec 2015 11:45:08 +0100 Subject: [PATCH 16/46] AudioReader: added channelIndex parameter in constructors --- src/AvTranscoder/reader/AudioReader.cpp | 8 ++++---- src/AvTranscoder/reader/AudioReader.hpp | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/AvTranscoder/reader/AudioReader.cpp b/src/AvTranscoder/reader/AudioReader.cpp index 22095674..ed379fdc 100644 --- a/src/AvTranscoder/reader/AudioReader.cpp +++ b/src/AvTranscoder/reader/AudioReader.cpp @@ -9,8 +9,8 @@ namespace avtranscoder { -AudioReader::AudioReader( const std::string& filename, const size_t audioStreamIndex ) - : IReader( filename, audioStreamIndex ) +AudioReader::AudioReader( const std::string& filename, const size_t streamIndex, const int channelIndex ) + : IReader( filename, streamIndex, channelIndex ) , _audioStreamProperties(NULL) , _outputSampleRate( 0 ) , _outputNbChannels( 0 ) @@ -19,8 +19,8 @@ AudioReader::AudioReader( const std::string& filename, const size_t audioStreamI init(); } -AudioReader::AudioReader( InputFile& inputFile, const size_t audioStreamIndex ) - : IReader( inputFile, audioStreamIndex ) +AudioReader::AudioReader( InputFile& inputFile, const size_t streamIndex, const int channelIndex ) + : IReader( inputFile, streamIndex, channelIndex ) , _audioStreamProperties(NULL) , _outputSampleRate( 0 ) , _outputNbChannels( 0 ) diff --git a/src/AvTranscoder/reader/AudioReader.hpp b/src/AvTranscoder/reader/AudioReader.hpp index 00dc20db..00774fcd 100644 --- a/src/AvTranscoder/reader/AudioReader.hpp +++ b/src/AvTranscoder/reader/AudioReader.hpp @@ -15,8 +15,8 @@ class AvExport AudioReader : public IReader //@{ // @note Transform the input stream to s16 sample format (to listen). // @see updateOutput - AudioReader( const std::string& filename, const size_t audioStreamIndex = 0 ); - AudioReader( InputFile& inputFile, const size_t audioStreamIndex = 0 ); + AudioReader( const std::string& filename, const size_t streamIndex = 0, const int channelIndex = -1 ); + AudioReader( InputFile& inputFile, const size_t streamIndex = 0, const int channelIndex = -1 ); //@} ~AudioReader(); From ebe4cabf4885d371687b6a9bdf00cfe8c7988f5f Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 1 Dec 2015 11:47:52 +0100 Subject: [PATCH 17/46] AudioReader: renamed getOutputChannels to getOutputNbChannels --- src/AvTranscoder/reader/AudioReader.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AvTranscoder/reader/AudioReader.hpp b/src/AvTranscoder/reader/AudioReader.hpp index 00774fcd..1307e75b 100644 --- a/src/AvTranscoder/reader/AudioReader.hpp +++ b/src/AvTranscoder/reader/AudioReader.hpp @@ -30,7 +30,7 @@ class AvExport AudioReader : public IReader //@{ // @brief Output info size_t getOutputSampleRate() const { return _outputSampleRate; } - size_t getOutputChannels() const { return _outputNbChannels; } + size_t getOutputNbChannels() const { return _outputNbChannels; } AVSampleFormat getOutputSampleFormat() const { return _outputSampleFormat; } //@} From decb49c9931bd7280c0edd253518e14ae046e55f Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 1 Dec 2015 12:32:35 +0100 Subject: [PATCH 18/46] AudioTransform: improved ecxception message when cannot init audio context --- src/AvTranscoder/transform/AudioTransform.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/AvTranscoder/transform/AudioTransform.cpp b/src/AvTranscoder/transform/AudioTransform.cpp index 559688b6..3a8b682e 100644 --- a/src/AvTranscoder/transform/AudioTransform.cpp +++ b/src/AvTranscoder/transform/AudioTransform.cpp @@ -63,7 +63,15 @@ bool AudioTransform::init( const Frame& srcFrame, const Frame& dstFrame ) if( InitResampleContext( _audioConvertContext ) < 0 ) { FreeResampleContext( &_audioConvertContext ); - throw std::runtime_error( "unable to open audio convert context" ); + std::stringstream msg; + msg << "Unable to open audio convert context:" << std::endl; + msg << "in_channel_layout " << av_get_default_channel_layout( src.desc().getChannels() ) << std::endl; + msg << "out_channel_layout " << av_get_default_channel_layout( dst.desc().getChannels() ) << std::endl; + msg << "in_sample_rate " << src.desc().getSampleRate() << std::endl; + msg << "out_sample_rate " << dst.desc().getSampleRate() << std::endl; + msg << "in_sample_fmt " << src.desc().getSampleFormat() << std::endl; + msg << "out_sample_fmt " << dst.desc().getSampleFormat() << std::endl; + throw std::runtime_error( msg.str() ); } return true; From c6bc636503a20c538c4542f80586311dad9c46e1 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 1 Dec 2015 12:38:59 +0100 Subject: [PATCH 19/46] readers: removed printInfo method * Just need to get the properties. * See next commit. --- app/avPlay/Window.cpp | 7 +++++-- src/AvTranscoder/reader/AudioReader.cpp | 6 ------ src/AvTranscoder/reader/AudioReader.hpp | 1 - src/AvTranscoder/reader/IReader.cpp | 8 -------- src/AvTranscoder/reader/IReader.hpp | 4 ---- src/AvTranscoder/reader/VideoReader.cpp | 6 ------ src/AvTranscoder/reader/VideoReader.hpp | 1 - 7 files changed, 5 insertions(+), 28 deletions(-) diff --git a/app/avPlay/Window.cpp b/app/avPlay/Window.cpp index bb6d6b30..7d90930a 100644 --- a/app/avPlay/Window.cpp +++ b/app/avPlay/Window.cpp @@ -1,6 +1,7 @@ - #include "Window.hpp" +#include + #ifdef __APPLE__ #include #include @@ -421,7 +422,9 @@ void Window::displayInformations() std::cout << textureType << " " << _width << "x" << _height << std::endl; // stream info - _reader->printInfo(); + const avtranscoder::VideoProperties* properties = _reader->getVideoProperties(); + if( properties != NULL ) + std::cout << *properties << std::endl; } void Window::move( float x, float y ) diff --git a/src/AvTranscoder/reader/AudioReader.cpp b/src/AvTranscoder/reader/AudioReader.cpp index ed379fdc..51dd32bf 100644 --- a/src/AvTranscoder/reader/AudioReader.cpp +++ b/src/AvTranscoder/reader/AudioReader.cpp @@ -4,7 +4,6 @@ #include #include #include -#include namespace avtranscoder { @@ -72,9 +71,4 @@ void AudioReader::updateOutput( const size_t sampleRate, const size_t nbChannels _dstFrame = new AudioFrame( AudioFrameDesc( _outputSampleRate, _outputNbChannels, _outputSampleFormat ) ); } -void AudioReader::printInfo() -{ - std::cout << *_audioStreamProperties << std::endl; -} - } diff --git a/src/AvTranscoder/reader/AudioReader.hpp b/src/AvTranscoder/reader/AudioReader.hpp index 1307e75b..0b3ad8ea 100644 --- a/src/AvTranscoder/reader/AudioReader.hpp +++ b/src/AvTranscoder/reader/AudioReader.hpp @@ -37,7 +37,6 @@ class AvExport AudioReader : public IReader // @brief Input info const AudioProperties* getAudioProperties() const {return _audioStreamProperties;} - void printInfo(); private: void init(); diff --git a/src/AvTranscoder/reader/IReader.cpp b/src/AvTranscoder/reader/IReader.cpp index b9a1ad81..6530f80e 100644 --- a/src/AvTranscoder/reader/IReader.cpp +++ b/src/AvTranscoder/reader/IReader.cpp @@ -1,7 +1,5 @@ #include "IReader.hpp" -#include - #include namespace avtranscoder @@ -76,10 +74,4 @@ Frame* IReader::readFrameAt( const size_t frame ) return _dstFrame; } -void IReader::printInfo() -{ - assert( _streamProperties != NULL ); - std::cout << *_streamProperties << std::endl; -} - } diff --git a/src/AvTranscoder/reader/IReader.hpp b/src/AvTranscoder/reader/IReader.hpp index 992ea8c8..18d0ff73 100644 --- a/src/AvTranscoder/reader/IReader.hpp +++ b/src/AvTranscoder/reader/IReader.hpp @@ -48,10 +48,6 @@ class AvExport IReader */ Frame* readFrameAt( const size_t frame ); - /** - * @brief Print info of the source stream read. - */ - virtual void printInfo(); protected: InputFile* _inputFile; diff --git a/src/AvTranscoder/reader/VideoReader.cpp b/src/AvTranscoder/reader/VideoReader.cpp index 61f2830f..9a0e9f77 100644 --- a/src/AvTranscoder/reader/VideoReader.cpp +++ b/src/AvTranscoder/reader/VideoReader.cpp @@ -4,7 +4,6 @@ #include #include #include -#include namespace avtranscoder { @@ -73,9 +72,4 @@ void VideoReader::updateOutput(const size_t width, const size_t height, const st _dstFrame = new VideoFrame( VideoFrameDesc( _outputWidth, _outputHeight, getOutputPixelFormat() ) ); } -void VideoReader::printInfo() -{ - std::cout << *_videoStreamProperties << std::endl; -} - } diff --git a/src/AvTranscoder/reader/VideoReader.hpp b/src/AvTranscoder/reader/VideoReader.hpp index a7ac0058..37251d09 100644 --- a/src/AvTranscoder/reader/VideoReader.hpp +++ b/src/AvTranscoder/reader/VideoReader.hpp @@ -40,7 +40,6 @@ class AvExport VideoReader : public IReader // @brief Input info const VideoProperties* getVideoProperties() const {return _videoStreamProperties;} - void printInfo(); private: void init(); From 31c9d2178a717d7d774f150b633a71339b7ba624 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 1 Dec 2015 12:40:10 +0100 Subject: [PATCH 20/46] IReader: added getSourceProperties method --- src/AvTranscoder/reader/IReader.hpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/AvTranscoder/reader/IReader.hpp b/src/AvTranscoder/reader/IReader.hpp index 18d0ff73..ebba0c51 100644 --- a/src/AvTranscoder/reader/IReader.hpp +++ b/src/AvTranscoder/reader/IReader.hpp @@ -48,6 +48,10 @@ class AvExport IReader */ Frame* readFrameAt( const size_t frame ); + /** + * @brief Get the properties of the source stream read. + */ + const StreamProperties* getSourceProperties() const { return _streamProperties; } protected: InputFile* _inputFile; From 6e22c0a928f2f2ab52df7480c93a399bb3709173 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 1 Dec 2015 12:41:03 +0100 Subject: [PATCH 21/46] Video/AudioReader: renamed getter to properties Indicate that these are 'source' properties. --- app/avPlay/Window.cpp | 2 +- src/AvTranscoder/reader/AudioReader.hpp | 5 ++--- src/AvTranscoder/reader/VideoReader.hpp | 5 ++--- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/app/avPlay/Window.cpp b/app/avPlay/Window.cpp index 7d90930a..85f69cfe 100644 --- a/app/avPlay/Window.cpp +++ b/app/avPlay/Window.cpp @@ -422,7 +422,7 @@ void Window::displayInformations() std::cout << textureType << " " << _width << "x" << _height << std::endl; // stream info - const avtranscoder::VideoProperties* properties = _reader->getVideoProperties(); + const avtranscoder::VideoProperties* properties = _reader->getSourceVideoProperties(); if( properties != NULL ) std::cout << *properties << std::endl; } diff --git a/src/AvTranscoder/reader/AudioReader.hpp b/src/AvTranscoder/reader/AudioReader.hpp index 0b3ad8ea..85baac51 100644 --- a/src/AvTranscoder/reader/AudioReader.hpp +++ b/src/AvTranscoder/reader/AudioReader.hpp @@ -34,9 +34,8 @@ class AvExport AudioReader : public IReader AVSampleFormat getOutputSampleFormat() const { return _outputSampleFormat; } //@} - // @brief Input info - const AudioProperties* getAudioProperties() const {return _audioStreamProperties;} - + // @brief Get source audio properties + const AudioProperties* getSourceAudioProperties() const {return _audioStreamProperties;} private: void init(); diff --git a/src/AvTranscoder/reader/VideoReader.hpp b/src/AvTranscoder/reader/VideoReader.hpp index 37251d09..1d44a5b9 100644 --- a/src/AvTranscoder/reader/VideoReader.hpp +++ b/src/AvTranscoder/reader/VideoReader.hpp @@ -37,9 +37,8 @@ class AvExport VideoReader : public IReader AVPixelFormat getOutputPixelFormat() const { return _outputPixelProperties.getAVPixelFormat(); } //@} - // @brief Input info - const VideoProperties* getVideoProperties() const {return _videoStreamProperties;} - + // @brief Get source video properties + const VideoProperties* getSourceVideoProperties() const { return _videoStreamProperties; } private: void init(); From b731e361606493f46d2cbc3226f078a002bb6266 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 1 Dec 2015 13:41:03 +0100 Subject: [PATCH 22/46] AudioProperties: renamed getChannels to getNbChannels --- src/AvTranscoder/mediaProperty/AudioProperties.cpp | 6 +++--- src/AvTranscoder/mediaProperty/AudioProperties.hpp | 2 +- src/AvTranscoder/transcoder/Transcoder.cpp | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/AvTranscoder/mediaProperty/AudioProperties.cpp b/src/AvTranscoder/mediaProperty/AudioProperties.cpp index edd9e492..1cb8a1ea 100644 --- a/src/AvTranscoder/mediaProperty/AudioProperties.cpp +++ b/src/AvTranscoder/mediaProperty/AudioProperties.cpp @@ -109,7 +109,7 @@ size_t AudioProperties::getSampleRate() const return _codecContext->sample_rate; } -size_t AudioProperties::getChannels() const +size_t AudioProperties::getNbChannels() const { if( ! _codecContext ) throw std::runtime_error( "unknown codec context" ); @@ -136,7 +136,7 @@ size_t AudioProperties::getNbSamples() const throw std::runtime_error( "unknown format context" ); size_t nbSamples = _formatContext->streams[_streamIndex]->nb_frames; if(nbSamples == 0) - nbSamples = getSampleRate() * getChannels() * getDuration(); + nbSamples = getSampleRate() * getNbChannels() * getDuration(); return nbSamples; } @@ -160,7 +160,7 @@ PropertyVector AudioProperties::getPropertiesAsVector() const addProperty( data, "sampleRate", &AudioProperties::getSampleRate ); addProperty( data, "bitRate", &AudioProperties::getBitRate ); addProperty( data, "nbSamples", &AudioProperties::getNbSamples ); - addProperty( data, "channels", &AudioProperties::getChannels ); + addProperty( data, "nbChannels", &AudioProperties::getNbChannels ); addProperty( data, "channelLayout", &AudioProperties::getChannelLayout ); addProperty( data, "channelName", &AudioProperties::getChannelName ); addProperty( data, "channelDescription", &AudioProperties::getChannelDescription ); diff --git a/src/AvTranscoder/mediaProperty/AudioProperties.hpp b/src/AvTranscoder/mediaProperty/AudioProperties.hpp index e6e8a1d4..f4e62521 100644 --- a/src/AvTranscoder/mediaProperty/AudioProperties.hpp +++ b/src/AvTranscoder/mediaProperty/AudioProperties.hpp @@ -20,7 +20,7 @@ class AvExport AudioProperties : public StreamProperties std::string getChannelDescription() const; size_t getSampleRate() const; - size_t getChannels() const; + size_t getNbChannels() const; size_t getBitRate() const; ///< 0 if unknown size_t getNbSamples() const; diff --git a/src/AvTranscoder/transcoder/Transcoder.cpp b/src/AvTranscoder/transcoder/Transcoder.cpp index 5f1ae685..6c178cbf 100644 --- a/src/AvTranscoder/transcoder/Transcoder.cpp +++ b/src/AvTranscoder/transcoder/Transcoder.cpp @@ -428,7 +428,7 @@ ProfileLoader::Profile Transcoder::getProfileFromFile( InputFile& inputFile, con ss << audioProperties->getSampleRate(); profile[ constants::avProfileSampleRate ] = ss.str(); ss.str( "" ); - ss << audioProperties->getChannels(); + ss << audioProperties->getNbChannels(); profile[ constants::avProfileChannel ] = ss.str(); } From db709eb9dbd38707a300c8c1d2ad727053fdb5fd Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 1 Dec 2015 14:25:16 +0100 Subject: [PATCH 23/46] decoders: renamed 'subStreamIndex' parameter to 'channelIndex' --- src/AvTranscoder/decoder/AudioDecoder.cpp | 6 +++--- src/AvTranscoder/decoder/AudioDecoder.hpp | 2 +- src/AvTranscoder/decoder/IDecoder.hpp | 4 ++-- src/AvTranscoder/decoder/VideoDecoder.cpp | 2 +- src/AvTranscoder/decoder/VideoDecoder.hpp | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/AvTranscoder/decoder/AudioDecoder.cpp b/src/AvTranscoder/decoder/AudioDecoder.cpp index 346ce765..df0495b3 100644 --- a/src/AvTranscoder/decoder/AudioDecoder.cpp +++ b/src/AvTranscoder/decoder/AudioDecoder.cpp @@ -124,7 +124,7 @@ bool AudioDecoder::decodeNextFrame( Frame& frameBuffer ) return true; } -bool AudioDecoder::decodeNextFrame( Frame& frameBuffer, const size_t subStreamIndex ) +bool AudioDecoder::decodeNextFrame( Frame& frameBuffer, const size_t channelIndex ) { if( ! decodeNextFrame() ) return false; @@ -138,7 +138,7 @@ bool AudioDecoder::decodeNextFrame( Frame& frameBuffer, const size_t subStreamIn size_t nbSubStreams = avCodecContext.channels; size_t bytePerSample = av_get_bytes_per_sample( (AVSampleFormat)_frame->format ); - if( subStreamIndex > nbSubStreams - 1 ) + if( channelIndex > nbSubStreams - 1 ) { throw std::runtime_error( "The subStream doesn't exist"); } @@ -155,7 +155,7 @@ bool AudioDecoder::decodeNextFrame( Frame& frameBuffer, const size_t subStreamIn unsigned char* dst = audioBuffer.getData(); // offset - src += subStreamIndex * bytePerSample; + src += channelIndex * bytePerSample; for( int sample = 0; sample < _frame->nb_samples; ++sample ) { diff --git a/src/AvTranscoder/decoder/AudioDecoder.hpp b/src/AvTranscoder/decoder/AudioDecoder.hpp index 973fd7ea..ce8b7d49 100644 --- a/src/AvTranscoder/decoder/AudioDecoder.hpp +++ b/src/AvTranscoder/decoder/AudioDecoder.hpp @@ -19,7 +19,7 @@ class AvExport AudioDecoder : public IDecoder void setupDecoder( const ProfileLoader::Profile& profile = ProfileLoader::Profile() ); bool decodeNextFrame( Frame& frameBuffer ); - bool decodeNextFrame( Frame& frameBuffer, const size_t subStreamIndex ); + bool decodeNextFrame( Frame& frameBuffer, const size_t channelIndex ); void flushDecoder(); diff --git a/src/AvTranscoder/decoder/IDecoder.hpp b/src/AvTranscoder/decoder/IDecoder.hpp index 3b65fe47..ca970c81 100644 --- a/src/AvTranscoder/decoder/IDecoder.hpp +++ b/src/AvTranscoder/decoder/IDecoder.hpp @@ -30,10 +30,10 @@ class AvExport IDecoder /** * @brief Decode substream of next frame * @param frameBuffer: the frame decoded - * @param subStreamIndex: index of substream to extract + * @param channelIndex: index of channel to extract * @return status of decoding */ - virtual bool decodeNextFrame( Frame& frameBuffer, const size_t subStreamIndex ) = 0; + virtual bool decodeNextFrame( Frame& frameBuffer, const size_t channelIndex ) = 0; /** * @brief Set the next frame of the input stream (which bypass the work of decoding) diff --git a/src/AvTranscoder/decoder/VideoDecoder.cpp b/src/AvTranscoder/decoder/VideoDecoder.cpp index ae54d737..6b7621cb 100644 --- a/src/AvTranscoder/decoder/VideoDecoder.cpp +++ b/src/AvTranscoder/decoder/VideoDecoder.cpp @@ -116,7 +116,7 @@ bool VideoDecoder::decodeNextFrame( Frame& frameBuffer ) return true; } -bool VideoDecoder::decodeNextFrame( Frame& frameBuffer, const size_t subStreamIndex ) +bool VideoDecoder::decodeNextFrame( Frame& frameBuffer, const size_t channelIndex ) { return false; } diff --git a/src/AvTranscoder/decoder/VideoDecoder.hpp b/src/AvTranscoder/decoder/VideoDecoder.hpp index e82ed011..4a8f4200 100644 --- a/src/AvTranscoder/decoder/VideoDecoder.hpp +++ b/src/AvTranscoder/decoder/VideoDecoder.hpp @@ -19,7 +19,7 @@ class AvExport VideoDecoder : public IDecoder void setupDecoder( const ProfileLoader::Profile& profile = ProfileLoader::Profile() ); bool decodeNextFrame( Frame& frameBuffer ); - bool decodeNextFrame( Frame& frameBuffer, const size_t subStreamIndex ); + bool decodeNextFrame( Frame& frameBuffer, const size_t channelIndex ); void flushDecoder(); From 1e2123cb97716fa98de9a3c85de49af2aa172981 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 1 Dec 2015 14:26:48 +0100 Subject: [PATCH 24/46] AudioDecoder: refactore decodeNextFrame methods * Added const to local variables when it's possible. * Renamed several local variables. --- src/AvTranscoder/decoder/AudioDecoder.cpp | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/src/AvTranscoder/decoder/AudioDecoder.cpp b/src/AvTranscoder/decoder/AudioDecoder.cpp index df0495b3..5f3060ab 100644 --- a/src/AvTranscoder/decoder/AudioDecoder.cpp +++ b/src/AvTranscoder/decoder/AudioDecoder.cpp @@ -107,7 +107,8 @@ bool AudioDecoder::decodeNextFrame( Frame& frameBuffer ) AVCodecContext& avCodecContext = _inputStream->getAudioCodec().getAVCodecContext(); - size_t decodedSize = av_samples_get_buffer_size( NULL, avCodecContext.channels, _frame->nb_samples, avCodecContext.sample_fmt, 1 ); + const int noAlignment = 1; + const size_t decodedSize = av_samples_get_buffer_size( NULL, avCodecContext.channels, _frame->nb_samples, avCodecContext.sample_fmt, noAlignment ); if( decodedSize == 0 ) return false; @@ -130,22 +131,20 @@ bool AudioDecoder::decodeNextFrame( Frame& frameBuffer, const size_t channelInde return false; AVCodecContext& avCodecContext = _inputStream->getAudioCodec().getAVCodecContext(); + const size_t srcNbChannels = avCodecContext.channels; + const size_t bytePerSample = av_get_bytes_per_sample( (AVSampleFormat)_frame->format ); - const int output_nbChannels = 1; - const int output_align = 1; - size_t decodedSize = av_samples_get_buffer_size(NULL, output_nbChannels, _frame->nb_samples, avCodecContext.sample_fmt, output_align); - - size_t nbSubStreams = avCodecContext.channels; - size_t bytePerSample = av_get_bytes_per_sample( (AVSampleFormat)_frame->format ); + const int dstNbChannels = 1; + const int noAlignment = 1; + const size_t decodedSize = av_samples_get_buffer_size(NULL, dstNbChannels, _frame->nb_samples, avCodecContext.sample_fmt, noAlignment); + if( decodedSize == 0 ) + return false; - if( channelIndex > nbSubStreams - 1 ) + if( channelIndex > srcNbChannels - 1 ) { throw std::runtime_error( "The subStream doesn't exist"); } - if( decodedSize == 0 ) - return false; - AudioFrame& audioBuffer = static_cast( frameBuffer ); audioBuffer.setNbSamples( _frame->nb_samples ); audioBuffer.resize( decodedSize ); @@ -161,7 +160,7 @@ bool AudioDecoder::decodeNextFrame( Frame& frameBuffer, const size_t channelInde { memcpy( dst, src, bytePerSample ); dst += bytePerSample; - src += bytePerSample * nbSubStreams; + src += bytePerSample * srcNbChannels; } return true; From 0f415e730f6a50ff46c246ea2ed43080d9533e33 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 1 Dec 2015 14:32:05 +0100 Subject: [PATCH 25/46] AudioDecoder: improved exception message when decodeNextFrame and the specified channel does not exist --- src/AvTranscoder/decoder/AudioDecoder.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/AvTranscoder/decoder/AudioDecoder.cpp b/src/AvTranscoder/decoder/AudioDecoder.cpp index 5f3060ab..2000652c 100644 --- a/src/AvTranscoder/decoder/AudioDecoder.cpp +++ b/src/AvTranscoder/decoder/AudioDecoder.cpp @@ -13,6 +13,7 @@ extern "C" { } #include +#include namespace avtranscoder { @@ -142,7 +143,13 @@ bool AudioDecoder::decodeNextFrame( Frame& frameBuffer, const size_t channelInde if( channelIndex > srcNbChannels - 1 ) { - throw std::runtime_error( "The subStream doesn't exist"); + std::stringstream msg; + msg << "The channel at index "; + msg << channelIndex; + msg << " doesn't exist (srcNbChannels = "; + msg << srcNbChannels; + msg << ")."; + throw std::runtime_error( msg.str() ); } AudioFrame& audioBuffer = static_cast( frameBuffer ); From 3a7a040e54f4e3e32f27f0958b0e862b86362300 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 1 Dec 2015 14:37:15 +0100 Subject: [PATCH 26/46] VideoTransform: log video conversion as info Previously debug. --- src/AvTranscoder/transform/VideoTransform.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/AvTranscoder/transform/VideoTransform.cpp b/src/AvTranscoder/transform/VideoTransform.cpp index 6b6452bf..384817b2 100644 --- a/src/AvTranscoder/transform/VideoTransform.cpp +++ b/src/AvTranscoder/transform/VideoTransform.cpp @@ -63,13 +63,13 @@ bool VideoTransform::init( const Frame& srcFrame, const Frame& dstFrame ) const char* dstPixFmt; dstPixFmt = av_get_pix_fmt_name( dstPixelFormat ); - LOG_DEBUG( "Video conversion from " << ( srcPixFmt != NULL ? srcPixFmt : "None" ) << " to " << ( dstPixFmt != NULL ? dstPixFmt : "None" ) ) - - LOG_DEBUG( "Source, width = " << src.desc().getWidth() ) - LOG_DEBUG( "Source, height = " << src.desc().getHeight() ) - - LOG_DEBUG( "Destination, width = " << dst.desc().getWidth() ) - LOG_DEBUG( "Destination, height = " << dst.desc().getHeight() ) + std::stringstream msg; + msg << "Video conversion from " << ( srcPixFmt != NULL ? srcPixFmt : "None" ) << " to " << ( dstPixFmt != NULL ? dstPixFmt : "None" ) << std::endl; + msg << "Source, width = " << src.desc().getWidth() << std::endl; + msg << "Source, height = " << src.desc().getHeight() << std::endl; + msg << "Destination, width = " << dst.desc().getWidth() << std::endl; + msg << "Destination, height = " << dst.desc().getHeight() << std::endl; + LOG_INFO( msg.str() ) return true; } From e3beddffa5d6fa7337f21e62d34e66d9ab836d16 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 1 Dec 2015 17:52:51 +0100 Subject: [PATCH 27/46] AudioTransform: added log of audio conversion as info --- src/AvTranscoder/transform/AudioTransform.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/AvTranscoder/transform/AudioTransform.cpp b/src/AvTranscoder/transform/AudioTransform.cpp index 3a8b682e..1501e708 100644 --- a/src/AvTranscoder/transform/AudioTransform.cpp +++ b/src/AvTranscoder/transform/AudioTransform.cpp @@ -26,6 +26,7 @@ extern "C" { } #include +#include namespace avtranscoder { @@ -73,6 +74,14 @@ bool AudioTransform::init( const Frame& srcFrame, const Frame& dstFrame ) msg << "out_sample_fmt " << dst.desc().getSampleFormat() << std::endl; throw std::runtime_error( msg.str() ); } + + std::stringstream msg; + msg << "Audio conversion from " << src.desc().getSampleFormatName() << " to " << dst.desc().getSampleFormatName() << std::endl; + msg << "Source, number of channels = " << src.desc().getChannels() << std::endl; + msg << "Source, sample rate = " << src.desc().getSampleRate() << std::endl; + msg << "Destination, number of channels = " << dst.desc().getChannels() << std::endl; + msg << "Destination, sample rate = " << dst.desc().getSampleRate() << std::endl; + LOG_INFO( msg.str() ) return true; } From 2cbc5eb397b5d783600b6b1f1b133def0ae3e6ae Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 1 Dec 2015 18:29:53 +0100 Subject: [PATCH 28/46] pyTest: fix tests - renamed getChannels to getNbChannels --- test/pyTest/testOffset.py | 6 +++--- test/pyTest/testProperties.py | 2 +- test/pyTest/testSetFrame.py | 2 +- test/pyTest/testTranscoderTranscodeAudioWave.py | 8 ++++---- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/test/pyTest/testOffset.py b/test/pyTest/testOffset.py index d38ae677..8e9128bf 100644 --- a/test/pyTest/testOffset.py +++ b/test/pyTest/testOffset.py @@ -103,7 +103,7 @@ def testRewrapAudioPositiveOffset(): # check output duration assert_equals( src_audioStream.getDuration() + offset, dst_audioStream.getDuration() ) - assert_equals( src_audioStream.getNbSamples() + ( offset * dst_audioStream.getSampleRate() * dst_audioStream.getChannels() ), dst_audioStream.getNbSamples() ) + assert_equals( src_audioStream.getNbSamples() + ( offset * dst_audioStream.getSampleRate() * dst_audioStream.getNbChannels() ), dst_audioStream.getNbSamples() ) def testRewrapAudioNegativeOffset(): @@ -134,7 +134,7 @@ def testRewrapAudioNegativeOffset(): # check output duration assert_equals( src_audioStream.getDuration() + offset, dst_audioStream.getDuration() ) - assert_equals( src_audioStream.getNbSamples() + ( offset * dst_audioStream.getSampleRate() * dst_audioStream.getChannels() ), dst_audioStream.getNbSamples() ) + assert_equals( src_audioStream.getNbSamples() + ( offset * dst_audioStream.getSampleRate() * dst_audioStream.getNbChannels() ), dst_audioStream.getNbSamples() ) def testTranscodeVideoPositiveOffset(): @@ -295,7 +295,7 @@ def testMultipleOffsetFromSameInputFile(): assert_equals( src_videoStream.getDuration() + offset_1, dst_videoStream.getDuration() ) assert_equals( src_videoStream.getNbFrames() + ( offset_1 * dst_videoStream.getFps() ), dst_videoStream.getNbFrames() ) assert_equals( src_audioStream.getDuration() + offset_1, dst_audioStream.getDuration() ) - assert_equals( src_audioStream.getNbSamples() + ( offset_1 * dst_audioStream.getSampleRate() * dst_audioStream.getChannels() ), dst_audioStream.getNbSamples() ) + assert_equals( src_audioStream.getNbSamples() + ( offset_1 * dst_audioStream.getSampleRate() * dst_audioStream.getNbChannels() ), dst_audioStream.getNbSamples() ) def testMultipleOffsetFromSameStream(): diff --git a/test/pyTest/testProperties.py b/test/pyTest/testProperties.py index 3cc5cd19..5e735345 100644 --- a/test/pyTest/testProperties.py +++ b/test/pyTest/testProperties.py @@ -120,6 +120,6 @@ def testCheckAudioProperties(): assert_equals( audioStream.getCodecName(), expectedCodecName ) assert_equals( audioStream.getNbSamples(), expectedSamples ) assert_equals( round(audioStream.getDuration(), 2), expectedDuration ) - assert_equals( audioStream.getChannels(), expectedChannels ) + assert_equals( audioStream.getNbChannels(), expectedChannels ) assert_equals( audioStream.getChannelLayout(), expectedChannelLayout ) assert_equals( audioStream.getSampleRate(), expectedSampleRate ) \ No newline at end of file diff --git a/test/pyTest/testSetFrame.py b/test/pyTest/testSetFrame.py index 5b8c01af..dce017ef 100644 --- a/test/pyTest/testSetFrame.py +++ b/test/pyTest/testSetFrame.py @@ -106,5 +106,5 @@ def testSetAudioFrame(): assert_equals( "s32", dst_audioStream.getSampleFormatName() ) assert_equals( "signed 32 bits", dst_audioStream.getSampleFormatLongName() ) assert_equals( 48000, dst_audioStream.getSampleRate() ) - assert_equals( 1, dst_audioStream.getChannels() ) + assert_equals( 1, dst_audioStream.getNbChannels() ) diff --git a/test/pyTest/testTranscoderTranscodeAudioWave.py b/test/pyTest/testTranscoderTranscodeAudioWave.py index e268e9f6..5839a19d 100644 --- a/test/pyTest/testTranscoderTranscodeAudioWave.py +++ b/test/pyTest/testTranscoderTranscodeAudioWave.py @@ -36,7 +36,7 @@ def testTranscodeWave24b48k5_1(): assert_equals( "s32", dst_audioStream.getSampleFormatName() ) assert_equals( "signed 32 bits", dst_audioStream.getSampleFormatLongName() ) assert_equals( 48000, dst_audioStream.getSampleRate() ) - assert_equals( 6, dst_audioStream.getChannels() ) + assert_equals( 6, dst_audioStream.getNbChannels() ) def testTranscodeWave24b48kstereo(): """ @@ -64,7 +64,7 @@ def testTranscodeWave24b48kstereo(): assert_equals( "s32", dst_audioStream.getSampleFormatName() ) assert_equals( "signed 32 bits", dst_audioStream.getSampleFormatLongName() ) assert_equals( 48000, dst_audioStream.getSampleRate() ) - assert_equals( 2, dst_audioStream.getChannels() ) + assert_equals( 2, dst_audioStream.getNbChannels() ) def testTranscodeWave24b48kmono(): """ @@ -92,7 +92,7 @@ def testTranscodeWave24b48kmono(): assert_equals( "s32", dst_audioStream.getSampleFormatName() ) assert_equals( "signed 32 bits", dst_audioStream.getSampleFormatLongName() ) assert_equals( 48000, dst_audioStream.getSampleRate() ) - assert_equals( 1, dst_audioStream.getChannels() ) + assert_equals( 1, dst_audioStream.getNbChannels() ) def testTranscodeWave16b48kmono(): """ @@ -120,4 +120,4 @@ def testTranscodeWave16b48kmono(): assert_equals( "s16", dst_audioStream.getSampleFormatName() ) assert_equals( "signed 16 bits", dst_audioStream.getSampleFormatLongName() ) assert_equals( 48000, dst_audioStream.getSampleRate() ) - assert_equals( 1, dst_audioStream.getChannels() ) + assert_equals( 1, dst_audioStream.getNbChannels() ) From 1a635be9c06a3b0aa3a265c31b4c3c373646cb02 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Wed, 2 Dec 2015 11:39:09 +0100 Subject: [PATCH 29/46] readers: return an empty frame when there is nothing to decode EOF or error in the decoding process. --- src/AvTranscoder/reader/IReader.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/AvTranscoder/reader/IReader.cpp b/src/AvTranscoder/reader/IReader.cpp index 6530f80e..f466d9e2 100644 --- a/src/AvTranscoder/reader/IReader.cpp +++ b/src/AvTranscoder/reader/IReader.cpp @@ -64,13 +64,18 @@ Frame* IReader::readFrameAt( const size_t frame ) } _currentFrame = frame; // decode + bool decodingStatus = false; if( _channelIndex != -1 ) - _decoder->decodeNextFrame( *_srcFrame, _channelIndex ); + decodingStatus = _decoder->decodeNextFrame( *_srcFrame, _channelIndex ); else - _decoder->decodeNextFrame( *_srcFrame ); + decodingStatus = _decoder->decodeNextFrame( *_srcFrame ); + if( ! decodingStatus ) + { + _dstFrame->clear(); + return _dstFrame; + } // transform _transform->convert( *_srcFrame, *_dstFrame ); - // return buffer return _dstFrame; } From 0c3bf14e142ad4ba7dd6e3dbcda51b80cb71764d Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Wed, 2 Dec 2015 11:43:07 +0100 Subject: [PATCH 30/46] AudioReader: fix nbChannels of output when extract one channel No need to call updateOutput AudioReader::method when specify a channelIndex in constructor. --- src/AvTranscoder/reader/AudioReader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AvTranscoder/reader/AudioReader.cpp b/src/AvTranscoder/reader/AudioReader.cpp index 51dd32bf..fa8d49ae 100644 --- a/src/AvTranscoder/reader/AudioReader.cpp +++ b/src/AvTranscoder/reader/AudioReader.cpp @@ -49,7 +49,7 @@ void AudioReader::init() AudioFrame* srcFrame = static_cast(_srcFrame); // create dst frame _outputSampleRate = srcFrame->desc().getSampleRate(); - _outputNbChannels = srcFrame->desc().getChannels(); + _outputNbChannels = (_channelIndex == -1) ? srcFrame->desc().getChannels() : 1; _dstFrame = new AudioFrame( AudioFrameDesc( _outputSampleRate, _outputNbChannels, _outputSampleFormat ) ); } From f2cc0ca1b72a7f193911ededed7c4a7a8e4c552f Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Wed, 2 Dec 2015 11:48:08 +0100 Subject: [PATCH 31/46] pyTest: added pyTest to check readers --- test/pyTest/testReader.py | 76 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 test/pyTest/testReader.py diff --git a/test/pyTest/testReader.py b/test/pyTest/testReader.py new file mode 100644 index 00000000..7a26a9a1 --- /dev/null +++ b/test/pyTest/testReader.py @@ -0,0 +1,76 @@ +import os + +# Check if environment is setup to run the tests +if os.environ.get('AVTRANSCODER_TEST_VIDEO_AVI_FILE') is None or \ + os.environ.get('AVTRANSCODER_TEST_AUDIO_WAVE_FILE') is None: + from nose.plugins.skip import SkipTest + raise SkipTest("Need to define environment variables " + "AVTRANSCODER_TEST_VIDEO_AVI_FILE and " + "AVTRANSCODER_TEST_AUDIO_WAVE_FILE") + +from nose.tools import * + +from pyAvTranscoder import avtranscoder as av + + +def testVideoReaderCreateNewInputFile(): + """ + Read a video stream with the VideoReader. + The InputFile is created inside the reader. + """ + inputFileName = os.environ['AVTRANSCODER_TEST_VIDEO_AVI_FILE'] + reader = av.VideoReader(inputFileName) + + # read all frames and check their size + for i in xrange(0, reader.getSourceVideoProperties().getNbFrames()): + frame = reader.readNextFrame() + assert_equals( frame.getSize(), reader.getOutputWidth() * reader.getOutputHeight() * reader.getOutputNbComponents() ) + + # check if the next frame is empty + frame = reader.readNextFrame() + assert_equals( frame.getSize(), 0 ) + + +def testVideoReaderReferenceInputFile(): + """ + Read a video stream with the VideoReader. + The InputFile is a reference for the reader. + """ + inputFileName = os.environ['AVTRANSCODER_TEST_VIDEO_AVI_FILE'] + inputFile = av.InputFile(inputFileName) + reader = av.VideoReader(inputFile) + + # read all frames and check their size + for i in xrange(0, reader.getSourceVideoProperties().getNbFrames()): + frame = reader.readNextFrame() + assert_equals( frame.getSize(), reader.getOutputWidth() * reader.getOutputHeight() * reader.getOutputNbComponents() ) + + # check if the next frame is empty + frame = reader.readNextFrame() + assert_equals( frame.getSize(), 0 ) + + +def testAudioReaderChannelsExtraction(): + """ + Read the same audio stream with several AudioReaders. + Compare decoded frames from reader of all channels, and of one channel. + """ + inputFileName = os.environ['AVTRANSCODER_TEST_AUDIO_WAVE_FILE'] + inputFile = av.InputFile(inputFileName) + streamIndex = inputFile.getProperties().getAudioProperties()[0].getStreamIndex() + channelIndex = 0 + + # create reader to read all channels of the audio stream + readerOfAllChannels = av.AudioReader(inputFile, streamIndex) + nbChannels = readerOfAllChannels.getOutputNbChannels() + # read first frame + frame = readerOfAllChannels.readNextFrame() + sizeOfFrameWithAllChannels = frame.getSize() + + # create reader to read one channel of the audio stream + readerOfOneChannel = av.AudioReader(inputFile, streamIndex, channelIndex) + # read first frame + frame = readerOfOneChannel.readNextFrame() + sizeOfFrameWithOneChannels = frame.getSize() + + assert_equals( sizeOfFrameWithAllChannels / nbChannels, sizeOfFrameWithOneChannels ) From 34bb99ebaa1d4c23fbe3a8b3d236083d3d7f77e1 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 12 Jan 2016 13:49:52 +0100 Subject: [PATCH 32/46] AudioFrame: renamed get/setChannels to get/setNbChannels --- src/AvTranscoder/codec/AudioCodec.cpp | 2 +- src/AvTranscoder/frame/AudioFrame.cpp | 2 +- src/AvTranscoder/frame/AudioFrame.hpp | 4 ++-- src/AvTranscoder/reader/AudioReader.cpp | 2 +- src/AvTranscoder/transcoder/StreamTranscoder.cpp | 4 ++-- src/AvTranscoder/transform/AudioTransform.cpp | 14 +++++++------- 6 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/AvTranscoder/codec/AudioCodec.cpp b/src/AvTranscoder/codec/AudioCodec.cpp index 4cbec76d..42acc1fb 100644 --- a/src/AvTranscoder/codec/AudioCodec.cpp +++ b/src/AvTranscoder/codec/AudioCodec.cpp @@ -31,7 +31,7 @@ AudioFrameDesc AudioCodec::getAudioFrameDesc() const void AudioCodec::setAudioParameters(const AudioFrameDesc& audioFrameDesc) { _avCodecContext->sample_rate = audioFrameDesc.getSampleRate(); - _avCodecContext->channels = audioFrameDesc.getChannels(); + _avCodecContext->channels = audioFrameDesc.getNbChannels(); _avCodecContext->sample_fmt = audioFrameDesc.getSampleFormat(); } } diff --git a/src/AvTranscoder/frame/AudioFrame.cpp b/src/AvTranscoder/frame/AudioFrame.cpp index 8375e81a..88a83f87 100644 --- a/src/AvTranscoder/frame/AudioFrame.cpp +++ b/src/AvTranscoder/frame/AudioFrame.cpp @@ -60,7 +60,7 @@ void AudioFrameDesc::setParameters(const ProfileLoader::Profile& profile) setSampleRate(atoi(profile.find(constants::avProfileSampleRate)->second.c_str())); // channel if(profile.count(constants::avProfileChannel)) - setChannels(atoi(profile.find(constants::avProfileChannel)->second.c_str())); + setNbChannels(atoi(profile.find(constants::avProfileChannel)->second.c_str())); // sample format if(profile.count(constants::avProfileSampleFormat)) setSampleFormat(profile.find(constants::avProfileSampleFormat)->second); diff --git a/src/AvTranscoder/frame/AudioFrame.hpp b/src/AvTranscoder/frame/AudioFrame.hpp index e39b02ed..b37c6c2b 100644 --- a/src/AvTranscoder/frame/AudioFrame.hpp +++ b/src/AvTranscoder/frame/AudioFrame.hpp @@ -21,7 +21,7 @@ class AvExport AudioFrameDesc AudioFrameDesc(const size_t sampleRate, const size_t channels, const std::string& sampleFormat); size_t getSampleRate() const { return _sampleRate; } - size_t getChannels() const { return _channels; } + size_t getNbChannels() const { return _channels; } AVSampleFormat getSampleFormat() const { return _sampleFormat; } std::string getSampleFormatName() const; double getFps() const { return _fps; } @@ -29,7 +29,7 @@ class AvExport AudioFrameDesc size_t getDataSize() const; void setSampleRate(const size_t sampleRate) { _sampleRate = sampleRate; } - void setChannels(const size_t channels) { _channels = channels; } + void setNbChannels(const size_t channels) { _channels = channels; } void setSampleFormat(const std::string& sampleFormatName); void setSampleFormat(const AVSampleFormat sampleFormat) { _sampleFormat = sampleFormat; } void setFps(const double fps) { _fps = fps; } diff --git a/src/AvTranscoder/reader/AudioReader.cpp b/src/AvTranscoder/reader/AudioReader.cpp index 37a98d3b..8ace54f9 100644 --- a/src/AvTranscoder/reader/AudioReader.cpp +++ b/src/AvTranscoder/reader/AudioReader.cpp @@ -49,7 +49,7 @@ void AudioReader::init() AudioFrame* srcFrame = static_cast(_srcFrame); // create dst frame _outputSampleRate = srcFrame->desc().getSampleRate(); - _outputNbChannels = (_channelIndex == -1) ? srcFrame->desc().getChannels() : 1; + _outputNbChannels = (_channelIndex == -1) ? srcFrame->desc().getNbChannels() : 1; _dstFrame = new AudioFrame(AudioFrameDesc(_outputSampleRate, _outputNbChannels, _outputSampleFormat)); } diff --git a/src/AvTranscoder/transcoder/StreamTranscoder.cpp b/src/AvTranscoder/transcoder/StreamTranscoder.cpp index 5133e9bd..c7d90332 100644 --- a/src/AvTranscoder/transcoder/StreamTranscoder.cpp +++ b/src/AvTranscoder/transcoder/StreamTranscoder.cpp @@ -186,7 +186,7 @@ StreamTranscoder::StreamTranscoder(IInputStream& inputStream, IOutputFile& outpu if(subStreamIndex > -1) { // @todo manage downmix ? - outputFrameDesc.setChannels(1); + outputFrameDesc.setNbChannels(1); } outputAudio->setupAudioEncoder(outputFrameDesc, profile); @@ -196,7 +196,7 @@ StreamTranscoder::StreamTranscoder(IInputStream& inputStream, IOutputFile& outpu // buffers to process AudioFrameDesc inputFrameDesc(_inputStream->getAudioCodec().getAudioFrameDesc()); if(subStreamIndex > -1) - inputFrameDesc.setChannels(1); + inputFrameDesc.setNbChannels(1); _sourceBuffer = new AudioFrame(inputFrameDesc); _frameBuffer = new AudioFrame(outputAudio->getAudioCodec().getAudioFrameDesc()); diff --git a/src/AvTranscoder/transform/AudioTransform.cpp b/src/AvTranscoder/transform/AudioTransform.cpp index 11b2106b..029daa7f 100644 --- a/src/AvTranscoder/transform/AudioTransform.cpp +++ b/src/AvTranscoder/transform/AudioTransform.cpp @@ -54,8 +54,8 @@ bool AudioTransform::init(const Frame& srcFrame, const Frame& dstFrame) const AudioFrame& src = static_cast(srcFrame); const AudioFrame& dst = static_cast(dstFrame); - av_opt_set_int(_audioConvertContext, "in_channel_layout", av_get_default_channel_layout(src.desc().getChannels()), 0); - av_opt_set_int(_audioConvertContext, "out_channel_layout", av_get_default_channel_layout(dst.desc().getChannels()), 0); + av_opt_set_int(_audioConvertContext, "in_channel_layout", av_get_default_channel_layout(src.desc().getNbChannels()), 0); + av_opt_set_int(_audioConvertContext, "out_channel_layout", av_get_default_channel_layout(dst.desc().getNbChannels()), 0); av_opt_set_int(_audioConvertContext, "in_sample_rate", src.desc().getSampleRate(), 0); av_opt_set_int(_audioConvertContext, "out_sample_rate", dst.desc().getSampleRate(), 0); SetSampleFormat(_audioConvertContext, "in_sample_fmt", src.desc().getSampleFormat(), 0); @@ -66,8 +66,8 @@ bool AudioTransform::init(const Frame& srcFrame, const Frame& dstFrame) FreeResampleContext(&_audioConvertContext); std::stringstream msg; msg << "Unable to open audio convert context:" << std::endl; - msg << "in_channel_layout " << av_get_default_channel_layout(src.desc().getChannels()) << std::endl; - msg << "out_channel_layout " << av_get_default_channel_layout(dst.desc().getChannels()) << std::endl; + msg << "in_channel_layout " << av_get_default_channel_layout(src.desc().getNbChannels()) << std::endl; + msg << "out_channel_layout " << av_get_default_channel_layout(dst.desc().getNbChannels()) << std::endl; msg << "in_sample_rate " << src.desc().getSampleRate() << std::endl; msg << "out_sample_rate " << dst.desc().getSampleRate() << std::endl; msg << "in_sample_fmt " << src.desc().getSampleFormat() << std::endl; @@ -78,9 +78,9 @@ bool AudioTransform::init(const Frame& srcFrame, const Frame& dstFrame) std::stringstream msg; msg << "Audio conversion from " << src.desc().getSampleFormatName() << " to " << dst.desc().getSampleFormatName() << std::endl; - msg << "Source, number of channels = " << src.desc().getChannels() << std::endl; + msg << "Source, number of channels = " << src.desc().getNbChannels() << std::endl; msg << "Source, sample rate = " << src.desc().getSampleRate() << std::endl; - msg << "Destination, number of channels = " << dst.desc().getChannels() << std::endl; + msg << "Destination, number of channels = " << dst.desc().getNbChannels() << std::endl; msg << "Destination, sample rate = " << dst.desc().getSampleRate() << std::endl; LOG_INFO(msg.str()) @@ -93,7 +93,7 @@ void AudioTransform::updateOutputFrame(const size_t nbInputSamples, Frame& dstFr // resize buffer of output frame const int dstSampleSize = av_get_bytes_per_sample(dst.desc().getSampleFormat()); - const size_t bufferSizeNeeded = nbInputSamples * dst.desc().getChannels() * dstSampleSize; + const size_t bufferSizeNeeded = nbInputSamples * dst.desc().getNbChannels() * dstSampleSize; dstFrame.resize(bufferSizeNeeded); // set nbSamples of output frame From f1ad8db432ea82dc755bb6a4cdbf7880fb800de9 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 12 Jan 2016 15:12:32 +0100 Subject: [PATCH 33/46] AudioFrame: renamed get/setNbSamples to get/setNbSamplesPerChannel --- src/AvTranscoder/decoder/AudioDecoder.cpp | 4 ++-- src/AvTranscoder/decoder/AudioGenerator.cpp | 4 ++-- src/AvTranscoder/encoder/AudioEncoder.cpp | 2 +- src/AvTranscoder/frame/AudioFrame.hpp | 4 ++-- src/AvTranscoder/transform/AudioTransform.cpp | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/AvTranscoder/decoder/AudioDecoder.cpp b/src/AvTranscoder/decoder/AudioDecoder.cpp index 91068f27..88c6432b 100644 --- a/src/AvTranscoder/decoder/AudioDecoder.cpp +++ b/src/AvTranscoder/decoder/AudioDecoder.cpp @@ -112,7 +112,7 @@ bool AudioDecoder::decodeNextFrame(Frame& frameBuffer) return false; AudioFrame& audioBuffer = static_cast(frameBuffer); - audioBuffer.setNbSamples(_frame->nb_samples); + audioBuffer.setNbSamplesPerChannel(_frame->nb_samples); audioBuffer.resize(decodedSize); // @todo manage cases with data of frame not only on data[0] (use _frame.linesize) @@ -152,7 +152,7 @@ bool AudioDecoder::decodeNextFrame(Frame& frameBuffer, const size_t channelIndex } AudioFrame& audioBuffer = static_cast(frameBuffer); - audioBuffer.setNbSamples(_frame->nb_samples); + audioBuffer.setNbSamplesPerChannel(_frame->nb_samples); audioBuffer.resize(decodedSize); // @todo manage cases with data of frame not only on data[0] (use _frame.linesize) diff --git a/src/AvTranscoder/decoder/AudioGenerator.cpp b/src/AvTranscoder/decoder/AudioGenerator.cpp index 588064aa..eae58331 100644 --- a/src/AvTranscoder/decoder/AudioGenerator.cpp +++ b/src/AvTranscoder/decoder/AudioGenerator.cpp @@ -47,7 +47,7 @@ bool AudioGenerator::decodeNextFrame(Frame& frameBuffer) if(!_inputFrame) { AudioFrame& audioBuffer = static_cast(frameBuffer); - audioBuffer.setNbSamples(_frameDesc.getSampleRate() / _frameDesc.getFps()); + audioBuffer.setNbSamplesPerChannel(_frameDesc.getSampleRate() / _frameDesc.getFps()); // Generate the silent only once if(!_silent) @@ -56,7 +56,7 @@ bool AudioGenerator::decodeNextFrame(Frame& frameBuffer) _silent = new AudioFrame(audioBuffer.desc()); _silent->assign(_frameDesc.getDataSize(), fillChar); - _silent->setNbSamples(audioBuffer.getNbSamples()); + _silent->setNbSamplesPerChannel(audioBuffer.getNbSamplesPerChannel()); } frameBuffer.refData(*_silent); } diff --git a/src/AvTranscoder/encoder/AudioEncoder.cpp b/src/AvTranscoder/encoder/AudioEncoder.cpp index 69f21311..3cc17563 100644 --- a/src/AvTranscoder/encoder/AudioEncoder.cpp +++ b/src/AvTranscoder/encoder/AudioEncoder.cpp @@ -119,7 +119,7 @@ bool AudioEncoder::encodeFrame(const Frame& sourceFrame, Frame& codedFrame) const AudioFrame& sourceAudioFrame = static_cast(sourceFrame); - _frame->nb_samples = sourceAudioFrame.getNbSamples(); + _frame->nb_samples = sourceAudioFrame.getNbSamplesPerChannel(); _frame->format = avCodecContext.sample_fmt; _frame->channel_layout = avCodecContext.channel_layout; diff --git a/src/AvTranscoder/frame/AudioFrame.hpp b/src/AvTranscoder/frame/AudioFrame.hpp index b37c6c2b..85b19db0 100644 --- a/src/AvTranscoder/frame/AudioFrame.hpp +++ b/src/AvTranscoder/frame/AudioFrame.hpp @@ -55,8 +55,8 @@ class AvExport AudioFrame : public Frame const AudioFrameDesc& desc() const { return _audioFrameDesc; } - size_t getNbSamples() const { return _nbSamples; } - void setNbSamples(size_t nbSamples) { _nbSamples = nbSamples; } + size_t getNbSamplesPerChannel() const { return _nbSamples; } + void setNbSamplesPerChannel(const size_t nbSamples) { _nbSamples = nbSamples; } private: const AudioFrameDesc _audioFrameDesc; diff --git a/src/AvTranscoder/transform/AudioTransform.cpp b/src/AvTranscoder/transform/AudioTransform.cpp index 029daa7f..3cf07b62 100644 --- a/src/AvTranscoder/transform/AudioTransform.cpp +++ b/src/AvTranscoder/transform/AudioTransform.cpp @@ -106,7 +106,7 @@ void AudioTransform::convert(const Frame& srcFrame, Frame& dstFrame) _isInit = init(srcFrame, dstFrame); // if number of samples change from previous frame - const size_t nbSamplesOfCurrentFrame = static_cast(srcFrame).getNbSamples(); + const size_t nbSamplesOfCurrentFrame = static_cast(srcFrame).getNbSamplesPerChannel(); if(nbSamplesOfCurrentFrame != _nbSamplesOfPreviousFrame) { updateOutputFrame(nbSamplesOfCurrentFrame, dstFrame); From 43f5210c9522b42153f52298ef979cc993877ca6 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 12 Jan 2016 15:17:55 +0100 Subject: [PATCH 34/46] AudioTransform: renamed _nbSamplesOfPreviousFrame to _previousNbInputSamplesPerChannel --- src/AvTranscoder/transform/AudioTransform.cpp | 18 +++++++++--------- src/AvTranscoder/transform/AudioTransform.hpp | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/AvTranscoder/transform/AudioTransform.cpp b/src/AvTranscoder/transform/AudioTransform.cpp index 3cf07b62..a204198a 100644 --- a/src/AvTranscoder/transform/AudioTransform.cpp +++ b/src/AvTranscoder/transform/AudioTransform.cpp @@ -33,7 +33,7 @@ namespace avtranscoder AudioTransform::AudioTransform() : _audioConvertContext(NULL) - , _nbSamplesOfPreviousFrame(0) + , _previousNbInputSamplesPerChannel(0) , _isInit(false) { } @@ -97,7 +97,7 @@ void AudioTransform::updateOutputFrame(const size_t nbInputSamples, Frame& dstFr dstFrame.resize(bufferSizeNeeded); // set nbSamples of output frame - dst.setNbSamples(nbInputSamples); + dst.setNbSamplesPerChannel(nbInputSamples); } void AudioTransform::convert(const Frame& srcFrame, Frame& dstFrame) @@ -106,11 +106,11 @@ void AudioTransform::convert(const Frame& srcFrame, Frame& dstFrame) _isInit = init(srcFrame, dstFrame); // if number of samples change from previous frame - const size_t nbSamplesOfCurrentFrame = static_cast(srcFrame).getNbSamplesPerChannel(); - if(nbSamplesOfCurrentFrame != _nbSamplesOfPreviousFrame) + const size_t nbInputSamplesPerChannel = static_cast(srcFrame).getNbSamplesPerChannel(); + if(nbInputSamplesPerChannel != _previousNbInputSamplesPerChannel) { - updateOutputFrame(nbSamplesOfCurrentFrame, dstFrame); - _nbSamplesOfPreviousFrame = nbSamplesOfCurrentFrame; + updateOutputFrame(nbInputSamplesPerChannel, dstFrame); + _previousNbInputSamplesPerChannel = nbInputSamplesPerChannel; } const unsigned char* srcData = srcFrame.getData(); @@ -118,11 +118,11 @@ void AudioTransform::convert(const Frame& srcFrame, Frame& dstFrame) int nbOutputSamplesPerChannel; #ifdef AVTRANSCODER_LIBAV_DEPENDENCY - nbOutputSamplesPerChannel = avresample_convert(_audioConvertContext, (uint8_t**)&dstData, 0, nbSamplesOfCurrentFrame, - (uint8_t**)&srcData, 0, nbSamplesOfCurrentFrame); + nbOutputSamplesPerChannel = avresample_convert(_audioConvertContext, (uint8_t**)&dstData, 0, nbInputSamplesPerChannel, + (uint8_t**)&srcData, 0, nbInputSamplesPerChannel); #else nbOutputSamplesPerChannel = - swr_convert(_audioConvertContext, &dstData, nbSamplesOfCurrentFrame, &srcData, nbSamplesOfCurrentFrame); + swr_convert(_audioConvertContext, &dstData, nbInputSamplesPerChannel, &srcData, nbInputSamplesPerChannel); #endif if(nbOutputSamplesPerChannel < 0) diff --git a/src/AvTranscoder/transform/AudioTransform.hpp b/src/AvTranscoder/transform/AudioTransform.hpp index 8bc5391f..2b2ca446 100644 --- a/src/AvTranscoder/transform/AudioTransform.hpp +++ b/src/AvTranscoder/transform/AudioTransform.hpp @@ -38,7 +38,7 @@ class AvExport AudioTransform : public ITransform private: ResampleContext* _audioConvertContext; - size_t _nbSamplesOfPreviousFrame; ///< To check if the number of samples change between frames + size_t _previousNbInputSamplesPerChannel; ///< To check if the number of samples change between frames bool _isInit; }; From 7493be6e91789c31151bdb12912610f35badd463 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 12 Jan 2016 17:46:04 +0100 Subject: [PATCH 35/46] Library: updated avtranscoder license value --- src/AvTranscoder/Library.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AvTranscoder/Library.cpp b/src/AvTranscoder/Library.cpp index 299512ab..80cedf17 100644 --- a/src/AvTranscoder/Library.cpp +++ b/src/AvTranscoder/Library.cpp @@ -77,7 +77,7 @@ Libraries getLibraries() { Libraries libs; - libs.push_back(Library("avtranscoder", "GPL or LGPL version 3", AVTRANSCODER_VERSION_MAJOR, AVTRANSCODER_VERSION_MINOR, + libs.push_back(Library("avtranscoder", "GPL v2 or LGPL v2.1", AVTRANSCODER_VERSION_MAJOR, AVTRANSCODER_VERSION_MINOR, AVTRANSCODER_VERSION_MICRO)); libs.push_back( Library("avutil", avutil_license(), LIBAVUTIL_VERSION_MAJOR, LIBAVUTIL_VERSION_MINOR, LIBAVUTIL_VERSION_MICRO)); From d613b665006d72c834918d65bbaf0f1b648ababd Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 12 Jan 2016 17:59:36 +0100 Subject: [PATCH 36/46] frame: split Frame and CodedData * CodedData: describes coded data. * Frame: describes decoded (raw) audio or video data. * Need to use AVFrame instead of AVPacket in avtranscoder Frame class. --- .../frame/{Frame.cpp => CodedData.cpp} | 30 +++---- src/AvTranscoder/frame/CodedData.hpp | 89 +++++++++++++++++++ src/AvTranscoder/frame/Frame.hpp | 85 ++---------------- src/AvTranscoder/frame/frame.i | 2 + 4 files changed, 111 insertions(+), 95 deletions(-) rename src/AvTranscoder/frame/{Frame.cpp => CodedData.cpp} (68%) create mode 100644 src/AvTranscoder/frame/CodedData.hpp diff --git a/src/AvTranscoder/frame/Frame.cpp b/src/AvTranscoder/frame/CodedData.cpp similarity index 68% rename from src/AvTranscoder/frame/Frame.cpp rename to src/AvTranscoder/frame/CodedData.cpp index 55c4007d..44eeaa6a 100644 --- a/src/AvTranscoder/frame/Frame.cpp +++ b/src/AvTranscoder/frame/CodedData.cpp @@ -1,47 +1,47 @@ -#include "Frame.hpp" +#include "CodedData.hpp" #include namespace avtranscoder { -Frame::Frame() +CodedData::CodedData() : _avStream(NULL) { initAVPacket(); } -Frame::Frame(const size_t dataSize) +CodedData::CodedData(const size_t dataSize) : _avStream(NULL) { av_new_packet(&_packet, dataSize); } -Frame::Frame(const AVPacket& avPacket) +CodedData::CodedData(const AVPacket& avPacket) : _avStream(NULL) { copyAVPacket(avPacket); } -Frame::Frame(const Frame& other) +CodedData::CodedData(const CodedData& other) { copyAVPacket(other.getAVPacket()); _avStream = other.getAVStream(); } -Frame& Frame::operator=(const Frame& other) +CodedData& CodedData::operator=(const CodedData& other) { copyAVPacket(other.getAVPacket()); _avStream = other.getAVStream(); return *this; } -Frame::~Frame() +CodedData::~CodedData() { av_free_packet(&_packet); } -void Frame::resize(const size_t newSize) +void CodedData::resize(const size_t newSize) { if((int)newSize < _packet.size) av_shrink_packet(&_packet, newSize); @@ -49,45 +49,45 @@ void Frame::resize(const size_t newSize) av_grow_packet(&_packet, newSize - _packet.size); } -void Frame::refData(unsigned char* buffer, const size_t size) +void CodedData::refData(unsigned char* buffer, const size_t size) { _packet.data = buffer; _packet.size = size; } -void Frame::copyData(unsigned char* buffer, const size_t size) +void CodedData::copyData(unsigned char* buffer, const size_t size) { resize(size); if(size != 0) memcpy(_packet.data, buffer, _packet.size); } -void Frame::refData(Frame& frame) +void CodedData::refData(CodedData& frame) { _packet.data = frame.getData(); _packet.size = frame.getSize(); } -void Frame::clear() +void CodedData::clear() { av_free_packet(&_packet); initAVPacket(); } -void Frame::assign(const size_t size, const int value) +void CodedData::assign(const size_t size, const int value) { resize(size); memset(_packet.data, value, size); } -void Frame::initAVPacket() +void CodedData::initAVPacket() { av_init_packet(&_packet); _packet.data = NULL; _packet.size = 0; } -void Frame::copyAVPacket(const AVPacket& avPacket) +void CodedData::copyAVPacket(const AVPacket& avPacket) { #if AVTRANSCODER_FFMPEG_DEPENDENCY && LIBAVCODEC_VERSION_INT > AV_VERSION_INT(54, 56, 0) // Need const_cast for libav versions from 54.56. to 55.56. diff --git a/src/AvTranscoder/frame/CodedData.hpp b/src/AvTranscoder/frame/CodedData.hpp new file mode 100644 index 00000000..834e3c72 --- /dev/null +++ b/src/AvTranscoder/frame/CodedData.hpp @@ -0,0 +1,89 @@ +#ifndef _AV_TRANSCODER_FRAME_CODEDDATA_HPP_ +#define _AV_TRANSCODER_FRAME_CODEDDATA_HPP_ + +#include + +extern "C" { +#include +} + +struct AVStream; + +namespace avtranscoder +{ + +/** + * @brief This class describes coded data. + */ +class AvExport CodedData +{ +public: + /// Create a frame with empty buffer data + CodedData(); + + /// Create a frame with a the given buffer size + CodedData(const size_t dataSize); + +#ifndef SWIG + /// Create a frame from the given AVPAcket (copy data of given packet) + CodedData(const AVPacket& avPacket); +#endif + + /// Override copy constructor in order to copy AVPacket data + CodedData(const CodedData& other); + + /// Override operator = in order to copy AVPacket data + CodedData& operator=(const CodedData& other); + + /// Free buffer of data + ~CodedData(); + + void refAVStream(const AVStream& avStream) { _avStream = &avStream; } + /// Resize data buffer + void resize(const size_t newSize); + + ///@{ + /// Ref to external data buffer + void refData(CodedData& frame); + void refData(unsigned char* buffer, const size_t size); + ///@} + + /// Copy external data buffer + void copyData(unsigned char* buffer, const size_t size); + + /** + * @brief Resize the buffer with the given size, and copy the given value + * @note Use this function to check if we can modify the buffer + */ + void assign(const size_t size, const int value); + + /// Clear existing data and set size to 0 + void clear(); + + unsigned char* getData() { return _packet.data; } + size_t getSize() const { return _packet.size; } + +#ifndef SWIG + /** + * @return the AVStream which contains the packet + * @note may be NULL in case of generated packets + */ + const AVStream* getAVStream() const { return _avStream; } + AVPacket& getAVPacket() { return _packet; } + const AVPacket& getAVPacket() const { return _packet; } + const unsigned char* getData() const { return _packet.data; } +#endif + +private: + void initAVPacket(); + void copyAVPacket(const AVPacket& avPacket); + +private: + AVPacket _packet; + + // Stream which contains the packet + const AVStream* _avStream; //< Has link (no ownership) +}; +} + +#endif diff --git a/src/AvTranscoder/frame/Frame.hpp b/src/AvTranscoder/frame/Frame.hpp index cb6169d2..dfc502b1 100644 --- a/src/AvTranscoder/frame/Frame.hpp +++ b/src/AvTranscoder/frame/Frame.hpp @@ -1,91 +1,16 @@ #ifndef _AV_TRANSCODER_FRAME_FRAME_HPP_ #define _AV_TRANSCODER_FRAME_FRAME_HPP_ -#include - -extern "C" { -#include -} - -struct AVStream; +#include "CodedData.hpp" namespace avtranscoder { -class AvExport Frame -{ -public: - /// Create a frame with empty buffer data - Frame(); - - /// Create a frame with a the given buffer size - Frame(const size_t dataSize); - -#ifndef SWIG - /// Create a frame from the given AVPAcket (copy data of given packet) - Frame(const AVPacket& avPacket); -#endif - - /// Override copy constructor in order to copy AVPacket data - Frame(const Frame& other); - - /// Override operator = in order to copy AVPacket data - Frame& operator=(const Frame& other); - - /// Free buffer of data - ~Frame(); - - void refAVStream(const AVStream& avStream) { _avStream = &avStream; } - /// Resize data buffer - void resize(const size_t newSize); - - ///@{ - /// Ref to external data buffer - void refData(Frame& frame); - void refData(unsigned char* buffer, const size_t size); - ///@} - - /// Copy external data buffer - void copyData(unsigned char* buffer, const size_t size); - - /** - * @brief Resize the buffer with the given size, and copy the given value - * @note Use this function to check if we can modify the buffer - */ - void assign(const size_t size, const int value); - - /// Clear existing data and set size to 0 - void clear(); - - unsigned char* getData() { return _packet.data; } - size_t getSize() const { return _packet.size; } - -#ifndef SWIG - /** - * @return the AVStream which contains the packet - * @note may be NULL in case of generated packets - */ - const AVStream* getAVStream() const { return _avStream; } - AVPacket& getAVPacket() { return _packet; } - const AVPacket& getAVPacket() const { return _packet; } - const unsigned char* getData() const { return _packet.data; } -#endif - -private: - void initAVPacket(); - void copyAVPacket(const AVPacket& avPacket); - -private: - AVPacket _packet; - - // Stream which contains the packet - const AVStream* _avStream; //< Has link (no ownership) -}; +/** + * @brief This class describes decoded (raw) audio or video data. + */ +typedef CodedData Frame; -// Typedef to represent buffer of coded data. -// Example 1: in case of image, no sense to get size if coded data. -// Example 2: in case of audio, no sense to get number of channels if coded data. -typedef Frame CodedData; } #endif diff --git a/src/AvTranscoder/frame/frame.i b/src/AvTranscoder/frame/frame.i index d3959127..e2b12346 100644 --- a/src/AvTranscoder/frame/frame.i +++ b/src/AvTranscoder/frame/frame.i @@ -1,11 +1,13 @@ %apply char * { unsigned char * }; %{ +#include #include #include #include %} +%include %include %include %include From 8fb40045121eb6bd56c46a03903ab7c88b74d01a Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 12 Jan 2016 18:06:54 +0100 Subject: [PATCH 37/46] Renamed frame folder to data --- src/AvTranscoder/avTranscoder.i | 2 +- src/AvTranscoder/codec/AudioCodec.hpp | 2 +- src/AvTranscoder/codec/VideoCodec.hpp | 2 +- src/AvTranscoder/{frame => data}/AudioFrame.cpp | 0 src/AvTranscoder/{frame => data}/AudioFrame.hpp | 0 src/AvTranscoder/{frame => data}/CodedData.cpp | 0 src/AvTranscoder/{frame => data}/CodedData.hpp | 0 src/AvTranscoder/{frame => data}/Frame.hpp | 0 src/AvTranscoder/{frame => data}/VideoFrame.cpp | 0 src/AvTranscoder/{frame => data}/VideoFrame.hpp | 0 src/AvTranscoder/data/data.i | 13 +++++++++++++ src/AvTranscoder/decoder/AudioDecoder.cpp | 2 +- src/AvTranscoder/decoder/IDecoder.hpp | 2 +- src/AvTranscoder/decoder/VideoDecoder.cpp | 2 +- src/AvTranscoder/encoder/IEncoder.hpp | 2 +- src/AvTranscoder/frame/frame.i | 13 ------------- src/AvTranscoder/reader/AudioReader.cpp | 2 +- src/AvTranscoder/reader/IReader.hpp | 2 +- src/AvTranscoder/reader/VideoReader.cpp | 2 +- src/AvTranscoder/stream/IInputStream.hpp | 2 +- src/AvTranscoder/stream/IOutputStream.hpp | 2 +- src/AvTranscoder/transform/AudioTransform.cpp | 2 +- src/AvTranscoder/transform/AudioTransform.hpp | 2 +- src/AvTranscoder/transform/ITransform.hpp | 2 +- src/AvTranscoder/transform/VideoTransform.cpp | 2 +- src/AvTranscoder/transform/VideoTransform.hpp | 2 +- 26 files changed, 30 insertions(+), 30 deletions(-) rename src/AvTranscoder/{frame => data}/AudioFrame.cpp (100%) rename src/AvTranscoder/{frame => data}/AudioFrame.hpp (100%) rename src/AvTranscoder/{frame => data}/CodedData.cpp (100%) rename src/AvTranscoder/{frame => data}/CodedData.hpp (100%) rename src/AvTranscoder/{frame => data}/Frame.hpp (100%) rename src/AvTranscoder/{frame => data}/VideoFrame.cpp (100%) rename src/AvTranscoder/{frame => data}/VideoFrame.hpp (100%) create mode 100644 src/AvTranscoder/data/data.i delete mode 100644 src/AvTranscoder/frame/frame.i diff --git a/src/AvTranscoder/avTranscoder.i b/src/AvTranscoder/avTranscoder.i index 1ec80796..c5578383 100644 --- a/src/AvTranscoder/avTranscoder.i +++ b/src/AvTranscoder/avTranscoder.i @@ -23,7 +23,7 @@ %include "AvTranscoder/progress/progress.i" %include "AvTranscoder/properties/properties.i" -%include "AvTranscoder/frame/frame.i" +%include "AvTranscoder/data/data.i" %include "AvTranscoder/profile/profile.i" %include diff --git a/src/AvTranscoder/codec/AudioCodec.hpp b/src/AvTranscoder/codec/AudioCodec.hpp index 2ac1691b..0082a196 100644 --- a/src/AvTranscoder/codec/AudioCodec.hpp +++ b/src/AvTranscoder/codec/AudioCodec.hpp @@ -2,7 +2,7 @@ #define _AV_TRANSCODER_CODEC_AUDIO_CODEC_HPP_ #include "ICodec.hpp" -#include +#include namespace avtranscoder { diff --git a/src/AvTranscoder/codec/VideoCodec.hpp b/src/AvTranscoder/codec/VideoCodec.hpp index 63470d21..76998ee5 100644 --- a/src/AvTranscoder/codec/VideoCodec.hpp +++ b/src/AvTranscoder/codec/VideoCodec.hpp @@ -2,7 +2,7 @@ #define _AV_TRANSCODER_CODEC_VIDEO_CODEC_HPP_ #include "ICodec.hpp" -#include +#include namespace avtranscoder { diff --git a/src/AvTranscoder/frame/AudioFrame.cpp b/src/AvTranscoder/data/AudioFrame.cpp similarity index 100% rename from src/AvTranscoder/frame/AudioFrame.cpp rename to src/AvTranscoder/data/AudioFrame.cpp diff --git a/src/AvTranscoder/frame/AudioFrame.hpp b/src/AvTranscoder/data/AudioFrame.hpp similarity index 100% rename from src/AvTranscoder/frame/AudioFrame.hpp rename to src/AvTranscoder/data/AudioFrame.hpp diff --git a/src/AvTranscoder/frame/CodedData.cpp b/src/AvTranscoder/data/CodedData.cpp similarity index 100% rename from src/AvTranscoder/frame/CodedData.cpp rename to src/AvTranscoder/data/CodedData.cpp diff --git a/src/AvTranscoder/frame/CodedData.hpp b/src/AvTranscoder/data/CodedData.hpp similarity index 100% rename from src/AvTranscoder/frame/CodedData.hpp rename to src/AvTranscoder/data/CodedData.hpp diff --git a/src/AvTranscoder/frame/Frame.hpp b/src/AvTranscoder/data/Frame.hpp similarity index 100% rename from src/AvTranscoder/frame/Frame.hpp rename to src/AvTranscoder/data/Frame.hpp diff --git a/src/AvTranscoder/frame/VideoFrame.cpp b/src/AvTranscoder/data/VideoFrame.cpp similarity index 100% rename from src/AvTranscoder/frame/VideoFrame.cpp rename to src/AvTranscoder/data/VideoFrame.cpp diff --git a/src/AvTranscoder/frame/VideoFrame.hpp b/src/AvTranscoder/data/VideoFrame.hpp similarity index 100% rename from src/AvTranscoder/frame/VideoFrame.hpp rename to src/AvTranscoder/data/VideoFrame.hpp diff --git a/src/AvTranscoder/data/data.i b/src/AvTranscoder/data/data.i new file mode 100644 index 00000000..2e154743 --- /dev/null +++ b/src/AvTranscoder/data/data.i @@ -0,0 +1,13 @@ +%apply char * { unsigned char * }; + +%{ +#include +#include +#include +#include +%} + +%include +%include +%include +%include diff --git a/src/AvTranscoder/decoder/AudioDecoder.cpp b/src/AvTranscoder/decoder/AudioDecoder.cpp index 88c6432b..13513001 100644 --- a/src/AvTranscoder/decoder/AudioDecoder.cpp +++ b/src/AvTranscoder/decoder/AudioDecoder.cpp @@ -2,7 +2,7 @@ #include #include -#include +#include extern "C" { #include diff --git a/src/AvTranscoder/decoder/IDecoder.hpp b/src/AvTranscoder/decoder/IDecoder.hpp index 5ee8d5af..a7232f6d 100644 --- a/src/AvTranscoder/decoder/IDecoder.hpp +++ b/src/AvTranscoder/decoder/IDecoder.hpp @@ -2,7 +2,7 @@ #define _AV_TRANSCODER_ESSENCE_STREAM_IDECODER_HPP_ #include -#include +#include #include namespace avtranscoder diff --git a/src/AvTranscoder/decoder/VideoDecoder.cpp b/src/AvTranscoder/decoder/VideoDecoder.cpp index 79c18bd9..99856e8c 100644 --- a/src/AvTranscoder/decoder/VideoDecoder.cpp +++ b/src/AvTranscoder/decoder/VideoDecoder.cpp @@ -2,7 +2,7 @@ #include #include -#include +#include extern "C" { #include diff --git a/src/AvTranscoder/encoder/IEncoder.hpp b/src/AvTranscoder/encoder/IEncoder.hpp index 9598579b..db9ccfca 100644 --- a/src/AvTranscoder/encoder/IEncoder.hpp +++ b/src/AvTranscoder/encoder/IEncoder.hpp @@ -1,7 +1,7 @@ #ifndef _AV_TRANSCODER_ESSENCE_STREAM_IENCODER_HPP_ #define _AV_TRANSCODER_ESSENCE_STREAM_IENCODER_HPP_ -#include +#include #include #include diff --git a/src/AvTranscoder/frame/frame.i b/src/AvTranscoder/frame/frame.i deleted file mode 100644 index e2b12346..00000000 --- a/src/AvTranscoder/frame/frame.i +++ /dev/null @@ -1,13 +0,0 @@ -%apply char * { unsigned char * }; - -%{ -#include -#include -#include -#include -%} - -%include -%include -%include -%include diff --git a/src/AvTranscoder/reader/AudioReader.cpp b/src/AvTranscoder/reader/AudioReader.cpp index 8ace54f9..530e3453 100644 --- a/src/AvTranscoder/reader/AudioReader.cpp +++ b/src/AvTranscoder/reader/AudioReader.cpp @@ -1,7 +1,7 @@ #include "AudioReader.hpp" #include -#include +#include #include #include diff --git a/src/AvTranscoder/reader/IReader.hpp b/src/AvTranscoder/reader/IReader.hpp index 76e43e88..6b654770 100644 --- a/src/AvTranscoder/reader/IReader.hpp +++ b/src/AvTranscoder/reader/IReader.hpp @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include namespace avtranscoder diff --git a/src/AvTranscoder/reader/VideoReader.cpp b/src/AvTranscoder/reader/VideoReader.cpp index 81a4a9b7..cae21a40 100644 --- a/src/AvTranscoder/reader/VideoReader.cpp +++ b/src/AvTranscoder/reader/VideoReader.cpp @@ -1,7 +1,7 @@ #include "VideoReader.hpp" #include -#include +#include #include #include diff --git a/src/AvTranscoder/stream/IInputStream.hpp b/src/AvTranscoder/stream/IInputStream.hpp index 626dc4e6..c091b36b 100644 --- a/src/AvTranscoder/stream/IInputStream.hpp +++ b/src/AvTranscoder/stream/IInputStream.hpp @@ -7,7 +7,7 @@ #include #include -#include +#include namespace avtranscoder { diff --git a/src/AvTranscoder/stream/IOutputStream.hpp b/src/AvTranscoder/stream/IOutputStream.hpp index 928057cc..edb867ef 100644 --- a/src/AvTranscoder/stream/IOutputStream.hpp +++ b/src/AvTranscoder/stream/IOutputStream.hpp @@ -3,7 +3,7 @@ #include #include -#include +#include namespace avtranscoder { diff --git a/src/AvTranscoder/transform/AudioTransform.cpp b/src/AvTranscoder/transform/AudioTransform.cpp index a204198a..f66c198e 100644 --- a/src/AvTranscoder/transform/AudioTransform.cpp +++ b/src/AvTranscoder/transform/AudioTransform.cpp @@ -1,6 +1,6 @@ #include "AudioTransform.hpp" -#include +#include extern "C" { #include diff --git a/src/AvTranscoder/transform/AudioTransform.hpp b/src/AvTranscoder/transform/AudioTransform.hpp index 2b2ca446..bc2b7ef6 100644 --- a/src/AvTranscoder/transform/AudioTransform.hpp +++ b/src/AvTranscoder/transform/AudioTransform.hpp @@ -4,7 +4,7 @@ #include "ITransform.hpp" #include -#include +#include #ifdef AVTRANSCODER_LIBAV_DEPENDENCY #define ResampleContext AVAudioResampleContext diff --git a/src/AvTranscoder/transform/ITransform.hpp b/src/AvTranscoder/transform/ITransform.hpp index 7af00fea..83266093 100644 --- a/src/AvTranscoder/transform/ITransform.hpp +++ b/src/AvTranscoder/transform/ITransform.hpp @@ -2,7 +2,7 @@ #define _AV_TRANSCODER_ESSENCE_TRANSFORM_ESSENCE_TRANSFORM_HPP_ #include -#include +#include namespace avtranscoder { diff --git a/src/AvTranscoder/transform/VideoTransform.cpp b/src/AvTranscoder/transform/VideoTransform.cpp index bede2427..a3dc80c2 100644 --- a/src/AvTranscoder/transform/VideoTransform.cpp +++ b/src/AvTranscoder/transform/VideoTransform.cpp @@ -1,6 +1,6 @@ #include "VideoTransform.hpp" -#include +#include extern "C" { #include diff --git a/src/AvTranscoder/transform/VideoTransform.hpp b/src/AvTranscoder/transform/VideoTransform.hpp index 0bdcec5c..4f4a3b77 100644 --- a/src/AvTranscoder/transform/VideoTransform.hpp +++ b/src/AvTranscoder/transform/VideoTransform.hpp @@ -5,7 +5,7 @@ #include "ITransform.hpp" -#include +#include class SwsContext; From d60088d922b1593f8b4f86da7dd5a5e971a19932 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Mon, 18 Jan 2016 17:59:12 +0100 Subject: [PATCH 38/46] util: added getPixel/SampleFormatName functions --- src/AvTranscoder/util.cpp | 12 ++++++++++++ src/AvTranscoder/util.hpp | 12 ++++++++++++ 2 files changed, 24 insertions(+) diff --git a/src/AvTranscoder/util.cpp b/src/AvTranscoder/util.cpp index 99380cb3..39166989 100644 --- a/src/AvTranscoder/util.cpp +++ b/src/AvTranscoder/util.cpp @@ -105,6 +105,18 @@ AVSampleFormat getAVSampleFormat(const std::string& sampleFormat) return av_get_sample_fmt(sampleFormat.c_str()); } +std::string getPixelFormatName(const AVPixelFormat pixelFormat) +{ + const char* formatName = av_get_pix_fmt_name(pixelFormat); + return formatName ? std::string(formatName) : ""; +} + +std::string getSampleFormatName(const AVSampleFormat sampleFormat) +{ + const char* formatName = av_get_sample_fmt_name(sampleFormat); + return formatName ? std::string(formatName) : ""; +} + NamesArray getFormatsNames() { NamesArray formatsNames; diff --git a/src/AvTranscoder/util.hpp b/src/AvTranscoder/util.hpp index 1d29f372..97ccd826 100644 --- a/src/AvTranscoder/util.hpp +++ b/src/AvTranscoder/util.hpp @@ -50,6 +50,18 @@ AVPixelFormat AvExport getAVPixelFormat(const std::string& pixelFormat); */ AVSampleFormat AvExport getAVSampleFormat(const std::string& sampleFormat); +/** + * @return The name of the given pixel format. + * @note Returns an empty string if the format is not found. + */ +std::string AvExport getPixelFormatName(const AVPixelFormat pixelFormat); + +/** + * @return The name of the given sample format. + * @note Returns an empty string if the format is not found. + */ +std::string AvExport getSampleFormatName(const AVSampleFormat sampleFormat); + #ifndef SWIG /** * @brief Get array of short/long names of all format supported by FFmpeg / libav. From 37601a886f2598409ca2efa6794c9b0aa9335fe0 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 19 Jan 2016 11:26:43 +0100 Subject: [PATCH 39/46] data: Frame class describes raw data with an AVFrame * Create decoded/coded folders to split classes in data directory. * Video/AudioFrameDesc are struct with puclic access to their attributes. * Sorry for this huge commit, but it is hard to split it. --- app/avPlay/Window.cpp | 6 +- src/AvTranscoder/codec/AudioCodec.cpp | 6 +- src/AvTranscoder/codec/AudioCodec.hpp | 2 +- src/AvTranscoder/codec/VideoCodec.cpp | 10 +- src/AvTranscoder/codec/VideoCodec.hpp | 2 +- src/AvTranscoder/data/AudioFrame.cpp | 71 ---------- src/AvTranscoder/data/AudioFrame.hpp | 67 --------- src/AvTranscoder/data/Frame.hpp | 16 --- src/AvTranscoder/data/VideoFrame.cpp | 67 --------- src/AvTranscoder/data/VideoFrame.hpp | 63 --------- .../data/{ => coded}/CodedData.cpp | 0 .../data/{ => coded}/CodedData.hpp | 13 +- src/AvTranscoder/data/data.i | 16 +-- src/AvTranscoder/data/decoded/AudioFrame.cpp | 128 ++++++++++++++++++ src/AvTranscoder/data/decoded/AudioFrame.hpp | 73 ++++++++++ src/AvTranscoder/data/decoded/Frame.cpp | 90 ++++++++++++ src/AvTranscoder/data/decoded/Frame.hpp | 85 ++++++++++++ src/AvTranscoder/data/decoded/VideoFrame.cpp | 112 +++++++++++++++ src/AvTranscoder/data/decoded/VideoFrame.hpp | 73 ++++++++++ src/AvTranscoder/decoder/AudioDecoder.cpp | 127 +++++++---------- src/AvTranscoder/decoder/AudioDecoder.hpp | 6 - src/AvTranscoder/decoder/AudioGenerator.cpp | 15 +- src/AvTranscoder/decoder/AudioGenerator.hpp | 1 + src/AvTranscoder/decoder/IDecoder.hpp | 2 +- src/AvTranscoder/decoder/VideoDecoder.cpp | 76 +++-------- src/AvTranscoder/decoder/VideoDecoder.hpp | 6 - src/AvTranscoder/decoder/VideoGenerator.cpp | 22 +-- src/AvTranscoder/decoder/VideoGenerator.hpp | 1 + src/AvTranscoder/encoder/AudioEncoder.cpp | 52 +------ src/AvTranscoder/encoder/AudioEncoder.hpp | 5 +- src/AvTranscoder/encoder/IEncoder.hpp | 7 +- src/AvTranscoder/encoder/VideoEncoder.cpp | 43 +----- src/AvTranscoder/encoder/VideoEncoder.hpp | 5 +- src/AvTranscoder/reader/AudioReader.cpp | 9 +- src/AvTranscoder/reader/IReader.hpp | 2 +- src/AvTranscoder/reader/VideoReader.cpp | 7 +- src/AvTranscoder/stream/IInputStream.hpp | 2 +- src/AvTranscoder/stream/IOutputStream.hpp | 2 +- .../transcoder/StreamTranscoder.cpp | 10 +- src/AvTranscoder/transform/AudioTransform.cpp | 75 +++++----- src/AvTranscoder/transform/AudioTransform.hpp | 7 +- src/AvTranscoder/transform/ITransform.hpp | 2 +- src/AvTranscoder/transform/VideoTransform.cpp | 48 +++---- src/AvTranscoder/transform/VideoTransform.hpp | 8 +- test/pyTest/testReader.py | 12 +- test/pyTest/testSetFrame.py | 14 +- 46 files changed, 776 insertions(+), 690 deletions(-) delete mode 100644 src/AvTranscoder/data/AudioFrame.cpp delete mode 100644 src/AvTranscoder/data/AudioFrame.hpp delete mode 100644 src/AvTranscoder/data/Frame.hpp delete mode 100644 src/AvTranscoder/data/VideoFrame.cpp delete mode 100644 src/AvTranscoder/data/VideoFrame.hpp rename src/AvTranscoder/data/{ => coded}/CodedData.cpp (100%) rename src/AvTranscoder/data/{ => coded}/CodedData.hpp (90%) create mode 100644 src/AvTranscoder/data/decoded/AudioFrame.cpp create mode 100644 src/AvTranscoder/data/decoded/AudioFrame.hpp create mode 100644 src/AvTranscoder/data/decoded/Frame.cpp create mode 100644 src/AvTranscoder/data/decoded/Frame.hpp create mode 100644 src/AvTranscoder/data/decoded/VideoFrame.cpp create mode 100644 src/AvTranscoder/data/decoded/VideoFrame.hpp diff --git a/app/avPlay/Window.cpp b/app/avPlay/Window.cpp index 64118db6..4bb9d006 100644 --- a/app/avPlay/Window.cpp +++ b/app/avPlay/Window.cpp @@ -550,7 +550,7 @@ void Window::showAlphaChannelTexture() void Window::displayNextFrame() { - const char* buffer = (const char*)_reader->readNextFrame()->getData(); + const char* buffer = (const char*)_reader->readNextFrame()->getData()[0]; loadNewTexture(buffer, _reader->getOutputNbComponents(), _reader->getOutputWidth(), _reader->getOutputHeight(), GL_RGB, GL_UNSIGNED_BYTE); display(); @@ -558,7 +558,7 @@ void Window::displayNextFrame() void Window::displayPrevFrame() { - const char* buffer = (const char*)_reader->readPrevFrame()->getData(); + const char* buffer = (const char*)_reader->readPrevFrame()->getData()[0]; loadNewTexture(buffer, _reader->getOutputNbComponents(), _reader->getOutputWidth(), _reader->getOutputHeight(), GL_RGB, GL_UNSIGNED_BYTE); display(); @@ -571,7 +571,7 @@ void Window::displayFirstFrame() void Window::displayAtFrame(const size_t frame) { - const char* buffer = (const char*)_reader->readFrameAt(frame)->getData(); + const char* buffer = (const char*)_reader->readFrameAt(frame)->getData()[0]; loadNewTexture(buffer, _reader->getOutputNbComponents(), _reader->getOutputWidth(), _reader->getOutputHeight(), GL_RGB, GL_UNSIGNED_BYTE); display(); diff --git a/src/AvTranscoder/codec/AudioCodec.cpp b/src/AvTranscoder/codec/AudioCodec.cpp index 42acc1fb..16eb2e21 100644 --- a/src/AvTranscoder/codec/AudioCodec.cpp +++ b/src/AvTranscoder/codec/AudioCodec.cpp @@ -30,8 +30,8 @@ AudioFrameDesc AudioCodec::getAudioFrameDesc() const void AudioCodec::setAudioParameters(const AudioFrameDesc& audioFrameDesc) { - _avCodecContext->sample_rate = audioFrameDesc.getSampleRate(); - _avCodecContext->channels = audioFrameDesc.getNbChannels(); - _avCodecContext->sample_fmt = audioFrameDesc.getSampleFormat(); + _avCodecContext->sample_rate = audioFrameDesc._sampleRate; + _avCodecContext->channels = audioFrameDesc._nbChannels; + _avCodecContext->sample_fmt = audioFrameDesc._sampleFormat; } } diff --git a/src/AvTranscoder/codec/AudioCodec.hpp b/src/AvTranscoder/codec/AudioCodec.hpp index 0082a196..9b380171 100644 --- a/src/AvTranscoder/codec/AudioCodec.hpp +++ b/src/AvTranscoder/codec/AudioCodec.hpp @@ -2,7 +2,7 @@ #define _AV_TRANSCODER_CODEC_AUDIO_CODEC_HPP_ #include "ICodec.hpp" -#include +#include namespace avtranscoder { diff --git a/src/AvTranscoder/codec/VideoCodec.cpp b/src/AvTranscoder/codec/VideoCodec.cpp index f09e5d29..081aba82 100644 --- a/src/AvTranscoder/codec/VideoCodec.cpp +++ b/src/AvTranscoder/codec/VideoCodec.cpp @@ -27,17 +27,17 @@ VideoFrameDesc VideoCodec::getVideoFrameDesc() const VideoFrameDesc videoFrameDesc(_avCodecContext->width, _avCodecContext->height, _avCodecContext->pix_fmt); double fps = 1.0 * _avCodecContext->time_base.den / (_avCodecContext->time_base.num * _avCodecContext->ticks_per_frame); if(!std::isinf(fps)) - videoFrameDesc.setFps(fps); + videoFrameDesc._fps = fps; return videoFrameDesc; } void VideoCodec::setImageParameters(const VideoFrameDesc& videoFrameDesc) { - _avCodecContext->width = videoFrameDesc.getWidth(); - _avCodecContext->height = videoFrameDesc.getHeight(); - _avCodecContext->pix_fmt = videoFrameDesc.getPixelFormat(); + _avCodecContext->width = videoFrameDesc._width; + _avCodecContext->height = videoFrameDesc._height; + _avCodecContext->pix_fmt = videoFrameDesc._pixelFormat; _avCodecContext->time_base.num = 1; - _avCodecContext->time_base.den = videoFrameDesc.getFps(); + _avCodecContext->time_base.den = videoFrameDesc._fps; _avCodecContext->ticks_per_frame = 1; } } diff --git a/src/AvTranscoder/codec/VideoCodec.hpp b/src/AvTranscoder/codec/VideoCodec.hpp index 76998ee5..aec23e43 100644 --- a/src/AvTranscoder/codec/VideoCodec.hpp +++ b/src/AvTranscoder/codec/VideoCodec.hpp @@ -2,7 +2,7 @@ #define _AV_TRANSCODER_CODEC_VIDEO_CODEC_HPP_ #include "ICodec.hpp" -#include +#include namespace avtranscoder { diff --git a/src/AvTranscoder/data/AudioFrame.cpp b/src/AvTranscoder/data/AudioFrame.cpp deleted file mode 100644 index 88a83f87..00000000 --- a/src/AvTranscoder/data/AudioFrame.cpp +++ /dev/null @@ -1,71 +0,0 @@ -#include "AudioFrame.hpp" - -#include -#include -#include - -namespace avtranscoder -{ - -AudioFrameDesc::AudioFrameDesc(const size_t sampleRate, const size_t channels, const AVSampleFormat sampleFormat) - : _sampleRate(sampleRate) - , _channels(channels) - , _sampleFormat(sampleFormat) - , _fps(1.) -{ -} - -AudioFrameDesc::AudioFrameDesc(const size_t sampleRate, const size_t channels, const std::string& sampleFormat) - : _sampleRate(sampleRate) - , _channels(channels) - , _sampleFormat(av_get_sample_fmt(sampleFormat.c_str())) - , _fps(1.) -{ -} - -std::string AudioFrameDesc::getSampleFormatName() const -{ - const char* formatName = av_get_sample_fmt_name(_sampleFormat); - return formatName ? std::string(formatName) : "unknown sample format"; -} - -size_t AudioFrameDesc::getDataSize() const -{ - if(_sampleFormat == AV_SAMPLE_FMT_NONE) - throw std::runtime_error("incorrect sample format"); - - const size_t size = (_sampleRate / _fps) * _channels * av_get_bytes_per_sample(_sampleFormat); - if(size == 0) - { - std::stringstream msg; - msg << "Unable to determine audio buffer size:" << std::endl; - msg << "sampleRate = " << _sampleRate << std::endl; - msg << "fps = " << _fps << std::endl; - msg << "channels = " << _channels << std::endl; - msg << "bytes per sample = " << av_get_bytes_per_sample(_sampleFormat) << std::endl; - throw std::runtime_error(msg.str()); - } - return size; -} - -void AudioFrameDesc::setSampleFormat(const std::string& sampleFormatName) -{ - _sampleFormat = av_get_sample_fmt(sampleFormatName.c_str()); -} - -void AudioFrameDesc::setParameters(const ProfileLoader::Profile& profile) -{ - // sample rate - if(profile.count(constants::avProfileSampleRate)) - setSampleRate(atoi(profile.find(constants::avProfileSampleRate)->second.c_str())); - // channel - if(profile.count(constants::avProfileChannel)) - setNbChannels(atoi(profile.find(constants::avProfileChannel)->second.c_str())); - // sample format - if(profile.count(constants::avProfileSampleFormat)) - setSampleFormat(profile.find(constants::avProfileSampleFormat)->second); - // fps - if(profile.count(constants::avProfileFrameRate)) - setFps(atof(profile.find(constants::avProfileFrameRate)->second.c_str())); -} -} diff --git a/src/AvTranscoder/data/AudioFrame.hpp b/src/AvTranscoder/data/AudioFrame.hpp deleted file mode 100644 index 85b19db0..00000000 --- a/src/AvTranscoder/data/AudioFrame.hpp +++ /dev/null @@ -1,67 +0,0 @@ -#ifndef _AV_TRANSCODER_FRAME_AUDIO_FRAME_HPP_ -#define _AV_TRANSCODER_FRAME_AUDIO_FRAME_HPP_ - -#include "Frame.hpp" -#include - -extern "C" { -#include -} - -namespace avtranscoder -{ - -/// @brief Description of a number of samples, which corresponds to one video frame -class AvExport AudioFrameDesc -{ -public: - AudioFrameDesc(const size_t sampleRate = 0, const size_t channels = 0, - const AVSampleFormat sampleFormat = AV_SAMPLE_FMT_NONE); - - AudioFrameDesc(const size_t sampleRate, const size_t channels, const std::string& sampleFormat); - - size_t getSampleRate() const { return _sampleRate; } - size_t getNbChannels() const { return _channels; } - AVSampleFormat getSampleFormat() const { return _sampleFormat; } - std::string getSampleFormatName() const; - double getFps() const { return _fps; } - - size_t getDataSize() const; - - void setSampleRate(const size_t sampleRate) { _sampleRate = sampleRate; } - void setNbChannels(const size_t channels) { _channels = channels; } - void setSampleFormat(const std::string& sampleFormatName); - void setSampleFormat(const AVSampleFormat sampleFormat) { _sampleFormat = sampleFormat; } - void setFps(const double fps) { _fps = fps; } - - void setParameters(const ProfileLoader::Profile& profile); - -private: - size_t _sampleRate; - size_t _channels; - AVSampleFormat _sampleFormat; - double _fps; -}; - -class AvExport AudioFrame : public Frame -{ -public: - AudioFrame(const AudioFrameDesc& ref) - : Frame(ref.getDataSize()) - , _audioFrameDesc(ref) - , _nbSamples(0) - { - } - - const AudioFrameDesc& desc() const { return _audioFrameDesc; } - - size_t getNbSamplesPerChannel() const { return _nbSamples; } - void setNbSamplesPerChannel(const size_t nbSamples) { _nbSamples = nbSamples; } - -private: - const AudioFrameDesc _audioFrameDesc; - size_t _nbSamples; -}; -} - -#endif diff --git a/src/AvTranscoder/data/Frame.hpp b/src/AvTranscoder/data/Frame.hpp deleted file mode 100644 index dfc502b1..00000000 --- a/src/AvTranscoder/data/Frame.hpp +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef _AV_TRANSCODER_FRAME_FRAME_HPP_ -#define _AV_TRANSCODER_FRAME_FRAME_HPP_ - -#include "CodedData.hpp" - -namespace avtranscoder -{ - -/** - * @brief This class describes decoded (raw) audio or video data. - */ -typedef CodedData Frame; - -} - -#endif diff --git a/src/AvTranscoder/data/VideoFrame.cpp b/src/AvTranscoder/data/VideoFrame.cpp deleted file mode 100644 index 32ed2660..00000000 --- a/src/AvTranscoder/data/VideoFrame.cpp +++ /dev/null @@ -1,67 +0,0 @@ -#include "VideoFrame.hpp" - -extern "C" { -#include -#include -} - -#include -#include - -namespace avtranscoder -{ - -VideoFrameDesc::VideoFrameDesc(const size_t width, const size_t height, const AVPixelFormat pixelFormat) - : _width(width) - , _height(height) - , _pixelFormat(pixelFormat) - , _fps(1.0) -{ -} -VideoFrameDesc::VideoFrameDesc(const size_t width, const size_t height, const std::string& pixelFormat) - : _width(width) - , _height(height) - , _pixelFormat(av_get_pix_fmt(pixelFormat.c_str())) - , _fps(1.0) -{ -} - -std::string VideoFrameDesc::getPixelFormatName() const -{ - const char* formatName = av_get_pix_fmt_name(_pixelFormat); - return formatName ? std::string(formatName) : "unknown pixel format"; -} - -size_t VideoFrameDesc::getDataSize() const -{ - if(_pixelFormat == AV_PIX_FMT_NONE) - throw std::runtime_error("incorrect pixel format"); - - size_t size = avpicture_get_size(_pixelFormat, _width, _height); - if(size == 0) - throw std::runtime_error("unable to determine image buffer size"); - - return size; -} - -void VideoFrameDesc::setPixelFormat(const std::string& pixelFormat) -{ - _pixelFormat = av_get_pix_fmt(pixelFormat.c_str()); -} - -void VideoFrameDesc::setParameters(const ProfileLoader::Profile& profile) -{ - // width - if(profile.count(constants::avProfileWidth)) - setWidth(atoi(profile.find(constants::avProfileWidth)->second.c_str())); - // height - if(profile.count(constants::avProfileHeight)) - setHeight(atoi(profile.find(constants::avProfileHeight)->second.c_str())); - // pixel format - if(profile.count(constants::avProfilePixelFormat)) - setPixelFormat(profile.find(constants::avProfilePixelFormat)->second); - // fps - if(profile.count(constants::avProfileFrameRate)) - setFps(atof(profile.find(constants::avProfileFrameRate)->second.c_str())); -} -} diff --git a/src/AvTranscoder/data/VideoFrame.hpp b/src/AvTranscoder/data/VideoFrame.hpp deleted file mode 100644 index 131b183d..00000000 --- a/src/AvTranscoder/data/VideoFrame.hpp +++ /dev/null @@ -1,63 +0,0 @@ -#ifndef _AV_TRANSCODER_FRAME_VIDEO_FRAME_HPP_ -#define _AV_TRANSCODER_FRAME_VIDEO_FRAME_HPP_ - -#include "Frame.hpp" -#include - -extern "C" { -#include -} - -namespace avtranscoder -{ - -class AvExport VideoFrameDesc -{ -public: - VideoFrameDesc(const size_t width = 0, const size_t height = 0, const AVPixelFormat pixelFormat = AV_PIX_FMT_NONE); - VideoFrameDesc(const size_t width, const size_t height, const std::string& pixelFormat); - - size_t getWidth() const { return _width; } - size_t getHeight() const { return _height; } - AVPixelFormat getPixelFormat() const { return _pixelFormat; } - std::string getPixelFormatName() const; - double getFps() const { return _fps; } - - size_t getDataSize() const; - - void setWidth(const size_t width) { _width = width; } - void setHeight(const size_t height) { _height = height; } - void setPixelFormat(const std::string& pixelFormat); - void setPixelFormat(const AVPixelFormat pixelFormat) { _pixelFormat = pixelFormat; } - void setFps(const double fps) { _fps = fps; } - - void setParameters(const ProfileLoader::Profile& profile); - -private: - size_t _width; - size_t _height; - AVPixelFormat _pixelFormat; - double _fps; -}; - -// template< template Alloc > -// class AvExport ImageBase -class AvExport VideoFrame : public Frame -{ -public: - VideoFrame(const VideoFrameDesc& ref) - : Frame(ref.getDataSize()) - , _videoFrameDesc(ref) - { - } - - const VideoFrameDesc& desc() const { return _videoFrameDesc; } - -private: - const VideoFrameDesc _videoFrameDesc; -}; - -// typedef ImageBase VideoFrame; -} - -#endif diff --git a/src/AvTranscoder/data/CodedData.cpp b/src/AvTranscoder/data/coded/CodedData.cpp similarity index 100% rename from src/AvTranscoder/data/CodedData.cpp rename to src/AvTranscoder/data/coded/CodedData.cpp diff --git a/src/AvTranscoder/data/CodedData.hpp b/src/AvTranscoder/data/coded/CodedData.hpp similarity index 90% rename from src/AvTranscoder/data/CodedData.hpp rename to src/AvTranscoder/data/coded/CodedData.hpp index 834e3c72..e40da4a2 100644 --- a/src/AvTranscoder/data/CodedData.hpp +++ b/src/AvTranscoder/data/coded/CodedData.hpp @@ -18,14 +18,14 @@ namespace avtranscoder class AvExport CodedData { public: - /// Create a frame with empty buffer data + /// Create an empty data buffer CodedData(); - /// Create a frame with a the given buffer size + /// Create a data buffer with a the given size CodedData(const size_t dataSize); #ifndef SWIG - /// Create a frame from the given AVPAcket (copy data of given packet) + /// Create a data buffer from the given AVPAcket (copy data of given packet) CodedData(const AVPacket& avPacket); #endif @@ -38,7 +38,9 @@ class AvExport CodedData /// Free buffer of data ~CodedData(); +#ifndef SWIG void refAVStream(const AVStream& avStream) { _avStream = &avStream; } +#endif /// Resize data buffer void resize(const size_t newSize); @@ -61,6 +63,10 @@ class AvExport CodedData void clear(); unsigned char* getData() { return _packet.data; } +#ifndef SWIG + const unsigned char* getData() const { return _packet.data; } +#endif + size_t getSize() const { return _packet.size; } #ifndef SWIG @@ -71,7 +77,6 @@ class AvExport CodedData const AVStream* getAVStream() const { return _avStream; } AVPacket& getAVPacket() { return _packet; } const AVPacket& getAVPacket() const { return _packet; } - const unsigned char* getData() const { return _packet.data; } #endif private: diff --git a/src/AvTranscoder/data/data.i b/src/AvTranscoder/data/data.i index 2e154743..117c1f74 100644 --- a/src/AvTranscoder/data/data.i +++ b/src/AvTranscoder/data/data.i @@ -1,13 +1,13 @@ %apply char * { unsigned char * }; %{ -#include -#include -#include -#include +#include +#include +#include +#include %} -%include -%include -%include -%include +%include +%include +%include +%include diff --git a/src/AvTranscoder/data/decoded/AudioFrame.cpp b/src/AvTranscoder/data/decoded/AudioFrame.cpp new file mode 100644 index 00000000..8ae8ceff --- /dev/null +++ b/src/AvTranscoder/data/decoded/AudioFrame.cpp @@ -0,0 +1,128 @@ +#include "AudioFrame.hpp" + +#include + +extern "C" { +#include +#include +} + +#include + +namespace avtranscoder +{ + +AudioFrameDesc::AudioFrameDesc(const size_t sampleRate, const size_t nbChannels, const AVSampleFormat sampleFormat) + : _sampleRate(sampleRate) + , _nbChannels(nbChannels) + , _sampleFormat(sampleFormat) + , _fps(25.) +{ +} + +AudioFrameDesc::AudioFrameDesc(const size_t sampleRate, const size_t nbChannels, const std::string& sampleFormatName) + : _sampleRate(sampleRate) + , _nbChannels(nbChannels) + , _sampleFormat(getAVSampleFormat(sampleFormatName)) + , _fps(25.) +{ +} + +void AudioFrameDesc::setParameters(const ProfileLoader::Profile& profile) +{ + // sample rate + if(profile.count(constants::avProfileSampleRate)) + _sampleRate = atoi(profile.find(constants::avProfileSampleRate)->second.c_str()); + // channel + if(profile.count(constants::avProfileChannel)) + _nbChannels = atoi(profile.find(constants::avProfileChannel)->second.c_str()); + // sample format + if(profile.count(constants::avProfileSampleFormat)) + _sampleFormat = getAVSampleFormat(profile.find(constants::avProfileSampleFormat)->second.c_str()); + // fps + if(profile.count(constants::avProfileFrameRate)) + _fps = atof(profile.find(constants::avProfileFrameRate)->second.c_str()); +} + +AudioFrame::AudioFrame(const AudioFrameDesc& ref) + : Frame() +{ + allocateAVSample(ref); +} + +AudioFrame::AudioFrame(const Frame& otherFrame) + : Frame(otherFrame) +{ +} + +size_t AudioFrame::getSize() const +{ + if(getSampleFormat() == AV_SAMPLE_FMT_NONE) + { + LOG_WARN("Incorrect sample format when get size of audio frame: return a size of 0.") + return 0; + } + + const size_t size = getNbSamplesPerChannel() * getNbChannels() * av_get_bytes_per_sample(getSampleFormat()); + if(size == 0) + { + std::stringstream msg; + msg << "Unable to determine audio buffer size:" << std::endl; + msg << "nb sample per channel = " << getNbSamplesPerChannel() << std::endl; + msg << "channels = " << getNbChannels() << std::endl; + msg << "bytes per sample = " << av_get_bytes_per_sample(getSampleFormat()) << std::endl; + throw std::runtime_error(msg.str()); + } + return size; +} + +void AudioFrame::allocateAVSample(const AudioFrameDesc& desc) +{ + // Set Frame properties + _frame->sample_rate = desc._sampleRate; + _frame->channels = desc._nbChannels; + _frame->channel_layout = av_get_default_channel_layout(desc._nbChannels); + _frame->format = desc._sampleFormat; + _frame->nb_samples = desc._sampleRate / desc._fps; // cannot be known before calling avcodec_decode_audio4 + + // Allocate data + const int align = 0; + const int ret = + av_samples_alloc(_frame->data, _frame->linesize, _frame->channels, _frame->nb_samples, desc._sampleFormat, align); + if(ret < 0) + { + std::stringstream os; + os << "Unable to allocate an audio frame of "; + os << "sample rate = " << _frame->sample_rate << ", "; + os << "nb channels = " << _frame->channels << ", "; + os << "channel layout = " << av_get_channel_name(_frame->channels) << ", "; + os << "nb samples = " << _frame->nb_samples << ", "; + os << "sample format = " << getSampleFormatName(desc._sampleFormat); + throw std::runtime_error(os.str()); + } +} + +void AudioFrame::assign(const unsigned char value) +{ + // Create the audio buffer + const int audioSize = getSize(); + unsigned char audioBuffer[audioSize]; + memset(audioBuffer, value, audioSize); + + // Fill the picture + assign(audioBuffer); +} + +void AudioFrame::assign(const unsigned char* ptrValue) +{ + const int align = 0; + const int ret = av_samples_fill_arrays(_frame->data, _frame->linesize, ptrValue, getNbChannels(), + getNbSamplesPerChannel(), getSampleFormat(), align); + if(ret < 0) + { + std::stringstream os; + os << "Unable to assign an audio buffer: " << getDescriptionFromErrorCode(ret); + throw std::runtime_error(os.str()); + } +} +} diff --git a/src/AvTranscoder/data/decoded/AudioFrame.hpp b/src/AvTranscoder/data/decoded/AudioFrame.hpp new file mode 100644 index 00000000..d2eff720 --- /dev/null +++ b/src/AvTranscoder/data/decoded/AudioFrame.hpp @@ -0,0 +1,73 @@ +#ifndef _AV_TRANSCODER_FRAME_AUDIO_FRAME_HPP_ +#define _AV_TRANSCODER_FRAME_AUDIO_FRAME_HPP_ + +#include "Frame.hpp" +#include + +namespace avtranscoder +{ + +/** + * @brief Description to create an audio frame. + * This corresponds to the number of samples, which corresponds to one video frame. + */ +struct AvExport AudioFrameDesc +{ +public: + AudioFrameDesc(const size_t sampleRate = 0, const size_t channels = 0, + const AVSampleFormat sampleFormat = AV_SAMPLE_FMT_NONE); + AudioFrameDesc(const size_t sampleRate, const size_t channels, const std::string& sampleFormatName); + + /** + * @brief Set the attributes from the given profile. + * @see Profile + */ + void setParameters(const ProfileLoader::Profile& profile); + +public: + size_t _sampleRate; + size_t _nbChannels; + AVSampleFormat _sampleFormat; + double _fps; +}; + +/** + * @brief This class describes decoded audio data. + */ +class AvExport AudioFrame : public Frame +{ +public: + /** + * @note Allocated data will be initialized to silence. + */ + AudioFrame(const AudioFrameDesc& ref); + AudioFrame(const Frame& otherFrame); + + size_t getSampleRate() const { return av_frame_get_sample_rate(_frame); } + size_t getNbChannels() const { return av_frame_get_channels(_frame); } + AVSampleFormat getSampleFormat() const { return static_cast(_frame->format); } + size_t getNbSamplesPerChannel() const { return _frame->nb_samples; } + AudioFrameDesc desc() const { return AudioFrameDesc(getSampleRate(), getNbChannels(), getSampleFormat()); } + + size_t getSize() const; ///< in bytes + + void setNbSamplesPerChannel(const size_t nbSamples) { _frame->nb_samples = nbSamples; } + + /** + * @brief Assign the given value to all the data of the audio frame. + */ + void assign(const unsigned char value); + + /** + * @brief Assign the given ptr of data to the data of the audio frame. + * @warning the given ptr should have the size of the audio frame.. + * @see getSize + */ + void assign(const unsigned char* ptrValue); + +private: + void allocateAVSample(const AudioFrameDesc& ref); +}; +} + +#endif diff --git a/src/AvTranscoder/data/decoded/Frame.cpp b/src/AvTranscoder/data/decoded/Frame.cpp new file mode 100644 index 00000000..3b9a59e7 --- /dev/null +++ b/src/AvTranscoder/data/decoded/Frame.cpp @@ -0,0 +1,90 @@ +#include "Frame.hpp" +#include + +namespace avtranscoder +{ + +Frame::Frame() + : _frame(NULL) +{ + allocateAVFrame(); +} + +Frame::Frame(const Frame& otherFrame) + : _frame(NULL) +{ + // allocate frame + allocateAVFrame(); + // check if the frame could be a valid video/audio frame + if(otherFrame.getAVFrame().format == -1) + return; + // reference the other frame + refFrame(otherFrame); +} + +Frame::~Frame() +{ + if(_frame != NULL) + { +#if LIBAVCODEC_VERSION_MAJOR > 54 + av_frame_free(&_frame); +#else +#if LIBAVCODEC_VERSION_MAJOR > 53 + avcodec_free_frame(&_frame); +#else + av_free(_frame); +#endif +#endif + _frame = NULL; + } +} + +unsigned char* Frame::getPlaneData(const size_t plane) +{ + AVBufferRef* buffer = av_frame_get_plane_buffer(_frame, plane); + if(buffer != NULL) + return buffer->data; + return NULL; +} + +void Frame::copyData(const Frame& frameToRef) +{ + const int ret = av_frame_copy(_frame, &frameToRef.getAVFrame()); + if(ret < 0) + { + throw std::ios_base::failure("Unable to copy data of other frame: " + getDescriptionFromErrorCode(ret)); + } +} + +void Frame::copyProperties(const Frame& otherFrame) +{ + av_frame_copy_props(_frame, &otherFrame.getAVFrame()); +} + +void Frame::refFrame(const Frame& otherFrame) +{ + const int ret = av_frame_ref(_frame, &otherFrame.getAVFrame()); + if(ret < 0) + { + throw std::ios_base::failure("Unable to reference other frame: " + getDescriptionFromErrorCode(ret)); + } +} + +void Frame::clear() +{ + av_frame_unref(_frame); +} + +void Frame::allocateAVFrame() +{ +#if LIBAVCODEC_VERSION_MAJOR > 54 + _frame = av_frame_alloc(); +#else + _frame = avcodec_alloc_frame(); +#endif + if(_frame == NULL) + { + throw std::runtime_error("Unable to allocate an empty Frame."); + } +} +} diff --git a/src/AvTranscoder/data/decoded/Frame.hpp b/src/AvTranscoder/data/decoded/Frame.hpp new file mode 100644 index 00000000..c2fe8cc0 --- /dev/null +++ b/src/AvTranscoder/data/decoded/Frame.hpp @@ -0,0 +1,85 @@ +#ifndef _AV_TRANSCODER_FRAME_FRAME_HPP_ +#define _AV_TRANSCODER_FRAME_FRAME_HPP_ + +#include + +extern "C" { +#include +} + +namespace avtranscoder +{ + +/** + * @brief This class describes decoded (raw) audio or video data. + */ +class AvExport Frame +{ +public: + /** + * @brief Allocate an empty frame. + */ + Frame(); + + /** + * @brief Copy properties and reference data of the other frame + */ + Frame(const Frame& otherFrame); + + virtual ~Frame(); + + /** + * @brief Get all the data of the frame. + */ + unsigned char** getData() { return _frame->data; } + + /** + * @return The specified data plane. + */ + unsigned char* getPlaneData(const size_t plane); + + /** + * @brief Returns the size in byte. + * For video, size in bytes of each picture line. + * For audio, size in bytes of each plane. + * @note For audio, only linesize[0] may be set. For planar audio, each channel + * plane must be the same size. + */ + int* getLineSize() const { return _frame->linesize; } + + /** + * @brief Copy the data of the given Frame. + */ + void copyData(const Frame& frameToRef); + + /** + * @brief Copy all the fields that do not affect the data layout in the buffers. + */ + void copyProperties(const Frame& otherFrame); + + /** + * @brief Copy frame properties and create a new reference to data of the given frame. + * @warning This method allocates new data that will be freed only by calling the destructor of the referenced frame. + */ + void refFrame(const Frame& otherFrame); + + /** + * @brief Unreference all the buffers referenced by frame and reset the frame fields. + */ + void clear(); + +#ifndef SWIG + AVFrame& getAVFrame() { return *_frame; } + const AVFrame& getAVFrame() const { return *_frame; } + const unsigned char** getData() const { return const_cast(_frame->data); } +#endif + +private: + void allocateAVFrame(); + +protected: + AVFrame* _frame; +}; +} + +#endif diff --git a/src/AvTranscoder/data/decoded/VideoFrame.cpp b/src/AvTranscoder/data/decoded/VideoFrame.cpp new file mode 100644 index 00000000..38e5f67f --- /dev/null +++ b/src/AvTranscoder/data/decoded/VideoFrame.cpp @@ -0,0 +1,112 @@ +#include "VideoFrame.hpp" + +#include + +extern "C" { +#include +#include +} + +#include +#include + +namespace avtranscoder +{ + +VideoFrameDesc::VideoFrameDesc(const size_t width, const size_t height, const AVPixelFormat pixelFormat) + : _width(width) + , _height(height) + , _pixelFormat(pixelFormat) + , _fps(1.0) +{ +} + +VideoFrameDesc::VideoFrameDesc(const size_t width, const size_t height, const std::string& pixelFormatName) + : _width(width) + , _height(height) + , _pixelFormat(getAVPixelFormat(pixelFormatName)) + , _fps(1.0) +{ +} + +void VideoFrameDesc::setParameters(const ProfileLoader::Profile& profile) +{ + // width + if(profile.count(constants::avProfileWidth)) + _width = atoi(profile.find(constants::avProfileWidth)->second.c_str()); + // height + if(profile.count(constants::avProfileHeight)) + _height = atoi(profile.find(constants::avProfileHeight)->second.c_str()); + // pixel format + if(profile.count(constants::avProfilePixelFormat)) + _pixelFormat = getAVPixelFormat(profile.find(constants::avProfilePixelFormat)->second); + // fps + if(profile.count(constants::avProfileFrameRate)) + _fps = atof(profile.find(constants::avProfileFrameRate)->second.c_str()); +} + +VideoFrame::VideoFrame(const VideoFrameDesc& ref) + : Frame() +{ + allocateAVPicture(ref); +} + +VideoFrame::VideoFrame(const Frame& otherFrame) + : Frame(otherFrame) +{ +} + +size_t VideoFrame::getSize() const +{ + if(getPixelFormat() == AV_PIX_FMT_NONE) + { + LOG_WARN("Incorrect pixel format when get size of video frame: return a size of 0.") + return 0; + } + + const size_t size = avpicture_get_size(getPixelFormat(), getWidth(), getHeight()); + if(size == 0) + throw std::runtime_error("unable to determine image buffer size"); + return size; +} + +void VideoFrame::allocateAVPicture(const VideoFrameDesc& desc) +{ + const int ret = avpicture_alloc(reinterpret_cast(_frame), desc._pixelFormat, desc._width, desc._height); + if(ret < 0) + { + std::stringstream os; + os << "Unable to allocate an image frame of "; + os << "width = " << desc._width << ", "; + os << "height = " << desc._height << ", "; + os << "pixel format = " << desc._pixelFormat; + throw std::runtime_error(os.str()); + } + _frame->width = desc._width; + _frame->height = desc._height; + _frame->format = desc._pixelFormat; +} + +void VideoFrame::assign(const unsigned char value) +{ + // Create the image buffer + const int imageSize = getSize(); + unsigned char imageBuffer[imageSize]; + memset(imageBuffer, value, imageSize); + + // Fill the picture + assign(imageBuffer); +} + +void VideoFrame::assign(const unsigned char* ptrValue) +{ + const int ret = + avpicture_fill(reinterpret_cast(_frame), ptrValue, getPixelFormat(), getWidth(), getHeight()); + if(ret < 0) + { + std::stringstream os; + os << "Unable to assign an image buffer of " << getSize() << " bytes: " << getDescriptionFromErrorCode(ret); + throw std::runtime_error(os.str()); + } +} +} diff --git a/src/AvTranscoder/data/decoded/VideoFrame.hpp b/src/AvTranscoder/data/decoded/VideoFrame.hpp new file mode 100644 index 00000000..ae9e22f9 --- /dev/null +++ b/src/AvTranscoder/data/decoded/VideoFrame.hpp @@ -0,0 +1,73 @@ +#ifndef _AV_TRANSCODER_FRAME_VIDEO_FRAME_HPP_ +#define _AV_TRANSCODER_FRAME_VIDEO_FRAME_HPP_ + +#include "Frame.hpp" +#include + +extern "C" { +#include +#include +} + +namespace avtranscoder +{ + +/** + * @brief Description to create a video frame. + * @param width + * @param height + * @param pixelFormat + */ +struct AvExport VideoFrameDesc +{ +public: + VideoFrameDesc(const size_t width = 0, const size_t height = 0, const AVPixelFormat pixelFormat = AV_PIX_FMT_NONE); + VideoFrameDesc(const size_t width, const size_t height, const std::string& pixelFormatName); + + /** + * @brief Set the attributes from the given profile. + * @see Profile + */ + void setParameters(const ProfileLoader::Profile& profile); + +public: + size_t _width; + size_t _height; + AVPixelFormat _pixelFormat; + double _fps; +}; + +/** + * @brief This class describes decoded video data. + */ +class AvExport VideoFrame : public Frame +{ +public: + VideoFrame(const VideoFrameDesc& ref); + VideoFrame(const Frame& otherFrame); + + size_t getWidth() const { return _frame->width; } + size_t getHeight() const { return _frame->height; } + AVPixelFormat getPixelFormat() const { return static_cast(_frame->format); } + VideoFrameDesc desc() const { return VideoFrameDesc(getWidth(), getHeight(), getPixelFormat()); } + + size_t getSize() const; ///< in bytes/** + + /** + * @brief Assign the given value to all the data of the picture. + */ + void assign(const unsigned char value); + + /** + * @brief Assign the given ptr of data to the data of the picture. + * @warning the given ptr should have the size of the picture. + * @see getSize + */ + void assign(const unsigned char* ptrValue); + +private: + void allocateAVPicture(const VideoFrameDesc& desc); +}; +} + +#endif diff --git a/src/AvTranscoder/decoder/AudioDecoder.cpp b/src/AvTranscoder/decoder/AudioDecoder.cpp index 13513001..c0a681b1 100644 --- a/src/AvTranscoder/decoder/AudioDecoder.cpp +++ b/src/AvTranscoder/decoder/AudioDecoder.cpp @@ -2,7 +2,7 @@ #include #include -#include +#include extern "C" { #include @@ -20,35 +20,12 @@ namespace avtranscoder AudioDecoder::AudioDecoder(InputStream& inputStream) : _inputStream(&inputStream) - , _frame(NULL) , _isSetup(false) { -#if LIBAVCODEC_VERSION_MAJOR > 54 - _frame = av_frame_alloc(); -#else - _frame = avcodec_alloc_frame(); -#endif - if(_frame == NULL) - { - throw std::runtime_error("unable to setup frame buffer"); - } } AudioDecoder::~AudioDecoder() { - if(_frame != NULL) - { -#if LIBAVCODEC_VERSION_MAJOR > 54 - av_frame_free(&_frame); -#else -#if LIBAVCODEC_VERSION_MAJOR > 53 - avcodec_free_frame(&_frame); -#else - av_free(_frame); -#endif -#endif - _frame = NULL; - } } void AudioDecoder::setupDecoder(const ProfileLoader::Profile& profile) @@ -100,46 +77,62 @@ void AudioDecoder::setupDecoder(const ProfileLoader::Profile& profile) bool AudioDecoder::decodeNextFrame(Frame& frameBuffer) { - if(!decodeNextFrame()) - return false; - - AVCodecContext& avCodecContext = _inputStream->getAudioCodec().getAVCodecContext(); + bool decodeNextFrame = false; - const int noAlignment = 1; - const size_t decodedSize = av_samples_get_buffer_size(NULL, avCodecContext.channels, _frame->nb_samples, - avCodecContext.sample_fmt, noAlignment); - if(decodedSize == 0) - return false; + if(!_isSetup) + setupDecoder(); - AudioFrame& audioBuffer = static_cast(frameBuffer); - audioBuffer.setNbSamplesPerChannel(_frame->nb_samples); - audioBuffer.resize(decodedSize); + int got_frame = 0; + while(!got_frame) + { + CodedData data; - // @todo manage cases with data of frame not only on data[0] (use _frame.linesize) - unsigned char* const src = _frame->data[0]; - unsigned char* dst = audioBuffer.getData(); + const bool nextPacketRead = _inputStream->readNextPacket(data); + // if error or end of file + if(!nextPacketRead) + { + data.clear(); + return false; + } - av_samples_copy(&dst, &src, 0, 0, _frame->nb_samples, avCodecContext.channels, avCodecContext.sample_fmt); + // decoding + int ret = avcodec_decode_audio4(&_inputStream->getAudioCodec().getAVCodecContext(), &frameBuffer.getAVFrame(), + &got_frame, &data.getAVPacket()); + if(ret < 0) + { + throw std::runtime_error("an error occured during audio decoding" + getDescriptionFromErrorCode(ret)); + } - return true; + // if no frame could be decompressed + if(!nextPacketRead && ret == 0 && got_frame == 0) + decodeNextFrame = false; + else + decodeNextFrame = true; + } + return decodeNextFrame; } bool AudioDecoder::decodeNextFrame(Frame& frameBuffer, const size_t channelIndex) { - if(!decodeNextFrame()) + AudioFrame& audioBuffer = static_cast(frameBuffer); + + // decode all data of the next frame + AudioFrame allDataOfNextFrame(audioBuffer.desc()); + if(!decodeNextFrame(allDataOfNextFrame)) return false; AVCodecContext& avCodecContext = _inputStream->getAudioCodec().getAVCodecContext(); const size_t srcNbChannels = avCodecContext.channels; - const size_t bytePerSample = av_get_bytes_per_sample((AVSampleFormat)_frame->format); + const size_t bytePerSample = av_get_bytes_per_sample((AVSampleFormat)frameBuffer.getAVFrame().format); const int dstNbChannels = 1; - const int noAlignment = 1; - const size_t decodedSize = - av_samples_get_buffer_size(NULL, dstNbChannels, _frame->nb_samples, avCodecContext.sample_fmt, noAlignment); + const int noAlignment = 0; + const size_t decodedSize = av_samples_get_buffer_size(NULL, dstNbChannels, frameBuffer.getAVFrame().nb_samples, + avCodecContext.sample_fmt, noAlignment); if(decodedSize == 0) return false; + // check if the expected channel exists if(channelIndex > srcNbChannels - 1) { std::stringstream msg; @@ -151,18 +144,21 @@ bool AudioDecoder::decodeNextFrame(Frame& frameBuffer, const size_t channelIndex throw std::runtime_error(msg.str()); } - AudioFrame& audioBuffer = static_cast(frameBuffer); - audioBuffer.setNbSamplesPerChannel(_frame->nb_samples); - audioBuffer.resize(decodedSize); + // copy frame properties of decoded frame + audioBuffer.copyProperties(allDataOfNextFrame); + av_frame_set_channels(&audioBuffer.getAVFrame(), 1); + av_frame_set_channel_layout(&audioBuffer.getAVFrame(), AV_CH_LAYOUT_MONO); + audioBuffer.setNbSamplesPerChannel(allDataOfNextFrame.getNbSamplesPerChannel()); // @todo manage cases with data of frame not only on data[0] (use _frame.linesize) - unsigned char* src = _frame->data[0]; - unsigned char* dst = audioBuffer.getData(); + unsigned char* src = allDataOfNextFrame.getAVFrame().data[0]; + unsigned char* dst = audioBuffer.getData()[0]; // offset src += channelIndex * bytePerSample; - for(int sample = 0; sample < _frame->nb_samples; ++sample) + // extract one channel + for(int sample = 0; sample < allDataOfNextFrame.getAVFrame().nb_samples; ++sample) { memcpy(dst, src, bytePerSample); dst += bytePerSample; @@ -172,33 +168,6 @@ bool AudioDecoder::decodeNextFrame(Frame& frameBuffer, const size_t channelIndex return true; } -bool AudioDecoder::decodeNextFrame() -{ - if(!_isSetup) - setupDecoder(); - - int got_frame = 0; - while(!got_frame) - { - CodedData data; - - bool nextPacketRead = _inputStream->readNextPacket(data); - if(!nextPacketRead) // error or end of file - data.clear(); - - int ret = avcodec_decode_audio4(&_inputStream->getAudioCodec().getAVCodecContext(), _frame, &got_frame, - &data.getAVPacket()); - if(!nextPacketRead && ret == 0 && got_frame == 0) // no frame could be decompressed - return false; - - if(ret < 0) - { - throw std::runtime_error("an error occured during audio decoding" + getDescriptionFromErrorCode(ret)); - } - } - 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 1d401eef..a2a6f2b8 100644 --- a/src/AvTranscoder/decoder/AudioDecoder.hpp +++ b/src/AvTranscoder/decoder/AudioDecoder.hpp @@ -3,8 +3,6 @@ #include "IDecoder.hpp" -struct AVFrame; - namespace avtranscoder { @@ -23,12 +21,8 @@ class AvExport AudioDecoder : public IDecoder void flushDecoder(); -private: - bool decodeNextFrame(); - 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/AudioGenerator.cpp b/src/AvTranscoder/decoder/AudioGenerator.cpp index eae58331..0e644841 100644 --- a/src/AvTranscoder/decoder/AudioGenerator.cpp +++ b/src/AvTranscoder/decoder/AudioGenerator.cpp @@ -33,7 +33,7 @@ AudioGenerator::~AudioGenerator() void AudioGenerator::setAudioFrameDesc(const AudioFrameDesc& frameDesc) { _frameDesc = frameDesc; - _frameDesc.setFps(25.); + _frameDesc._fps = 25.; } void AudioGenerator::setFrame(Frame& inputFrame) @@ -46,24 +46,19 @@ bool AudioGenerator::decodeNextFrame(Frame& frameBuffer) // Generate silent if(!_inputFrame) { - AudioFrame& audioBuffer = static_cast(frameBuffer); - audioBuffer.setNbSamplesPerChannel(_frameDesc.getSampleRate() / _frameDesc.getFps()); - // Generate the silent only once if(!_silent) { - int fillChar = 0; - + AudioFrame& audioBuffer = static_cast(frameBuffer); _silent = new AudioFrame(audioBuffer.desc()); - _silent->assign(_frameDesc.getDataSize(), fillChar); - _silent->setNbSamplesPerChannel(audioBuffer.getNbSamplesPerChannel()); } - frameBuffer.refData(*_silent); + frameBuffer.getAVFrame().nb_samples = _silent->getAVFrame().nb_samples; + frameBuffer.copyData(*_silent); } // Take audio frame from _inputFrame else { - frameBuffer.refData(_inputFrame->getData(), _inputFrame->getSize()); + frameBuffer.copyData(*_inputFrame); } return true; } diff --git a/src/AvTranscoder/decoder/AudioGenerator.hpp b/src/AvTranscoder/decoder/AudioGenerator.hpp index 2ff09bb6..016658a6 100644 --- a/src/AvTranscoder/decoder/AudioGenerator.hpp +++ b/src/AvTranscoder/decoder/AudioGenerator.hpp @@ -21,6 +21,7 @@ class AvExport AudioGenerator : public IDecoder const AudioFrameDesc& getAudioFrameDesc() const { return _frameDesc; } void setAudioFrameDesc(const AudioFrameDesc& frameDesc); + void setFrame(Frame& inputFrame); private: diff --git a/src/AvTranscoder/decoder/IDecoder.hpp b/src/AvTranscoder/decoder/IDecoder.hpp index a7232f6d..c9af9148 100644 --- a/src/AvTranscoder/decoder/IDecoder.hpp +++ b/src/AvTranscoder/decoder/IDecoder.hpp @@ -2,7 +2,7 @@ #define _AV_TRANSCODER_ESSENCE_STREAM_IDECODER_HPP_ #include -#include +#include #include namespace avtranscoder diff --git a/src/AvTranscoder/decoder/VideoDecoder.cpp b/src/AvTranscoder/decoder/VideoDecoder.cpp index 99856e8c..72e5759e 100644 --- a/src/AvTranscoder/decoder/VideoDecoder.cpp +++ b/src/AvTranscoder/decoder/VideoDecoder.cpp @@ -2,7 +2,7 @@ #include #include -#include +#include extern "C" { #include @@ -18,35 +18,12 @@ namespace avtranscoder VideoDecoder::VideoDecoder(InputStream& inputStream) : _inputStream(&inputStream) - , _frame(NULL) , _isSetup(false) { -#if LIBAVCODEC_VERSION_MAJOR > 54 - _frame = av_frame_alloc(); -#else - _frame = avcodec_alloc_frame(); -#endif - if(_frame == NULL) - { - throw std::runtime_error("unable to setup frame buffer"); - } } VideoDecoder::~VideoDecoder() { - if(_frame != NULL) - { -#if LIBAVCODEC_VERSION_MAJOR > 54 - av_frame_free(&_frame); -#else -#if LIBAVCODEC_VERSION_MAJOR > 53 - avcodec_free_frame(&_frame); -#else - av_free(_frame); -#endif -#endif - _frame = NULL; - } } void VideoDecoder::setupDecoder(const ProfileLoader::Profile& profile) @@ -98,30 +75,8 @@ void VideoDecoder::setupDecoder(const ProfileLoader::Profile& profile) bool VideoDecoder::decodeNextFrame(Frame& frameBuffer) { - if(!decodeNextFrame()) - return false; - - size_t decodedSize = avpicture_get_size((AVPixelFormat)_frame->format, _frame->width, _frame->height); - if(decodedSize == 0) - return false; - - VideoFrame& imageBuffer = static_cast(frameBuffer); - imageBuffer.resize(decodedSize); - - // Copy pixel data from an AVPicture into one contiguous buffer. - avpicture_layout((AVPicture*)_frame, (AVPixelFormat)_frame->format, _frame->width, _frame->height, imageBuffer.getData(), - frameBuffer.getSize()); - - return true; -} - -bool VideoDecoder::decodeNextFrame(Frame& frameBuffer, const size_t subStreamIndex) -{ - return false; -} + bool decodeNextFrame = false; -bool VideoDecoder::decodeNextFrame() -{ if(!_isSetup) setupDecoder(); @@ -130,21 +85,34 @@ bool VideoDecoder::decodeNextFrame() { CodedData data; - bool nextPacketRead = _inputStream->readNextPacket(data); - if(!nextPacketRead) // error or end of file + const bool nextPacketRead = _inputStream->readNextPacket(data); + // if error or end of file + if(!nextPacketRead) + { data.clear(); - - int ret = avcodec_decode_video2(&_inputStream->getVideoCodec().getAVCodecContext(), _frame, &got_frame, - &data.getAVPacket()); - if(!nextPacketRead && ret == 0 && got_frame == 0) // no frame could be decompressed return false; + } + // decoding + const int ret = avcodec_decode_video2(&_inputStream->getVideoCodec().getAVCodecContext(), &frameBuffer.getAVFrame(), + &got_frame, &data.getAVPacket()); if(ret < 0) { throw std::runtime_error("an error occured during video decoding - " + getDescriptionFromErrorCode(ret)); } + + // if no frame could be decompressed + if(!nextPacketRead && ret == 0 && got_frame == 0) + decodeNextFrame = false; + else + decodeNextFrame = true; } - return true; + return decodeNextFrame; +} + +bool VideoDecoder::decodeNextFrame(Frame& frameBuffer, const size_t subStreamIndex) +{ + return false; } void VideoDecoder::flushDecoder() diff --git a/src/AvTranscoder/decoder/VideoDecoder.hpp b/src/AvTranscoder/decoder/VideoDecoder.hpp index c1bdea82..69b8419d 100644 --- a/src/AvTranscoder/decoder/VideoDecoder.hpp +++ b/src/AvTranscoder/decoder/VideoDecoder.hpp @@ -3,8 +3,6 @@ #include "IDecoder.hpp" -struct AVFrame; - namespace avtranscoder { @@ -23,12 +21,8 @@ class AvExport VideoDecoder : public IDecoder void flushDecoder(); -private: - bool decodeNextFrame(); - 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/VideoGenerator.cpp b/src/AvTranscoder/decoder/VideoGenerator.cpp index 31cce744..74f16a6f 100644 --- a/src/AvTranscoder/decoder/VideoGenerator.cpp +++ b/src/AvTranscoder/decoder/VideoGenerator.cpp @@ -1,5 +1,6 @@ #include "VideoGenerator.hpp" +#include #include namespace avtranscoder @@ -50,30 +51,29 @@ bool VideoGenerator::decodeNextFrame(Frame& frameBuffer) // Generate the black image only once if(!_blackImage) { - // @todo support PAL (0 to 255) and NTFS (16 to 235) - char fillChar = 0; + VideoFrame& imageBuffer = static_cast(frameBuffer); - // input of convert + // Input of convert + // @todo support PAL (0 to 255) and NTFS (16 to 235) VideoFrameDesc desc(_frameDesc); - desc.setPixelFormat("rgb24"); - + desc._pixelFormat = getAVPixelFormat("rgb24"); VideoFrame intermediateBuffer(desc); - intermediateBuffer.assign(_frameDesc.getDataSize(), fillChar); + const unsigned char fillChar = 0; + intermediateBuffer.assign(fillChar); - // output of convert - VideoFrame& imageBuffer = static_cast(frameBuffer); + // Output of convert _blackImage = new VideoFrame(imageBuffer.desc()); - // convert and store the black image + // Convert and store the black image VideoTransform videoTransform; videoTransform.convert(intermediateBuffer, *_blackImage); } - frameBuffer.refData(*_blackImage); + frameBuffer.copyData(*_blackImage); } // Take image from _inputFrame else { - frameBuffer.refData(_inputFrame->getData(), _inputFrame->getSize()); + frameBuffer.copyData(*_inputFrame); } return true; } diff --git a/src/AvTranscoder/decoder/VideoGenerator.hpp b/src/AvTranscoder/decoder/VideoGenerator.hpp index 3c07f4b4..888c2c3c 100644 --- a/src/AvTranscoder/decoder/VideoGenerator.hpp +++ b/src/AvTranscoder/decoder/VideoGenerator.hpp @@ -21,6 +21,7 @@ class AvExport VideoGenerator : public IDecoder const VideoFrameDesc& getVideoFrameDesc() const { return _frameDesc; } void setVideoFrameDesc(const VideoFrameDesc& frameDesc); + void setNextFrame(Frame& inputFrame); private: diff --git a/src/AvTranscoder/encoder/AudioEncoder.cpp b/src/AvTranscoder/encoder/AudioEncoder.cpp index 3cc17563..afede6e4 100644 --- a/src/AvTranscoder/encoder/AudioEncoder.cpp +++ b/src/AvTranscoder/encoder/AudioEncoder.cpp @@ -13,26 +13,11 @@ namespace avtranscoder AudioEncoder::AudioEncoder(const std::string& audioCodecName) : _codec(eCodecTypeEncoder, audioCodecName) - , _frame(NULL) { -#if LIBAVCODEC_VERSION_MAJOR > 54 - _frame = av_frame_alloc(); -#else - _frame = avcodec_alloc_frame(); -#endif } AudioEncoder::~AudioEncoder() { -#if LIBAVCODEC_VERSION_MAJOR > 54 - av_frame_free(&_frame); -#else -#if LIBAVCODEC_VERSION_MAJOR > 53 - avcodec_free_frame(&_frame); -#else - av_free(_frame); -#endif -#endif } void AudioEncoder::setupAudioEncoder(const AudioFrameDesc& frameDesc, const ProfileLoader::Profile& profile) @@ -106,39 +91,10 @@ void AudioEncoder::setupEncoder(const ProfileLoader::Profile& profile) } } -bool AudioEncoder::encodeFrame(const Frame& sourceFrame, Frame& codedFrame) +bool AudioEncoder::encodeFrame(const Frame& sourceFrame, CodedData& codedFrame) { AVCodecContext& avCodecContext = _codec.getAVCodecContext(); -// Set default frame parameters -#if LIBAVCODEC_VERSION_MAJOR > 54 - av_frame_unref(_frame); -#else - avcodec_get_frame_defaults(_frame); -#endif - - const AudioFrame& sourceAudioFrame = static_cast(sourceFrame); - - _frame->nb_samples = sourceAudioFrame.getNbSamplesPerChannel(); - _frame->format = avCodecContext.sample_fmt; - _frame->channel_layout = avCodecContext.channel_layout; - - // we calculate the size of the samples buffer in bytes - int bufferSize = - av_samples_get_buffer_size(NULL, avCodecContext.channels, _frame->nb_samples, avCodecContext.sample_fmt, 0); - if(bufferSize < 0) - { - throw std::runtime_error("Encode audio frame error: buffer size < 0 - " + getDescriptionFromErrorCode(bufferSize)); - } - - int retvalue = avcodec_fill_audio_frame(_frame, avCodecContext.channels, avCodecContext.sample_fmt, - sourceAudioFrame.getData(), bufferSize, 0); - if(retvalue < 0) - { - throw std::runtime_error("Encode audio frame error: avcodec fill audio frame - " + - getDescriptionFromErrorCode(retvalue)); - } - AVPacket& packet = codedFrame.getAVPacket(); packet.stream_index = 0; @@ -154,14 +110,14 @@ bool AudioEncoder::encodeFrame(const Frame& sourceFrame, Frame& codedFrame) #if LIBAVCODEC_VERSION_MAJOR > 53 int gotPacket = 0; - int ret = avcodec_encode_audio2(&avCodecContext, &packet, _frame, &gotPacket); + int ret = avcodec_encode_audio2(&avCodecContext, &packet, &sourceFrame.getAVFrame(), &gotPacket); if(ret != 0 && gotPacket == 0) { throw std::runtime_error("Encode audio frame error: avcodec encode audio frame - " + getDescriptionFromErrorCode(ret)); } #else - int ret = avcodec_encode_audio(&avCodecContext, packet.data, packet.size, _frame); + int ret = avcodec_encode_audio(&avCodecContext, packet.data, packet.size, &sourceFrame.getAVFrame()); if(ret < 0) { throw std::runtime_error("Encode audio frame error: avcodec encode audio frame - " + @@ -175,7 +131,7 @@ bool AudioEncoder::encodeFrame(const Frame& sourceFrame, Frame& codedFrame) return ret == 0; } -bool AudioEncoder::encodeFrame(Frame& codedFrame) +bool AudioEncoder::encodeFrame(CodedData& codedFrame) { AVCodecContext& avCodecContext = _codec.getAVCodecContext(); diff --git a/src/AvTranscoder/encoder/AudioEncoder.hpp b/src/AvTranscoder/encoder/AudioEncoder.hpp index c00089db..50f3246d 100644 --- a/src/AvTranscoder/encoder/AudioEncoder.hpp +++ b/src/AvTranscoder/encoder/AudioEncoder.hpp @@ -18,15 +18,14 @@ class AvExport AudioEncoder : public IEncoder const ProfileLoader::Profile& profile = ProfileLoader::Profile()); void setupEncoder(const ProfileLoader::Profile& profile = ProfileLoader::Profile()); - bool encodeFrame(const Frame& sourceFrame, Frame& codedFrame); - bool encodeFrame(Frame& codedFrame); + bool encodeFrame(const Frame& sourceFrame, CodedData& codedFrame); + bool encodeFrame(CodedData& codedFrame); ICodec& getCodec() { return _codec; } AudioCodec& getAudioCodec() { return _codec; } private: AudioCodec _codec; - AVFrame* _frame; ///< Contains the encoded data to pass to the Frame when encodeFrame }; } diff --git a/src/AvTranscoder/encoder/IEncoder.hpp b/src/AvTranscoder/encoder/IEncoder.hpp index db9ccfca..55e8d3fa 100644 --- a/src/AvTranscoder/encoder/IEncoder.hpp +++ b/src/AvTranscoder/encoder/IEncoder.hpp @@ -1,7 +1,8 @@ #ifndef _AV_TRANSCODER_ESSENCE_STREAM_IENCODER_HPP_ #define _AV_TRANSCODER_ESSENCE_STREAM_IENCODER_HPP_ -#include +#include +#include #include #include @@ -26,14 +27,14 @@ class AvExport IEncoder * @param codedFrame data of the coded frame if present (first frames can be delayed) * @return status of encoding */ - virtual bool encodeFrame(const Frame& sourceFrame, Frame& codedFrame) = 0; + virtual bool encodeFrame(const Frame& sourceFrame, CodedData& codedFrame) = 0; /** * @brief Get delayed encoded frames * @param codedFrame data of the coded frame if present (first frames can be delayed) * @return status of encoding */ - virtual bool encodeFrame(Frame& codedFrame) = 0; + virtual bool encodeFrame(CodedData& codedFrame) = 0; /** * @brief Get codec used for encoding. diff --git a/src/AvTranscoder/encoder/VideoEncoder.cpp b/src/AvTranscoder/encoder/VideoEncoder.cpp index 0e6b0ae0..8c7f14e8 100644 --- a/src/AvTranscoder/encoder/VideoEncoder.cpp +++ b/src/AvTranscoder/encoder/VideoEncoder.cpp @@ -14,26 +14,11 @@ namespace avtranscoder VideoEncoder::VideoEncoder(const std::string& videoCodecName) : _codec(eCodecTypeEncoder, videoCodecName) - , _frame(NULL) { -#if LIBAVCODEC_VERSION_MAJOR > 54 - _frame = av_frame_alloc(); -#else - _frame = avcodec_alloc_frame(); -#endif } VideoEncoder::~VideoEncoder() { -#if LIBAVCODEC_VERSION_MAJOR > 54 - av_frame_free(&_frame); -#else -#if LIBAVCODEC_VERSION_MAJOR > 53 - avcodec_free_frame(&_frame); -#else - av_free(_frame); -#endif -#endif } void VideoEncoder::setupVideoEncoder(const VideoFrameDesc& frameDesc, const ProfileLoader::Profile& profile) @@ -119,30 +104,10 @@ void VideoEncoder::setupEncoder(const ProfileLoader::Profile& profile) } } -bool VideoEncoder::encodeFrame(const Frame& sourceFrame, Frame& codedFrame) +bool VideoEncoder::encodeFrame(const Frame& sourceFrame, CodedData& codedFrame) { AVCodecContext& avCodecContext = _codec.getAVCodecContext(); -// Set default frame parameters -#if LIBAVCODEC_VERSION_MAJOR > 54 - av_frame_unref(_frame); -#else - avcodec_get_frame_defaults(_frame); -#endif - - const VideoFrame& sourceImageFrame = static_cast(sourceFrame); - - _frame->width = avCodecContext.width; - _frame->height = avCodecContext.height; - _frame->format = avCodecContext.pix_fmt; - - int bufferSize = avpicture_fill((AVPicture*)_frame, const_cast(sourceImageFrame.getData()), - avCodecContext.pix_fmt, avCodecContext.width, avCodecContext.height); - if(bufferSize < 0) - { - throw std::runtime_error("Encode video frame error: buffer size < 0 - " + getDescriptionFromErrorCode(bufferSize)); - } - AVPacket& packet = codedFrame.getAVPacket(); packet.stream_index = 0; @@ -158,14 +123,14 @@ bool VideoEncoder::encodeFrame(const Frame& sourceFrame, Frame& codedFrame) #if LIBAVCODEC_VERSION_MAJOR > 53 int gotPacket = 0; - int ret = avcodec_encode_video2(&avCodecContext, &packet, _frame, &gotPacket); + int ret = avcodec_encode_video2(&avCodecContext, &packet, &sourceFrame.getAVFrame(), &gotPacket); if(ret != 0 && gotPacket == 0) { throw std::runtime_error("Encode video frame error: avcodec encode video frame - " + getDescriptionFromErrorCode(ret)); } #else - int ret = avcodec_encode_video(&avCodecContext, packet.data, packet.size, _frame); + int ret = avcodec_encode_video(&avCodecContext, packet.data, packet.size, &sourceFrame.getAVFrame()); if(ret < 0) { throw std::runtime_error("Encode video frame error: avcodec encode video frame - " + @@ -179,7 +144,7 @@ bool VideoEncoder::encodeFrame(const Frame& sourceFrame, Frame& codedFrame) return ret == 0; } -bool VideoEncoder::encodeFrame(Frame& codedFrame) +bool VideoEncoder::encodeFrame(CodedData& codedFrame) { AVCodecContext& avCodecContext = _codec.getAVCodecContext(); diff --git a/src/AvTranscoder/encoder/VideoEncoder.hpp b/src/AvTranscoder/encoder/VideoEncoder.hpp index 4a27e1da..6f8a910d 100644 --- a/src/AvTranscoder/encoder/VideoEncoder.hpp +++ b/src/AvTranscoder/encoder/VideoEncoder.hpp @@ -18,15 +18,14 @@ class AvExport VideoEncoder : public IEncoder const ProfileLoader::Profile& profile = ProfileLoader::Profile()); void setupEncoder(const ProfileLoader::Profile& profile = ProfileLoader::Profile()); - bool encodeFrame(const Frame& sourceFrame, Frame& codedFrame); - bool encodeFrame(Frame& codedFrame); + bool encodeFrame(const Frame& sourceFrame, CodedData& codedFrame); + bool encodeFrame(CodedData& codedFrame); ICodec& getCodec() { return _codec; } VideoCodec& getVideoCodec() { return _codec; } private: VideoCodec _codec; - AVFrame* _frame; ///< Contains the encoded data to pass to the Frame when encodeFrame }; } diff --git a/src/AvTranscoder/reader/AudioReader.cpp b/src/AvTranscoder/reader/AudioReader.cpp index 530e3453..f47bf919 100644 --- a/src/AvTranscoder/reader/AudioReader.cpp +++ b/src/AvTranscoder/reader/AudioReader.cpp @@ -1,7 +1,8 @@ #include "AudioReader.hpp" +#include #include -#include +#include #include #include @@ -48,8 +49,8 @@ void AudioReader::init() _srcFrame = new AudioFrame(_inputFile->getStream(_streamIndex).getAudioCodec().getAudioFrameDesc()); AudioFrame* srcFrame = static_cast(_srcFrame); // create dst frame - _outputSampleRate = srcFrame->desc().getSampleRate(); - _outputNbChannels = (_channelIndex == -1) ? srcFrame->desc().getNbChannels() : 1; + _outputSampleRate = srcFrame->getSampleRate(); + _outputNbChannels = (_channelIndex == -1) ? srcFrame->getNbChannels() : 1; _dstFrame = new AudioFrame(AudioFrameDesc(_outputSampleRate, _outputNbChannels, _outputSampleFormat)); } @@ -65,7 +66,7 @@ void AudioReader::updateOutput(const size_t sampleRate, const size_t nbChannels, { _outputSampleRate = sampleRate; _outputNbChannels = nbChannels; - _outputSampleFormat = av_get_sample_fmt(sampleFormat.c_str()); + _outputSampleFormat = getAVSampleFormat(sampleFormat); // update dst frame delete _dstFrame; _dstFrame = new AudioFrame(AudioFrameDesc(_outputSampleRate, _outputNbChannels, _outputSampleFormat)); diff --git a/src/AvTranscoder/reader/IReader.hpp b/src/AvTranscoder/reader/IReader.hpp index 6b654770..51e41083 100644 --- a/src/AvTranscoder/reader/IReader.hpp +++ b/src/AvTranscoder/reader/IReader.hpp @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include namespace avtranscoder diff --git a/src/AvTranscoder/reader/VideoReader.cpp b/src/AvTranscoder/reader/VideoReader.cpp index cae21a40..d5ddd5f7 100644 --- a/src/AvTranscoder/reader/VideoReader.cpp +++ b/src/AvTranscoder/reader/VideoReader.cpp @@ -1,7 +1,7 @@ #include "VideoReader.hpp" #include -#include +#include #include #include @@ -48,9 +48,8 @@ void VideoReader::init() _srcFrame = new VideoFrame(_inputFile->getStream(_streamIndex).getVideoCodec().getVideoFrameDesc()); VideoFrame* srcFrame = static_cast(_srcFrame); // create dst frame - _outputWidth = srcFrame->desc().getWidth(); - _outputHeight = srcFrame->desc().getHeight(); - _outputPixelProperties = PixelProperties("rgb24"); + _outputWidth = srcFrame->getWidth(); + _outputHeight = srcFrame->getHeight(); _dstFrame = new VideoFrame(VideoFrameDesc(_outputWidth, _outputHeight, getOutputPixelFormat())); } diff --git a/src/AvTranscoder/stream/IInputStream.hpp b/src/AvTranscoder/stream/IInputStream.hpp index c091b36b..f1752e2c 100644 --- a/src/AvTranscoder/stream/IInputStream.hpp +++ b/src/AvTranscoder/stream/IInputStream.hpp @@ -7,7 +7,7 @@ #include #include -#include +#include namespace avtranscoder { diff --git a/src/AvTranscoder/stream/IOutputStream.hpp b/src/AvTranscoder/stream/IOutputStream.hpp index edb867ef..3bf279ee 100644 --- a/src/AvTranscoder/stream/IOutputStream.hpp +++ b/src/AvTranscoder/stream/IOutputStream.hpp @@ -3,7 +3,7 @@ #include #include -#include +#include namespace avtranscoder { diff --git a/src/AvTranscoder/transcoder/StreamTranscoder.cpp b/src/AvTranscoder/transcoder/StreamTranscoder.cpp index c7d90332..e03093e1 100644 --- a/src/AvTranscoder/transcoder/StreamTranscoder.cpp +++ b/src/AvTranscoder/transcoder/StreamTranscoder.cpp @@ -186,7 +186,7 @@ StreamTranscoder::StreamTranscoder(IInputStream& inputStream, IOutputFile& outpu if(subStreamIndex > -1) { // @todo manage downmix ? - outputFrameDesc.setNbChannels(1); + outputFrameDesc._nbChannels = 1; } outputAudio->setupAudioEncoder(outputFrameDesc, profile); @@ -196,7 +196,7 @@ StreamTranscoder::StreamTranscoder(IInputStream& inputStream, IOutputFile& outpu // buffers to process AudioFrameDesc inputFrameDesc(_inputStream->getAudioCodec().getAudioFrameDesc()); if(subStreamIndex > -1) - inputFrameDesc.setNbChannels(1); + inputFrameDesc._nbChannels = 1; _sourceBuffer = new AudioFrame(inputFrameDesc); _frameBuffer = new AudioFrame(outputAudio->getAudioCodec().getAudioFrameDesc()); @@ -346,7 +346,7 @@ void StreamTranscoder::preProcessCodecLatency() bool StreamTranscoder::processFrame() { const EProcessCase processCase = getProcessCase(); - std::string msg = "Current process case of the stream is a "; + std::string msg = "Current process case of the stream is a "; switch(processCase) { case eProcessCaseTranscode: @@ -467,10 +467,10 @@ bool StreamTranscoder::processTranscode(const int subStreamIndex) CodedData data; if(decodingStatus) { - LOG_DEBUG("Convert (" << _sourceBuffer->getSize() << " bytes)") + LOG_DEBUG("Convert") _transform->convert(*_sourceBuffer, *_frameBuffer); - LOG_DEBUG("Encode (" << _frameBuffer->getSize() << " bytes)") + LOG_DEBUG("Encode") _outputEncoder->encodeFrame(*_frameBuffer, data); } else diff --git a/src/AvTranscoder/transform/AudioTransform.cpp b/src/AvTranscoder/transform/AudioTransform.cpp index f66c198e..593965ea 100644 --- a/src/AvTranscoder/transform/AudioTransform.cpp +++ b/src/AvTranscoder/transform/AudioTransform.cpp @@ -1,6 +1,7 @@ #include "AudioTransform.hpp" -#include +#include +#include extern "C" { #include @@ -33,7 +34,6 @@ namespace avtranscoder AudioTransform::AudioTransform() : _audioConvertContext(NULL) - , _previousNbInputSamplesPerChannel(0) , _isInit(false) { } @@ -45,6 +45,7 @@ AudioTransform::~AudioTransform() bool AudioTransform::init(const Frame& srcFrame, const Frame& dstFrame) { + // Set convert context _audioConvertContext = AllocResampleContext(); if(!_audioConvertContext) { @@ -54,80 +55,66 @@ bool AudioTransform::init(const Frame& srcFrame, const Frame& dstFrame) const AudioFrame& src = static_cast(srcFrame); const AudioFrame& dst = static_cast(dstFrame); - av_opt_set_int(_audioConvertContext, "in_channel_layout", av_get_default_channel_layout(src.desc().getNbChannels()), 0); - av_opt_set_int(_audioConvertContext, "out_channel_layout", av_get_default_channel_layout(dst.desc().getNbChannels()), 0); - av_opt_set_int(_audioConvertContext, "in_sample_rate", src.desc().getSampleRate(), 0); - av_opt_set_int(_audioConvertContext, "out_sample_rate", dst.desc().getSampleRate(), 0); - SetSampleFormat(_audioConvertContext, "in_sample_fmt", src.desc().getSampleFormat(), 0); - SetSampleFormat(_audioConvertContext, "out_sample_fmt", dst.desc().getSampleFormat(), 0); + av_opt_set_int(_audioConvertContext, "in_channel_layout", av_get_default_channel_layout(src.getNbChannels()), 0); + av_opt_set_int(_audioConvertContext, "out_channel_layout", av_get_default_channel_layout(dst.getNbChannels()), 0); + av_opt_set_int(_audioConvertContext, "in_sample_rate", src.getSampleRate(), 0); + av_opt_set_int(_audioConvertContext, "out_sample_rate", dst.getSampleRate(), 0); + SetSampleFormat(_audioConvertContext, "in_sample_fmt", src.getSampleFormat(), 0); + SetSampleFormat(_audioConvertContext, "out_sample_fmt", dst.getSampleFormat(), 0); if(InitResampleContext(_audioConvertContext) < 0) { FreeResampleContext(&_audioConvertContext); std::stringstream msg; msg << "Unable to open audio convert context:" << std::endl; - msg << "in_channel_layout " << av_get_default_channel_layout(src.desc().getNbChannels()) << std::endl; - msg << "out_channel_layout " << av_get_default_channel_layout(dst.desc().getNbChannels()) << std::endl; - msg << "in_sample_rate " << src.desc().getSampleRate() << std::endl; - msg << "out_sample_rate " << dst.desc().getSampleRate() << std::endl; - msg << "in_sample_fmt " << src.desc().getSampleFormat() << std::endl; - msg << "out_sample_fmt " << dst.desc().getSampleFormat() << std::endl; + msg << "in_channel_layout " << av_get_default_channel_layout(src.getNbChannels()) << std::endl; + msg << "out_channel_layout " << av_get_default_channel_layout(dst.getNbChannels()) << std::endl; + msg << "in_sample_rate " << src.getSampleRate() << std::endl; + msg << "out_sample_rate " << dst.getSampleRate() << std::endl; + msg << "in_sample_fmt " << src.getSampleFormat() << std::endl; + msg << "out_sample_fmt " << dst.getSampleFormat() << std::endl; throw std::runtime_error(msg.str()); } std::stringstream msg; - msg << "Audio conversion from " << src.desc().getSampleFormatName() << " to " << dst.desc().getSampleFormatName() - << std::endl; - msg << "Source, number of channels = " << src.desc().getNbChannels() << std::endl; - msg << "Source, sample rate = " << src.desc().getSampleRate() << std::endl; - msg << "Destination, number of channels = " << dst.desc().getNbChannels() << std::endl; - msg << "Destination, sample rate = " << dst.desc().getSampleRate() << std::endl; + msg << "Audio conversion from " << getSampleFormatName(src.getSampleFormat()) << " to " + << getSampleFormatName(dst.getSampleFormat()) << std::endl; + msg << "Source, number of channels = " << src.getNbChannels() << std::endl; + msg << "Source, sample rate = " << src.getSampleRate() << std::endl; + msg << "Destination, number of channels = " << dst.getNbChannels() << std::endl; + msg << "Destination, sample rate = " << dst.getSampleRate() << std::endl; LOG_INFO(msg.str()) return true; } -void AudioTransform::updateOutputFrame(const size_t nbInputSamples, Frame& dstFrame) const -{ - AudioFrame& dst = static_cast(dstFrame); - - // resize buffer of output frame - const int dstSampleSize = av_get_bytes_per_sample(dst.desc().getSampleFormat()); - const size_t bufferSizeNeeded = nbInputSamples * dst.desc().getNbChannels() * dstSampleSize; - dstFrame.resize(bufferSizeNeeded); - - // set nbSamples of output frame - dst.setNbSamplesPerChannel(nbInputSamples); -} - void AudioTransform::convert(const Frame& srcFrame, Frame& dstFrame) { if(!_isInit) _isInit = init(srcFrame, dstFrame); // if number of samples change from previous frame - const size_t nbInputSamplesPerChannel = static_cast(srcFrame).getNbSamplesPerChannel(); - if(nbInputSamplesPerChannel != _previousNbInputSamplesPerChannel) - { - updateOutputFrame(nbInputSamplesPerChannel, dstFrame); - _previousNbInputSamplesPerChannel = nbInputSamplesPerChannel; - } + const size_t nbInputSamplesPerChannel = srcFrame.getAVFrame().nb_samples; - const unsigned char* srcData = srcFrame.getData(); - unsigned char* dstData = dstFrame.getData(); + const unsigned char** srcData = srcFrame.getData(); + unsigned char** dstData = dstFrame.getData(); int nbOutputSamplesPerChannel; #ifdef AVTRANSCODER_LIBAV_DEPENDENCY - nbOutputSamplesPerChannel = avresample_convert(_audioConvertContext, (uint8_t**)&dstData, 0, nbInputSamplesPerChannel, - (uint8_t**)&srcData, 0, nbInputSamplesPerChannel); + nbOutputSamplesPerChannel = + avresample_convert(_audioConvertContext, dstData, 0, nbInputSamplesPerChannel, srcData, 0, nbInputSamplesPerChannel); #else nbOutputSamplesPerChannel = - swr_convert(_audioConvertContext, &dstData, nbInputSamplesPerChannel, &srcData, nbInputSamplesPerChannel); + swr_convert(_audioConvertContext, dstData, nbInputSamplesPerChannel, srcData, nbInputSamplesPerChannel); #endif if(nbOutputSamplesPerChannel < 0) { throw std::runtime_error("unable to convert audio samples"); } + else + { + dstFrame.getAVFrame().nb_samples = nbOutputSamplesPerChannel; + } } } diff --git a/src/AvTranscoder/transform/AudioTransform.hpp b/src/AvTranscoder/transform/AudioTransform.hpp index bc2b7ef6..e670605c 100644 --- a/src/AvTranscoder/transform/AudioTransform.hpp +++ b/src/AvTranscoder/transform/AudioTransform.hpp @@ -4,7 +4,7 @@ #include "ITransform.hpp" #include -#include +#include #ifdef AVTRANSCODER_LIBAV_DEPENDENCY #define ResampleContext AVAudioResampleContext @@ -32,14 +32,9 @@ class AvExport AudioTransform : public ITransform private: bool init(const Frame& srcFrame, const Frame& dstFrame); - /// Update output buffer if source has a different size from the last process - void updateOutputFrame(const size_t nbInputSamples, Frame& dstFrame) const; - private: ResampleContext* _audioConvertContext; - size_t _previousNbInputSamplesPerChannel; ///< To check if the number of samples change between frames - bool _isInit; }; } diff --git a/src/AvTranscoder/transform/ITransform.hpp b/src/AvTranscoder/transform/ITransform.hpp index 83266093..0dba77d4 100644 --- a/src/AvTranscoder/transform/ITransform.hpp +++ b/src/AvTranscoder/transform/ITransform.hpp @@ -2,7 +2,7 @@ #define _AV_TRANSCODER_ESSENCE_TRANSFORM_ESSENCE_TRANSFORM_HPP_ #include -#include +#include namespace avtranscoder { diff --git a/src/AvTranscoder/transform/VideoTransform.cpp b/src/AvTranscoder/transform/VideoTransform.cpp index a3dc80c2..90131b1d 100644 --- a/src/AvTranscoder/transform/VideoTransform.cpp +++ b/src/AvTranscoder/transform/VideoTransform.cpp @@ -1,6 +1,6 @@ #include "VideoTransform.hpp" -#include +#include extern "C" { #include @@ -12,8 +12,6 @@ extern "C" { #endif } -#define MAX_SWS_PLANE 4 - #include #include #include @@ -24,10 +22,6 @@ namespace avtranscoder VideoTransform::VideoTransform() : _imageConvertContext(NULL) - , _srcData((uint8_t)MAX_SWS_PLANE, NULL) - , _dstData((uint8_t)MAX_SWS_PLANE, NULL) - , _srcLineSize(MAX_SWS_PLANE, 0) - , _dstLineSize(MAX_SWS_PLANE, 0) , _isInit(false) { } @@ -39,24 +33,22 @@ VideoTransform::~VideoTransform() bool VideoTransform::init(const Frame& srcFrame, const Frame& dstFrame) { + // Set convert context const VideoFrame& src = static_cast(srcFrame); const VideoFrame& dst = static_cast(dstFrame); - const AVPixelFormat srcPixelFormat = src.desc().getPixelFormat(); - const AVPixelFormat dstPixelFormat = dst.desc().getPixelFormat(); + const AVPixelFormat srcPixelFormat = src.getPixelFormat(); + const AVPixelFormat dstPixelFormat = dst.getPixelFormat(); _imageConvertContext = - sws_getCachedContext(_imageConvertContext, src.desc().getWidth(), src.desc().getHeight(), srcPixelFormat, - dst.desc().getWidth(), dst.desc().getHeight(), dstPixelFormat, SWS_POINT, NULL, NULL, NULL); + sws_getCachedContext(_imageConvertContext, src.getWidth(), src.getHeight(), srcPixelFormat, dst.getWidth(), + dst.getHeight(), dstPixelFormat, SWS_POINT, NULL, NULL, NULL); if(!_imageConvertContext) { throw std::runtime_error("unable to create color convert context"); } - av_image_fill_linesizes(&_srcLineSize[0], srcPixelFormat, src.desc().getWidth()); - av_image_fill_linesizes(&_dstLineSize[0], dstPixelFormat, dst.desc().getWidth()); - const char* srcPixFmt; srcPixFmt = av_get_pix_fmt_name(srcPixelFormat); const char* dstPixFmt; @@ -65,10 +57,10 @@ bool VideoTransform::init(const Frame& srcFrame, const Frame& dstFrame) std::stringstream msg; msg << "Video conversion from " << (srcPixFmt != NULL ? srcPixFmt : "None") << " to " << (dstPixFmt != NULL ? dstPixFmt : "None") << std::endl; - msg << "Source, width = " << src.desc().getWidth() << std::endl; - msg << "Source, height = " << src.desc().getHeight() << std::endl; - msg << "Destination, width = " << dst.desc().getWidth() << std::endl; - msg << "Destination, height = " << dst.desc().getHeight() << std::endl; + msg << "Source, width = " << src.getWidth() << std::endl; + msg << "Source, height = " << src.getHeight() << std::endl; + msg << "Destination, width = " << dst.getWidth() << std::endl; + msg << "Destination, height = " << dst.getHeight() << std::endl; LOG_INFO(msg.str()) return true; @@ -79,29 +71,23 @@ void VideoTransform::convert(const Frame& srcFrame, Frame& dstFrame) const VideoFrame& src = static_cast(srcFrame); VideoFrame& dst = static_cast(dstFrame); - assert(src.desc().getWidth() != 0); - assert(src.desc().getHeight() != 0); - assert(src.desc().getPixelFormat() != AV_PIX_FMT_NONE); + assert(src.getWidth() != 0); + assert(src.getHeight() != 0); + assert(src.getPixelFormat() != AV_PIX_FMT_NONE); if(!_isInit) _isInit = init(srcFrame, dstFrame); - const AVPixelFormat srcPixelFormat = src.desc().getPixelFormat(); - const AVPixelFormat dstPixelFormat = dst.desc().getPixelFormat(); - - // Fill plane data pointers - av_image_fill_pointers(&_srcData[0], srcPixelFormat, src.desc().getHeight(), (uint8_t*)src.getData(), &_srcLineSize[0]); - av_image_fill_pointers(&_dstData[0], dstPixelFormat, dst.desc().getHeight(), (uint8_t*)dst.getData(), &_dstLineSize[0]); - if(!_imageConvertContext) { throw std::runtime_error("unknown color convert context"); } - int ret = sws_scale(_imageConvertContext, &_srcData[0], &_srcLineSize[0], 0, src.desc().getHeight(), &_dstData[0], - &_dstLineSize[0]); + // Convert + const int ret = sws_scale(_imageConvertContext, src.getData(), src.getLineSize(), 0, src.getHeight(), dst.getData(), + dst.getLineSize()); - if(ret != (int)dst.desc().getHeight()) + if(ret != (int)dst.getHeight()) throw std::runtime_error("error in color converter"); } } diff --git a/src/AvTranscoder/transform/VideoTransform.hpp b/src/AvTranscoder/transform/VideoTransform.hpp index 4f4a3b77..7d17d0f7 100644 --- a/src/AvTranscoder/transform/VideoTransform.hpp +++ b/src/AvTranscoder/transform/VideoTransform.hpp @@ -5,7 +5,7 @@ #include "ITransform.hpp" -#include +#include class SwsContext; @@ -28,12 +28,6 @@ class AvExport VideoTransform : public ITransform bool init(const Frame& srcFrame, const Frame& dstFrame); SwsContext* _imageConvertContext; - - std::vector _srcData; - std::vector _dstData; - std::vector _srcLineSize; - std::vector _dstLineSize; - bool _isInit; }; } diff --git a/test/pyTest/testReader.py b/test/pyTest/testReader.py index 7a26a9a1..f78a64f8 100644 --- a/test/pyTest/testReader.py +++ b/test/pyTest/testReader.py @@ -23,11 +23,11 @@ def testVideoReaderCreateNewInputFile(): # read all frames and check their size for i in xrange(0, reader.getSourceVideoProperties().getNbFrames()): - frame = reader.readNextFrame() + frame = av.VideoFrame(reader.readNextFrame()) assert_equals( frame.getSize(), reader.getOutputWidth() * reader.getOutputHeight() * reader.getOutputNbComponents() ) # check if the next frame is empty - frame = reader.readNextFrame() + frame = av.VideoFrame(reader.readNextFrame()) assert_equals( frame.getSize(), 0 ) @@ -42,11 +42,11 @@ def testVideoReaderReferenceInputFile(): # read all frames and check their size for i in xrange(0, reader.getSourceVideoProperties().getNbFrames()): - frame = reader.readNextFrame() + frame = av.VideoFrame(reader.readNextFrame()) assert_equals( frame.getSize(), reader.getOutputWidth() * reader.getOutputHeight() * reader.getOutputNbComponents() ) # check if the next frame is empty - frame = reader.readNextFrame() + frame = av.VideoFrame(reader.readNextFrame()) assert_equals( frame.getSize(), 0 ) @@ -64,13 +64,13 @@ def testAudioReaderChannelsExtraction(): readerOfAllChannels = av.AudioReader(inputFile, streamIndex) nbChannels = readerOfAllChannels.getOutputNbChannels() # read first frame - frame = readerOfAllChannels.readNextFrame() + frame = av.AudioFrame(readerOfAllChannels.readNextFrame()) sizeOfFrameWithAllChannels = frame.getSize() # create reader to read one channel of the audio stream readerOfOneChannel = av.AudioReader(inputFile, streamIndex, channelIndex) # read first frame - frame = readerOfOneChannel.readNextFrame() + frame = av.AudioFrame(readerOfOneChannel.readNextFrame()) sizeOfFrameWithOneChannels = frame.getSize() assert_equals( sizeOfFrameWithAllChannels / nbChannels, sizeOfFrameWithOneChannels ) diff --git a/test/pyTest/testSetFrame.py b/test/pyTest/testSetFrame.py index dce017ef..513167d5 100644 --- a/test/pyTest/testSetFrame.py +++ b/test/pyTest/testSetFrame.py @@ -27,15 +27,15 @@ def testSetVideoFrame(): transcoder.preProcessCodecLatency() p = av.ConsoleProgress() - # process 10 frames - nbFrames = 10 - for i in range(0, nbFrames): + # process 51 frames + nbFrames = 255 + for i in range(0, nbFrames, 5): transcoder.processFrame() p.progress( i, nbFrames ) # set video frame frame = av.VideoFrame( imageDesc ) - frame.assign(frame.getSize(), i) + frame.assign(i) videoDecoder.setNextFrame( frame ) # end process @@ -80,15 +80,15 @@ def testSetAudioFrame(): transcoder.preProcessCodecLatency() p = av.ConsoleProgress() - # process 10 frames - nbFrames = 10 + # process 51 frames + nbFrames = 255 for i in range(0, nbFrames): transcoder.processFrame() p.progress( i, nbFrames ) # set video frame frame = av.AudioFrame( audioDesc ) - frame.assign(frame.getSize(), i) + frame.assign(i) audioDecoder.setNextFrame( frame ) # end process From 38c91a9f00c2528dcae3cefae3ce038176433b1f Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 19 Jan 2016 11:27:20 +0100 Subject: [PATCH 40/46] OutputFile: log in debug if eWrappingWaitingForData --- src/AvTranscoder/file/OutputFile.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/AvTranscoder/file/OutputFile.cpp b/src/AvTranscoder/file/OutputFile.cpp index 39424de4..8edecbc0 100644 --- a/src/AvTranscoder/file/OutputFile.cpp +++ b/src/AvTranscoder/file/OutputFile.cpp @@ -215,7 +215,9 @@ IOutputStream::EWrappingStatus OutputFile::wrap(const CodedData& data, const siz const double currentStreamDuration = _outputStreams.at(streamIndex)->getStreamDuration(); if(currentStreamDuration < _previousProcessedStreamDuration) { - // if the current stream is strictly shorter than the previous, wait for more data + LOG_DEBUG("The output stream " << streamIndex << " is strictly shorter than the previous duration saved (" + << currentStreamDuration << "s < " << _previousProcessedStreamDuration + << "s): wait for more data.") return IOutputStream::eWrappingWaitingForData; } From 5e80e129ec274b878e40d379d8ceec95700dc3fa Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 19 Jan 2016 11:49:35 +0100 Subject: [PATCH 41/46] AudioFrameDesc: removed _fps attribute * Not used. * AudioGenerator: removed _frameDesc attributes and the methods to manipulate it. --- src/AvTranscoder/codec/AudioCodec.cpp | 3 +-- src/AvTranscoder/data/decoded/AudioFrame.cpp | 7 +------ src/AvTranscoder/data/decoded/AudioFrame.hpp | 1 - src/AvTranscoder/decoder/AudioGenerator.cpp | 11 +---------- src/AvTranscoder/decoder/AudioGenerator.hpp | 4 ---- src/AvTranscoder/transcoder/StreamTranscoder.cpp | 3 --- 6 files changed, 3 insertions(+), 26 deletions(-) diff --git a/src/AvTranscoder/codec/AudioCodec.cpp b/src/AvTranscoder/codec/AudioCodec.cpp index 16eb2e21..f5460f5e 100644 --- a/src/AvTranscoder/codec/AudioCodec.cpp +++ b/src/AvTranscoder/codec/AudioCodec.cpp @@ -24,8 +24,7 @@ AudioCodec::AudioCodec(const ECodecType type, AVCodecContext& avCodecContext) AudioFrameDesc AudioCodec::getAudioFrameDesc() const { assert(_avCodecContext != NULL); - AudioFrameDesc audioFrameDesc(_avCodecContext->sample_rate, _avCodecContext->channels, _avCodecContext->sample_fmt); - return audioFrameDesc; + return AudioFrameDesc(_avCodecContext->sample_rate, _avCodecContext->channels, _avCodecContext->sample_fmt); } void AudioCodec::setAudioParameters(const AudioFrameDesc& audioFrameDesc) diff --git a/src/AvTranscoder/data/decoded/AudioFrame.cpp b/src/AvTranscoder/data/decoded/AudioFrame.cpp index 8ae8ceff..583beb01 100644 --- a/src/AvTranscoder/data/decoded/AudioFrame.cpp +++ b/src/AvTranscoder/data/decoded/AudioFrame.cpp @@ -16,7 +16,6 @@ AudioFrameDesc::AudioFrameDesc(const size_t sampleRate, const size_t nbChannels, : _sampleRate(sampleRate) , _nbChannels(nbChannels) , _sampleFormat(sampleFormat) - , _fps(25.) { } @@ -24,7 +23,6 @@ AudioFrameDesc::AudioFrameDesc(const size_t sampleRate, const size_t nbChannels, : _sampleRate(sampleRate) , _nbChannels(nbChannels) , _sampleFormat(getAVSampleFormat(sampleFormatName)) - , _fps(25.) { } @@ -39,9 +37,6 @@ void AudioFrameDesc::setParameters(const ProfileLoader::Profile& profile) // sample format if(profile.count(constants::avProfileSampleFormat)) _sampleFormat = getAVSampleFormat(profile.find(constants::avProfileSampleFormat)->second.c_str()); - // fps - if(profile.count(constants::avProfileFrameRate)) - _fps = atof(profile.find(constants::avProfileFrameRate)->second.c_str()); } AudioFrame::AudioFrame(const AudioFrameDesc& ref) @@ -83,7 +78,7 @@ void AudioFrame::allocateAVSample(const AudioFrameDesc& desc) _frame->channels = desc._nbChannels; _frame->channel_layout = av_get_default_channel_layout(desc._nbChannels); _frame->format = desc._sampleFormat; - _frame->nb_samples = desc._sampleRate / desc._fps; // cannot be known before calling avcodec_decode_audio4 + _frame->nb_samples = desc._sampleRate / 25.; // cannot be known before calling avcodec_decode_audio4 // Allocate data const int align = 0; diff --git a/src/AvTranscoder/data/decoded/AudioFrame.hpp b/src/AvTranscoder/data/decoded/AudioFrame.hpp index d2eff720..3a68fa16 100644 --- a/src/AvTranscoder/data/decoded/AudioFrame.hpp +++ b/src/AvTranscoder/data/decoded/AudioFrame.hpp @@ -28,7 +28,6 @@ struct AvExport AudioFrameDesc size_t _sampleRate; size_t _nbChannels; AVSampleFormat _sampleFormat; - double _fps; }; /** diff --git a/src/AvTranscoder/decoder/AudioGenerator.cpp b/src/AvTranscoder/decoder/AudioGenerator.cpp index 0e644841..33309f10 100644 --- a/src/AvTranscoder/decoder/AudioGenerator.cpp +++ b/src/AvTranscoder/decoder/AudioGenerator.cpp @@ -6,14 +6,12 @@ namespace avtranscoder AudioGenerator::AudioGenerator() : _inputFrame(NULL) , _silent(NULL) - , _frameDesc() { } AudioGenerator::AudioGenerator(const AudioGenerator& audioGenerator) : _inputFrame(NULL) , _silent(NULL) - , _frameDesc(audioGenerator.getAudioFrameDesc()) { } @@ -21,7 +19,6 @@ AudioGenerator& AudioGenerator::operator=(const AudioGenerator& audioGenerator) { _inputFrame = NULL; _silent = NULL; - _frameDesc = audioGenerator.getAudioFrameDesc(); return *this; } @@ -30,13 +27,7 @@ AudioGenerator::~AudioGenerator() delete _silent; } -void AudioGenerator::setAudioFrameDesc(const AudioFrameDesc& frameDesc) -{ - _frameDesc = frameDesc; - _frameDesc._fps = 25.; -} - -void AudioGenerator::setFrame(Frame& inputFrame) +void AudioGenerator::setNextFrame(Frame& inputFrame) { _inputFrame = &inputFrame; } diff --git a/src/AvTranscoder/decoder/AudioGenerator.hpp b/src/AvTranscoder/decoder/AudioGenerator.hpp index 016658a6..26e1c215 100644 --- a/src/AvTranscoder/decoder/AudioGenerator.hpp +++ b/src/AvTranscoder/decoder/AudioGenerator.hpp @@ -19,15 +19,11 @@ class AvExport AudioGenerator : public IDecoder bool decodeNextFrame(Frame& frameBuffer); bool decodeNextFrame(Frame& frameBuffer, const size_t subStreamIndex); - const AudioFrameDesc& getAudioFrameDesc() const { return _frameDesc; } - void setAudioFrameDesc(const AudioFrameDesc& frameDesc); - void setFrame(Frame& inputFrame); private: Frame* _inputFrame; ///< Has link (no ownership) AudioFrame* _silent; ///< The generated silent (has ownership) - AudioFrameDesc _frameDesc; ///< The description of the silent (sample rate...) }; } diff --git a/src/AvTranscoder/transcoder/StreamTranscoder.cpp b/src/AvTranscoder/transcoder/StreamTranscoder.cpp index e03093e1..0ae48dba 100644 --- a/src/AvTranscoder/transcoder/StreamTranscoder.cpp +++ b/src/AvTranscoder/transcoder/StreamTranscoder.cpp @@ -82,7 +82,6 @@ StreamTranscoder::StreamTranscoder(IInputStream& inputStream, IOutputFile& outpu // generator decoder AudioGenerator* generatorAudio = new AudioGenerator(); - generatorAudio->setAudioFrameDesc(inputFrameDesc); _generator = generatorAudio; // buffers to process @@ -206,7 +205,6 @@ StreamTranscoder::StreamTranscoder(IInputStream& inputStream, IOutputFile& outpu // generator decoder AudioGenerator* generatorAudio = new AudioGenerator(); - generatorAudio->setAudioFrameDesc(outputAudio->getAudioCodec().getAudioFrameDesc()); _generator = generatorAudio; break; @@ -266,7 +264,6 @@ StreamTranscoder::StreamTranscoder(const ICodec& inputCodec, IOutputFile& output // generator decoder AudioGenerator* generatorAudio = new AudioGenerator(); const AudioCodec& inputAudioCodec = static_cast(inputCodec); - generatorAudio->setAudioFrameDesc(inputAudioCodec.getAudioFrameDesc()); _generator = generatorAudio; _currentDecoder = _generator; From 99e933e048f9f8ead250f7fa0579364a7337e6ef Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 19 Jan 2016 11:51:28 +0100 Subject: [PATCH 42/46] AudioGenerator: fixed name of setFrame method Renamed to inherit the setNextFrame method in based class. --- src/AvTranscoder/decoder/AudioGenerator.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AvTranscoder/decoder/AudioGenerator.hpp b/src/AvTranscoder/decoder/AudioGenerator.hpp index 26e1c215..4f677043 100644 --- a/src/AvTranscoder/decoder/AudioGenerator.hpp +++ b/src/AvTranscoder/decoder/AudioGenerator.hpp @@ -19,7 +19,7 @@ class AvExport AudioGenerator : public IDecoder bool decodeNextFrame(Frame& frameBuffer); bool decodeNextFrame(Frame& frameBuffer, const size_t subStreamIndex); - void setFrame(Frame& inputFrame); + void setNextFrame(Frame& inputFrame); private: Frame* _inputFrame; ///< Has link (no ownership) From f6467b124e166f421975a2e34baf36ff76208770 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 19 Jan 2016 13:36:33 +0100 Subject: [PATCH 43/46] Frame: fixed compilation error with gcc-4.8 --- src/AvTranscoder/data/decoded/Frame.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/AvTranscoder/data/decoded/Frame.cpp b/src/AvTranscoder/data/decoded/Frame.cpp index 3b9a59e7..91e6b19c 100644 --- a/src/AvTranscoder/data/decoded/Frame.cpp +++ b/src/AvTranscoder/data/decoded/Frame.cpp @@ -1,5 +1,6 @@ #include "Frame.hpp" -#include + +#include namespace avtranscoder { From a2c8493b04e462531fefdc24cf1a118de482318b Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 19 Jan 2016 13:39:20 +0100 Subject: [PATCH 44/46] Video/AudioFrame: fixed compilation error with msvc "cannot allocate an array of constant size 0". --- src/AvTranscoder/data/decoded/AudioFrame.cpp | 3 ++- src/AvTranscoder/data/decoded/VideoFrame.cpp | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/AvTranscoder/data/decoded/AudioFrame.cpp b/src/AvTranscoder/data/decoded/AudioFrame.cpp index 583beb01..4da72ccd 100644 --- a/src/AvTranscoder/data/decoded/AudioFrame.cpp +++ b/src/AvTranscoder/data/decoded/AudioFrame.cpp @@ -100,8 +100,9 @@ void AudioFrame::allocateAVSample(const AudioFrameDesc& desc) void AudioFrame::assign(const unsigned char value) { // Create the audio buffer + // The buffer will be freed in destructor of based class const int audioSize = getSize(); - unsigned char audioBuffer[audioSize]; + unsigned char* audioBuffer = new unsigned char[audioSize]; memset(audioBuffer, value, audioSize); // Fill the picture diff --git a/src/AvTranscoder/data/decoded/VideoFrame.cpp b/src/AvTranscoder/data/decoded/VideoFrame.cpp index 38e5f67f..c7f8dcf8 100644 --- a/src/AvTranscoder/data/decoded/VideoFrame.cpp +++ b/src/AvTranscoder/data/decoded/VideoFrame.cpp @@ -90,8 +90,9 @@ void VideoFrame::allocateAVPicture(const VideoFrameDesc& desc) void VideoFrame::assign(const unsigned char value) { // Create the image buffer + // The buffer will be freed in destructor of based class const int imageSize = getSize(); - unsigned char imageBuffer[imageSize]; + unsigned char* imageBuffer = new unsigned char[imageSize]; memset(imageBuffer, value, imageSize); // Fill the picture From 28dc37c3f5d4f3c81901e3fa8693753911be3865 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 19 Jan 2016 14:56:27 +0100 Subject: [PATCH 45/46] Frame: removed getPlaneData method * Not tested. * Not used. * Can be done by accessing the full buffer thanks to getData method. --- src/AvTranscoder/data/decoded/Frame.cpp | 8 -------- src/AvTranscoder/data/decoded/Frame.hpp | 5 ----- 2 files changed, 13 deletions(-) diff --git a/src/AvTranscoder/data/decoded/Frame.cpp b/src/AvTranscoder/data/decoded/Frame.cpp index 91e6b19c..9a35e7da 100644 --- a/src/AvTranscoder/data/decoded/Frame.cpp +++ b/src/AvTranscoder/data/decoded/Frame.cpp @@ -40,14 +40,6 @@ Frame::~Frame() } } -unsigned char* Frame::getPlaneData(const size_t plane) -{ - AVBufferRef* buffer = av_frame_get_plane_buffer(_frame, plane); - if(buffer != NULL) - return buffer->data; - return NULL; -} - void Frame::copyData(const Frame& frameToRef) { const int ret = av_frame_copy(_frame, &frameToRef.getAVFrame()); diff --git a/src/AvTranscoder/data/decoded/Frame.hpp b/src/AvTranscoder/data/decoded/Frame.hpp index c2fe8cc0..505f66a8 100644 --- a/src/AvTranscoder/data/decoded/Frame.hpp +++ b/src/AvTranscoder/data/decoded/Frame.hpp @@ -33,11 +33,6 @@ class AvExport Frame */ unsigned char** getData() { return _frame->data; } - /** - * @return The specified data plane. - */ - unsigned char* getPlaneData(const size_t plane); - /** * @brief Returns the size in byte. * For video, size in bytes of each picture line. From 54d4cbe5416937a1188c7189686be6895aee1c30 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 19 Jan 2016 17:44:49 +0100 Subject: [PATCH 46/46] AudioDecoder: fixed memory leak when decodeNextFrame with a specific channel index --- src/AvTranscoder/decoder/AudioDecoder.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/AvTranscoder/decoder/AudioDecoder.cpp b/src/AvTranscoder/decoder/AudioDecoder.cpp index c0a681b1..fa7da88a 100644 --- a/src/AvTranscoder/decoder/AudioDecoder.cpp +++ b/src/AvTranscoder/decoder/AudioDecoder.cpp @@ -117,7 +117,7 @@ bool AudioDecoder::decodeNextFrame(Frame& frameBuffer, const size_t channelIndex AudioFrame& audioBuffer = static_cast(frameBuffer); // decode all data of the next frame - AudioFrame allDataOfNextFrame(audioBuffer.desc()); + AudioFrame allDataOfNextFrame(audioBuffer); if(!decodeNextFrame(allDataOfNextFrame)) return false; @@ -151,7 +151,7 @@ bool AudioDecoder::decodeNextFrame(Frame& frameBuffer, const size_t channelIndex audioBuffer.setNbSamplesPerChannel(allDataOfNextFrame.getNbSamplesPerChannel()); // @todo manage cases with data of frame not only on data[0] (use _frame.linesize) - unsigned char* src = allDataOfNextFrame.getAVFrame().data[0]; + unsigned char* src = allDataOfNextFrame.getData()[0]; unsigned char* dst = audioBuffer.getData()[0]; // offset