@@ -12,18 +12,19 @@ extern "C" {
12
12
namespace avtranscoder
13
13
{
14
14
15
- AudioFrameDesc::AudioFrameDesc (const size_t sampleRate, const size_t nbChannels, const AVSampleFormat sampleFormat )
15
+ AudioFrameDesc::AudioFrameDesc (const size_t sampleRate, const size_t nbChannels, const std::string& sampleFormatName )
16
16
: _sampleRate(sampleRate)
17
17
, _nbChannels(nbChannels)
18
- , _sampleFormat(sampleFormat )
18
+ , _sampleFormat(getAVSampleFormat(sampleFormatName) )
19
19
{
20
20
}
21
21
22
- AudioFrameDesc::AudioFrameDesc (const size_t sampleRate, const size_t nbChannels, const std::string& sampleFormatName )
23
- : _sampleRate(sampleRate )
24
- , _nbChannels(nbChannels )
25
- , _sampleFormat(getAVSampleFormat(sampleFormatName) )
22
+ AudioFrameDesc::AudioFrameDesc (const ProfileLoader::Profile& profile )
23
+ : _sampleRate(0 )
24
+ , _nbChannels(0 )
25
+ , _sampleFormat(AV_SAMPLE_FMT_NONE )
26
26
{
27
+ setParameters (profile);
27
28
}
28
29
29
30
void AudioFrameDesc::setParameters (const ProfileLoader::Profile& profile)
@@ -39,15 +40,19 @@ void AudioFrameDesc::setParameters(const ProfileLoader::Profile& profile)
39
40
_sampleFormat = getAVSampleFormat (profile.find (constants::avProfileSampleFormat)->second .c_str ());
40
41
}
41
42
42
- AudioFrame::AudioFrame (const AudioFrameDesc& ref)
43
- : Frame()
43
+ AudioFrame::AudioFrame (const AudioFrameDesc& desc, const bool forceDataAllocation)
44
+ : IFrame()
45
+ , _desc(desc)
44
46
{
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 ();
47
53
48
- AudioFrame::AudioFrame (const Frame& otherFrame)
49
- : Frame(otherFrame)
50
- {
54
+ if (forceDataAllocation)
55
+ allocateData ();
51
56
}
52
57
53
58
std::string AudioFrame::getChannelLayoutDesc () const
@@ -57,75 +62,95 @@ std::string AudioFrame::getChannelLayoutDesc() const
57
62
return std::string (buf);
58
63
}
59
64
60
- size_t AudioFrame::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_t AudioFrame::getBytesPerSample () const
74
+ {
75
+ return av_get_bytes_per_sample (getSampleFormat ());
76
+ }
77
+
78
+ size_t AudioFrame::getDataSize () const
61
79
{
62
80
if (getSampleFormat () == AV_SAMPLE_FMT_NONE)
63
81
{
64
82
LOG_WARN (" Incorrect sample format when get size of audio frame: return a size of 0." )
65
83
return 0 ;
66
84
}
67
85
68
- const size_t size = getNbSamplesPerChannel () * getNbChannels () * av_get_bytes_per_sample ( getSampleFormat () );
86
+ const size_t size = getNbSamplesPerChannel () * getNbChannels () * getBytesPerSample ( );
69
87
if (size == 0 )
70
88
{
71
89
std::stringstream msg;
72
90
msg << " Unable to determine audio buffer size:" << std::endl;
73
91
msg << " nb sample per channel = " << getNbSamplesPerChannel () << std::endl;
74
92
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;
76
94
throw std::runtime_error (msg.str ());
77
95
}
78
96
return size;
79
97
}
80
98
81
- void AudioFrame::allocateAVSample ( const AudioFrameDesc& desc )
99
+ void AudioFrame::allocateData ( )
82
100
{
101
+ if (_dataAllocated)
102
+ LOG_WARN (" The AudioFrame seems to already have allocated data. This could lead to memory leaks." )
103
+
83
104
// 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 ();
89
111
90
112
// Allocate data
91
113
const int align = 0 ;
92
114
const int 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);
94
116
if (ret < 0 )
95
117
{
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
- throw std::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
+ throw std::bad_alloc ();
104
128
}
129
+ _dataAllocated = true ;
105
130
}
106
131
107
- void AudioFrame::assign ( const unsigned char value )
132
+ void AudioFrame::freeData ( )
108
133
{
109
- // Create the audio buffer
110
- // The buffer will be freed in destructor of based class
111
- const int audioSize = getSize ();
112
- unsigned char * audioBuffer = new unsigned char [audioSize];
113
- memset (audioBuffer, value, audioSize);
114
-
115
- // Fill the picture
116
- assign (audioBuffer);
134
+ av_freep (&_frame->data [0 ]);
135
+ _dataAllocated = false ;
117
136
}
118
137
119
- void AudioFrame::assign (const unsigned char * ptrValue)
138
+ void AudioFrame::assignBuffer (const unsigned char * ptrValue)
120
139
{
121
140
const int align = 0 ;
122
141
const int ret = av_samples_fill_arrays (_frame->data , _frame->linesize , ptrValue, getNbChannels (),
123
142
getNbSamplesPerChannel (), getSampleFormat (), align);
124
143
if (ret < 0 )
125
144
{
126
- std::stringstream os ;
127
- os << " Unable to assign an audio buffer: " << getDescriptionFromErrorCode (ret);
128
- throw std::runtime_error (os .str ());
145
+ std::stringstream msg ;
146
+ msg << " Unable to assign an audio buffer: " << getDescriptionFromErrorCode (ret);
147
+ throw std::runtime_error (msg .str ());
129
148
}
130
149
}
150
+
151
+ size_t AudioFrame::getDefaultNbSamples () const
152
+ {
153
+ return _desc._sampleRate / 25 .;
154
+ }
155
+
131
156
}
0 commit comments