FFmpeg命令行参数分析-vn—ffmpeg.c源码分析

作者:罗上文,微信:Loken1,公众号:FFmpeg弦外之音

vn 的全称是 video no,也就是去掉视频的意思。这也是一个可以用于 输入 或者 输出的 参数,定义如下:

{ "vn", OPT_VIDEO | OPT_BOOL  | OPT_OFFSET | OPT_INPUT | OPT_OUTPUT,{ .off = OFFSET(video_disable) }, "disable video" }

vn 参数作用于输出文件

vn 一个比较常用的场景就是在输出的时候,把视频流删除,只保留音频流,命令如下:

ffmpeg -i juren.mp4 -vn juren.flv

-vn 去掉视频的实现原理如下:

1,vn 参数会赋值到 OptionsContextvideo_disable 字段。常规操作

2,video_disable 会在 open_output_file() 函数被使用,导致 new_video_stream() 函数没有执行,所以 muxer 里没有视频的流,如下:

1-1

虽然输出文件没有了视频流,但是输入文件还是会把视频流的 AVPacket 读取出来,那读取出来的 AVPacket 会如何处理呢?

实际上是这样的,在 ffmpeg.c 里面,InputStream 是管理输入流的数据结构,默认所有的 InputStreamdiscard 字段都是 1,默认是丢弃的,所以读取出来的 AVPacket 默认就是会丢弃,代码如下:

1-2

1-3


那什么情况下 InputStreamdiscard 字段会被设置为 0 呢?有两种情况。

1,new_video_stream() 函数被执行的情况,如下:

1-4

提示:new_video_stream 里面会执行 new_output_stream

由于本文的命令使用了 -vn 选项,所以 new_video_stream() 函数不会被执行,所以输入文件的视频流 AVPacket 默认就是丢弃的。


2,在复杂滤镜里面使用了 输入文件的视频流,命令如下:

ffmpeg -i juren.mp4 -complex_filter "[0:v]...省略" juren.flv

上面的命令使用了 [0:v],也就是第一个输入文件的视频流,所以 discard 字段会被设置为 0 ,代码如下:

1-5


vn 参数作用于输入文件

vn 用在输入文件前面的场景,我个人来说是比较少用的,不过是支持这样设置。命令如下:

ffmpeg -vn -i juren.mp4 juren.flv

上面这条命令的作用是 ,在 ffmpeg.c 里面的实现流程如下:

1,vn 参数会赋值到 OptionsContextvideo_disable 字段。常规操作

2,video_disable 变量转移给 ist->user_set_discard,代码如下:

1-6

ist->user_set_discard 在哪里被使用了呢?在 new_output_stream() 里面,如下:

1-7

上图中是直接设置的 AVStream 里面的 discard 字段,一旦 AVStream 里面的 discard 字段设置为非 0 ,av_read_frame() 读取输入文件的时候,就不会返回这个流的 AVPacket

因此在输入文件前面加 -vn,可能会带来一些性能提升,因为 av_read_frame() 就不会读取出来视频流的 AVPacket

而如果在输出文件前面加 -vnav_read_frame() 会把 AVPacket 读取出来然后再丢弃。会多一些内存释放的操作。



感谢 NETINT(镕铭微电子) 赞助《FFmpeg原理》免费版一书的服务器费用,下面是 VPU 产品介绍

版权所属 xianwanzhiyin.net 罗上文 2024 all right reserved,powered by Gitbook该文件修订时间: 2023-07-26 11:33:12

results matching ""

    No results matching ""