在上一章节(视频又又又又花屏了)中使用了av_parser_parse2
函数解决了 H264流 花屏的问题, 考虑到篇幅问题,前文并未对其进行深入探讨,本文将对其相关概念进行深入探讨。
其实av_parser_parse2
函数只是解析器(av_parser
)组件的一部分,而解析器组件是FFmpeg中用于处理音视频流的一个重要工具,特别是在解析音视频流时具有很大的作用。
解析器是 FFmpeg 提供的一套用于将原始流(如从文件、网络或其他源获取的压缩数据)解析为适合解码器处理的数据包(AVPacket
)的工具。其可根据不同的音视频编码格式,分离出一个个完整的压缩数据包。
尤其适用于一些基于块的数据格式(如 MP4、MPEG2、H264 等)。流媒体协议中数据并非总是以完整的压缩数据包的形式传输,而是以多个小的块或者片段进行传输。而解析器可以将这些碎片重新组合成完整的数据包,并确保数据包的完整性。 这也是为什么前文出现的花屏问题经过解析器后便可以正常显示的原因。
解析器用于将数据流中的原始数据解析/拼接为解码器可以处理的压缩数据包。所以其应用于的场景可以有:
解析器工作流程一般分为以下几个步骤:
av_parser_init
函数依据流的编码类型初始化解析器。//功能: 初始化解析器
//参数: codec_id:流的编码类型
//返回值:解析器上下文结构体
AVCodecParserContext *av_parser_init(enum AVCodecID codec_id);
av_parser_parse2
函数将接收到的数据输入到解析器中。解析器会处理原始流数据,并产生一个或多个完整的压缩数据包(AVPacket
)。//功能:解析数据流,
//参数:s:解析器上下文,
// avctx:解码器上下文,
// poutbuf:解析后的数据包,
// poutbuf_size:解析后的数据包大小,
// buf:待解析的数据,
// buf_size:待解析的数据大小,
// pts:时间戳,
// dts:解码时间戳,
// pos:数据包在文件中的位置
//返回值:解析数据时所使用的字节数,
int av_parser_parse2(AVCodecParserContext *s,
AVCodecContext *avctx,
uint8_t **poutbuf, int *poutbuf_size,
const uint8_t *buf, int buf_size,
int64_t pts, int64_t dts,
int64_t pos);
AVPacket
)可以送入解码器进行解码处理。av_parser_close
函数关闭解析器并释放相关资源。//功能:关闭解析器
//参数:s:解析器上下文
//返回值:无
void av_parser_close(AVCodecParserContext *s);
前文使用解析器解析的 H264 流,可参考前文,视频又又又又花屏了
依据如上的介绍,使用解析器是需要先初始化解析器,并且初始化解析器时需要指定流的编码类型。那在不知道流的编码类型时,如何使用解析器呢?由于涉及内容较多,将会在后续章节讲解,欢迎大家关注
本文详细介绍了 FFmpeg 中解析器的基本概念、使用场景、相关接口,并提供了代码示例。 如果你也在学习音视频,欢迎关注我的公众号,一起交流学习!