@@ -38,6 +38,8 @@ FrameBuffer::~FrameBuffer()
38
38
39
39
void FrameBuffer::addFrame (IFrame* frame)
40
40
{
41
+ LOG_DEBUG (" Add a new frame to frame buffer. New buffer size: " << _frameQueue.size () + 1 );
42
+ // Copy the input frame to store it into the queue
41
43
AudioFrame* newAudioFrame = new AudioFrame (_audioFrameDesc, false );
42
44
const size_t expectedNbSamples = frame->getDataSize () / (newAudioFrame->getNbChannels () * newAudioFrame->getBytesPerSample ());
43
45
newAudioFrame->setNbSamplesPerChannel (expectedNbSamples);
@@ -51,16 +53,19 @@ void FrameBuffer::addFrame(IFrame* frame)
51
53
void FrameBuffer::popFrame ()
52
54
{
53
55
_frameQueue.pop ();
56
+ LOG_DEBUG (" Pop frame from buffer. Remaining frames in buffer: " << _frameQueue.size ());
54
57
}
55
58
56
59
IFrame* FrameBuffer::getFrame (const size_t size)
57
60
{
61
+ LOG_DEBUG (" Get a " << size << " bytes frame from a " << _totalDataSize << " bytes frame buffer" );
58
62
IFrame* next = _frameQueue.front ();
59
63
const size_t nextFrameSize = next->getDataSize ();
60
64
61
65
// If no expected size, or if the expected size equals the front frame of the queue (with no offset)
62
66
if (size == 0 || (size == nextFrameSize && _positionInFrontFrame == 0 ))
63
67
{
68
+ // Directly return the front frame of the queue
64
69
_totalDataSize -= nextFrameSize;
65
70
popFrame ();
66
71
return next;
@@ -77,30 +82,34 @@ IFrame* FrameBuffer::getFrame(const size_t size)
77
82
unsigned char * outputData = new unsigned char [size];
78
83
while (extractedDataSize != size && _frameQueue.size () != 0 )
79
84
{
85
+ // Get the front frame from queue
80
86
next = _frameQueue.front ();
81
- size_t dataToGet = size - extractedDataSize;
82
- size_t remainingDataInNextFrame = next->getDataSize () - _positionInFrontFrame;
87
+ size_t remainingDataInFrontFrame = next->getDataSize () - _positionInFrontFrame;
83
88
84
- if (dataToGet > remainingDataInNextFrame)
85
- dataToGet = remainingDataInNextFrame;
89
+ // Compute the data size to get from the frame
90
+ size_t dataToGet = size - extractedDataSize;
91
+ if (dataToGet > remainingDataInFrontFrame)
92
+ dataToGet = remainingDataInFrontFrame;
86
93
94
+ // Copy the data from the frame to temporal buffer
87
95
for (size_t i = 0 ; i < dataToGet; i++)
88
96
outputData[extractedDataSize++] = next->getData ()[0 ][_positionInFrontFrame + i];
89
97
90
- if (dataToGet < remainingDataInNextFrame )
98
+ if (dataToGet < remainingDataInFrontFrame )
91
99
{
100
+ // Set new position into front frame
92
101
_positionInFrontFrame += dataToGet;
93
102
}
94
103
else
95
104
{
105
+ // The whole front frame has been read, so pop it from queue
96
106
popFrame ();
97
107
_positionInFrontFrame = 0 ;
98
108
}
99
109
}
100
110
101
111
_totalDataSize -= extractedDataSize;
102
112
newAudioFrame->assignBuffer (outputData);
103
-
104
113
return newAudioFrame;
105
114
}
106
115
@@ -155,6 +164,27 @@ size_t FilterGraph::getMinInputFrameSize(const std::vector<IFrame*>& inputs)
155
164
return minFrameSize;
156
165
}
157
166
167
+ bool FilterGraph::hasBufferedFrames ()
168
+ {
169
+ if (!_inputFramesBuffer.size ())
170
+ return false ;
171
+
172
+ for (std::vector<FrameBuffer>::iterator it = _inputFramesBuffer.begin (); it != _inputFramesBuffer.end (); ++it)
173
+ {
174
+ if (it->isEmpty ())
175
+ return false ;
176
+ }
177
+ return true ;
178
+ }
179
+
180
+ bool FilterGraph::hasBufferedFrames (const size_t index)
181
+ {
182
+ if (index >= _inputFramesBuffer.size ())
183
+ return false ;
184
+
185
+ return !_inputFramesBuffer.at (index).isEmpty ();
186
+ }
187
+
158
188
bool FilterGraph::areInputFrameSizeEqual (const std::vector<IFrame*>& inputs)
159
189
{
160
190
if (!inputs.size () || inputs.size () == 1 )
@@ -196,7 +226,14 @@ void FilterGraph::process(const std::vector<IFrame*>& inputs, IFrame& output)
196
226
{
197
227
// Fill the frame buffer with inputs
198
228
for (size_t index = 0 ; index < inputs.size (); ++index)
229
+ {
230
+ if (!inputs.at (index)->getDataSize ())
231
+ {
232
+ LOG_DEBUG (" Empty frame from filter graph input " << index << " . Remaining frames in buffer: " << _inputFramesBuffer.at (index).getBufferSize ());
233
+ continue ;
234
+ }
199
235
_inputFramesBuffer.at (index).addFrame (inputs.at (index));
236
+ }
200
237
201
238
// Get the minimum input frames size
202
239
minInputFrameSize = getMinInputFrameSize (inputs);
@@ -206,12 +243,8 @@ void FilterGraph::process(const std::vector<IFrame*>& inputs, IFrame& output)
206
243
// Setup input frames into the filter graph
207
244
for (size_t index = 0 ; index < inputs.size (); ++index)
208
245
{
209
- IFrame* inputFrame = NULL ;
210
- if (bypassBuffers)
211
- inputFrame = inputs.at (index);
212
- else
213
- inputFrame = _inputFramesBuffer.at (index).getFrame (minInputFrameSize);
214
-
246
+ // Retrieve frame from buffer or directly from input
247
+ IFrame* inputFrame = (bypassBuffers)? inputs.at (index) : _inputFramesBuffer.at (index).getFrame (minInputFrameSize);
215
248
const int ret = av_buffersrc_add_frame_flags (_filters.at (index)->getAVFilterContext (), &inputFrame->getAVFrame (), AV_BUFFERSRC_FLAG_PUSH);
216
249
217
250
if (ret < 0 )
0 commit comments