Skip to content

Commit 928309b

Browse files
authored
Merge pull request #296 from cchampet/fix_DecodersCloseCodec
Video/AudioDecoder: fix the codec state when calling decoder destructor
2 parents 354c5b2 + ca157d8 commit 928309b

File tree

7 files changed

+27
-11
lines changed

7 files changed

+27
-11
lines changed

src/AvTranscoder/codec/ICodec.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,6 @@ ICodec::ICodec(const ECodecType type, AVCodecContext& avCodecContext)
4444

4545
ICodec::~ICodec()
4646
{
47-
avcodec_close(_avCodecContext);
48-
4947
if(!_isCodecContextAllocated)
5048
return;
5149

@@ -73,14 +71,21 @@ void ICodec::openCodec()
7371
msg += ") ";
7472
}
7573

76-
avcodec_close(_avCodecContext);
74+
closeCodec();
7775

7876
msg += getDescriptionFromErrorCode(ret);
7977

8078
throw std::runtime_error(msg);
8179
}
8280
}
8381

82+
void ICodec::closeCodec()
83+
{
84+
if(!_avCodecContext)
85+
throw std::runtime_error("Unable to close a codec without codec context");
86+
avcodec_close(_avCodecContext);
87+
}
88+
8489
std::string ICodec::getCodecName() const
8590
{
8691
assert(_avCodecContext != NULL);

src/AvTranscoder/codec/ICodec.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ class AvExport ICodec
3737

3838
/// Initialize the codec context.
3939
void openCodec();
40+
/// Reset the codec context.
41+
void closeCodec();
4042

4143
std::string getCodecName() const;
4244
AVCodecID getCodecId() const;

src/AvTranscoder/decoder/AudioDecoder.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ AudioDecoder::AudioDecoder(InputStream& inputStream)
2727

2828
AudioDecoder::~AudioDecoder()
2929
{
30+
if(_isSetup)
31+
_inputStream->getAudioCodec().closeCodec();
3032
}
3133

3234
void AudioDecoder::setupDecoder(const ProfileLoader::Profile& profile)
@@ -73,7 +75,7 @@ void AudioDecoder::setupDecoder(const ProfileLoader::Profile& profile)
7375
}
7476

7577
// open decoder
76-
_inputStream->getAudioCodec().openCodec();
78+
codec.openCodec();
7779
_isSetup = true;
7880
}
7981

src/AvTranscoder/decoder/VideoDecoder.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ VideoDecoder::VideoDecoder(InputStream& inputStream)
2424

2525
VideoDecoder::~VideoDecoder()
2626
{
27+
if(_isSetup)
28+
_inputStream->getVideoCodec().closeCodec();
2729
}
2830

2931
void VideoDecoder::setupDecoder(const ProfileLoader::Profile& profile)
@@ -70,7 +72,7 @@ void VideoDecoder::setupDecoder(const ProfileLoader::Profile& profile)
7072
}
7173

7274
// open decoder
73-
_inputStream->getVideoCodec().openCodec();
75+
codec.openCodec();
7476
_isSetup = true;
7577
}
7678

src/AvTranscoder/transcoder/Transcoder.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,12 @@ Transcoder::Transcoder(IOutputFile& outputFile)
2525

2626
Transcoder::~Transcoder()
2727
{
28-
for(std::vector<InputFile*>::iterator it = _inputFiles.begin(); it != _inputFiles.end(); ++it)
28+
for(std::vector<StreamTranscoder*>::iterator it = _streamTranscodersAllocated.begin();
29+
it != _streamTranscodersAllocated.end(); ++it)
2930
{
3031
delete(*it);
3132
}
32-
for(std::vector<StreamTranscoder*>::iterator it = _streamTranscodersAllocated.begin();
33-
it != _streamTranscodersAllocated.end(); ++it)
33+
for(std::vector<InputFile*>::iterator it = _inputFiles.begin(); it != _inputFiles.end(); ++it)
3434
{
3535
delete(*it);
3636
}

test/pyTest/testAudioReader.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,15 +55,18 @@ def testAudioReaderChannelsExtraction():
5555

5656
assert_equals( sizeOfFrameWithAllChannels / nbChannels, sizeOfFrameWithOneChannels )
5757

58+
# Force to call the readers destructor before the inputFile destructor (which cannot happen in C++)
59+
readerOfAllChannels = None
60+
readerOfOneChannel = None
61+
5862

5963
def testAudioReaderWithGenerator():
6064
"""
6165
Read an audio stream with the AudioReader.
6266
When there is no more data to decode, switch to a generator and process some frames.
6367
"""
6468
inputFileName = os.environ['AVTRANSCODER_TEST_AUDIO_WAVE_FILE']
65-
inputFile = av.InputFile(inputFileName)
66-
reader = av.AudioReader(inputFile)
69+
reader = av.AudioReader(inputFileName)
6770

6871
# read all frames and check their size
6972
while True:

test/pyTest/testVideoReader.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ def testVideoReaderCreateNewInputFile():
2525
assert_equals( frame.getDataSize(), reader.getOutputWidth() * reader.getOutputHeight() * bytesPerPixel )
2626

2727
# check if there is no next frame
28-
frame = reader.readNextFrame()
2928
assert_equals( reader.readNextFrame(), None )
3029

3130

@@ -47,6 +46,9 @@ def testVideoReaderReferenceInputFile():
4746
# check if there is no next frame
4847
assert_equals( reader.readNextFrame(), None )
4948

49+
# Force to call the reader destructor before the inputFile destructor (which cannot happen in C++)
50+
reader = None
51+
5052

5153
def testVideoReaderWithGenerator():
5254
"""

0 commit comments

Comments
 (0)
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