ffmpeg api 滤镜
时间: 2023-12-10 10:04:07 浏览: 46
滤镜是FFmpeg中的一个重要概念,它可以对音视频进行各种处理,例如裁剪、旋转、缩放、调整亮度、对比度等等。FFmpeg提供了丰富的滤镜库,可以通过API在代码中使用滤镜。下面是一个简单的使用FFmpeg API添加滤镜的例子:
```c
#include <libavfilter/avfilter.h>
#include <libavfilter/buffersink.h>
#include <libavfilter/buffersrc.h>
AVFilterContext *buffersink_ctx;
AVFilterContext *buffersrc_ctx;
AVFilterGraph *filter_graph;
int video_stream_index = -1;
// 初始化滤镜
int init_filters(const char *filters_descr) {
char args[512];
int ret = 0;
AVFilter *buffersrc = avfilter_get_by_name("buffer");
AVFilter *buffersink = avfilter_get_by_name("buffersink");
AVFilterInOut *outputs = avfilter_inout_alloc();
AVFilterInOut *inputs = avfilter_inout_alloc();
enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE };
filter_graph = avfilter_graph_alloc();
if (!outputs || !inputs || !filter_graph) {
ret = AVERROR(ENOMEM);
goto end;
}
// 设置输入参数
snprintf(args, sizeof(args),
"video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
buffersrc_ctx->inputs[0]->width, buffersrc_ctx->inputs[0]->height, buffersrc_ctx->inputs[0]->format,
buffersrc_ctx->inputs[0]->time_base.num, buffersrc_ctx->inputs[0]->time_base.den,
buffersrc_ctx->inputs[0]->sample_aspect_ratio.num, buffersrc_ctx->inputs[0]->sample_aspect_ratio.den);
// 添加输入滤镜
ret = avfilter_graph_create_filter(&buffersrc_ctx, buffersrc, "in", args, NULL, filter_graph);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot create buffer source\n");
goto end;
}
// 添加输出滤镜
ret = avfilter_graph_create_filter(&buffersink_ctx, buffersink, "out", NULL, NULL, filter_graph);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot create buffer sink\n");
goto end;
}
// 设置输出参数
ret = av_opt_set_int_list(buffersink_ctx, "pix_fmts", pix_fmts, AV_PIX_FMT_NONE, AV_OPT_SEARCH_CHILDREN);
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Cannot set output pixel format\n");
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;
if ((ret = avfilter_graph_config(filter_graph, NULL)) < 0)
goto end;
end:
avfilter_inout_free(&inputs);
avfilter_inout_free(&outputs);
return ret;
}
// 处理滤镜
int filter_encode_write_frame(AVFrame *frame, AVCodecContext *enc_ctx, AVFormatContext *fmt_ctx) {
int ret;
AVFrame *filt_frame = av_frame_alloc();
if (!filt_frame) {
ret = AVERROR(ENOMEM);
goto end;
}
// 添加滤镜
if (av_buffersrc_add_frame_flags(buffersrc_ctx, frame, AV_BUFFERSRC_FLAG_KEEP_REF) < 0) {
av_log(NULL, AV_LOG_ERROR, "Error while feeding the filtergraph\n");
goto end;
}
// 获取输出帧
while (1) {
ret = av_buffersink_get_frame(buffersink_ctx, filt_frame);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
break;
if (ret < 0)
goto end;
// 编码并写入文件
filt_frame->pict_type = AV_PICTURE_TYPE_NONE;
ret = encode_write_frame(filt_frame, enc_ctx, fmt_ctx);
av_frame_unref(filt_frame);
if (ret < 0)
goto end;
}
end:
av_frame_free(&filt_frame);
return ret;
}
```