【音视频】滤镜使用与处理

这个系列文章我们来介绍一位海外工程师如何探索安卓音视频基础技术,对于想要开始学习音视频技术的朋友,这些文章是份不错的入门资料,本篇介绍滤镜使用与处理。

——来自公众号“关键帧Keyframe”的分享

1、滤镜架构总览

AVFilterGraph
├─ AVFilterContext① → buffer (源)
├─ AVFilterContext② → scale/overlay/...
└─ AVFilterContext③ → buffersink (汇)
  • AVFilter:类型(如 scale
  • AVFilterContext:实例(含参数)
  • AVBufferRef:零拷贝帧传递

2、核心 API 速查

操作函数
创建图avfilter_graph_alloc()
实例化滤镜avfilter_graph_create_filter()
字符串解析avfilter_graph_parse_ptr()
验证连接avfilter_graph_config()
送帧av_buffersrc_add_frame_flags()
取帧av_buffersink_get_frame()
释放avfilter_graph_free()

3、三阶段工作流程

3.1、 阶段一:构建 FilterGraph

AVFilterGraph *graph = avfilter_graph_alloc();

/* 1. 源 buffer */
AVFilterContext *src_ctx;
snprintf(args, sizeof(args), "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d",
         width, height, pix_fmt, time_base.num, time_base.den);
avfilter_graph_create_filter(&src_ctx, avfilter_get_by_name("buffer"),
                             "in_buffer", args, NULL, graph);

/* 2. 汇 buffersink */
AVFilterContext *sink_ctx;
avfilter_graph_create_filter(&sink_ctx, avfilter_get_by_name("buffersink"),
                             "out_buffersink", NULL, NULL, graph);

/* 3. 解析中间滤镜链 */
constchar *graph_desc = "[in_buffer]scale=iw/2:-1[scaled];[scaled]overlay=10:10[out_buffersink]";
AVFilterInOut *inputs = avfilter_inout_alloc();
inputs->name       = av_strdup("out_buffersink");
inputs->filter_ctx = sink_ctx;
AVFilterInOut *outputs = avfilter_inout_alloc();
outputs->name       = av_strdup("in_buffer");
outputs->filter_ctx = src_ctx;

avfilter_graph_parse_ptr(graph, graph_desc, &inputs, &outputs, NULL);
avfilter_graph_config(graph, NULL);   // 验证连通性

3.2、 阶段二:数据泵送

/* 输入:解码帧 → filter */
av_buffersrc_add_frame_flags(src_ctx, decoded_frame, AV_BUFFERSRC_FLAG_KEEP_REF);

/* 输出:拉取已处理帧 */
AVFrame *filt_frame = av_frame_alloc();
int ret = av_buffersink_get_frame(sink_ctx, filt_frame);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
    // 需要更多输入或已结束
}

3.3、 阶段三:资源清理

av_frame_free(&filt_frame);
avfilter_graph_free(&graph);   // 递归释放所有节点

4、命令行滤镜速用

4.1、描述格式

[input_stream]filter=params[label];[label]next_filter[out]

4.2、常用滤镜示例

效果命令
文字水印-vf "drawtext=fontfile=/System/Fonts/Helvetica.ttc:text='Hello':fontcolor=yellow:fontsize=48:x=20:y=20"
图片水印-filter_complex "[1:v]scale=176:144[logo];[0:v][logo]overlay=x=0:y=0"
画中画-filter_complex "[1:v]scale=480x320[pip];[0:v][pip]overlay=W-w-10:H-h-10"
色度键-filter_complex "[0:v]chromakey=0x00FF00:0.1:0.2[ck];[ck]overlay=10:10"
倍速视频:-vf setpts=PTS/2 音频:-af atempo=2.0
测试图-f lavfi -i testsrc=duration=5:size=qcif:rate=25

5、高级组合案例

5.1、四宫格拼接

ffmpeg -i p1.mp4 -i p2.mp4 -i p3.mp4 -i p4.mp4 -filter_complex "
nullsrc=size=1280x720[bg];
[0:v]scale=640x360,setpts=PTS-STARTPTS[p1];
[1:v]scale=640x360,setpts=PTS-STARTPTS[p2];
[2:v]scale=640x360,setpts=PTS-PTS_STARTPTS[p3];
[3:v]scale=640x360,setpts=PTS-STARTPTS[p4];
[bg][p1]overlay=shortest=1[x];
[x][p2]overlay=shortest=1:x=640[y];
[y][p3]overlay=shortest=1:y=360[z];
[z][p4]overlay=shortest=1:x=640:y=360
" -c:v libx264 -preset fast out.mp4

5.2、音频频谱可视化

ffmpeg -i music.mp3 -filter_complex \
"[0:a]showspectrum=s=1280x480:mode=combined:slide=scroll:color=intensity[spectrum];
[spectrum]format=yuv420p[v]" -map "[v]" -map 0:a -c:v libx264 -c:a copy spectrum.mp4

6、音频滤镜精选

功能Filter示例
音量调整volume-af volume=0.8
通道合并amerge-af amerge=inputs=2
降噪arnndn-af arnndn=model=rnnoise-2018-09-01.rnnn
变速不变调atempo-af atempo=1.25
静音检测silencedetect-af silencedetect=noise=-30dB:d=0.5

7、性能与最佳实践

  1. 零拷贝
    AV_BUFFERSRC_FLAG_KEEP_REF 避免帧复制
  2. 格式减少转换
    尽量在 graph 内保持相同像素格式与采样率
  3. 线程安全
    每个线程独立 graph,不共享上下文
  4. 错误处理
    检查 EAGAIN/AVERROR_EOF 控制流
  5. 验证连通性
    调用 avfilter_graph_config() 捕获连接错误

8、错误码速查

返回值含义处理
0成功继续
EAGAIN需更多输入继续送帧
AVERROR_EOF无更多输出发送 NULL 刷新
AVERROR(EINVAL)参数非法检查 graph 描述

9、一行命令记忆

ffmpeg -i in.mp4 -filter_complex \
"[0:v]scale=iw/2:-1,setsar=1[scaled];[scaled]drawtext=text='Hi':fontcolor=white:fontsize=48:x=(w-text_w)/2:y=(h-text_h)/2" \
-c:v libx264 -preset fast -c:a copy out.mp4

效果:缩放一半 + 居中文字,全程 GPU 零拷贝 可在 60 fps 下实时完成。

10、后续拓展

  • 实时滤镜链:结合 硬件加速 实现 直播美颜/贴纸
  • 自定义滤镜:编写 avfilter 插件接入 AI 分割/超分
  • 动态图合成:将 Audio Spectrum、Face Detection 实时叠加

版权声明:本文内容转自互联网,本文观点仅代表作者本人。本站仅提供信息存储空间服务,所有权归原作者所有。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至1393616908@qq.com 举报,一经查实,本站将立刻删除。

(0)

相关推荐

发表回复

登录后才能评论