Skip to content

Commit cb8ae5d

Browse files
author
Valentin NOEL
committed
FilterGraph: use FrameBuffers for each filter graph input
Returning frames with the same size as inputs of the graph, avoiding to overflow the internal filter buffers.
1 parent 80017d6 commit cb8ae5d

File tree

2 files changed

+39
-2
lines changed

2 files changed

+39
-2
lines changed

src/AvTranscoder/filter/FilterGraph.cpp

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,31 +124,59 @@ FilterGraph::FilterGraph(const ICodec& codec)
124124

125125
FilterGraph::~FilterGraph()
126126
{
127+
_inputFramesBuffer.clear();
127128
for(std::vector<Filter*>::iterator it = _filters.begin(); it < _filters.end(); ++it)
128129
{
129130
delete(*it);
130131
}
131132
avfilter_graph_free(&_graph);
132133
}
133134

135+
size_t FilterGraph::getMinInputFrameSize(const std::vector<IFrame*>& inputs)
136+
{
137+
if(!inputs.size())
138+
return 0;
139+
140+
int minFrameSize = inputs.at(0)->getDataSize();
141+
for(size_t index = 1; index < inputs.size(); ++index)
142+
{
143+
if(minFrameSize > inputs.at(index)->getDataSize())
144+
minFrameSize = inputs.at(index)->getDataSize();
145+
}
146+
return minFrameSize;
147+
}
148+
134149
void FilterGraph::process(const std::vector<IFrame*>& inputs, IFrame& output)
135150
{
136151
// init filter graph
137152
if(!_isInit)
138153
init(inputs, output);
139154

140155
// setup input frames
156+
157+
// Fill the frame buffer with inputs
141158
for(size_t index = 0; index < inputs.size(); ++index)
142159
{
143-
const int ret = av_buffersrc_add_frame_flags(_filters.at(index)->getAVFilterContext(), &inputs.at(index)->getAVFrame(), AV_BUFFERSRC_FLAG_PUSH);
160+
_inputFramesBuffer.at(index).addFrame(inputs.at(index));
161+
}
162+
163+
// Get the minimum input frames size
164+
const size_t minInputFrameSize = getMinInputFrameSize(inputs);
165+
166+
// Setup input frames into the filter graph
167+
for(size_t index = 0; index < inputs.size(); ++index)
168+
{
169+
IFrame* inputBufferedFrame = _inputFramesBuffer.at(index).getFrame(minInputFrameSize);
170+
const int ret = av_buffersrc_add_frame_flags(_filters.at(index)->getAVFilterContext(), &inputBufferedFrame->getAVFrame(), AV_BUFFERSRC_FLAG_PUSH);
171+
144172
if(ret < 0)
145173
{
146174
throw std::runtime_error("Error when adding a frame to the source buffer used to start to process filters: " +
147175
getDescriptionFromErrorCode(ret));
148176
}
149177
}
150178

151-
// pull filtered data from the filter graph
179+
// Pull filtered data from the filter graph
152180
for(;;)
153181
{
154182
const int ret = av_buffersink_get_frame(_filters.at(_filters.size() - 1)->getAVFilterContext(), &output.getAVFrame());
@@ -246,6 +274,11 @@ void FilterGraph::addInBuffer(const std::vector<IFrame*>& inputs)
246274
filterOptions << "sample_rate=" << audioFrame->getSampleRate() << ":";
247275
filterOptions << "sample_fmt=" << getSampleFormatName(audioFrame->getSampleFormat()) << ":";
248276
filterOptions << "channel_layout=0x" << std::hex << audioFrame->getChannelLayout();
277+
278+
const AudioFrameDesc audioFrameDesc(audioFrame->getSampleRate(),
279+
audioFrame->getNbChannels(),
280+
getSampleFormatName(audioFrame->getSampleFormat()));
281+
_inputFramesBuffer.push_back(FrameBuffer(audioFrameDesc));
249282
}
250283
// video frame
251284
else if((*it)->isVideoFrame())

src/AvTranscoder/filter/FilterGraph.hpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,11 +127,15 @@ class AvExport FilterGraph
127127
void addOutBuffer(const IFrame& output);
128128
//@}
129129

130+
size_t getMinInputFrameSize(const std::vector<IFrame*>& inputs);
131+
130132
private:
131133
AVFilterGraph* _graph; ///< The graph which holds the filters.
132134
std::vector<Filter*> _filters; ///< List of filters to process.
133135
const ICodec& _codec; ///< Codec of the stream on which the filters will be applied.
134136

137+
std::vector<FrameBuffer> _inputFramesBuffer;
138+
135139
/**
136140
* @brief Is the FilterGraph initialized.
137141
* @see init

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