FFmpeg常用API总结

常用 API 分析

通用 API

  1. av_register_all

     编译配置(--enable、--disable) FFmpeg 的时候,会生成两个文件:config.mk、config.h。config.mk 会实际上就是 makefile 文件需要包含进去的子模块,会作用在编译阶段,帮助开发者便宜出正确的库;而 config.h 是作用在运行阶段,这一阶段将确保需要注册哪些容器以及编解码格式到 FFmpeg 框架中。所以该函数的内部实现会先调用 avcodec_register_all 来注册所有 config.h 里面开放的编解码器,然后会注册所有的 Muxer 和 Demuxer,最后注册所有的 Protocol。如此,在 config 的过程中,enable、disable 的选项就作用到了运行时,该函数的源码分析涉及的源文件包括 url.c、alformats.c、mux.c、format.c 等文件。

  1. av_find_codec

在 avcodec_register_all 函数里面已经把编码器和解码器都存放到了一个链表中,因此都是从该链表进行遍历查找

  1. avcodec_open2 分析

打开编解码其的时候就会用到该函数,参数有三个,第一个是 AVCodecContext,如果想要传入私有参数,比如 preset、tune、profile,则可以为设置到 priv_data 参数中。具体到函数实现时,它会找到对应的实现文件,比如,如果打开的是 libx264 编码器,那么实际上的 Codec 为 libx264.c 中的 ff_libx264_encoder,Codec 的生命周期方法就会委托给该结构体对应的函数指针所指向的函数。open 对应的就是 init 函数指针所指向的函数,该函数会调用具体的编码库的 API,并以对应的 AVCodecContext 中的 priv_data 来填充对应第三方库所需要的私有参数。

  1. av_codec_close 分析

和 open 类似,找到对应的实现文件中的 close 函数指针所指向的函数,然后该函数会调用对应第三方库的 API 来关闭掉对应编码库。

其实 FFmpeg 所做的事情就是透明化所有的编码库,用自己的封装来为开发者提供统一的接口,开发者只需要在打开编解码库时指定编解码器的 ID 即可,之后编码、解码、关闭资源都会找到对应的实现文件去做具体的事情。

解码时用到的 API

  1. avformat_open_input

该函数会根据提供的的文件路径判断文件的格式,继而决定使用哪一个 Demuxer。比如,如果是 flv 文件,那么 Demuxer 就会使用对应的 ff_flv_demuxer,之后关键的生命周期方法 read_header、read_packet、read_seek、read_close 都会使用 ff_flv_demuxer 中函数指针指定的函数。read_header 函数会将 AVStream 结构体构造好。

  1. avformat_find_stream_info

这个函数非常重要,该方法的作用是将所有 Stream 的 MetaData 信息填充好,方法内部会先查找对应的解码器,并打开,紧接着利用 Demuxer 中的 read_packet 函数读取一段数据进行解码,解码数据越多,分析出的流数据就会越准确,本地资源会比较快,网络资源则较慢。该函数提供了几个参数可以控制读取数据的长度,分别为:probe_size、max_analyze、fps_probe_size,这几个参数的值越小,读取速度越快,信息则相对不够准确。

  1. av_read_frame

该方法读取出来的数据是 AVPacket,该函数的实现首先会委托到 Demuxer 的 read_packet 方法,然后在该函数中把未处理完的压缩数据进行缓存处理。

  1. avcodec_decode

如果要解码 H264,会找到 ff_h264_decoder,其中最重要的三个声明周期方法为 init、decode、close。

编码时用到的 API

  1. avformat_alloc_output_context

和 avformat_open_input 类似,该函数最终会找到对应的格式复制给 AVFormatContext 中的 oformat。

  1. avio_open2

该方法首先调用函数 ffurl_open,构造除 URLContext,这个结构体包含了 URLProtocol,接着调用 avio_alloc_context 方法,分配除 AVIOContext 结构体,并将上一部构造出来的 URLProtocol 传递进来,然后复制给 AVFormatContext 的属性。

编码步骤其实是解码的一个逆过程,解码过程中的 av_find_stream_info 对应到编码就是 avformat_new_stream 和 av_format_write_header,该步骤会将音频流或视频流的信息填充好,分配出 AVStream 结构体。read_header 则对应于 av_write_header,再之后是 av_write_frame、av_write_tailer,注意,av_write_header 和 av_write_tailer 必须成对出现。

发布了538 篇原创文章 · 获赞 1318 · 访问量 194万+

猜你喜欢

转载自blog.csdn.net/fanyun_01/article/details/103734344