音视频封装 -- ffmpeg初识
1 FFmpeg
音视频编解码开源项目,堪称自由软件中最完备的一套多媒体支持库,几乎实现了所有当下常见的数据封装格式、多媒体传输协议以及音视频编解码器。
FF: Fast Forward
深入学习可参考雷神博客:http://blog.****.net/leixiaohua1020/article/details/15811977/
2 FFMPEG从功能上划分为几个模块:
- 核心工具(libavutils):提供公用的功能函数
- 媒体格式(libavformat):实现多媒体文件的读包和写包
- 编解码(libavcodec):完成音视频的编解码
- 设备(libavdevice):管理音视频设备的操作
-
后处理(libavfilter, libswscale, libpostproc):进行音视频后处理。
(目前音视频封装仅使用到libavutils、libavformat、libavcodec中的内容)
3 FFMPEG 关键结构体说明
- ① 解封装(flv,avi,rmvb,mp4,ts)
AVFormatContext:主要存储视音频封装格式中包含的信息
AVInputFormat:存储输入视音频使用的封装格式。每种视音频封装格式都对应一个AVInputFormat结构。 - ② 存数据
视频的话,每个结构体一般是存一帧;音频可能有好几帧
解码前数据:AVPacket
解码后数据:AVFrame - ③ 解码(h264,mpeg2,aac,mp3)
每个AVStream存储一个视频/音频流的相关数据;每个AVStream对应一个AVCodecContext,存储该视频/音频流使用解码方式的相关数据;每个AVCodecContext中对应一个AVCodec,包含该视频/音频对应的解码器。每种解码器都对应一个AVCodec结构。 - ④ 解协议(http,rtsp,rtmp,mms)
AVIOContext,URLProtocol,URLContext主要存储视音频使用的协议的类型以及状态。URLProtocol存储输入视音频使用的封装格式。每种协议都对应一个URLProtocol结构。(注意:FFMPEG中文件也被当做一种协议“file”)
各关键结构体之间的关系:
4 FFMPEG 关键API说明
- ① av_register_all()
ffmpeg用来注册codecs、muxders、demuxders等。该函数在所有基于ffmpeg的应用程序中几乎都是第一个被调用的。只有调用了该函数,才能使用复用器,编码器等。 - ② avformat_alloc_context()
avformat_alloc_context()是AVFormatContext的初始化函数,与之对应的销毁函数是 avformat_free_context()。
avformat_alloc_context()调用av_malloc()为AVFormatContext结构体分配了内存,而且同时也给AVFormatContext中的internal字段分配内存。此外调用了一个avformat_get_context_defaults()函数。该函数用于设置AVFormatContext的字段的默认值。 - ③ avformat_open_input()
用于打开多媒体数据并且获得一些相关的信息。 - ④ avformat_find_stream_info()
可以读取一部分视音频数据并且获得一些相关的信息。该函数主要用于给每个媒体流(音频/视频)的AVStream结构体赋值。实现了解码器的查找,解码器的打开,视音频帧的读取,视音频帧的解码等工作。换句话说,该函数实际上已经“走通”了解码的整个流程。 - ⑤ av_read_frame()
读取码流中的音频若干帧或者视频一帧。例如,解码视频的时候,每解码一个视频帧,需要先调用 av_read_frame()获得一帧视频的压缩数据,然后才能对该数据进行解码(例如H.264中一帧压缩数据通常对应一个NAL)。