From 94d4600d5b2c826d5941588c5ca7827937ac1b9b Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Thu, 7 Apr 2016 17:41:21 +0200 Subject: [PATCH 01/13] InputFile: updated log when read next frame --- src/AvTranscoder/file/InputFile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AvTranscoder/file/InputFile.cpp b/src/AvTranscoder/file/InputFile.cpp index 93dcaddb..e20ffd84 100644 --- a/src/AvTranscoder/file/InputFile.cpp +++ b/src/AvTranscoder/file/InputFile.cpp @@ -68,7 +68,7 @@ bool InputFile::readNextPacket(CodedData& data, const size_t streamIndex) const int ret = av_read_frame(&_formatContext.getAVFormatContext(), &data.getAVPacket()); if(ret < 0) // error or end of file { - LOG_INFO("No more data to read on file '" << _filename << "' for stream " << streamIndex) + LOG_INFO("Stop reading the next frame of file '" << _filename << "', stream " << streamIndex << " (" << getDescriptionFromErrorCode(ret) << ")") return false; } From 66102e3617d6dcec513c45eb8037b8103d0cf269 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Thu, 7 Apr 2016 17:45:37 +0200 Subject: [PATCH 02/13] Video/AudioDecoder: fixed decoding if the reading process failed It could be possible to have no more data to read from the input, but to have data stored in the decoder. --- src/AvTranscoder/decoder/AudioDecoder.cpp | 14 ++++++++------ src/AvTranscoder/decoder/VideoDecoder.cpp | 14 ++++++++------ 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/AvTranscoder/decoder/AudioDecoder.cpp b/src/AvTranscoder/decoder/AudioDecoder.cpp index 9c8695fd..3b20e8bc 100644 --- a/src/AvTranscoder/decoder/AudioDecoder.cpp +++ b/src/AvTranscoder/decoder/AudioDecoder.cpp @@ -87,13 +87,8 @@ bool AudioDecoder::decodeNextFrame(Frame& frameBuffer) { CodedData data; + // reading const bool nextPacketRead = _inputStream->readNextPacket(data); - // if error or end of file - if(!nextPacketRead && !decodeNextFrame) - { - data.clear(); - return false; - } // decoding // @note could be called several times to return the remaining frames (last call with an empty packet) @@ -110,6 +105,13 @@ bool AudioDecoder::decodeNextFrame(Frame& frameBuffer) decodeNextFrame = false; else decodeNextFrame = true; + + // if no frame read and decompressed + if(!nextPacketRead && !decodeNextFrame) + { + data.clear(); + return false; + } } return decodeNextFrame; } diff --git a/src/AvTranscoder/decoder/VideoDecoder.cpp b/src/AvTranscoder/decoder/VideoDecoder.cpp index 5affcb56..51363466 100644 --- a/src/AvTranscoder/decoder/VideoDecoder.cpp +++ b/src/AvTranscoder/decoder/VideoDecoder.cpp @@ -85,13 +85,8 @@ bool VideoDecoder::decodeNextFrame(Frame& frameBuffer) { CodedData data; + // reading const bool nextPacketRead = _inputStream->readNextPacket(data); - // if error or end of file - if(!nextPacketRead && !decodeNextFrame) - { - data.clear(); - return false; - } // decoding // @note could be called several times to return the remaining frames (last call with an empty packet) @@ -108,6 +103,13 @@ bool VideoDecoder::decodeNextFrame(Frame& frameBuffer) decodeNextFrame = false; else decodeNextFrame = true; + + // if no frame read and decompressed + if(!nextPacketRead && !decodeNextFrame) + { + data.clear(); + return false; + } } return decodeNextFrame; } From ee005ba13aab5c06f216684c03fe430a92461b81 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Fri, 8 Apr 2016 15:10:44 +0200 Subject: [PATCH 03/13] decoded data: added doc --- src/AvTranscoder/data/decoded/AudioFrame.hpp | 3 +++ src/AvTranscoder/data/decoded/Frame.hpp | 1 + src/AvTranscoder/data/decoded/VideoFrame.hpp | 3 +++ 3 files changed, 7 insertions(+) diff --git a/src/AvTranscoder/data/decoded/AudioFrame.hpp b/src/AvTranscoder/data/decoded/AudioFrame.hpp index f3a89a17..c2d2669c 100644 --- a/src/AvTranscoder/data/decoded/AudioFrame.hpp +++ b/src/AvTranscoder/data/decoded/AudioFrame.hpp @@ -66,6 +66,9 @@ class AvExport AudioFrame : public Frame void assign(const unsigned char* ptrValue); private: + /** + * @brief Allocate the audio buffer of the frame. + */ void allocateAVSample(const AudioFrameDesc& ref); }; } diff --git a/src/AvTranscoder/data/decoded/Frame.hpp b/src/AvTranscoder/data/decoded/Frame.hpp index 58a72a3f..aa3e45b1 100644 --- a/src/AvTranscoder/data/decoded/Frame.hpp +++ b/src/AvTranscoder/data/decoded/Frame.hpp @@ -18,6 +18,7 @@ class AvExport Frame public: /** * @brief Allocate an empty frame. + * @warn This only allocates the AVFrame itself, not the data buffers. */ Frame(); diff --git a/src/AvTranscoder/data/decoded/VideoFrame.hpp b/src/AvTranscoder/data/decoded/VideoFrame.hpp index ae9e22f9..b7bbdcfb 100644 --- a/src/AvTranscoder/data/decoded/VideoFrame.hpp +++ b/src/AvTranscoder/data/decoded/VideoFrame.hpp @@ -66,6 +66,9 @@ class AvExport VideoFrame : public Frame void assign(const unsigned char* ptrValue); private: + /** + * @brief Allocate the image buffer of the frame. + */ void allocateAVPicture(const VideoFrameDesc& desc); }; } From e89e84b407bcfff4c7b17452eb57c4ab74fb413e Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Fri, 8 Apr 2016 15:31:57 +0200 Subject: [PATCH 04/13] IDecoder: added doc to decodeNextFrame method --- src/AvTranscoder/decoder/IDecoder.hpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/AvTranscoder/decoder/IDecoder.hpp b/src/AvTranscoder/decoder/IDecoder.hpp index c9af9148..a373a9be 100644 --- a/src/AvTranscoder/decoder/IDecoder.hpp +++ b/src/AvTranscoder/decoder/IDecoder.hpp @@ -23,6 +23,9 @@ class AvExport IDecoder /** * @brief Decode next frame * @param frameBuffer: the frame decoded + * @warn the frameBuffer reference belongs to the decoder and is valid only until the + * next call to this function or until closing or flushing the + * decoder. The caller may not write to it. * @return status of decoding */ virtual bool decodeNextFrame(Frame& frameBuffer) = 0; From 7419075d1e4e085459c8b2c4c4ca86d880b251b1 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Fri, 8 Apr 2016 15:33:23 +0200 Subject: [PATCH 05/13] VideoGenerator: defined one line methods in the header --- src/AvTranscoder/decoder/VideoGenerator.cpp | 10 ---------- src/AvTranscoder/decoder/VideoGenerator.hpp | 4 ++-- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/src/AvTranscoder/decoder/VideoGenerator.cpp b/src/AvTranscoder/decoder/VideoGenerator.cpp index 32092077..92c345ff 100644 --- a/src/AvTranscoder/decoder/VideoGenerator.cpp +++ b/src/AvTranscoder/decoder/VideoGenerator.cpp @@ -35,16 +35,6 @@ VideoGenerator::~VideoGenerator() delete _blackImage; } -void VideoGenerator::setVideoFrameDesc(const VideoFrameDesc& frameDesc) -{ - _frameDesc = frameDesc; -} - -void VideoGenerator::setNextFrame(Frame& inputFrame) -{ - _inputFrame = &inputFrame; -} - bool VideoGenerator::decodeNextFrame(Frame& frameBuffer) { // Generate black image diff --git a/src/AvTranscoder/decoder/VideoGenerator.hpp b/src/AvTranscoder/decoder/VideoGenerator.hpp index 888c2c3c..2359c9c8 100644 --- a/src/AvTranscoder/decoder/VideoGenerator.hpp +++ b/src/AvTranscoder/decoder/VideoGenerator.hpp @@ -20,9 +20,9 @@ class AvExport VideoGenerator : public IDecoder bool decodeNextFrame(Frame& frameBuffer, const size_t channelIndex); const VideoFrameDesc& getVideoFrameDesc() const { return _frameDesc; } - void setVideoFrameDesc(const VideoFrameDesc& frameDesc); + void setVideoFrameDesc(const VideoFrameDesc& frameDesc) { _frameDesc = frameDesc; } - void setNextFrame(Frame& inputFrame); + void setNextFrame(Frame& inputFrame) { _inputFrame = &inputFrame; } private: Frame* _inputFrame; ///< A frame given from outside (has link, no ownership) From 64afc627c91bb5ba490334e5cbd15bc5f3d2b596 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Fri, 8 Apr 2016 15:33:57 +0200 Subject: [PATCH 06/13] VideoGenerator: fixed decoding if the given frame is not valid --- src/AvTranscoder/data/decoded/VideoFrame.hpp | 6 ++++++ src/AvTranscoder/decoder/VideoGenerator.cpp | 8 ++++++++ 2 files changed, 14 insertions(+) diff --git a/src/AvTranscoder/data/decoded/VideoFrame.hpp b/src/AvTranscoder/data/decoded/VideoFrame.hpp index b7bbdcfb..eeea4b09 100644 --- a/src/AvTranscoder/data/decoded/VideoFrame.hpp +++ b/src/AvTranscoder/data/decoded/VideoFrame.hpp @@ -70,6 +70,12 @@ class AvExport VideoFrame : public Frame * @brief Allocate the image buffer of the frame. */ void allocateAVPicture(const VideoFrameDesc& desc); + + /** + * @note To allocate new image buffer if needed. + * @see allocateAVPicture + */ + friend class VideoGenerator; }; } diff --git a/src/AvTranscoder/decoder/VideoGenerator.cpp b/src/AvTranscoder/decoder/VideoGenerator.cpp index 92c345ff..8f448dcb 100644 --- a/src/AvTranscoder/decoder/VideoGenerator.cpp +++ b/src/AvTranscoder/decoder/VideoGenerator.cpp @@ -37,6 +37,14 @@ VideoGenerator::~VideoGenerator() bool VideoGenerator::decodeNextFrame(Frame& frameBuffer) { + // check the given frame + if(!frameBuffer.isVideoFrame()) + { + LOG_WARN("The given frame is not a valid video frame: allocate a new AVPicture to put generated data into it."); + frameBuffer.clear(); + static_cast(frameBuffer).allocateAVPicture(_frameDesc); + } + // Generate black image if(!_inputFrame) { From 3723ffcf2213e0aaba96d9b0330f7d4a597829f4 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Fri, 8 Apr 2016 15:35:13 +0200 Subject: [PATCH 07/13] AudioGenerator: fixed decoding if the given frame is not valid --- src/AvTranscoder/data/decoded/AudioFrame.hpp | 6 ++++++ src/AvTranscoder/decoder/AudioGenerator.cpp | 10 ++++++++++ src/AvTranscoder/decoder/AudioGenerator.hpp | 3 +++ src/AvTranscoder/reader/AudioReader.cpp | 4 +++- src/AvTranscoder/transcoder/StreamTranscoder.cpp | 3 +++ 5 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/AvTranscoder/data/decoded/AudioFrame.hpp b/src/AvTranscoder/data/decoded/AudioFrame.hpp index c2d2669c..132d8224 100644 --- a/src/AvTranscoder/data/decoded/AudioFrame.hpp +++ b/src/AvTranscoder/data/decoded/AudioFrame.hpp @@ -70,6 +70,12 @@ class AvExport AudioFrame : public Frame * @brief Allocate the audio buffer of the frame. */ void allocateAVSample(const AudioFrameDesc& ref); + + /** + * @note To allocate new audio buffer if needed. + * @see allocateAVSample + */ + friend class AudioGenerator; }; } diff --git a/src/AvTranscoder/decoder/AudioGenerator.cpp b/src/AvTranscoder/decoder/AudioGenerator.cpp index a50611bb..26d2e7ab 100644 --- a/src/AvTranscoder/decoder/AudioGenerator.cpp +++ b/src/AvTranscoder/decoder/AudioGenerator.cpp @@ -16,6 +16,7 @@ AudioGenerator::AudioGenerator() AudioGenerator::AudioGenerator(const AudioGenerator& audioGenerator) : _inputFrame(NULL) , _silent(NULL) + , _frameDesc(audioGenerator.getAudioFrameDesc()) { } @@ -23,6 +24,7 @@ AudioGenerator& AudioGenerator::operator=(const AudioGenerator& audioGenerator) { _inputFrame = NULL; _silent = NULL; + _frameDesc = audioGenerator.getAudioFrameDesc(); return *this; } @@ -38,6 +40,14 @@ void AudioGenerator::setNextFrame(Frame& inputFrame) bool AudioGenerator::decodeNextFrame(Frame& frameBuffer) { + // check the given frame + if(!frameBuffer.isAudioFrame()) + { + LOG_WARN("The given frame is not a valid audio frame: allocate a new AVSample to put generated data into it."); + frameBuffer.clear(); + static_cast(frameBuffer).allocateAVSample(_frameDesc); + } + // Check channel layout of the given frame to be able to copy audio data to it. // @see Frame.copyData method if(frameBuffer.getAVFrame().channel_layout == 0) diff --git a/src/AvTranscoder/decoder/AudioGenerator.hpp b/src/AvTranscoder/decoder/AudioGenerator.hpp index 5c5631ad..977e8d4e 100644 --- a/src/AvTranscoder/decoder/AudioGenerator.hpp +++ b/src/AvTranscoder/decoder/AudioGenerator.hpp @@ -20,10 +20,13 @@ class AvExport AudioGenerator : public IDecoder bool decodeNextFrame(Frame& frameBuffer, const size_t subStreamIndex); void setNextFrame(Frame& inputFrame); + const AudioFrameDesc& getAudioFrameDesc() const { return _frameDesc; } + void setAudioFrameDesc(const AudioFrameDesc& frameDesc) { _frameDesc = frameDesc; } private: Frame* _inputFrame; ///< Has link (no ownership) AudioFrame* _silent; ///< The generated silent (has ownership) + AudioFrameDesc _frameDesc; ///< The description of the silence (sampleRate, channels...) }; } diff --git a/src/AvTranscoder/reader/AudioReader.cpp b/src/AvTranscoder/reader/AudioReader.cpp index 9495d8b5..f6cab2f5 100644 --- a/src/AvTranscoder/reader/AudioReader.cpp +++ b/src/AvTranscoder/reader/AudioReader.cpp @@ -44,7 +44,9 @@ void AudioReader::init() _decoder->setupDecoder(); // generator - _generator = new AudioGenerator(); + AudioGenerator* generator = new AudioGenerator(); + generator->setAudioFrameDesc(_inputFile->getStream(_streamIndex).getAudioCodec().getAudioFrameDesc()); + _generator = generator; // create transform _transform = new AudioTransform(); diff --git a/src/AvTranscoder/transcoder/StreamTranscoder.cpp b/src/AvTranscoder/transcoder/StreamTranscoder.cpp index c88870b5..74751da3 100644 --- a/src/AvTranscoder/transcoder/StreamTranscoder.cpp +++ b/src/AvTranscoder/transcoder/StreamTranscoder.cpp @@ -89,6 +89,7 @@ StreamTranscoder::StreamTranscoder(IInputStream& inputStream, IOutputFile& outpu // generator decoder AudioGenerator* generatorAudio = new AudioGenerator(); + generatorAudio->setAudioFrameDesc(inputFrameDesc); _generator = generatorAudio; // buffers to process @@ -219,6 +220,7 @@ StreamTranscoder::StreamTranscoder(IInputStream& inputStream, IOutputFile& outpu // generator decoder AudioGenerator* generatorAudio = new AudioGenerator(); + generatorAudio->setAudioFrameDesc(outputFrameDesc); _generator = generatorAudio; break; @@ -282,6 +284,7 @@ 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 84350d6d5cec17db44fbd49da688932ac993f6f9 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Fri, 8 Apr 2016 15:35:32 +0200 Subject: [PATCH 08/13] AudioGenerator: defined one line methods in the header --- src/AvTranscoder/decoder/AudioGenerator.cpp | 5 ----- src/AvTranscoder/decoder/AudioGenerator.hpp | 3 ++- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/AvTranscoder/decoder/AudioGenerator.cpp b/src/AvTranscoder/decoder/AudioGenerator.cpp index 26d2e7ab..47ad8a3d 100644 --- a/src/AvTranscoder/decoder/AudioGenerator.cpp +++ b/src/AvTranscoder/decoder/AudioGenerator.cpp @@ -33,11 +33,6 @@ AudioGenerator::~AudioGenerator() delete _silent; } -void AudioGenerator::setNextFrame(Frame& inputFrame) -{ - _inputFrame = &inputFrame; -} - bool AudioGenerator::decodeNextFrame(Frame& frameBuffer) { // check the given frame diff --git a/src/AvTranscoder/decoder/AudioGenerator.hpp b/src/AvTranscoder/decoder/AudioGenerator.hpp index 977e8d4e..ec487814 100644 --- a/src/AvTranscoder/decoder/AudioGenerator.hpp +++ b/src/AvTranscoder/decoder/AudioGenerator.hpp @@ -19,10 +19,11 @@ class AvExport AudioGenerator : public IDecoder bool decodeNextFrame(Frame& frameBuffer); bool decodeNextFrame(Frame& frameBuffer, const size_t subStreamIndex); - void setNextFrame(Frame& inputFrame); const AudioFrameDesc& getAudioFrameDesc() const { return _frameDesc; } void setAudioFrameDesc(const AudioFrameDesc& frameDesc) { _frameDesc = frameDesc; } + void setNextFrame(Frame& inputFrame) { _inputFrame = &inputFrame; } + private: Frame* _inputFrame; ///< Has link (no ownership) AudioFrame* _silent; ///< The generated silent (has ownership) From 5962a2eff363a94ccac7baa85a56182f18b5b34a Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Fri, 8 Apr 2016 15:46:36 +0200 Subject: [PATCH 09/13] VideoGenerator: updated constructor to give a FrameDesc Since all our generators are allocated, and their FrameDesc are set just after. --- src/AvTranscoder/decoder/VideoGenerator.cpp | 8 ++++---- src/AvTranscoder/decoder/VideoGenerator.hpp | 5 +---- src/AvTranscoder/reader/VideoReader.cpp | 4 +--- src/AvTranscoder/transcoder/StreamTranscoder.cpp | 14 ++++---------- 4 files changed, 10 insertions(+), 21 deletions(-) diff --git a/src/AvTranscoder/decoder/VideoGenerator.cpp b/src/AvTranscoder/decoder/VideoGenerator.cpp index 8f448dcb..c82d451d 100644 --- a/src/AvTranscoder/decoder/VideoGenerator.cpp +++ b/src/AvTranscoder/decoder/VideoGenerator.cpp @@ -8,17 +8,17 @@ namespace avtranscoder { -VideoGenerator::VideoGenerator() +VideoGenerator::VideoGenerator(const VideoFrameDesc& frameDesc) : _inputFrame(NULL) , _blackImage(NULL) - , _frameDesc() + , _frameDesc(frameDesc) { } VideoGenerator::VideoGenerator(const VideoGenerator& videoGenerator) : _inputFrame(NULL) , _blackImage(NULL) - , _frameDesc(videoGenerator.getVideoFrameDesc()) + , _frameDesc(videoGenerator._frameDesc) { } @@ -26,7 +26,7 @@ VideoGenerator& VideoGenerator::operator=(const VideoGenerator& videoGenerator) { _inputFrame = NULL; _blackImage = NULL; - _frameDesc = videoGenerator.getVideoFrameDesc(); + _frameDesc = videoGenerator._frameDesc; return *this; } diff --git a/src/AvTranscoder/decoder/VideoGenerator.hpp b/src/AvTranscoder/decoder/VideoGenerator.hpp index 2359c9c8..f09a6278 100644 --- a/src/AvTranscoder/decoder/VideoGenerator.hpp +++ b/src/AvTranscoder/decoder/VideoGenerator.hpp @@ -10,7 +10,7 @@ namespace avtranscoder class AvExport VideoGenerator : public IDecoder { public: - VideoGenerator(); + VideoGenerator(const VideoFrameDesc& frameDesc); VideoGenerator(const VideoGenerator& videoGenerator); VideoGenerator& operator=(const VideoGenerator& videoGenerator); @@ -19,9 +19,6 @@ class AvExport VideoGenerator : public IDecoder bool decodeNextFrame(Frame& frameBuffer); bool decodeNextFrame(Frame& frameBuffer, const size_t channelIndex); - const VideoFrameDesc& getVideoFrameDesc() const { return _frameDesc; } - void setVideoFrameDesc(const VideoFrameDesc& frameDesc) { _frameDesc = frameDesc; } - void setNextFrame(Frame& inputFrame) { _inputFrame = &inputFrame; } private: diff --git a/src/AvTranscoder/reader/VideoReader.cpp b/src/AvTranscoder/reader/VideoReader.cpp index 53fc00f1..d4a091ed 100644 --- a/src/AvTranscoder/reader/VideoReader.cpp +++ b/src/AvTranscoder/reader/VideoReader.cpp @@ -43,9 +43,7 @@ void VideoReader::init() _decoder->setupDecoder(); // generator - VideoGenerator* generator = new VideoGenerator(); - generator->setVideoFrameDesc(_inputFile->getStream(_streamIndex).getVideoCodec().getVideoFrameDesc()); - _generator = generator; + _generator = new VideoGenerator(_inputFile->getStream(_streamIndex).getVideoCodec().getVideoFrameDesc()); // create transform _transform = new VideoTransform(); diff --git a/src/AvTranscoder/transcoder/StreamTranscoder.cpp b/src/AvTranscoder/transcoder/StreamTranscoder.cpp index 74751da3..2bcd464e 100644 --- a/src/AvTranscoder/transcoder/StreamTranscoder.cpp +++ b/src/AvTranscoder/transcoder/StreamTranscoder.cpp @@ -51,9 +51,7 @@ StreamTranscoder::StreamTranscoder(IInputStream& inputStream, IOutputFile& outpu VideoFrameDesc inputFrameDesc(_inputStream->getVideoCodec().getVideoFrameDesc()); // generator decoder - VideoGenerator* generatorVideo = new VideoGenerator(); - generatorVideo->setVideoFrameDesc(inputFrameDesc); - _generator = generatorVideo; + _generator = new VideoGenerator(inputFrameDesc); // buffers to process _sourceBuffer = new VideoFrame(inputFrameDesc); @@ -174,9 +172,7 @@ StreamTranscoder::StreamTranscoder(IInputStream& inputStream, IOutputFile& outpu _transform = new VideoTransform(); // generator decoder - VideoGenerator* generatorVideo = new VideoGenerator(); - generatorVideo->setVideoFrameDesc(outputVideo->getVideoCodec().getVideoFrameDesc()); - _generator = generatorVideo; + _generator = new VideoGenerator(outputVideo->getVideoCodec().getVideoFrameDesc()); break; } @@ -251,11 +247,9 @@ StreamTranscoder::StreamTranscoder(const ICodec& inputCodec, IOutputFile& output { if(profile.find(constants::avProfileType)->second == constants::avProfileTypeVideo) { - // generator decoder - VideoGenerator* generatorVideo = new VideoGenerator(); const VideoCodec& inputVideoCodec = static_cast(inputCodec); - generatorVideo->setVideoFrameDesc(inputVideoCodec.getVideoFrameDesc()); - _generator = generatorVideo; + // generator decoder + _generator = new VideoGenerator(inputVideoCodec.getVideoFrameDesc()); _currentDecoder = _generator; // filter From a0e18d624182bb6fcd583917a15301b398e5d4f0 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Fri, 8 Apr 2016 15:47:00 +0200 Subject: [PATCH 10/13] AudioGenerator: updated constructor to give a FrameDesc Since all our generators are allocated, and their FrameDesc are set just after. --- src/AvTranscoder/decoder/AudioGenerator.cpp | 7 ++++--- src/AvTranscoder/decoder/AudioGenerator.hpp | 5 +---- src/AvTranscoder/reader/AudioReader.cpp | 4 +--- src/AvTranscoder/transcoder/StreamTranscoder.cpp | 14 ++++---------- 4 files changed, 10 insertions(+), 20 deletions(-) diff --git a/src/AvTranscoder/decoder/AudioGenerator.cpp b/src/AvTranscoder/decoder/AudioGenerator.cpp index 47ad8a3d..c29da4e7 100644 --- a/src/AvTranscoder/decoder/AudioGenerator.cpp +++ b/src/AvTranscoder/decoder/AudioGenerator.cpp @@ -7,16 +7,17 @@ namespace avtranscoder { -AudioGenerator::AudioGenerator() +AudioGenerator::AudioGenerator(const AudioFrameDesc& frameDesc) : _inputFrame(NULL) , _silent(NULL) + , _frameDesc(frameDesc) { } AudioGenerator::AudioGenerator(const AudioGenerator& audioGenerator) : _inputFrame(NULL) , _silent(NULL) - , _frameDesc(audioGenerator.getAudioFrameDesc()) + , _frameDesc(audioGenerator._frameDesc) { } @@ -24,7 +25,7 @@ AudioGenerator& AudioGenerator::operator=(const AudioGenerator& audioGenerator) { _inputFrame = NULL; _silent = NULL; - _frameDesc = audioGenerator.getAudioFrameDesc(); + _frameDesc = audioGenerator._frameDesc; return *this; } diff --git a/src/AvTranscoder/decoder/AudioGenerator.hpp b/src/AvTranscoder/decoder/AudioGenerator.hpp index ec487814..96825491 100644 --- a/src/AvTranscoder/decoder/AudioGenerator.hpp +++ b/src/AvTranscoder/decoder/AudioGenerator.hpp @@ -10,7 +10,7 @@ namespace avtranscoder class AvExport AudioGenerator : public IDecoder { public: - AudioGenerator(); + AudioGenerator(const AudioFrameDesc& frameDesc); AudioGenerator(const AudioGenerator& audioGenerator); AudioGenerator& operator=(const AudioGenerator& audioGenerator); @@ -19,9 +19,6 @@ 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) { _frameDesc = frameDesc; } - void setNextFrame(Frame& inputFrame) { _inputFrame = &inputFrame; } private: diff --git a/src/AvTranscoder/reader/AudioReader.cpp b/src/AvTranscoder/reader/AudioReader.cpp index f6cab2f5..3aca27ba 100644 --- a/src/AvTranscoder/reader/AudioReader.cpp +++ b/src/AvTranscoder/reader/AudioReader.cpp @@ -44,9 +44,7 @@ void AudioReader::init() _decoder->setupDecoder(); // generator - AudioGenerator* generator = new AudioGenerator(); - generator->setAudioFrameDesc(_inputFile->getStream(_streamIndex).getAudioCodec().getAudioFrameDesc()); - _generator = generator; + _generator = new AudioGenerator(_inputFile->getStream(_streamIndex).getAudioCodec().getAudioFrameDesc()); // create transform _transform = new AudioTransform(); diff --git a/src/AvTranscoder/transcoder/StreamTranscoder.cpp b/src/AvTranscoder/transcoder/StreamTranscoder.cpp index 2bcd464e..517bd076 100644 --- a/src/AvTranscoder/transcoder/StreamTranscoder.cpp +++ b/src/AvTranscoder/transcoder/StreamTranscoder.cpp @@ -86,9 +86,7 @@ StreamTranscoder::StreamTranscoder(IInputStream& inputStream, IOutputFile& outpu AudioFrameDesc inputFrameDesc(_inputStream->getAudioCodec().getAudioFrameDesc()); // generator decoder - AudioGenerator* generatorAudio = new AudioGenerator(); - generatorAudio->setAudioFrameDesc(inputFrameDesc); - _generator = generatorAudio; + _generator = new AudioGenerator(inputFrameDesc); // buffers to process _sourceBuffer = new AudioFrame(inputFrameDesc); @@ -215,9 +213,7 @@ StreamTranscoder::StreamTranscoder(IInputStream& inputStream, IOutputFile& outpu _transform = new AudioTransform(); // generator decoder - AudioGenerator* generatorAudio = new AudioGenerator(); - generatorAudio->setAudioFrameDesc(outputFrameDesc); - _generator = generatorAudio; + _generator = new AudioGenerator(outputFrameDesc); break; } @@ -275,11 +271,9 @@ StreamTranscoder::StreamTranscoder(const ICodec& inputCodec, IOutputFile& output } else if(profile.find(constants::avProfileType)->second == constants::avProfileTypeAudio) { - // generator decoder - AudioGenerator* generatorAudio = new AudioGenerator(); const AudioCodec& inputAudioCodec = static_cast(inputCodec); - generatorAudio->setAudioFrameDesc(inputAudioCodec.getAudioFrameDesc()); - _generator = generatorAudio; + // generator decoder + _generator = new AudioGenerator(inputAudioCodec.getAudioFrameDesc()); _currentDecoder = _generator; // filter From 2ff4b5152777956fab216f79eebd8d1c3154e3a1 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Fri, 8 Apr 2016 16:18:54 +0200 Subject: [PATCH 11/13] StreamTranscoder: fixed filtering process if the decoding failed --- src/AvTranscoder/transcoder/StreamTranscoder.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/AvTranscoder/transcoder/StreamTranscoder.cpp b/src/AvTranscoder/transcoder/StreamTranscoder.cpp index 517bd076..67f3e8a4 100644 --- a/src/AvTranscoder/transcoder/StreamTranscoder.cpp +++ b/src/AvTranscoder/transcoder/StreamTranscoder.cpp @@ -474,12 +474,12 @@ bool StreamTranscoder::processTranscode(const int subStreamIndex) else decodingStatus = _currentDecoder->decodeNextFrame(*_sourceBuffer, subStreamIndex); - LOG_DEBUG("Filtering") - _filterGraph->process(*_sourceBuffer); - CodedData data; if(decodingStatus) { + LOG_DEBUG("Filtering") + _filterGraph->process(*_sourceBuffer); + LOG_DEBUG("Convert") _transform->convert(*_sourceBuffer, *_frameBuffer); From 34fef169742415ed4427a3508a23d9daae22be23 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Fri, 8 Apr 2016 16:43:47 +0200 Subject: [PATCH 12/13] readers: added _currentDecoder attribute to easily switch between decoders * If we want to call the generator, no need to call decodeNextFrame on the other decoder each time. This commit avoids this. * This is the same solution in StreamTranscoder class. --- src/AvTranscoder/reader/AudioReader.cpp | 1 + src/AvTranscoder/reader/IReader.cpp | 14 +++++++++----- src/AvTranscoder/reader/IReader.hpp | 1 + src/AvTranscoder/reader/VideoReader.cpp | 1 + 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/AvTranscoder/reader/AudioReader.cpp b/src/AvTranscoder/reader/AudioReader.cpp index 3aca27ba..b7b487c4 100644 --- a/src/AvTranscoder/reader/AudioReader.cpp +++ b/src/AvTranscoder/reader/AudioReader.cpp @@ -42,6 +42,7 @@ void AudioReader::init() // setup decoder _decoder = new AudioDecoder(_inputFile->getStream(_streamIndex)); _decoder->setupDecoder(); + _currentDecoder = _decoder; // generator _generator = new AudioGenerator(_inputFile->getStream(_streamIndex).getAudioCodec().getAudioFrameDesc()); diff --git a/src/AvTranscoder/reader/IReader.cpp b/src/AvTranscoder/reader/IReader.cpp index 76bed7ff..c950571e 100644 --- a/src/AvTranscoder/reader/IReader.cpp +++ b/src/AvTranscoder/reader/IReader.cpp @@ -9,6 +9,8 @@ IReader::IReader(const std::string& filename, const size_t streamIndex, const in : _inputFile(NULL) , _streamProperties(NULL) , _decoder(NULL) + , _generator(NULL) + , _currentDecoder(NULL) , _srcFrame(NULL) , _dstFrame(NULL) , _transform(NULL) @@ -25,6 +27,8 @@ IReader::IReader(InputFile& inputFile, const size_t streamIndex, const int chann : _inputFile(&inputFile) , _streamProperties(NULL) , _decoder(NULL) + , _generator(NULL) + , _currentDecoder(NULL) , _srcFrame(NULL) , _dstFrame(NULL) , _transform(NULL) @@ -54,8 +58,7 @@ Frame* IReader::readPrevFrame() Frame* IReader::readFrameAt(const size_t frame) { - assert(_decoder != NULL); - assert(_generator != NULL); + assert(_currentDecoder != NULL); assert(_transform != NULL); assert(_srcFrame != NULL); assert(_dstFrame != NULL); @@ -70,16 +73,17 @@ Frame* IReader::readFrameAt(const size_t frame) // decode bool decodingStatus = false; if(_channelIndex != -1) - decodingStatus = _decoder->decodeNextFrame(*_srcFrame, _channelIndex); + decodingStatus = _currentDecoder->decodeNextFrame(*_srcFrame, _channelIndex); else - decodingStatus = _decoder->decodeNextFrame(*_srcFrame); + decodingStatus = _currentDecoder->decodeNextFrame(*_srcFrame); // if decoding failed if(!decodingStatus) { // generate data (ie silence or black) if(_continueWithGenerator) { - _generator->decodeNextFrame(*_srcFrame); + _currentDecoder = _generator; + return readFrameAt(frame); } // or return NULL else diff --git a/src/AvTranscoder/reader/IReader.hpp b/src/AvTranscoder/reader/IReader.hpp index 8d53b647..696e38d5 100644 --- a/src/AvTranscoder/reader/IReader.hpp +++ b/src/AvTranscoder/reader/IReader.hpp @@ -68,6 +68,7 @@ class AvExport IReader const StreamProperties* _streamProperties; IDecoder* _decoder; IDecoder* _generator; + IDecoder* _currentDecoder; ///< Link to _inputDecoder or _generator Frame* _srcFrame; Frame* _dstFrame; diff --git a/src/AvTranscoder/reader/VideoReader.cpp b/src/AvTranscoder/reader/VideoReader.cpp index d4a091ed..304a5d22 100644 --- a/src/AvTranscoder/reader/VideoReader.cpp +++ b/src/AvTranscoder/reader/VideoReader.cpp @@ -41,6 +41,7 @@ void VideoReader::init() // setup decoder _decoder = new VideoDecoder(_inputFile->getStream(_streamIndex)); _decoder->setupDecoder(); + _currentDecoder = _decoder; // generator _generator = new VideoGenerator(_inputFile->getStream(_streamIndex).getVideoCodec().getVideoFrameDesc()); From fd3be2c1bb1920fe4c95a7e618fd6eeb95cc8cd9 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Tue, 12 Apr 2016 12:00:02 +0200 Subject: [PATCH 13/13] Video/AudioGenerator: copy constructor and operator= are private * No need to define them, since _inputFrame, _blackImage/_silent are not copied. * With this update, _frameDesc can be a const attribute. --- src/AvTranscoder/decoder/AudioGenerator.cpp | 15 --------------- src/AvTranscoder/decoder/AudioGenerator.hpp | 8 +++++--- src/AvTranscoder/decoder/VideoGenerator.cpp | 15 --------------- src/AvTranscoder/decoder/VideoGenerator.hpp | 8 +++++--- 4 files changed, 10 insertions(+), 36 deletions(-) diff --git a/src/AvTranscoder/decoder/AudioGenerator.cpp b/src/AvTranscoder/decoder/AudioGenerator.cpp index c29da4e7..297ee009 100644 --- a/src/AvTranscoder/decoder/AudioGenerator.cpp +++ b/src/AvTranscoder/decoder/AudioGenerator.cpp @@ -14,21 +14,6 @@ AudioGenerator::AudioGenerator(const AudioFrameDesc& frameDesc) { } -AudioGenerator::AudioGenerator(const AudioGenerator& audioGenerator) - : _inputFrame(NULL) - , _silent(NULL) - , _frameDesc(audioGenerator._frameDesc) -{ -} - -AudioGenerator& AudioGenerator::operator=(const AudioGenerator& audioGenerator) -{ - _inputFrame = NULL; - _silent = NULL; - _frameDesc = audioGenerator._frameDesc; - return *this; -} - AudioGenerator::~AudioGenerator() { delete _silent; diff --git a/src/AvTranscoder/decoder/AudioGenerator.hpp b/src/AvTranscoder/decoder/AudioGenerator.hpp index 96825491..e12b2eba 100644 --- a/src/AvTranscoder/decoder/AudioGenerator.hpp +++ b/src/AvTranscoder/decoder/AudioGenerator.hpp @@ -9,10 +9,12 @@ namespace avtranscoder class AvExport AudioGenerator : public IDecoder { +private: + AudioGenerator& operator=(const AudioGenerator& audioGenerator); + AudioGenerator(const AudioGenerator& audioGenerator); + public: AudioGenerator(const AudioFrameDesc& frameDesc); - AudioGenerator(const AudioGenerator& audioGenerator); - AudioGenerator& operator=(const AudioGenerator& audioGenerator); ~AudioGenerator(); @@ -24,7 +26,7 @@ class AvExport AudioGenerator : public IDecoder private: Frame* _inputFrame; ///< Has link (no ownership) AudioFrame* _silent; ///< The generated silent (has ownership) - AudioFrameDesc _frameDesc; ///< The description of the silence (sampleRate, channels...) + const AudioFrameDesc _frameDesc; ///< The description of the silence (sampleRate, channels...) }; } diff --git a/src/AvTranscoder/decoder/VideoGenerator.cpp b/src/AvTranscoder/decoder/VideoGenerator.cpp index c82d451d..0d35df0e 100644 --- a/src/AvTranscoder/decoder/VideoGenerator.cpp +++ b/src/AvTranscoder/decoder/VideoGenerator.cpp @@ -15,21 +15,6 @@ VideoGenerator::VideoGenerator(const VideoFrameDesc& frameDesc) { } -VideoGenerator::VideoGenerator(const VideoGenerator& videoGenerator) - : _inputFrame(NULL) - , _blackImage(NULL) - , _frameDesc(videoGenerator._frameDesc) -{ -} - -VideoGenerator& VideoGenerator::operator=(const VideoGenerator& videoGenerator) -{ - _inputFrame = NULL; - _blackImage = NULL; - _frameDesc = videoGenerator._frameDesc; - return *this; -} - VideoGenerator::~VideoGenerator() { delete _blackImage; diff --git a/src/AvTranscoder/decoder/VideoGenerator.hpp b/src/AvTranscoder/decoder/VideoGenerator.hpp index f09a6278..b6a7a556 100644 --- a/src/AvTranscoder/decoder/VideoGenerator.hpp +++ b/src/AvTranscoder/decoder/VideoGenerator.hpp @@ -9,11 +9,13 @@ namespace avtranscoder class AvExport VideoGenerator : public IDecoder { -public: - VideoGenerator(const VideoFrameDesc& frameDesc); +private: VideoGenerator(const VideoGenerator& videoGenerator); VideoGenerator& operator=(const VideoGenerator& videoGenerator); +public: + VideoGenerator(const VideoFrameDesc& frameDesc); + ~VideoGenerator(); bool decodeNextFrame(Frame& frameBuffer); @@ -24,7 +26,7 @@ class AvExport VideoGenerator : public IDecoder private: Frame* _inputFrame; ///< A frame given from outside (has link, no ownership) VideoFrame* _blackImage; ///< The generated black image (has ownership) - VideoFrameDesc _frameDesc; ///< The description of the black image (width, height...) + const VideoFrameDesc _frameDesc; ///< The description of the black image (width, height...) }; }