一、FFmpeg解码过程流程图和关键的数据结构
FFmpeg解码涉及的知识点比较多,很容易被函数和结构体搞定不知所错,我们先从整体上对解码流程有个认知,画了张解码流程图,如下
1.1 解码流程如下
-
avformat_open_input 打开媒体文件
-
avformat_find_stream_info 初始化AVFormatContext_
-
匹配到视频流的index
-
avcodec_find_decoder 根据视频流信息的codec_id找到对应的解码器_
-
avcodec_open2 使用给定的AVCodec初始化AVCodecContext_
-
初始化输出文件、解码AVPacket和AVFrame结构体
-
av_read_frame 开始一帧一帧读取
-
avcodec_send_packet
-
avcodec_receive_frame
-
格式转换 、分别写入YUV文件
-
Opengl渲染(本篇不涉及,放到后面单独篇学习实践)
-
释放资源
1.2 关键函数
下面我们来看下解码流程中的关键函数
1. av_register_all
在3.x或者以前的版本在使用ffmpeg的复用/解复用器或者编解码器之前一定要先调用该函数。但是4.x之后ffmpeg修了了内部实现,该函数可以省略不写。
2. avformat_open_input
attribute_deprecated int av_open_input_file(AVFormatContext **ic_ptr,constchar *filename,
AVInputFormat *fmt,
int buf_size,
AVFormatParameters *ap);
以输入方式打开一个媒体文件,codecs并没有打开,只读取了文件的头信息.
3. avformat_find_stream_info
Read packets of a media file to get stream information
int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options);
获取多媒体信息
4. avcodec_find_decoder
Find a registered decoder with a matching codec ID
AVCodec *avcodec_find_decoder(enum AVCodecID id);
根据codecID找到一个注册过的解码器
5. avcodec_open2
Initialize the AVCodecContext to use the given AVCodec
int avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options);
使用给定的AVCodec初始化AVCodecContext_
6. av_read_frame
关注+后台私信我,领取2022最新最全学习提升资料包《Andoird音视频开发必备手册+音视频最新学习视频+大厂面试真题+项目实战源码讲义》资料内容包括(C/C++,Linux,FFmpeg ,webRTC ,rtmp ,hls ,rtsp ,ffplay ,srs)等等
Return the next frame of a stream.
@return 0 if OK, < 0 on error or end of file
int av_read_frame(AVFormatContext *s, AVPacket *pkt);
读取一帧数据,读到的是AVPacket
7. avcodec_send_packet
Supply raw packet data as input to a decoder.
@return 0 on success, otherwise negative error code
int avcodec_send_packet(AVCodecContext *avctx, const AVPacket *avpkt);
给解码器发送一帧压缩的AVPacket 数据
8. avcodec_receive_frame
Retur