H264数据裸流怎么看

1. 背景

H.264(又称 AVC,Advanced Video Coding)是一种广泛应用的视频压缩标准,具有较高的压缩效率和良好的视频质量。
在开发过程中,时常会遇到采用H264编码的视频流传输和播放有关的音视频问题,尤其是在初期会遇视频无法播放的问题:

  • 采集端编码问题(原始H164视频流就是错的)?
  • 播放端没接收到视频流(传输过程有问题)?
  • 播放端解码有问题(接收到的H264视频流是错的)?

下面通过对H264数据裸流的解析来加深对H264视频流的理解,以助于在遇到此类问题时快速发现问题所在。

2. 编码数据裸流

H264 的码流结构它主要有两种格式:Annex B 和 AVCC。Annex B 格式以 0x000001 或 0x00000001 开头,AVCC 格式以所在的 NALU 的长度开头,以 Annex B 为例。

[图片上传失败...(image-3032a9-1742465023083)]

对于一个 H.264 裸流来说,就是一系列 NALU 的集合 ,每个 NALU 既可以表示图像数据,也可以表示处理图像所需要的参数数据。

[图片上传失败...(image-a43f39-1742465023083)]

3. NALU

NALU(Network Abstraction Layer Unit,网络抽象层单元)是H.264编码标准中的一种数据封装结构,用于将编码后的视频数据组织成便于传输和存储的格式。NALU在H.264流媒体传输和存储中起到了关键作用
NALU头部是一个1字节(8位)的字段,其结构如下:

位数 名称 含义
1bit forbidden_zero_bit 始终为0,若为1表示数据错误
2bits nal_ref_idc 表示参考帧优先级(0~3)
5bits nal_unit_type 表示NALU的类型(如I帧、P帧等)

示例

也就是说看到的 67、47、27都是PPS,只是优先级不同

nal_ref_idc nal_unit_type NALU头部 (十六进制) 含义
3(最高优先级) 7 (SPS) 67 通常的 SPS
2(较高优先级) 7 (SPS) 47 也是 SPS,但优先级较低
1(次优先级) 7 (SPS) 27 SPS,最低优先级
3(最高优先级) 5 (IDR帧) 65 通常的 IDR帧

4. NALU类型(nal_unit_type)

NALU类型决定了该单元的功能,常见类型包括:

类型编号 名称 描述
1 非IDR图像片段 普通P帧、B帧的编码数据
5 IDR图像片段 关键帧(I帧),用于随机访问
6 SEI信息 补充增强信息(如时间戳、特效等)
7 SPS 序列参数集,描述视频基本参数(如分辨率)
8 PPS 图像参数集,描述编码块等局部信息
9 分隔符 标志帧间的边界

5. Web端接收到的数据

SPS

帧1
[图片上传失败...(image-a220a7-1742465023083)]

PPS

帧2
[图片上传失败...(image-8204f5-1742465023083)]

IDR

帧3
[图片上传失败...(image-78758f-1742465023083)]

P

帧4
[图片上传失败...(image-145c02-1742465023083)]

[图片上传失败...(image-fa4ddf-1742465023083)]

6. 帧的类型

必须的帧:

1. SPS (Sequence Parameter Set) - 帧 1:

  • NALU 类型: 7(67/47/27)
  • 内容: 0000 0001 6764 0033 acb4 0220 096f 2f29 ...
  • 作用: SPS 帧包含了视频序列的全局参数,例如视频的分辨率、编码级别、色彩格式等。解码器需要这些参数来正确解码视频流。
  • 是否必须: 必须。SPS 是初始化解码器所需的基本信息,缺少这个帧,解码器无法正确解码后续的帧。

2. PPS (Picture Parameter Set) - 帧 2:

  • NALU 类型: 8(68/48/28)
  • 内容: 0000 0001 68ee 06f2 c0 ...
  • 作用: PPS 帧包含了特定帧的编码参数,例如宏块类型、预测模式等,通常与 SPS 一起使用。
  • 是否必须: 必须。PPS 是解码每个视频帧时所需的参数,解码器需要它来正确解码和播放视频。

3. IDR (Instantaneous Decoder Refresh) Frame - 帧 3:

  • NALU 类型: 5(65/45/25)
  • 内容: 0000 0001 65b8 40f7 fbf4 689f 0291 9990 ...
  • 作用: IDR 帧是一个关键帧,解码器可以从这个帧开始重置并独立解码,不依赖于之前的帧。
  • 是否必须: 必须。IDR 帧是解码器重新同步视频流的关键,尤其是在随机访问点开始播放时。如果缺少这个帧,解码器可能会出现图像破损或无法正确播放视频。

非必须的帧:

4. P Frame - 帧 4:

  • NALU 类型: 1(61/41/21)
  • 内容: 0000 0001 41e2 1822 ffda 6ac0 007d 38a9 ...
  • 作用: P 帧是一种预测帧,依赖之前的帧(IDR 或其他 P 帧)进行解码,它保存了相对于参考帧的变化信息。
  • 是否必须: 非必须。虽然 P 帧对于保持视频流的连续性很重要,但它并不是解码器必须的帧。如果缺少 P 帧,视频可能会出现丢帧现象,但不会完全无法播放。

7. 帧的顺序:67->68->65->41

必须的顺序: SPS → PPS → IDR。
连续性: 这三者通常是连续出现的,确保解码器在收到 SPS 和 PPS 之后可以立即开始解码 IDR 帧。

1. SPS (Sequence Parameter Set)

  • 顺序: 必须第一个出现。
  • 原因: SPS 帧提供了全局参数,解码器需要这些参数来初始化解码器的状态,例如分辨率、编码级别等。解码器在收到 SPS 之前无法正确解码后续的任何帧。

2. PPS (Picture Parameter Set)

  • 顺序: 紧随 SPS 之后出现。
  • 原因: PPS 帧提供了特定帧的编码参数,解码器需要这些参数来解码实际的视频帧。PPS 通常在 SPS 之后出现,以便解码器在解码视频数据之前已具备所有必要的配置信息。

3. IDR (Instantaneous Decoder Refresh) Frame

  • 顺序: 在 SPS 和 PPS 之后出现。
  • 原因: IDR 帧是关键帧,解码器从这个帧开始解码视频流。IDR 帧依赖于之前提供的 SPS 和 PPS 来正确解码视频内容。

8. 总结

这样只需要查看采集端编码后和接收端接收到的H264裸流,是否符合上面所说的情况,缺少关键帧、没有有起始码、帧顺序不对所产生的问题都一目了然。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容