H265码流分析详解

Posted 老樊Lu码

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了H265码流分析详解相关的知识,希望对你有一定的参考价值。

一、HEVC的码流格式定义:

        根据《T-REC-H.265-201504-I!!PDF-E》协议描述。

        字节流格式由字节流NAL 单元语法结构序列构成。每一字节流NAL 单元语法结构包含有一个起始编码前缀,后面跟随一个nal_unit(NumBytesInNALunit)语法结构。它可能(一定情况下,它应该)包含一个额外的zero_byte 语法元素。它也可能包含一个或多个额外的trailing_zero_8bits 语法元素。当为第一个字节流NAL 单元时,也可能包含一个或多个额外的leading_zero_8bits语法元素。

分析下h265码流(字节流模式),nal单元如何分割,类型

 二、H265 nal单元的分割:

寻找0x000001或者0x00000001, 规则如下:

每个NALU前面都有起始码0x000001, 3bits

如果NALU类型为vps, sps, pps, 或者解码顺序为第一个AU的第一个NALU, 起始码前面再加一个0x00

视频流的首个NALU的起始码前加入0x00

实际分析中,不必要整的这么复杂,只要找到0x000001或者0x00000001即可

上图中的码流nal拆分为:

第一帧:

0000 0001 4001 0c01 ffff 0080 0000 0300 0003 0000 0300 0003 0000 b502 40

第二帧:

00 0000 0142 0101 0080 0000 0300 0003 0000 0300 0003 0000 a002 8080 2d1f e5b5 9246 d0ce 4924 b724 aa49 f292 c8

第三帧:

00 0000 0144 01c1 a558 1e48

第四帧:

0000 0126 0101 ad70 c8d7 0d55 

三、NAL类型分析

类型枚举定义:

enum NALUnitType {
    NAL_TRAIL_N    = 0,
    NAL_TRAIL_R    = 1,
    NAL_TSA_N      = 2,
    NAL_TSA_R      = 3,
    NAL_STSA_N     = 4,
    NAL_STSA_R     = 5,
    NAL_RADL_N     = 6,
    NAL_RADL_R     = 7,
    NAL_RASL_N     = 8,
    NAL_RASL_R     = 9,
    NAL_BLA_W_LP   = 16,
    NAL_BLA_W_RADL = 17,
    NAL_BLA_N_LP   = 18,
    NAL_IDR_W_RADL = 19,
    NAL_IDR_N_LP   = 20,
    NAL_CRA_NUT    = 21,
    NAL_VPS        = 32,
    NAL_SPS        = 33,
    NAL_PPS        = 34,
    NAL_AUD        = 35,
    NAL_EOS_NUT    = 36,
    NAL_EOB_NUT    = 37,
    NAL_FD_NUT     = 38,
    NAL_SEI_PREFIX = 39,
    NAL_SEI_SUFFIX = 40,
};

2.使用elecard分析结果如下图所示:

3.码流具体分析

类型判断方式为分隔符之后的第一个字节右移一位的值:

第1个NALU:0x00000001 NAL起始码 0x40>>1,0x20,十进制32,为NAL_VPS(Video Parameter Set视频参数集)

第2个NALU:0x00000001 NAL起始码 0x42>>1,0x21,十进制33,为NAL_SPS(Sequence Parameter Set序列参数集)

第3个NALU:0x00000001 NAL起始码 0x44 >> 1,0x22,十进制34,为NAL_PPS(Picture Parameter Set图像参数集)

第4个NALU:0x00000001 NAL起始码 0x4E >> 1,0x27,十进制39,为NAL_SEI_PREFIX(Supplemental enhancement information)

第5个NALU:0x00000001 NAL起始码 0x26 >> 1,0x13,十进制19, 为NAL_IDR_W_RADL(Instantaneous decoding refresh)

代码如下:

static int hevc_probe(char* pbuf, int buf_size)
{
    unsigned int code = -1;
    int vps = 0, sps = 0, pps = 0, irap = 0;
    int i;
    
    for (i = 0; i < buf_size - 1; i++) {
        code = (code << 8) + pbuf[i];
        if ((code & 0xffffff00) == 0x100) {
            char nal2 = pbuf[i + 1];
            int type = (code & 0x7E) >> 1;
            
            if (code & 0x81) // forbidden and reserved zero bits
                return 0;
            
            if (nal2 & 0xf8) // reserved zero
                return 0;
            
            switch (type) {
                case NAL_VPS:        vps++;  break;
                case NAL_SPS:        sps++;  break;
                case NAL_PPS:        pps++;  break;
                case NAL_BLA_N_LP:
                case NAL_BLA_W_LP:
                case NAL_BLA_W_RADL:
                case NAL_CRA_NUT:
                case NAL_IDR_N_LP:
                case NAL_IDR_W_RADL: irap++; break;
            }
        }
    }
    
    return 0;
}

以上是关于H265码流分析详解的主要内容,如果未能解决你的问题,请参考以下文章

H264码流分析详解

h265文件分析(纯c解析代码)

基于海思的H265码流实时传输系统设计

基于海思的H265码流实时传输系统设计

Android音视频——H265编码核心技术解析

音视频数据处理(二)-H265/HEVC视频码流分析