@@ -36,6 +36,11 @@ AudioFrameBuffer::~AudioFrameBuffer()
36
36
popFrame ();
37
37
}
38
38
39
+ size_t AudioFrameBuffer::getBytesPerSample ()
40
+ {
41
+ return av_get_bytes_per_sample (_audioFrameDesc._sampleFormat );
42
+ }
43
+
39
44
void AudioFrameBuffer::addFrame (IFrame* frame)
40
45
{
41
46
LOG_DEBUG (" Add a new" << frame->getDataSize () <<" bytes frame to frame buffer. New buffer size:" << _frameQueue.size () +1 );
@@ -113,6 +118,12 @@ IFrame* AudioFrameBuffer::getFrame(const size_t size)
113
118
return newAudioFrame;
114
119
}
115
120
121
+ IFrame*AudioFrameBuffer::getFrameSampleNb (const size_t sampleNb)
122
+ {
123
+ const size_t expectedSize = sampleNb *getBytesPerSample ();
124
+ return getFrame (expectedSize);
125
+ }
126
+
116
127
117
128
118
129
/* *****************
@@ -149,19 +160,29 @@ size_t FilterGraph::getAvailableFrameSize(const std::vector<IFrame*>& inputs, co
149
160
return frameSize;
150
161
}
151
162
152
- size_t FilterGraph::getMinInputFrameSize (const std::vector<IFrame*>& inputs)
163
+ size_t FilterGraph::getAvailableFrameSamplesNb (const std::vector<IFrame*>& inputs,const size_t & index)
164
+ {
165
+ if (_inputAudioFrameBuffers.empty ())
166
+ throw std::runtime_error (" Cannot compute filter graph input samples number for non-audio frames." );
167
+
168
+ const size_t bytesPerSample = _inputAudioFrameBuffers.at (index).getBytesPerSample ();
169
+ const size_t availableSamplesNb =getAvailableFrameSize (inputs, index) / bytesPerSample;
170
+ return availableSamplesNb;
171
+ }
172
+
173
+ size_t FilterGraph::getMinInputFrameSamplesNb (const std::vector<IFrame*>& inputs)
153
174
{
154
175
if (!inputs.size ())
155
176
return 0 ;
156
177
157
- size_t minFrameSize =getAvailableFrameSize (inputs,0 );
178
+ size_t minFrameSamplesNb =getAvailableFrameSamplesNb (inputs,0 );
158
179
for (size_t index =1 ; index < inputs.size (); ++index)
159
180
{
160
- const size_t availableFrameSize =getAvailableFrameSize (inputs, index);
161
- if (minFrameSize >availableFrameSize )
162
- minFrameSize =availableFrameSize ;
181
+ const size_t availableFrameSampleNb =getAvailableFrameSamplesNb (inputs, index);
182
+ if (minFrameSamplesNb >availableFrameSampleNb )
183
+ minFrameSamplesNb =availableFrameSampleNb ;
163
184
}
164
- return minFrameSize ;
185
+ return minFrameSamplesNb ;
165
186
}
166
187
167
188
bool FilterGraph::hasBufferedFrames ()
@@ -194,7 +215,16 @@ bool FilterGraph::areInputFrameSizesEqual(const std::vector<IFrame*>& inputs)
194
215
for (size_t index =1 ; index < inputs.size (); ++index)
195
216
{
196
217
if (frameSize != inputs.at (index)->getDataSize ())
197
- return false ;
218
+ {
219
+ if (_inputAudioFrameBuffers.empty ())
220
+ return false ;
221
+ else
222
+ {
223
+ const size_t refSampleNb = frameSize / _inputAudioFrameBuffers.at (0 ).getBytesPerSample ();
224
+ const size_t sampleNb = inputs.at (index)->getDataSize () / _inputAudioFrameBuffers.at (index).getBytesPerSample ();
225
+ return (refSampleNb == sampleNb);
226
+ }
227
+ }
198
228
}
199
229
return true ;
200
230
}
@@ -220,7 +250,7 @@ void FilterGraph::process(const std::vector<IFrame*>& inputs, IFrame& output)
220
250
221
251
// Check whether we can bypass the input audio buffers
222
252
const bool bypassBuffers = _inputAudioFrameBuffers.empty () || (areInputFrameSizesEqual (inputs) &&areFrameBuffersEmpty ());
223
- size_t minInputFrameSize =0 ;
253
+ size_t minInputFrameSamplesNb =0 ;
224
254
225
255
if (!bypassBuffers)
226
256
{
@@ -236,15 +266,15 @@ void FilterGraph::process(const std::vector<IFrame*>& inputs, IFrame& output)
236
266
}
237
267
238
268
// Get the minimum input frames size
239
- minInputFrameSize =getMinInputFrameSize (inputs);
269
+ minInputFrameSamplesNb =getMinInputFrameSamplesNb (inputs);
240
270
}
241
271
242
272
243
273
// Setup input frames into the filter graph
244
274
for (size_t index =0 ; index < inputs.size (); ++index)
245
275
{
246
276
// Retrieve frame from buffer or directly from input
247
- IFrame* inputFrame = (bypassBuffers)? inputs.at (index) : _inputAudioFrameBuffers.at (index).getFrame (minInputFrameSize );
277
+ IFrame* inputFrame = (bypassBuffers)? inputs.at (index) : _inputAudioFrameBuffers.at (index).getFrameSampleNb (minInputFrameSamplesNb );
248
278
const int ret =av_buffersrc_add_frame_flags (_filters.at (index)->getAVFilterContext (), &inputFrame->getAVFrame (), AV_BUFFERSRC_FLAG_PUSH);
249
279
250
280
if (ret <0 )