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 pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy