8 #include <libavfilter/avfilter.h>
9 #include <libavfilter/buffersrc.h>
10 #include <libavfilter/buffersink.h>
20 : _graph(avfilter_graph_alloc())
26 throw std::runtime_error(
"Unable to create filter graph: out of memory.");
31 for(std::vector<Filter*>::iterator it =
_filters.begin(); it <
_filters.end(); ++it)
35 avfilter_graph_free(&
_graph);
51 int ret = av_buffersrc_write_frame(
_filters.at(0)->getAVFilterContext(), &frame.
getAVFrame());
54 throw std::runtime_error(
"Error when adding a frame to the source buffer used to start to process filters: " +
62 if(ret == AVERROR_EOF || ret == AVERROR(EAGAIN))
72 const std::string& instanceName)
74 LOG_INFO(
"Add filter " << filterName <<
" to the graph.")
75 Filter* filter =
new Filter(filterName, filterOptions, instanceName);
84 for(
size_t i = 1; i <
_filters.size(); ++i)
91 for(
size_t index = 0; index <
_filters.size() - 1; ++index)
95 avfilter_link(
_filters.at(index)->getAVFilterContext(), 0,
_filters.at(index + 1)->getAVFilterContext(), 0);
98 throw std::runtime_error(
"Error when connecting filters.");
103 LOG_INFO(
"Configuring filter graph.")
104 const int err = avfilter_graph_config(
_graph, NULL);
115 AVFilterContext* context = NULL;
121 std::string msg(
"Cannot add filter ");
123 msg +=
" (instance=";
125 msg +=
") to the graph: ";
127 throw std::runtime_error(msg);
133 std::string filterName;
134 std::stringstream filterOptions;
138 filterName =
"abuffer";
142 filterOptions <<
"sample_rate=" << audioFrame.
getSampleRate() <<
":";
144 filterOptions <<
"channel_layout=0x" << std::hex << audioFrame.
getChannelLayout();
149 filterName =
"buffer";
151 filterOptions <<
"video_size=" << videoFrame.
getWidth() <<
"x" << videoFrame.
getHeight() <<
":";
160 throw std::runtime_error(
"Cannot create input buffer of filter graph: the given frame is invalid.");
163 Filter* in =
new Filter(filterName, filterOptions.str(),
"in");
164 LOG_INFO(
"Add filter '" << filterName <<
"' at the beginning of the graph.")
171 std::string filterName;
174 filterName =
"abuffersink";
176 filterName =
"buffersink";
178 throw std::runtime_error(
"Cannot create output buffer of filter graph: the given frame is invalid.");
size_t getChannelLayout() const
Describe a filter and its options.
bool _isInit
Is the FilterGraph initialized.
void pushOutBuffer(const Frame &frame)
bool isVideoFrame() const
This class describes decoded video data.
FilterGraph(const FilterGraph &otherFilterGraph)
void setAVFilterContext(AVFilterContext *newContext)
AVSampleFormat getSampleFormat() const
std::string getInstanceName() const
std::string getDescriptionFromErrorCode(const int code)
Get the string description corresponding to the error code provided by ffmpeg/libav.
bool isAudioFrame() const
std::string getPixelFormatName(const AVPixelFormat pixelFormat)
AVPixelFormat getPixelFormat() const
std::string getOptions() const
void init(const Frame &frame)
Initialize the graph of filters to process.
Filter & addFilter(const std::string &filterName, const std::string &filterOptions="", const std::string &instanceName="")
Add a filter.
void pushInBuffer(const Frame &frame)
Push the input and output buffer at the beginning and the end of the graph.
std::vector< Filter * > _filters
List of filters to process.
size_t getSampleRate() const
This class describes decoded audio data.
This class describes decoded (raw) audio or video data.
std::string getName() const
void process(Frame &frame)
Pull filtered data from the filter graph, and put result to the given frame.
AVCodecContext & getAVCodecContext()
void pushFilter(Filter &filter)
Push the given Filter to the graph.
const ICodec & _codec
Codec of the stream on which the filters will be applied.
std::string getSampleFormatName(const AVSampleFormat sampleFormat)
AVFilterGraph * _graph
The graph which holds the filters.