Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit6b535b3

Browse files
authored
Merge pull request#282 from cchampet/fix_memoryLeakWhenGenerateData
Fix memory leaks
2 parents103c33f +cd2db7b commit6b535b3

File tree

55 files changed

+948
-670
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+948
-670
lines changed

‎app/avProcessor/avProcessor.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ void parseConfigFile(const std::string& configFilename, avtranscoder::Transcoder
2828

2929
std::stringstreamss(streamId);
3030
size_t streamIndex =0;
31-
char separator;
31+
char separator ='x';
3232
std::vector<size_t> channelIndexArray;
3333
ss >> streamIndex;
3434
ss >> separator;

‎src/AvTranscoder/codec/AudioCodec.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#include"AudioCodec.hpp"
22

3+
#include<AvTranscoder/util.hpp>
4+
35
#include<cmath>
46
#include<cassert>
57

@@ -24,7 +26,7 @@ AudioCodec::AudioCodec(const ECodecType type, AVCodecContext& avCodecContext)
2426
AudioFrameDescAudioCodec::getAudioFrameDesc()const
2527
{
2628
assert(_avCodecContext !=NULL);
27-
returnAudioFrameDesc(_avCodecContext->sample_rate, _avCodecContext->channels, _avCodecContext->sample_fmt);
29+
returnAudioFrameDesc(_avCodecContext->sample_rate, _avCodecContext->channels,getSampleFormatName(_avCodecContext->sample_fmt));
2830
}
2931

3032
voidAudioCodec::setAudioParameters(const AudioFrameDesc& audioFrameDesc)

‎src/AvTranscoder/codec/ICodec.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ ICodec::~ICodec()
4949
if(!_isCodecContextAllocated)
5050
return;
5151

52-
av_free(_avCodecContext);
52+
avcodec_free_context(&_avCodecContext);
5353
_avCodecContext =NULL;
5454
}
5555

@@ -148,7 +148,8 @@ void ICodec::allocateContext()
148148
_avCodecContext =avcodec_alloc_context3(_avCodec);
149149
if(!_avCodecContext)
150150
{
151-
throwstd::runtime_error("Unable to allocate the codecContext and set its fields to default values");
151+
LOG_ERROR("Unable to allocate the codecContext and set its fields to default values.")
152+
throwstd::bad_alloc();
152153
}
153154
_avCodecContext->codec = _avCodec;
154155
}

‎src/AvTranscoder/codec/VideoCodec.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#include"VideoCodec.hpp"
22

3+
#include<AvTranscoder/util.hpp>
4+
35
#include<cmath>
46
#include<cassert>
57

