前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >花屏的屠刀——解析器

花屏的屠刀——解析器

作者头像
程序员的园
发布2025-03-07 15:47:40
发布2025-03-07 15:47:40
4600
代码可运行
举报
运行总次数:0
代码可运行

在上一章节(视频又又又又花屏了)中使用了av_parser_parse2函数解决了 H264流 花屏的问题, 考虑到篇幅问题,前文并未对其进行深入探讨,本文将对其相关概念进行深入探讨。

其实av_parser_parse2函数只是解析器(av_parser)组件的一部分,而解析器组件是FFmpeg中用于处理音视频流的一个重要工具,特别是在解析音视频流时具有很大的作用。

解析器

解析器是 FFmpeg 提供的一套用于将原始流(如从文件、网络或其他源获取的压缩数据)解析为适合解码器处理的数据包(AVPacket)的工具。其可根据不同的音视频编码格式,分离出一个个完整的压缩数据包。

尤其适用于一些基于块的数据格式(如 MP4、MPEG2、H264 等)。流媒体协议中数据并非总是以完整的压缩数据包的形式传输,而是以多个小的块或者片段进行传输。而解析器可以将这些碎片重新组合成完整的数据包,并确保数据包的完整性。 这也是为什么前文出现的花屏问题经过解析器后便可以正常显示的原因。

应用场景

解析器用于将数据流中的原始数据解析/拼接为解码器可以处理的压缩数据包。所以其应用于的场景可以有:

  • 处理网络流媒体数据:在流媒体应用中,音视频数据经常通过网络传输。这些数据往往被切割成多个小的数据块进行发送,而不是以完整的包形式传输。经解析器可将这些小的数据块重新拼接成一个完整的压缩数据包,供解码器使用。如前文所述的H264流
  • 处理文件中的音视频流: 当处理音视频文件时,某些格式的文件(如 MP4、MPEG2 等)中的数据流也可能被切割成多个小块。因此,在解码之前,必须先对这些数据进行解析,拼接成完整的压缩数据包。
  • 解决流的碎片化问题:在一些协议中,音视频流数据可能会被分成多个碎片进行传输(比如在HTTP或RTSP流中)。通过解析器可以正确地拼接这些碎片,并确保解码时的数据完整性。

使用流程

解析器工作流程一般分为以下几个步骤:

  • 初始化解析器:使用 av_parser_init 函数依据流的编码类型初始化解析器。
代码语言:javascript
代码运行次数:0
复制
//功能: 初始化解析器
//参数: codec_id:流的编码类型
//返回值:解析器上下文结构体
AVCodecParserContext *av_parser_init(enum AVCodecID codec_id);
  • 解析数据:通过 av_parser_parse2 函数将接收到的数据输入到解析器中。解析器会处理原始流数据,并产生一个或多个完整的压缩数据包(AVPacket)。
代码语言:javascript
代码运行次数:0
复制
//功能:解析数据流,
//参数: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 函数关闭解析器并释放相关资源。
代码语言:javascript
代码运行次数:0
复制
//功能:关闭解析器
//参数:s:解析器上下文
//返回值:无
void av_parser_close(AVCodecParserContext *s);

代码示例

前文使用解析器解析的 H264 流,可参考前文,视频又又又又花屏了

进阶

依据如上的介绍,使用解析器是需要先初始化解析器,并且初始化解析器时需要指定流的编码类型。那在不知道流的编码类型时,如何使用解析器呢?由于涉及内容较多,将会在后续章节讲解,欢迎大家关注

总结

本文详细介绍了 FFmpeg 中解析器的基本概念、使用场景、相关接口,并提供了代码示例。 如果你也在学习音视频,欢迎关注我的公众号,一起交流学习!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-03-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员的园 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 解析器
  • 应用场景
  • 使用流程
  • 代码示例
  • 进阶
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档