From bcc0b08be5cc82bb7870d193e547a51c3ddd7d3e Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Wed, 18 Jan 2017 15:11:17 +0100 Subject: [PATCH 1/4] ICodec: add closeCodec public method To be able to close a codec from outside of the class without calling ffmpeg/libav methods. --- src/AvTranscoder/codec/ICodec.cpp | 11 +++++++++-- src/AvTranscoder/codec/ICodec.hpp | 2 ++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/src/AvTranscoder/codec/ICodec.cpp b/src/AvTranscoder/codec/ICodec.cpp index 3e64cd76..51ef6161 100644 --- a/src/AvTranscoder/codec/ICodec.cpp +++ b/src/AvTranscoder/codec/ICodec.cpp @@ -44,7 +44,7 @@ ICodec::ICodec(const ECodecType type, AVCodecContext& avCodecContext) ICodec::~ICodec() { - avcodec_close(_avCodecContext); + closeCodec(); if(!_isCodecContextAllocated) return; @@ -73,7 +73,7 @@ void ICodec::openCodec() msg += ") "; } - avcodec_close(_avCodecContext); + closeCodec(); msg += getDescriptionFromErrorCode(ret); @@ -81,6 +81,13 @@ void ICodec::openCodec() } } +void ICodec::closeCodec() +{ + if(!_avCodecContext) + throw std::runtime_error("Unable to close a codec without codec context"); + avcodec_close(_avCodecContext); +} + std::string ICodec::getCodecName() const { assert(_avCodecContext != NULL); diff --git a/src/AvTranscoder/codec/ICodec.hpp b/src/AvTranscoder/codec/ICodec.hpp index ede6cafa..de3203dd 100644 --- a/src/AvTranscoder/codec/ICodec.hpp +++ b/src/AvTranscoder/codec/ICodec.hpp @@ -37,6 +37,8 @@ class AvExport ICodec /// Initialize the codec context. void openCodec(); + /// Reset the codec context. + void closeCodec(); std::string getCodecName() const; AVCodecID getCodecId() const; From d5d633facd651faefc68f28721e8187dd10ba456 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Wed, 18 Jan 2017 15:20:47 +0100 Subject: [PATCH 2/4] ICodec: fix how to close the codec * The decoder can open the codec (and so there is a flag _isSetup to check this). * If the codec was open by the decoder, it should close it at the end of its life. * So the codec itself is not responsible to close its context. --- src/AvTranscoder/codec/ICodec.cpp | 2 -- src/AvTranscoder/decoder/AudioDecoder.cpp | 4 +++- src/AvTranscoder/decoder/VideoDecoder.cpp | 4 +++- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/AvTranscoder/codec/ICodec.cpp b/src/AvTranscoder/codec/ICodec.cpp index 51ef6161..0e588acf 100644 --- a/src/AvTranscoder/codec/ICodec.cpp +++ b/src/AvTranscoder/codec/ICodec.cpp @@ -44,8 +44,6 @@ ICodec::ICodec(const ECodecType type, AVCodecContext& avCodecContext) ICodec::~ICodec() { - closeCodec(); - if(!_isCodecContextAllocated) return; diff --git a/src/AvTranscoder/decoder/AudioDecoder.cpp b/src/AvTranscoder/decoder/AudioDecoder.cpp index 4b7f6101..a995a3df 100644 --- a/src/AvTranscoder/decoder/AudioDecoder.cpp +++ b/src/AvTranscoder/decoder/AudioDecoder.cpp @@ -27,6 +27,8 @@ AudioDecoder::AudioDecoder(InputStream& inputStream) AudioDecoder::~AudioDecoder() { + if(_isSetup) + _inputStream->getAudioCodec().closeCodec(); } void AudioDecoder::setupDecoder(const ProfileLoader::Profile& profile) @@ -73,7 +75,7 @@ void AudioDecoder::setupDecoder(const ProfileLoader::Profile& profile) } // open decoder - _inputStream->getAudioCodec().openCodec(); + codec.openCodec(); _isSetup = true; } diff --git a/src/AvTranscoder/decoder/VideoDecoder.cpp b/src/AvTranscoder/decoder/VideoDecoder.cpp index 6b48536a..ae76fb05 100644 --- a/src/AvTranscoder/decoder/VideoDecoder.cpp +++ b/src/AvTranscoder/decoder/VideoDecoder.cpp @@ -24,6 +24,8 @@ VideoDecoder::VideoDecoder(InputStream& inputStream) VideoDecoder::~VideoDecoder() { + if(_isSetup) + _inputStream->getVideoCodec().closeCodec(); } void VideoDecoder::setupDecoder(const ProfileLoader::Profile& profile) @@ -70,7 +72,7 @@ void VideoDecoder::setupDecoder(const ProfileLoader::Profile& profile) } // open decoder - _inputStream->getVideoCodec().openCodec(); + codec.openCodec(); _isSetup = true; } From aa9387e59b4ada84daaafaeda0298f8406d3453f Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Wed, 18 Jan 2017 17:16:00 +0100 Subject: [PATCH 3/4] Transcoder: fix seg fault at the end of a transcode process The StreamTranscoders have to be destroy (close codec included) before removing the InputFiles (streams). --- src/AvTranscoder/transcoder/Transcoder.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/AvTranscoder/transcoder/Transcoder.cpp b/src/AvTranscoder/transcoder/Transcoder.cpp index fe9d1829..3e35ad4e 100644 --- a/src/AvTranscoder/transcoder/Transcoder.cpp +++ b/src/AvTranscoder/transcoder/Transcoder.cpp @@ -25,12 +25,12 @@ Transcoder::Transcoder(IOutputFile& outputFile) Transcoder::~Transcoder() { - for(std::vector::iterator it = _inputFiles.begin(); it != _inputFiles.end(); ++it) + for(std::vector::iterator it = _streamTranscodersAllocated.begin(); + it != _streamTranscodersAllocated.end(); ++it) { delete(*it); } - for(std::vector::iterator it = _streamTranscodersAllocated.begin(); - it != _streamTranscodersAllocated.end(); ++it) + for(std::vector::iterator it = _inputFiles.begin(); it != _inputFiles.end(); ++it) { delete(*it); } From ca157d83988a6ebf3bb82b2eb068419160cd07b5 Mon Sep 17 00:00:00 2001 From: Clement Champetier Date: Mon, 30 Jan 2017 19:25:23 +0100 Subject: [PATCH 4/4] pyTest: fix seg fault in the readers tests * Force to call the reader destructor before the inputFile destructor (which cannot happen in C++). * This is a new problem since the decoder has a link to the stream, which is needed to access the codec to close it. So the file, which handles the streams, should not be destroyed before the decoders. --- test/pyTest/testAudioReader.py | 7 +++++-- test/pyTest/testVideoReader.py | 4 +++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/test/pyTest/testAudioReader.py b/test/pyTest/testAudioReader.py index 30a9b080..7711f9d7 100644 --- a/test/pyTest/testAudioReader.py +++ b/test/pyTest/testAudioReader.py @@ -55,6 +55,10 @@ def testAudioReaderChannelsExtraction(): assert_equals( sizeOfFrameWithAllChannels / nbChannels, sizeOfFrameWithOneChannels ) + # Force to call the readers destructor before the inputFile destructor (which cannot happen in C++) + readerOfAllChannels = None + readerOfOneChannel = None + def testAudioReaderWithGenerator(): """ @@ -62,8 +66,7 @@ def testAudioReaderWithGenerator(): When there is no more data to decode, switch to a generator and process some frames. """ inputFileName = os.environ['AVTRANSCODER_TEST_AUDIO_WAVE_FILE'] - inputFile = av.InputFile(inputFileName) - reader = av.AudioReader(inputFile) + reader = av.AudioReader(inputFileName) # read all frames and check their size while True: diff --git a/test/pyTest/testVideoReader.py b/test/pyTest/testVideoReader.py index b4e782a7..bf853592 100644 --- a/test/pyTest/testVideoReader.py +++ b/test/pyTest/testVideoReader.py @@ -25,7 +25,6 @@ def testVideoReaderCreateNewInputFile(): assert_equals( frame.getDataSize(), reader.getOutputWidth() * reader.getOutputHeight() * bytesPerPixel ) # check if there is no next frame - frame = reader.readNextFrame() assert_equals( reader.readNextFrame(), None ) @@ -47,6 +46,9 @@ def testVideoReaderReferenceInputFile(): # check if there is no next frame assert_equals( reader.readNextFrame(), None ) + # Force to call the reader destructor before the inputFile destructor (which cannot happen in C++) + reader = None + def testVideoReaderWithGenerator(): """ 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