@@ -24,7 +26,7 @@ VideoCodec::VideoCodec(const ECodecType type, AVCodecContext& avCodecContext)
2426
VideoFrameDescVideoCodec::getVideoFrameDesc()const
2527
{
2628
assert(_avCodecContext !=NULL);
27-
VideoFrameDescvideoFrameDesc(_avCodecContext->width, _avCodecContext->height, _avCodecContext->pix_fmt);
29+
VideoFrameDescvideoFrameDesc(_avCodecContext->width, _avCodecContext->height,getPixelFormatName(_avCodecContext->pix_fmt));
2830
double fps =1.0 * _avCodecContext->time_base.den / (_avCodecContext->time_base.num * _avCodecContext->ticks_per_frame);
2931
if(!std::isinf(fps))
3032
videoFrameDesc._fps = fps;

‎src/AvTranscoder/data/coded/CodedData.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,12 @@ CodedData::CodedData()
1414
CodedData::CodedData(constsize_t dataSize)
1515
: _avStream(NULL)
1616
{
17-
av_new_packet(&_packet, dataSize);
17+
constint err =av_new_packet(&_packet, dataSize);
18+
if(err !=0)
19+
{
20+
LOG_ERROR("Unable to allocate the payload of a packet and initialize its fields with default values:" <<getDescriptionFromErrorCode(err))
21+
throwstd::bad_alloc();
22+
}
1823
}
1924

2025
CodedData::CodedData(const AVPacket& avPacket)

‎src/AvTranscoder/data/data.i

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@
22

33
%{
44
#include<AvTranscoder/data/coded/CodedData.hpp>
5-
#include<AvTranscoder/data/decoded/Frame.hpp>
5+
#include<AvTranscoder/data/decoded/IFrame.hpp>
66
#include<AvTranscoder/data/decoded/VideoFrame.hpp>
77
#include<AvTranscoder/data/decoded/AudioFrame.hpp>
88
%}
99

1010
%include <AvTranscoder/data/coded/CodedData.hpp>
11-
%include <AvTranscoder/data/decoded/Frame.hpp>
11+
%include <AvTranscoder/data/decoded/IFrame.hpp>
1212
%include <AvTranscoder/data/decoded/VideoFrame.hpp>
1313
%include <AvTranscoder/data/decoded/AudioFrame.hpp>

‎src/AvTranscoder/data/decoded/AudioFrame.cpp

Lines changed: 69 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,19 @@ extern "C" {
1212
namespaceavtranscoder
1313
{
1414

15-
AudioFrameDesc::AudioFrameDesc(constsize_t sampleRate,constsize_t nbChannels,constAVSampleFormat sampleFormat)
15+
AudioFrameDesc::AudioFrameDesc(constsize_t sampleRate,constsize_t nbChannels,conststd::string& sampleFormatName)
1616
: _sampleRate(sampleRate)
1717
, _nbChannels(nbChannels)
18-
, _sampleFormat(sampleFormat)
18+
, _sampleFormat(getAVSampleFormat(sampleFormatName))
1919
{
2020
}
2121

22-
AudioFrameDesc::AudioFrameDesc(constsize_t sampleRate,constsize_t nbChannels,const std::string& sampleFormatName)
23-
: _sampleRate(sampleRate)
24-
, _nbChannels(nbChannels)
25-
, _sampleFormat(getAVSampleFormat(sampleFormatName))
22+
AudioFrameDesc::AudioFrameDesc(constProfileLoader::Profile& profile)
23+
: _sampleRate(0)
24+
, _nbChannels(0)
25+
, _sampleFormat(AV_SAMPLE_FMT_NONE)
2626
{
27+
setParameters(profile);
2728
}
2829

2930
voidAudioFrameDesc::setParameters(const ProfileLoader::Profile& profile)
@@ -39,15 +40,19 @@ void AudioFrameDesc::setParameters(const ProfileLoader::Profile& profile)
3940
_sampleFormat =getAVSampleFormat(profile.find(constants::avProfileSampleFormat)->second.c_str());
4041
}
4142

42-
AudioFrame::AudioFrame(const AudioFrameDesc& ref)
43-
: Frame()
43+
AudioFrame::AudioFrame(const AudioFrameDesc& desc,constbool forceDataAllocation)
44+
: IFrame()
45+
, _desc(desc)
4446
{
45-
allocateAVSample(ref);
46-
}
47+
// Set Frame properties
48+
av_frame_set_sample_rate(_frame, desc._sampleRate);
49+
av_frame_set_channels(_frame, desc._nbChannels);
50+
av_frame_set_channel_layout(_frame,av_get_default_channel_layout(desc._nbChannels));
51+
_frame->format = desc._sampleFormat;
52+
_frame->nb_samples =getDefaultNbSamples();
4753

48-
AudioFrame::AudioFrame(const Frame& otherFrame)
49-
: Frame(otherFrame)
50-
{
54+
if(forceDataAllocation)
55+
allocateData();
5156
}
5257

5358
std::stringAudioFrame::getChannelLayoutDesc()const
@@ -57,75 +62,95 @@ std::string AudioFrame::getChannelLayoutDesc() const
5762
returnstd::string(buf);
5863
}
5964

60-
size_tAudioFrame::getSize()const
65+
AudioFrame::~AudioFrame()
66+
{
67+
if(_frame->buf[0])
68+
av_frame_unref(_frame);
69+
if(_dataAllocated)
70+
freeData();
71+
}
72+
73+
size_tAudioFrame::getBytesPerSample()const
74+
{
75+
returnav_get_bytes_per_sample(getSampleFormat());
76+
}
77+
78+
size_tAudioFrame::getDataSize()const
6179
{
6280
if(getSampleFormat() == AV_SAMPLE_FMT_NONE)
6381
{
6482
LOG_WARN("Incorrect sample format when get size of audio frame: return a size of 0.")
6583
return0;
6684
}
6785

68-
constsize_t size =getNbSamplesPerChannel() *getNbChannels() *av_get_bytes_per_sample(getSampleFormat());
86+
constsize_t size =getNbSamplesPerChannel() *getNbChannels() *getBytesPerSample();
6987
if(size ==0)
7088
{
7189
std::stringstream msg;
7290
msg <<"Unable to determine audio buffer size:" << std::endl;
7391
msg <<"nb sample per channel =" <<getNbSamplesPerChannel() << std::endl;
7492
msg <<"channels =" <<getNbChannels() << std::endl;
75-
msg <<"bytes per sample =" <<av_get_bytes_per_sample(getSampleFormat()) << std::endl;
93+
msg <<"bytes per sample =" <<getBytesPerSample() << std::endl;
7694
throwstd::runtime_error(msg.str());
7795
}
7896
return size;
7997
}
8098

81-
voidAudioFrame::allocateAVSample(const AudioFrameDesc& desc)
99+
voidAudioFrame::allocateData()
82100
{
101+
if(_dataAllocated)
102+
LOG_WARN("The AudioFrame seems to already have allocated data. This could lead to memory leaks.")
103+
83104
// Set Frame properties
84-
av_frame_set_sample_rate(_frame, desc._sampleRate);
85-
av_frame_set_channels(_frame, desc._nbChannels);
86-
av_frame_set_channel_layout(_frame,av_get_default_channel_layout(desc._nbChannels));
87-
_frame->format = desc._sampleFormat;
88-
_frame->nb_samples = desc._sampleRate /25.;// cannot be known before calling avcodec_decode_audio4
105+
av_frame_set_sample_rate(_frame, _desc._sampleRate);
106+
av_frame_set_channels(_frame, _desc._nbChannels);
107+
av_frame_set_channel_layout(_frame,av_get_default_channel_layout(_desc._nbChannels));
108+
_frame->format = _desc._sampleFormat;
109+
if(_frame->nb_samples ==0)
110+
_frame->nb_samples =getDefaultNbSamples();
89111

90112
// Allocate data
91113
constint align =0;
92114
constint ret =
93-
av_samples_alloc(_frame->data, _frame->linesize, _frame->channels, _frame->nb_samples,desc._sampleFormat, align);
115+
av_samples_alloc(_frame->data, _frame->linesize, _frame->channels, _frame->nb_samples,_desc._sampleFormat, align);
94116
if(ret <0)
95117
{
96-
std::stringstream os;
97-
os <<"Unable to allocate an audio frame of";
98-
os <<"sample rate =" << _frame->sample_rate <<",";
99-
os <<"nb channels =" << _frame->channels <<",";
100-
os <<"channel layout =" <<av_get_channel_name(_frame->channels) <<",";
101-
os <<"nb samples =" << _frame->nb_samples <<",";
102-
os <<"sample format =" <<getSampleFormatName(desc._sampleFormat);
103-
throwstd::runtime_error(os.str());
118+
const std::string formatName =getSampleFormatName(_desc._sampleFormat);
119+
std::stringstream msg;
120+
msg <<"Unable to allocate an audio frame of";
121+
msg <<"sample rate =" << _frame->sample_rate <<",";
122+
msg <<"nb channels =" << _frame->channels <<",";
123+
msg <<"channel layout =" <<av_get_channel_name(_frame->channels) <<",";
124+
msg <<"nb samples =" << _frame->nb_samples <<",";
125+
msg <<"sample format =" << (formatName.empty() ?"none" : formatName);
126+
LOG_ERROR(msg.str())
127+
throwstd::bad_alloc();
104128
}
129+
_dataAllocated =true;
105130
}
106131

107-
voidAudioFrame::assign(constunsignedchar value)
132+
voidAudioFrame::freeData()
108133
{
109-
// Create the audio buffer
110-
// The buffer will be freed in destructor of based class
111-
constint audioSize =getSize();
112-
unsignedchar* audioBuffer =newunsignedchar[audioSize];
113-
memset(audioBuffer, value, audioSize);
114-
115-
// Fill the picture
116-
assign(audioBuffer);
134+
av_freep(&_frame->data[0]);
135+
_dataAllocated =false;
117136
}
118137

119-
voidAudioFrame::assign(constunsignedchar* ptrValue)
138+
voidAudioFrame::assignBuffer(constunsignedchar* ptrValue)
120139
{
121140
constint align =0;
122141
constint ret =av_samples_fill_arrays(_frame->data, _frame->linesize, ptrValue,getNbChannels(),
123142
getNbSamplesPerChannel(),getSampleFormat(), align);
124143
if(ret <0)
125144
{
126-
std::stringstreamos;
127-
os <<"Unable to assign an audio buffer:" <<getDescriptionFromErrorCode(ret);
128-
throwstd::runtime_error(os.str());
145+
std::stringstreammsg;
146+
msg <<"Unable to assign an audio buffer:" <<getDescriptionFromErrorCode(ret);
147+
throwstd::runtime_error(msg.str());
129148
}
130149
}
150+
151+
size_tAudioFrame::getDefaultNbSamples()const
152+
{
153+
return _desc._sampleRate /25.;
154+
}
155+
131156
}

