h.265音视频开发,H265码音视频流解析

叁歲伎倆 2024-03-16 20:37 266阅读 0赞

H.265技术的应用

编码技术主要运用于视频播放设备、软件应用以及拍摄、录制视频的设备。人们最熟悉的莫过于PPS网络视频播放器。在PC屏客户端产品上面,PPS已经于2013年初推出了基于H.265标准的高清视频,并命名“臻高清”为自己的高清品牌。同时 PPS不断加大了在H.265技术应用方面的研究,把H.265推向手机客户端,且在性能上不断优化提升。

名词

  • CTU: 编码树单元
  • CU: 编码单元
  • PU: 以CU为根,对CU进行划分,一个预测单元PU包含一个亮度预测块PB和两个色度预测块PB.
  • TU: 以CU为根,变换单元TU是在CU的基础上划分的,跟PU没有关系,采用四叉树划分方式,具体划分有率失真代价决定,下图给出了某个CU划分成TU的结构。

H265-NALU-Type介绍

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,

H265码流格式

VPS:视频参数集,用于传输视频分级信息,有利于兼容标准在可分级视频编码或多视点视频的扩展。

NALU header定义:


























NALU header(){ Descriptor
forbidden_zero_bit f(1)
nalu unit type u(6)
nuh_layer_id u(6)
nuh_temporal_id_plus1 u(3)

H264的NALU type是首字节&0x1f,H265的NALU type是(首字节&0x7E)>>1;

NALU type定义:

  1. /**
  2. * Table 7-3: NAL unit type codes
  3. */
  4. enum HEVCNALUnitType {
  5. HEVC_NAL_TRAIL_N = 0,
  6. HEVC_NAL_TRAIL_R = 1,
  7. HEVC_NAL_TSA_N = 2,
  8. HEVC_NAL_TSA_R = 3,
  9. HEVC_NAL_STSA_N = 4,
  10. HEVC_NAL_STSA_R = 5,
  11. HEVC_NAL_RADL_N = 6,
  12. HEVC_NAL_RADL_R = 7,
  13. HEVC_NAL_RASL_N = 8,
  14. HEVC_NAL_RASL_R = 9,
  15. HEVC_NAL_VCL_N10 = 10,
  16. HEVC_NAL_VCL_R11 = 11,
  17. HEVC_NAL_VCL_N12 = 12,
  18. HEVC_NAL_VCL_R13 = 13,
  19. HEVC_NAL_VCL_N14 = 14,
  20. HEVC_NAL_VCL_R15 = 15,
  21. HEVC_NAL_BLA_W_LP = 16,
  22. HEVC_NAL_BLA_W_RADL = 17,
  23. HEVC_NAL_BLA_N_LP = 18,
  24. HEVC_NAL_IDR_W_RADL = 19,
  25. HEVC_NAL_IDR_N_LP = 20,
  26. HEVC_NAL_CRA_NUT = 21,
  27. HEVC_NAL_IRAP_VCL22 = 22,
  28. HEVC_NAL_IRAP_VCL23 = 23,
  29. HEVC_NAL_RSV_VCL24 = 24,
  30. HEVC_NAL_RSV_VCL25 = 25,
  31. HEVC_NAL_RSV_VCL26 = 26,
  32. HEVC_NAL_RSV_VCL27 = 27,
  33. HEVC_NAL_RSV_VCL28 = 28,
  34. HEVC_NAL_RSV_VCL29 = 29,
  35. HEVC_NAL_RSV_VCL30 = 30,
  36. HEVC_NAL_RSV_VCL31 = 31,
  37. HEVC_NAL_VPS = 32,
  38. HEVC_NAL_SPS = 33,
  39. HEVC_NAL_PPS = 34,
  40. HEVC_NAL_AUD = 35,
  41. HEVC_NAL_EOS_NUT = 36,
  42. HEVC_NAL_EOB_NUT = 37,
  43. HEVC_NAL_FD_NUT = 38,
  44. HEVC_NAL_SEI_PREFIX = 39,
  45. HEVC_NAL_SEI_SUFFIX = 40,
  46. };

丢帧

在性能不足,或者音画不同步时,需要进行丢帧,H264丢帧根据nal_ref_idc来判断,H265根据来NALU type判断。以下type是可以丢帧,且不花屏的:

HEVC_NAL_TRAIL_N、HEVC_NAL_TSA_N、HEVC_NAL_STSA_N、HEVC_NAL_RADL_N、HEVC_NAL_RASL_N。

H265码流分析

H265相比较于H264,除了包含SPS、PPS外,还多包含一个VPS;在NALU header上,H.264的HALU header是一个字节,而H.265则是两个字节。

以OX4001为例,头信息可以被解析成4个部分,其中:

  • forbidden_zero_bit = 0:占1个bit,与H.264相同,禁止位,用以检查传输过程中是否发生错误,0表示正常,1表示违反语法; nal_unit_type = 32:占6个bit,用来用以指定NALU类型 nuh_reserved_zero_6bits = 0:占6位,预留位,要求为0,用于未来扩展或3D视频编码
  • nuh_temporal_id_plus1 = 1:占3个bit,表示NAL所在的时间层ID 对比H.264的头信息,H.265移除了nal_ref_idc,此信息被合并到了nal_unit_type中,H.265NALU类型规定如下:

    nal_unit_type NALU类型 备注
    0 NAL_UNIT_CODE_SLICE_TRAIL_N 非关键帧
    1 NAL_UNIT_CODED_SLICE_TRAIL_R
    2 NAL_UNIT_CODED_SLICE_TSA_N
    3 NAL_UINT_CODED_SLICE_TSA_R
    4 NAL_UINT_CODED_SLICE_STSA_N
    5 NAL_UINT_CODED_SLICE_STSA_R
    6 NAL_UNIT_CODED_SLICE_RADL_N
    7 NAL_UNIT_CODED_SLICE_RADL_R
    8 NAL_UNIT_CODED_SLICE_RASL_N
    9 NAL_UNIT_CODE_SLICE_RASL_R
    10 ~ 15 NAL_UNIT_RESERVED_X 保留
    16 NAL_UNIT_CODED_SLICE_BLA_W_LP 关键帧
    17 NAL_UNIT_CODE_SLICE_BLA_W_RADL
    18 NAL_UNIT_CODE_SLICE_BLA_N_LP
    19 NAL_UNIT_CODE_SLICE_IDR_W_RADL
    20 NAL_UNIT_CODE_SLICE_IDR_N_LP
    21 NAL_UNIT_CODE_SLICE_CRA
    22 ~ 31 NAL_UNIT_RESERVED_X 保留
    32 NAL_UNIT_VPS VPS(Video Paramater Set)
    33 NAL_UNIT_SPS SPS
    34 NAL_UNIT_PPS PPS
    35 NAL_UNIT_ACCESS_UNIT_DELIMITER
    36 NAL_UNIT_EOS
    37 NAL_UNIT_EOB
    38 NAL_UNIT_FILLER_DATA
    39 NAL_UNIT_SEI Prefix SEI
    40 NAL_UNIT_SEI_SUFFIX Suffix SEI
    41 ~ 47 NAL_UNIT_RESERVED_X 保留
    48 ~ 63 NAL_UNIT_UNSPECIFIED_X 未规定
    64 NAL_UNIT_INVALID

H.265的NALU类型是在信息头的第一个字节的第2到7位,所以判断H.265NALU类型的方法是将NALU第一个字节与0x7E进行与操作并右移一位,即:

NALU类型 = (NALU头第一字节 & 0x7E) >> 1 与H.264类似,H.265码流也有两种封装格式,一种是用起始码作为分界的Annex B格式,另一种则是在NALU头添加NALU长度前缀的格式,称为HVCC。

H265码流分析帧类型

  • nal单元分割

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

  1. 每个NALU前面都有起始码0x000001, 3bits
  2. 如果NALU类型为vps, sps, pps, 或者解码顺序为第一个AU的第一个NALU, 起始码前面再加一个0x00
  3. 视频流的首个NALU的起始码前加入0x00 实际分析中,不必要整的这么复杂,只要找到0x000001或者0x00000001即可

    • 上图中的码流nal拆分为: 第一帧: 0000 0001 4001 0c01 ffff 0160 0000 0300 0003 0000 0300 0003 00ba 9702 40 第二帧: 00 0000 0142 0101 0160 0000 0300 0003 0000 0300 0003 00ba a00f 0804 47f9 65e4 91b6 1c5e 4924 fe79 fcf2 ffff ffcf e7f3 f3f9 d9 第三帧: 00 0000 0144 01c1 9095 8112 第四帧: 0000 0126 01af 1380 790b dc5c 557c 74…
    • NAL类型分析 类型枚举定义

    enum NALUnitType {

    1. NAL_TRAIL_N = 0,
    2. NAL_TRAIL_R = 1,
    3. NAL_TSA_N = 2,
    4. NAL_TSA_R = 3,
    5. NAL_STSA_N = 4,
    6. NAL_STSA_R = 5,
    7. NAL_RADL_N = 6,
    8. NAL_RADL_R = 7,
    9. NAL_RASL_N = 8,
    10. NAL_RASL_R = 9,
    11. NAL_BLA_W_LP = 16,
    12. NAL_BLA_W_RADL = 17,
    13. NAL_BLA_N_LP = 18,
    14. NAL_IDR_W_RADL = 19,
    15. NAL_IDR_N_LP = 20,
    16. NAL_CRA_NUT = 21,
    17. NAL_VPS = 32,
    18. NAL_SPS = 33,
    19. NAL_PPS = 34,
    20. NAL_AUD = 35,
    21. NAL_EOS_NUT = 36,
    22. NAL_EOB_NUT = 37,
    23. NAL_FD_NUT = 38,
    24. NAL_SEI_PREFIX = 39,
    25. NAL_SEI_SUFFIX = 40,

    };

类型判断方式为分隔符之后的第一个字节右移一位的值 第一帧:0x40 >> 1 , 得到0x20,十进制32,为NAL_VPS 第二帧:0x42 >> 1 , 得到0x21, 十进制33, 为NAL_SPS 第三帧:0x44 >> 1 , 得到0x22, 十进制34, 为NAL_PPS 第四帧:0x26 >> 1 , 得到0x13, 十进制19, 为NAL_IDR_W_RADL

  • 代码如下

    static int hevc_probe(char* pbuf, int buf_size)
    {

    1. unsigned int code = -1;
    2. int vps = 0, sps = 0, pps = 0, irap = 0;
    3. int i;
    4. for (i = 0; i < buf_size - 1; i++) {
    5. code = (code << 8) + pbuf[i];
    6. if ((code & 0xffffff00) == 0x100) {
    7. char nal2 = pbuf[i + 1];
    8. int type = (code & 0x7E) >> 1;
    9. if (code & 0x81) // forbidden and reserved zero bits
    10. return 0;
    11. if (nal2 & 0xf8) // reserved zero
    12. return 0;
    13. switch (type) {
    14. case NAL_VPS: vps++; break;
    15. case NAL_SPS: sps++; break;
    16. case NAL_PPS: pps++; break;
    17. case NAL_BLA_N_LP:
    18. case NAL_BLA_W_LP:
    19. case NAL_BLA_W_RADL:
    20. case NAL_CRA_NUT:
    21. case NAL_IDR_N_LP:
    22. case NAL_IDR_W_RADL: irap++; break;
    23. }
    24. }
    25. }
    26. return 0;

    }

image

以上主要解析了音视频开发中的,H265码流的码流格式、NALU-Type、码流分析、帧类型分析等等。

文末

H265码流结构

H265的视频流中也是存在多个GOP,每一个GOP里面包含多个视频编码帧。H265支持的视频编码帧类型有IDR帧、I帧、P帧、B帧,这些帧类型的含义和H264码流的帧类型的含义是一样,作用也是一样,比如IDR帧和I帧都是帧内压缩编码,IDR帧是即时解码刷新帧,也是关键帧;P帧是前向参考帧,B帧是双向参考帧。

发表评论

表情:
评论列表 (有 0 条评论,266人围观)

还没有评论,来说两句吧...

相关阅读

    相关 H.265视频编码与技术

    一. 概述 作为新一代视频编解码格式,H.265得到越来越广泛的应用。不久之前,苹果公司在翘首期盼中发布了iPhone6,该款手机较之以往的iPhone,不仅仅只是简单地增

    相关 rtsp之H265

    分两种情况: 1.不需要rtp分包的,直接保存rtp数据即可。 2、需要rtp分包的,直接上码流: 情况1:不需要分包 ![80a3ae8035d94a0a87369d