在上一篇博客 【FFmpeg】FFmpeg 播放器框架 ① ( “ 解封装 - 解码 - 播放 过程 “ 涉及到的函数和结构体 | AVFormatContext 结构体详解 ) 中 , 分析了 AVFormatContext 结构体 和 avformat_open_input 打开媒体文件的函数 , 本篇博客继续向后分析 ;
调用 avformat_open_input 打开媒体文件的函数 , 会把读取的 媒体文件信息 存放到 AVFormatContext 结构体中 ;
读取 多媒体流数据时 , 可以获取 不同类型的 多媒体流 AVStream 结构体<.font> , 得到的是一个 AVStream 结构体的指针数组 , 可以获取多个流数据 ;
从 音频流 / 视频流 / 字幕流 等多媒体流 读取出来的数据 会保存在 AVPacket 结构体 中 , 这是用于 存储压缩后的数据的结构体 , 该数据没有经过解码 , 无法进行播放 ;
压缩的数据需要进行解码 才可以播放出来 ;
解复用操作后会得到 音频包队列 和 视频包队列 , 都是 AVPacket 队列 , 其中的 压缩数据 需要进行解码 , 需要 创建 AVCodecContext 结构体对象 , 该对象用于描述 编码器 Encoder / 解码器 Decoder 的上下文信息 , 包含了 编解码过程 中所需的各种参数和配置选项 ;
音频解码 和 视频解码 操作 需要调用
int avcodec_send_packet(AVCodecContext *avctx, const AVPacket *avpkt);
和
int avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame);
两个函数 ,
解码器将 AVPacket 数据进行解码后得到 AVFrame 数据 , 其中
采样帧队列 和 图像帧队列 中的元素都是 AVFrame 结构体对象 ;
将 采样帧队列 和 图像帧队列 进行音视频同步校准操作 , 然后 采样帧送入 扬声器 , 图像帧送入 显示器 , 就可以完成音视频数据的播放操作 ;