常用结构体[1][2]
![ed98387758544965df7afa9f0767eb72.png](https://i-blog.csdnimg.cn/blog_migrate/ca6ff88dff5c9e4fefee8d63609fc120.jpeg)
一段音视频,一般先解协议http等获得mp4文件,再将mp4解封装为压缩视频H264等格式和压缩音频aac等格式存储于AVPacket,再分别对音视频解码获得原始数据存储在AVFrame。
1. 解协议(http,rtsp,rtmp,mms)
AVIOContext,URLProtocol,URLContext主要存储视音频使用的协议的类型以及状态。AVIOContext实现了带缓冲的读写操作,是管理输入输出数据的结构体。URLProtocol存储输入视音频使用的封装格式,每种协议都对应一个URLProtocol结构。(注意:FFMPEG中文件也被当做一种协议“file”)
2. 解封装(flv,avi,rmvb,mp4)
AVFormatContext是存储音视频封装格式中包含的信息的结构体。AVInputFormat存储输入视音频使用的封装格式。每种视音频封装格式都对应一个AVInputFormat 结构。
3. 解码(h264,mpeg2,aac,mp3)
每个AVStream存储一个视频/音频流的相关数据;
每个AVStream对应一个AVCodecContext,AVCodecContext 是一个描述编解码器上下文的结构体,包含了众多编解码器需要的参数信息;
每个AVCodecContext中对应一个AVCodec,AVCodec 是存储编码器信息的结构体,包含该视频/音频对应的解码器,每种编解码器都对应一个AVCodec结构体。
4. 存数据
视频的话,每个结构一般是存一帧,音频可能有好几帧。
解码前数据:AVPacket
解码后数据:AVFrame。AVFrame 结构体一般用于存储原始数据(即非压缩数据,例如对视频来说是 YUV,RGB,对音频来说是 PCM),此外还包含了一些相关的信息。
关键函数[3]
![64371f21d1f649d89649371bdf919260.png](https://i-blog.csdnimg.cn/blog_migrate/420409e39281088ad278bb9d61e64dca.png)
- av_register_all 注册库所支持的容器格式及其对应的CODEC。
- avformat_open_input 打开多媒体文件流,并读取文件的头,将读取到的信息填充到AVFormatContext结构体中。在使用结束后,要调用
avformat_close_input
关闭打开的流 - avformat_find_stream_info 上面提到,avformat_open_input只是读取文件的头来得到多媒体文件的信息,但是有些文件没有文件头或者文件头的格式不正确,这就造成只调用
avformat_open_input可能得不到解码所需要的必要信息,需要调用 avformat_find_stream_info进一步得到流的信息。
通过上面的三个函数已经获取了对多媒体文件进行解码的所需要信息,下面要做的就是根据这些信息得到相应的解码器。
结构体AVCodecContext描述了编解码器的上下文信息,包含了流中所使用的关于编解码器的所有信息,可以通过 AVFormatContext->AVStream->AVCodecContext
来得到,在有了AVCodecContext后,可以通过codec_id来找到相应的解码器,具体代码如下:
AVCodec* pCodec = nullptr;
pCodecCtxOrg = pFormatCtx->streams[videoStream]->codec; // codec context
// 找到video stream的 decoder
pCodec = avcodec_find_decoder(pCodecCtxOrg->codec_id);
- avcodec_find_decoder 可以通过codec_id或者名称来找到相应的解码器,返回值是一个AVCodec的指针。
- avcodec_open2 打开相应的编解码器。
- av_read_frame 从流中读取数据帧暂存到AVPacket中。
- avcodec_decode_video2 从AVPacket中解码数据到AVFrame中。
参考
- ^https://blog.csdn.net/cugkuan/article/details/17656485
- ^https://www.cnblogs.com/linuxAndMcu/p/12041578.html
- ^https://www.cnblogs.com/wangguchangqing/p/5744941.html