文章目录

  • 一、" 解封装 - 解码 - 播放 过程 " 涉及到的函数和结构体概述
  • 1、打开媒体文件
  • 3、解复用 - 读取媒体流
  • 4、音视频解码 - 将压缩数据 AVPacket 解码为 AVFrame 音频帧和视频帧
  • 5、音视频播放 - 播放 AVFrame 数据







一、" 解封装 - 解码 - 播放 过程 " 涉及到的函数和结构体概述




1、打开媒体文件



在上一篇博客 【FFmpeg】FFmpeg 播放器框架 ① ( “ 解封装 - 解码 - 播放 过程 “ 涉及到的函数和结构体 | AVFormatContext 结构体详解 ) 中 , 分析了 AVFormatContext 结构体 和 avformat_open_input 打开媒体文件的函数 , 本篇博客继续向后分析 ;

【FFmpeg】FFmpeg 播放器框架 ② ( 解复用 - 读取媒体流 | 将压缩数据 AVPacket 解码为 AVFrame 音频帧和视频帧 | 播放 AVFrame 数据 )_AVPacket

调用 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 结构体对象 ;

将 采样帧队列 和 图像帧队列 进行音视频同步校准操作 , 然后 采样帧送入 扬声器 , 图像帧送入 显示器 , 就可以完成音视频数据的播放操作 ;