#include <libavfilter/avfilter.h>
#include <libavfilter/buffersink.h>
#include <libavfilter/buffersrc.h>
AVFilterGraph* ffw_filtergraph_new() {
return avfilter_graph_alloc();
}
int ffw_filtersource_new(
AVFilterContext** filter_ctx,
AVFilterGraph* filter_graph,
const char* src_args)
{
const AVFilter* filter;
if (!(filter = avfilter_get_by_name("buffer"))) {
return AVERROR_FILTER_NOT_FOUND;
}
return avfilter_graph_create_filter(filter_ctx, filter, "in", src_args, NULL, filter_graph);
}
int ffw_filtersink_new(AVFilterContext** filter_ctx, AVFilterGraph* filter_graph) {
const AVFilter* filter;
if (!(filter = avfilter_get_by_name("buffersink"))) {
return AVERROR_FILTER_NOT_FOUND;
}
return avfilter_graph_create_filter(filter_ctx, filter, "out", NULL, NULL, filter_graph);
}
int ffw_filtergraph_init(
AVFilterGraph* filter_graph,
AVFilterContext* buffersrc_ctx,
AVFilterContext* buffersink_ctx,
const char* filters_descr)
{
AVFilterInOut* outputs;
AVFilterInOut* inputs;
int ret;
outputs = NULL;
inputs = NULL;
if (!(outputs = avfilter_inout_alloc())) {
ret = AVERROR(ENOMEM); goto end;
}
if (!(inputs = avfilter_inout_alloc())) {
ret = AVERROR(ENOMEM); goto end;
}
outputs->name = av_strdup("in");
outputs->filter_ctx = buffersrc_ctx;
outputs->pad_idx = 0;
outputs->next = NULL;
inputs->name = av_strdup("out");
inputs->filter_ctx = buffersink_ctx;
inputs->pad_idx = 0;
inputs->next = NULL;
if ((ret = avfilter_graph_parse_ptr(filter_graph, filters_descr, &inputs, &outputs, NULL)) < 0) {
goto end;
}
ret = avfilter_graph_config(filter_graph, NULL);
end:
avfilter_inout_free(&inputs);
avfilter_inout_free(&outputs);
return ret;
}
int ffw_filtergraph_push_frame(AVFilterContext* context, AVFrame* frame) {
int ret = av_buffersrc_add_frame(context, frame);
if (ret == 0 || ret == AVERROR_EOF) {
return 1;
} else if (ret == AVERROR(EAGAIN)) {
return 0;
}
return ret;
}
int ffw_filtergraph_take_frame(AVFilterContext* context, AVFrame** out) {
AVFrame* frame;
int ret;
if (!(frame = av_frame_alloc())) {
return AVERROR(ENOMEM);
}
ret = av_buffersink_get_frame(context, frame);
if (ret == AVERROR_EOF || ret == AVERROR(EAGAIN)) {
ret = 0;
} else if (ret >= 0) {
ret = 1;
}
if (ret > 0) {
*out = frame;
} else {
av_frame_free(&frame);
}
return ret;
}
void ffw_filtergraph_free(AVFilterGraph* filter_graph) {
avfilter_graph_free(&filter_graph);
}