上海网站邮箱制作,视觉传达设计培训机构有哪些,手机房屋设计软件,网站存在的问题目录
AVFormat 模块
AVFormat 前处理部分
AVFormat 读写处理部分
小结
思考 FFmpeg 目录中包含了 FFmpeg 库代码目录、构建工程目录、自测子系统目录等#xff0c;具体内容如下#xff1a; 现在你知道 FFmpeg 的源代码目录中都包含了哪些内容#xff0c;在之后使用 FFm…
目录
AVFormat 模块
AVFormat 前处理部分
AVFormat 读写处理部分
小结
思考 FFmpeg 目录中包含了 FFmpeg 库代码目录、构建工程目录、自测子系统目录等具体内容如下 现在你知道 FFmpeg 的源代码目录中都包含了哪些内容在之后使用 FFmpeg 的 API 做开发遇到问题时就可以通过查看源代码来了解更多、更详细的内部实现了。 AVFormat 模块
从 FFmpeg 的目录结构中可以看出libavformat 主要是用来做封装格式处理的模块如果不做转码只做切片或者封装格式转换的话基本上用 AVFormat 模块就可以下面我们来看一下 AVFormat 模块都有哪些常用接口提供给我们使用。
avformat_version、avformat_configuration、avformat_license 这三个接口都是用来调试的确定使用的 FFmpeg 版本、编译配置信息以及 License。因为 FFmpeg 本身是 LGPL 的但是FFmpeg 可以引入其他第三方库比如 libfdkaac 是 nonfree 的就有可能存在专利收费的法律风险。
如果引入了 libx264 这样的编码器FFmpeg 会自动切换成 GPL 的 License这个时候如果你想要基于 FFmpeg 做定制或者开发就需要注意 GPL 的 License 法律风险相关情况最好还是咨询一下开源 License 法律援助律师尽量避免给自己的项目和公司带来不必要的麻烦。 GPL 是 GNU 公共许可证的缩写。它通常会具有 “传染性”当某一项目使用了 GPL 下的软件部分的话那么该项目将被 “感染”变成了 GPL 协议下产品也就是你需要将其开源和免费。LGPL 是 GNU 宽松公共许可证的缩写它是 GPL 的一个为主要为类库使用设计的开源协议。和 GPL 不同LGPL 允许商业软件通过类库引用方式使用 LGPL 类库而不需要开源商业软件的代码。——关于开源许可 GPL 与 LGPL AVFormat 前处理部分
当我们做音视频内容处理的时候首先接触到的应该是 AVFormatContext 模块相关的操作也就是我们这里说的 AVFormat 部分但是操作 AVFormat 的时候会有一个前处理部分主要包含网络初始化、模块遍历、申请上下文空间、打开文件还有分析音视频流等操作。下面我们逐个了解一下 AVFormat 前处理部分的接口与作用。
avformat_network_init 和 avformat_network_deinit 两个接口是网络相关模块的初始化和撤销网络相关模块初始化。av_muxer_iterate 和 av_demuxer_iterate 两个接口是 muxer 和 demuxer 的遍历接口如果你想查找自己需要的 muxer 或者 demuxer 是否在当前使用的 FFmpeg 库中用这两个接口可以全面地查找。avformat_alloc_context 和 avformat_free_context 两个接口可以用来申请与释放 AVFormatContext 上下文结构。avformat_new_stream 接口用来创建新的 AVStream。av_stream_add_side_data 接口用来向 AVStream 中添加新的 side data 信息例如视频旋转信息通常是可以存储在 side data 里面的。av_stream_new_side_data 接口用来申请新的 side data。av_stream_get_side_data 接口用来获取 side data。avformat_alloc_output_context2 接口用来申请将要输出的文件的 AVFormatContext可以通过 avformat_free_context 释放申请的 AVFormatContext。av_find_input_format 接口可以根据传入的 short_name 来获得对应的 AVFormat 模块例如 MP4。avformat_open_input 接口主要用处是打开一个 AVInputFormat并挂在 AVFormatContext 模块上这个接口里面会调用 avformat_alloc_context可以通过接口 avformat_close_input 来关闭和释放 avformat_open_input 里对应的 alloc 操作。av_find_best_stream 接口用来找到多个视频流或多个音频流中最优的那个流。avformat_find_stream_info 接口主要用来建立 AVStream 的信息获得的信息大多数情况下是比较准确的。使用 avformat_find_stream_info 接口来获得 AVStream 信息的话会比较消耗时间。因为里面需要通过 try_decode 进行解码操作来获得更精准的 AVStream 信息所以有些固定场景不使用 avformat_find_stream_info是为了节省时间方面的开销。
我们可以通过 probesize、analyzeduration 来设置读取的音视频数据的阈值avformat_find_stream_info 里面也会遍历这个阈值所以通过设置 probesize 和 analyzeduration 也可以节省一些时间。
如果有多个类似 AAC 或者 H264 这样的 codec 的话avformat_find_stream_info 内部会使用最先遍历到的 codec其实我们可以在使用 avformat_find_stream_info 之前指定解码器预期的结果会更准确一些。
AVFormat 读写处理部分
看完 AVFormat 前处理部分的操作接下来我们进入 AVFormat 读写处理的部分。
av_read_frame 接口用来从 AVFormatContext 中读取 AVPacketAVPacket 里面存储的内容在之前有讲过这里就不重复讲解了。当拖动进度条的时候我们可以调用 avformat_seek_file旧版是 av_seek_frame接口seek 到自己想要指定的位置但前提是对应的封装格式得支持精确 seekseek 支持以下四种模式。
AVSEEK_FLAG_BACKWARD //往回seek
AVSEEK_FLAG_BYTE //以字节数的方式seek
AVSEEK_FLAG_ANY //可seek到任意帧
AVSEEK_FLAG_FRAME //以帧数量的方式seek
avformat_flush 接口主要是用来清空当前 AVFormatContext 中的 buffer。avformat_write_header 接口主要用在“写”操作的开头部分通常指传输协议的开始写封装格式头部。avformat_write_header 里会调用到 avformat_init_output通常 avformat_write_header 函数的最后一个参数可以传入 OptionOption 可以控制容器模块中的 Option关于如何查看封装容器格式的 Option 参数我们之前的时候讲过你可以回顾一下。
写 MP4 文件有很多 Option可以通过 ffmpeg -h muxermp4 看到生成 MP4 的一些列参数也就是 Option。
avformat_init_output 接口主要用来做容器格式初始化部分的操作例如打开文件或者有一些容器格式内部的信息需要初始化的时候。av_interleaved_write_frame 接口支持在写入 AVPacket 的时候根据 dts 时间戳交错写入数据。使用这个接口有一个需要注意的地方就是数据会先写入到 buffer 里用来交错存储数据这个 buffer 会不断变大如果有必要的话可以考虑自己调用 avio_flush 或者写 NULL 把 buffer 写到磁盘。
我们在存储音视频数据的时候如果是顺序读取音视频数据的话音视频数据交错存储比较好因为这样可以给内存、硬盘或者网络节省很多开销。
av_write_frame 接口是不按照交错的形式存储 AVPacket不过在写入文件的时候是直接写入到磁盘不会有 buffer所以可以考虑自己先做交错再用这个接口不过我一般选择使用 av_interleaved_write_frame因为比较方便不需要自己做数据交错排列的操作。av_write_trailer 接口是写数据到封装容器的收尾部分。可以关闭和释放在此之前申请的内存另外MP4 文件如果需要把 moov 移动到 MP4 文件头部也是在这个接口里面完成的。
小结
FFmpeg 中有很多重要的模块比如 AVFormat 模块、AVcodec 模块、AVfilter 模块等。其中 AVFormat 是用来做封装格式处理的模块。这个模块的内部提供了很多常用的接口比如前处理部分的 avformat_find_stream_info 等接口读写处理部分的 avformat_write_header、av_interleaved_write_frame 等接口了解这些接口的用途和可能出现的问题及解决办法可以让我们在实践中更好地使用它们去做容器封装和解封装方面的操作。 关于 AVFormat 模块中 API 接口更多的使用方式比如说参数相关的内容你还需要多看一看 avformat.h 头文件中的注释和参数说明。如果你还是掌握不住这些接口的使用方式的话也可以根据我的建议先把源代码下来去看一下 API 里实现的过程来加深理解。 思考
我们介绍最后一个接口 av_write_trailer 的时候提到它支持把 MP4 的 moov 移动到文件的头部在 FFmpeg 的命令行参数里面使用的是 -movflags faststart那么如果我用 API 的话需要在哪个接口里面传递这个参数呢