本系列 以 ffmpeg4.2 源码为准,下载地址:链接:百度网盘 提取码:g3k8
本系列主要分析各种 ffmpeg 命令参数 在代码里是如何实现的。a.mp4下载链接:百度网盘,提取码:nl0s 。
命令如下:ffmpeg -i a.mp4 -vn -acodec copy output.mp4
上面的命令是单独抽取文件中的音频流到 输出文件
命令行参数 -vn 定义如下:
ffmpeg_opt.h 3569行
{ "vn",OPT_VIDEO | OPT_BOOL | OPT_OFFSET | OPT_INPUT | OPT_OUTPUT,{ .off = OFFSET(video_disable) },"disable video" },
从上面定义可以看出,-vn 会解析赋值 给 OptionsContext 的 video_disable字段。
OptionsContext 的 video_disable字段 会在哪里使用呢?请看下图:
可以看到,o->video_disable 控制了 new_video_stream() 没有执行,导致输出 AVFormatContext没有 video 流。
虽然AVFormatContext没有 video 流,但是视频流的AVPacket 还是会从输入文件读取出来,那读取出来的 AVPacket 会如何处理呢?
在《FFmpeg 源码分析》中讲解过,有一个全局变量数组 input_streams[] ,数组里存储所有的输入流。
请看下图:
在 add_input_stream() 里面 创建输入流的时候, ist->discard 默认是 1 (默认读出来的AVPacket全部丢弃),只有执行了 new_video_stream() -> new_output_stream() 的时候才会把 ist->discard 设置成 0。
new_output_stream() 函数的代码如下:
可以看到 在 ffmpeg_opt.c 1559行,根据输出流来决定输入流的 discard 的值要不要开启。
输入流的 discard 如果是 1,会导致什么结果呢,再请看下图。
-vn 命令分析完毕。
总结:
vn 导致没有执行 new_video_stream(),导致 视频输入流的 ist->discard 一直是1 ,ist->discard等于1 再导致 process_input() 的时候丢弃读取出来的AVPacket。
扩展知识:
Qt creator 里面的 data breakpoit 特别好用,想知道某个变量在哪里被修改了,用 data breakpoit 断点变量的地址,下次变量被修改就可以自动停在相应的代码位置。
版权所属:知识星球:弦外之音,QQ:2338195090。 由于笔者的水平有限, 加之编写的同时还要参与开发工作,文中难免会出现一些错误或者不准确的地方,恳请读者批评指正。如果读者有任何宝贵意见,可以加我微信 Loken1。