一、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
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
Return decoded output data from a decoder.
@return 0 on success
int avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame);
接收解码器解码的一帧AVFrame数据
9. sws_scale
int sws_scale(struct SwsContext *c, const uint8_t *const srcSlice[],