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