ffmpeg命令分析-filter_complex

本文深入分析ffmpeg4.4中-filter_complex命令的使用,讲解如何将图片logo放置到视频左上角。重点探讨了复杂滤镜的概念,解释了init_complex_filters和init_simple_filtergraph的区别,并通过源码解析了filter初始化的过程,包括avfilter_graph_parse2的两次调用及其作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文 以 ffmpeg4.4 源码为准。

a.mp4下载链接:百度网盘,提取码:nl0s 。logo.jpg 地址:点击查看


命令如下:

ffmpeg.exe -i a.mp4 -i logo.jpg -filter_complex "[1:v]scale=176:144[logo];[0:v][logo]overlay=x=0:y=0" output.mp4 -y 

上面命令实现的功能就是 把 “弦外之音” 的 logo 放在视频左上角。

ffmpeg 命令行有两种 filter 用法:

1,-vf,普通滤镜, 在 《ffmpeg命令分析-vf》有过讲解。

什么是简单滤镜?只有一个输入流是简单滤镜

2,-filter_complex-lavfi 这两个命令参数是一样的,这是复杂滤镜,lavfi 是估计是 libavfilter 的缩写。

什么是复杂滤镜?有多个输入流的就是复杂滤镜,本文命令有2个输入流,属于复杂滤镜

复杂滤镜 就是本文的分析重点。

首先 filter_complex 在 ffmpeg_opt.c 的定义如下:

{ "filter_complex", HAS_ARG | OPT_EXPERT,                        { .func_arg = opt_filter_complex },
        "create a complex filtergraph", "graph_description" } 

从定义可以看出 filter_complex 会调用 opt_filter_complex 函数。

opt_filter_complex 函数的定义如下:

static int opt_filter_complex(void *optctx, const char *opt, const char *arg)
{
    GROW_ARRAY(filtergraphs, nb_filtergraphs);
    if (!(filtergraphs[nb_filtergraphs - 1] = av_mallocz(sizeof(*filtergraphs[0]))))
        return AVERROR(ENOMEM);
    filtergraphs[nb_filtergraphs - 1]->index      = nb_filtergraphs - 1;
    filtergraphs[nb_filtergraphs - 1]->graph_desc = av_strdup(arg);
    if (!filtergraphs[nb_filtergraphs - 1]->graph_desc)
        return AVERROR(ENOMEM);
​
    input_stream_potentially_available = 1;
​
    return 0;
} 

从上面的代码可以看出, opt_filter_complex 做的事情非常简单,就是 malloc 一个 struct FilterGraph,然后放进行 全局变量 filtergraphs 里面。

-filter_complex 后面的参数字符串 "[1:v]scale=176:144[logo];[0:v][logo]overlay=x=0:y=0" 就被放进行 graph_desc 进行保存。

ffmpeg 会通过 graph_desc 这个参数判断这个 FilterGraph 是不是一个复杂 FilterGraph ,通过 filtergraph_is_simple() 函数实现。


在之前文章 《ffmpeg源码分析-open_output_file》里,我们知道 init_simple_filtergraph函数 是在 open_output_file 里面执行的。

init_simple_filtergraph 是初始化 简单filter。init_complex_filters 是初始化 复杂filter,他们之间的调用流程如下:

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值