‎src/AvTranscoder/data/decoded/AudioFrame.hpp

Lines changed: 33 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#ifndef _AV_TRANSCODER_FRAME_AUDIO_FRAME_HPP_
22
#define_AV_TRANSCODER_FRAME_AUDIO_FRAME_HPP_
33

4-
#include"Frame.hpp"
4+
#include"IFrame.hpp"
55
#include<AvTranscoder/profile/ProfileLoader.hpp>
66

77
namespaceavtranscoder
@@ -14,9 +14,8 @@ namespace avtranscoder
1414
structAvExport AudioFrameDesc
1515
{
1616
public:
17-
AudioFrameDesc(constsize_t sampleRate =0,constsize_t channels =0,
18-
const AVSampleFormat sampleFormat = AV_SAMPLE_FMT_NONE);
1917
AudioFrameDesc(constsize_t sampleRate,constsize_t channels,const std::string& sampleFormatName);
18+
AudioFrameDesc(const ProfileLoader::Profile& profile);
2019

2120
/**
2221
* @brief Set the attributes from the given profile.
@@ -33,50 +32,59 @@ struct AvExport AudioFrameDesc
3332
/**
3433
* @brief This class describes decoded audio data.
3534
*/
36-
classAvExport AudioFrame : publicFrame
35+
classAvExport AudioFrame : publicIFrame
3736
{
37+
private:
38+
AudioFrame(const AudioFrame& otherFrame);
39+
AudioFrame&operator=(const AudioFrame& otherFrame);
40+
3841
public:
42+
AudioFrame(const AudioFrameDesc& desc,constbool forceDataAllocation =true);
43+
~AudioFrame();
44+
3945
/**
40-
* @note Allocated data will be initialized to silence.
46+
* @brief Allocated data will be initialized to silence.
47+
* @warning The allocated data should be freed by the caller.
48+
* @see freeData
4149
*/
42-
AudioFrame(const AudioFrameDesc& ref);
43-
AudioFrame(const Frame& otherFrame);
50+
voidallocateData();
51+
voidfreeData();
52+
size_tgetDataSize()const;
4453

4554
size_tgetSampleRate()const {returnav_frame_get_sample_rate(_frame); }
4655
size_tgetNbChannels()const {returnav_frame_get_channels(_frame); }
4756
size_tgetChannelLayout()const {returnav_frame_get_channel_layout(_frame); }
4857
std::stringgetChannelLayoutDesc()const;///< Get a description of a channel layout (example: '5.1').
4958
AVSampleFormatgetSampleFormat()const {returnstatic_cast<AVSampleFormat>(_frame->format); }
59+
size_tgetBytesPerSample()const;///< 0 if unknown sample format
5060
size_tgetNbSamplesPerChannel()const {return _frame->nb_samples; }
51-
AudioFrameDescdesc()const {returnAudioFrameDesc(getSampleRate(),getNbChannels(),getSampleFormat()); }
52-
53-
size_tgetSize()const;///< in bytes
54-
55-
voidsetNbSamplesPerChannel(constsize_t nbSamples) { _frame->nb_samples = nbSamples; }
5661

5762
/**
58-
* @brief Assign the given value to all the data of the audio frame.
63+
* @brief This methods dynamically updates the size that the data buffer would occupy if allocated.
64+
* @warning If the data buffer is already allocated, this could lead to memory leaks or seg fault.
5965
*/
60-
voidassign(constunsignedchar value);
66+
voidsetNbSamplesPerChannel(constsize_t nbSamples) { _frame->nb_samples = nbSamples; }
6167

62-
/**
63-
* @brief Assign the given ptr of data to the data of the audio frame.
64-
* @warning the given ptr should have the size of the audio frame..
65-
* @see getSize
66-
*/
67-
voidassign(constunsignedchar* ptrValue);
68+
voidassignBuffer(constunsignedchar* ptrValue);
6869

6970
private:
7071
/**
71-
* @brief Allocate the audio buffer of the frame.
72+
* @brief The number of samples of a frame cannot be known before calling avcodec_decode_audio4,
73+
* and can be variable in a same stream. Because we need to allocate some frames without knowing this parameter,
74+
* we access here a default number of samples.
75+
* @note This value depends on the sample rate (example: 1920 samples at 48kHz).
76+
* @return the number of samples of our default AudioFrame.
77+
* @see setNbSamplesPerChannel
7278
*/
73-
voidallocateAVSample(const AudioFrameDesc& ref);
79+
size_tgetDefaultNbSamples()const;
7480

81+
private:
7582
/**
76-
* @note To allocate new audio buffer if needed.
77-
* @see allocateAVSample
83+
* @brief Description of the frame to allocate.
84+
* @warning This description could be different from the current frame (a decoder could have reseted it).
85+
* We need to keep this description to allocate again the frame even if it was reseted.
7886
*/
79-
friendclassAudioGenerator;
87+
const AudioFrameDesc _desc;
8088
};
8189
}
8290

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp