我想,filter实际上是形成一个AVFilterGraph,就是一个filter的图。里面定义了filter的关系,frame进去后,经过怎样的路线图进行输入和输出。
总之,最后就是形成了filter_graph。
ffmpeg -re -i ~/input.flv -threads 2 -vf "split [main][tmp]; [tmp] crop=iw:ih/2:0:0, vflip [flip]; [main][flip] overlay=0:H/2" -vcodec libx264 -acodec libfdk_aac -f flv -y rtmp://dev:1935/live/livestream
等价于:
ffmpeg -re -i ~/input.flv -threads 2 -vf "[in] split [main][tmp]; [tmp] crop=iw:ih/2:0:0, vflip [flip]; [main][flip] overlay=0:H/2 [out]" -vcodec libx264 -acodec libfdk_aac -f
flv -y rtmp://dev:1935/live/livestream
其中,标签[in]和[out]是可以省略的。
应用了如下filter:
1. split:将流分成两路,[main]和[tmp]
2. [tmp]:这路流的处理filter是,corp裁剪取上半部分,vflip为翻转,输出为[flip]
3. [main][flip]:两路流经过overlay合并为一路。
结果就是将图像上半部分镜像翻转。
跟踪这个命令,看创建了哪些filter:
[winlin@dev6 ~]$ gdb --args ffmpeg -re -i ~/input.flv -threads 2 -vf "[in] split [main][tmp]; [tmp] crop=iw:ih/2:0:0, vflip [flip]; [main][flip] overlay=0:H/2 [out]" -vcodec libx264 -acodec libfdk_aac -f flv -y rtmp://dev:1935/live/livestream
(gdb) b avfilter_graph_create_filter

(gdb) b avfilter_get_by_name

调用路径如下:
(gdb) bt
#0  avfilter_get_by_name (name=0xf32760 "split") at libavfilter/avfilter.c:404
#1  0x000000000043fc4b in create_filter (filt_ctx=0x7fffffffd770, ctx=0xf37be0, index=0, filt_name=0xf32760 "split", args=0x0, log_ctx=0xf37be0)
    at libavfilter/graphparser.c:105
#2  0x000000000043fec4 in parse_filter (filt_ctx=0x7fffffffd770, buf=0x7fffffffd760, graph=0xf37be0, index=0, log_ctx=0xf37be0) at libavfilter/graphparser.c:169
#3  0x00000000004407df in avfilter_graph_parse2 (graph=0xf37be0, filters=0xf37c6b "[main][tmp]; [tmp] crop=iw:ih/2:0:0, vflip [flip]; [main][flip] overlay=0:H/2 [out]",
    inputs=0x7fffffffd9c8, outputs=0x7fffffffd9c0) at libavfilter/graphparser.c:404
#4  0x0000000000411d43 in configure_filtergraph (fg=0xf36c20) at ffmpeg_filter.c:762
#5  0x000000000041b369 in transcode_init () at ffmpeg.c:2283
#6  0x000000000041f1c0 in transcode () at ffmpeg.c:3138
可见,会在avfilter_graph_parse2中直接将参数转换,并avfilter_open对应的filter。
#0  avfilter_get_by_name (name=0xf32760 "split") at libavfilter/avfilter.c:404 filt_name=0xf32760 "split", args=0x0
#0  avfilter_get_by_name (name=0xf30f80 "crop") at libavfilter/avfilter.c:404 filt_name=0xf30f80 "crop", args=0xf31020 "iw:ih/2:0:0"
#0  avfilter_get_by_name (name=0xf328e0 "vflip") at libavfilter/avfilter.c:404 filt_name=0xf328e0 "vflip", args=0x0
#0  avfilter_get_by_name (name=0xf39000 "overlay") at libavfilter/avfilter.c:404 filt_name=0xf39000 "overlay", args=0xf39040 "0:H/2"
这个函数也调用avfilter_link来link这些filter:
          src: split           dest: crop
          src: crop           dest: vflip
          src: split           dest: overlay
          src: vflip           dest: overlay
实际上就是建立一个图的概念,就是filter graph了。
然后,是在configure_input_filter中创建video的bufferfilter,用来提供输入源的(即[in])。

args="video_size=400x300:pix_fmt=0:time_base=1/1000:pixel_aspect=1/1:sws_param=flags=2:frame_rate=15/1"

#0  avfilter_get_by_name (name=0xa3c837 "buffer") at libavfilter/avfilter.c:404 at libavfilter/avfiltergraph.c:94

这几个函数中,avfilter_graph_create_filter是从字符串创建的一个函数,实际上等同于三个函数:
args="video_size=400x300:pix_fmt=0:time_base=1/1000:pixel_aspect=1/1:sws_param=flags=2:frame_rate=15/1"
avfilter_graph_create_filter (AVFilterContext **filt_ctx, AVFilter *filt, AVFilterGraph *graph_ctx,  args)

avfilter_open(filt_ctx, filt, name)

avfilter_init_filter(*filt_ctx, args)

avfilter_graph_add_filter(graph_ctx, *filt_ctx)

就是说,从args解析filter参数,创建一个filter_ctx,然后添加到filter_graph。这应该也是filter的基本创建流程,其中init和add没有顺序。
接着,是在configure_output_filter中创建输出的ffbuffersink,用来作为输出的(即[out])。

#0  avfilter_get_by_name (name=0xa3c6d5 "ffbuffersink") at libavfilter/avfilter.c:404 args=0x0, opaque=0x0, graph_ctx=0xf37be0)

还创建了几个其他的filter。譬如:

#0  avfilter_get_by_name (name=0xa3c745 "format") at libavfilter/avfilter.c:404 args=0xf32d70 "yuv420p:yuvj420p:yuv422p:yuv444p"
#0  avfilter_get_by_name (name=0xa44462 "scale") at libavfilter/avfilter.c:404 args=0x7fffffffd5d0 "0:0:flags=0x4"

用来做输出变换的。

视频完了后,就是音频:
#0  avfilter_get_by_name (name=0xf29980 "anull") at libavfilter/avfilter.c:404
#0  avfilter_get_by_name (name=0xa3c8ff "abuffer") at libavfilter/avfilter.c:404 args=0x7fffffffd334 "time_base=1/44100:sample_rate=44100:sample_fmt=fltp:channel_layout=0x3"
#0  avfilter_get_by_name (name=0xa3c74c "ffabuffersink") at libavfilter/avfilter.c:404 args=0x0
#0  avfilter_get_by_name (name=0xa3c805 "aformat") at libavfilter/avfilter.c:404 args=0x7fffffffd1e0 "sample_fmts=s16:sample_rates=96000,88200
#0  avfilter_get_by_name (name=0xa444c6 "aresample") at libavfilter/avfilter.c:404 args=0xfaac80 ""
设置完就开始转码。

ffmpeg1.2的filter分析相关推荐

  1. Spring security (一)架构框架-Component、Service、Filter分析

      想要深入spring security的authentication (身份验证)和access-control(访问权限控制)工作流程,必须清楚spring security的主要技术点包括关键 ...

  2. ffmpeg的filter分析

    原文网址(转载请注明出处): (http://blog.csdn.net/newchenxf/article/details/51364105) 目录 目录 什么是ffmpeg filter 如何使用 ...

  3. ## 应用Python爬虫、Flask框架、Echarts、WordCloud等技术实现豆瓣Top250数据分析

    1.爬取豆瓣Top250信息,例如名称,评分,评价数,概况等 https://movie.douban.com/top250 2.url分析: https://movie.douban.com/top ...

  4. Nginx开发从入门到精通

    Nginx开发从入门到精通 缘起 nginx由于出色的性能,在世界范围内受到了越来越多人的关注,在淘宝内部它更是被广泛的使用,众多的开发以及运维同学都迫切的想要了解nginx模块的开发以及它的内部原理 ...

  5. NLTK学习笔记(八):文法--词关系研究的工具

    目录 文法 自定义文法 文法用途 开发文法 分析文法的算法 递归下降解析器 移进-归约解析器 基于特征的文法 属性和约束 处理特征结构 包含和统一 总结 对于一门语言来说,一句话有无限可能.问题是我们 ...

  6. 案例:爬取豆瓣电影Top250中的电影信息

    案例:爬取豆瓣电影Top250中的电影信息 豆瓣电影Top250首页 分析请求地址 在豆瓣电影Top250首页的底部可以确定电影信息一共有10页内容,每页25个电影信息,如下图: 切换页面,可以看到浏 ...

  7. Directshow完整介绍

    最近一段时间,在编写DirectShow应用程序时常常遇到一些问题,原因是对DirectShow技术没有较全面地掌握,对各个接口间的关系以及filter与filter之间连接的内部过程等都只是一知半解 ...

  8. DirectShow2

    以文本方式查看主题 -  温馨小筑  (http://www.learnsky.com/bbs/index.asp) --  电脑编程  (http://www.learnsky.com/bbs/li ...

  9. DirectShow编程(2)- 开始DirectShow旅程

    2. 开始DirectShow旅程     这个章节的内容主要是编写DirectShow应用所需的一些基本概念,可以把它当作一个高级介绍,理解这些内容只需具备一般的编程和有关多媒体的知识. 2.1. ...

  10. DirectShow编程

    3. 关于DirectShow 3.1. DirectShow体系概述     多媒体的难题     处理多媒体有几个主要的难题:     *多媒体流包含了巨大的数据量,而这些数据都必须非常快地被处理 ...

最新文章

  1. 关于vs中代码生成的运行库
  2. LeetCode--Search in Rotated Sorted Array
  3. 乌班图anaconda安装
  4. .NET Core 2.1.12 与 2.2.6 发布,修复 URL 重定向欺骗漏洞
  5. FutureTask源码分析
  6. BZOJ3653: 谈笑风生
  7. 操作系统实验报告(四)文件系统
  8. 大一c语言常见编程题,自己整理的C语言常见编程题
  9. python输入两个坐标求距离_python计算两个地址之间的距离方法
  10. 下载网页 TS视频并自动合成视频
  11. CSS盒子模型box-sizing属性详解
  12. 人工智能的发展历史概览
  13. mysql foxpro,如何使用MySql同步Visual Foxpro dbfs?
  14. 什么是ASIC芯片?与CPU、GPU、FPGA相比如何?
  15. 今天开始写博客记录程序媛成长过程
  16. javascript中使用getMonth()获得月份比实际月份少一个月
  17. 前端学习——Prop
  18. OneDrive登录失败
  19. Android 系统原生TTS使用
  20. EVE-NG物理机启动报错

热门文章

  1. getnumdevices.c setgetdevicetype例程
  2. 在java中什么管理内存_Java是如何管理内存
  3. python3.7升级pip_完美解决python3.7 pip升级 拒绝访问问题
  4. ElasticSearch2.1 基于空间位置geo_query距离计算
  5. 18.11 LVS DR模式搭建
  6. MySQL安装之后如何启动
  7. MySQL 如何删除有外键约束的表数据
  8. 14-一级指针和多级指针
  9. mybatis 注解使用
  10. lua 远程调试 【zeroBrane 使用mobdebug】(good转)