美文网首页使用FFMpeg 模仿Android MediaPlayer
H264系列--码流组成和分层结构

H264系列--码流组成和分层结构

作者: llm_5243 | 来源:发表于2021-03-10 17:08 被阅读0次

    Android FFmpeg专题结构

    H264码流结构

    无论是解析视频文件或这通过网络传输, 其实都是一串字节序列. H264码流就是按照一定的规则组织排列的字节串.

    直观理解的角度

    按照从大到小分为: 视频序列, 图像帧, 片,宏块,子块

    66.png

    码流功能的角度

    从码流功能的角度可以分为两层:NAL层和VCL层

    • NAL网络提取层:负责以网络所要求的恰当的方式对数据进行打包和传送
    • VCL视频编码层:包括核心压缩引擎和块,宏块和片的语法级别定义,设计目标是尽可能地独立于网络进行高效的编码

    码流解析的角度

    可以理解为有一个一个的NALU单元组成.


    68.png

    一个NALU单元分成两部分: NAL头和RBSP(Raw ByteSequence Payload)原始字节序列载荷.

    前面提到的一帧图像(I帧, P帧, B帧)就是一个NALU单元, NALU单元除了代表图像外还能包含其他类型的数据,如PPS和SPS, 详细的内容在下节列出来.

    前面提到的VCL层, 或者说VCL数据,是指视频编码生成的压缩比特流片段,被称为SODB(String of Data Bits),
    SODB是RBSP的原始帧, 即RBSP包含了SODB数据

    NALU

    一个NALU由 固定长度的Header和RBSP组成


    1720840-8f2f0d6c98874fa8.jpg

    HEADER

    NAL Header的结构如下:


    1720840-0db292febd810304.jpg
    • forbidden_zero_bit
      在网络传输中发生错误时,会被置为1,告诉接收方丢掉该单元;否则为0
    • nal_ref_idc
      用于表示当前NALU的重要性,值越大,越重要.
      解码器在解码处理不过来的时候,可以丢掉重要性为0的NALU.
    • nal_unit_type
      表示NALU数据的类型,有以下几种:


      72.png

    其中比较注意的应该是以下几个:

    • 1-4:I/P/B帧,如果nal_ref_idc 为0 则表示I帧,不为0则为P/B帧
    • 5:IDR帧,I帧的一种,告诉解码器,之前依赖的解码参数集合(接下来要出现的SPS\PPS等)可以被刷新了。
    • 6:SEI,英文全称Supplemental Enhancement Information,翻译为“补充增强信息”,提供了向视频码流中加入额外信息的方法。
    • 7:SPS,全称Sequence Paramater Set,翻译为“序列参数集”。SPS中保存了一组编码视频序列(Coded Video Sequence)的全局参数。因此该类型保存的是和编码序列相关的参数。
    • 8: PPS,全称Picture Paramater Set,翻译为“图像参数集”。该类型保存了整体图像相关的参数。
    • 9:AU分隔符,AU全称Access Unit,它是一个或者多个NALU的集合,代表了一个完整的帧。

    其中SPS,PPS 需要在I帧前出现,不然解码器没法解码.而SPS,PPS出现的频率也跟不同应用场景有关,对于一个本地h264流,可能只要在第一个I帧前面出现一次就可以,但对于直播流,每个I帧前面都应该插入sps或pps,因为直播时客户端进入的时间是不确定的.

    RBSP

    RBSP的结构如下:

    1720840-7a3721b879284848.jpg

    这部分还没研究,似乎目前解析时ffmpeg都给实现了.

    每个NALU前有一个起始码 0x00 00 01(或者0x00 00 00 01), 作为NALU的分割符

    下面是一个H264码流:


    SouthEast.jpg

    分析其中比较有代表性的3帧:

    • 00 00 00 01 67
      00 00 00 01是一个NALU 开始,67 是Header, 二进制为0110 0111, nal_unit_type 为00111, 即7为SPS帧
    • 00 00 00 01 68
      68 二进制为0110 1000, nal_unit_type 为00111, 即8为SPS帧
    • 00 00 00 01 65
      65 二进制为0110 0101,nal_unit_type 为00101, 即5为IDR帧

    H264 更详细的分层结构

    71.png

    关于多slice这块目前还没弄清楚,后面弄清楚了再修改.

    参考:
    https://www.jianshu.com/p/82cc851df834

    相关文章

      网友评论

        本文标题:H264系列--码流组成和分层结构

        本文链接:https://www.haomeiwen.com/subject/chcrqltx.html