HEVC/H265 HM10.0 分析(一)NALread.cpp

来源:互联网 发布:win7公用网络是黑色的 编辑:程序博客网 时间:2024/05/29 02:03

下面分析 NALread.cpp 函数和代码。


void read(InputNALUnit& nalu, vector<uint8_t>& nalUnitBuf){  /* perform anti-emulation prevention */  TComInputBitstream *pcBitstream = new TComInputBitstream(NULL);  convertPayloadToRBSP(nalUnitBuf, (nalUnitBuf[0] & 64) == 0);    nalu.m_Bitstream = new TComInputBitstream(&nalUnitBuf);  delete pcBitstream;  readNalUnitHeader(nalu);}

nalUnitBuf  是从文件流中读出的一个nal 单元,我们知道,H264,HEVC/H265  都是采用 Annex  B 中  Byte stream NAL unit syntax的要求格式,进行封装,好处是通过前面
的一两个字节就能够适用网络环境传输,通过 convertPayloadToRBSP  函数的目的就是去除伪起始码,NAL 包分为 VCL(videocoding layer) 和 非VCL包(sps,vps,pps等头部信息包)。


enum NalUnitType{  NAL_UNIT_CODED_SLICE_TRAIL_N = 0,   // 0  NAL_UNIT_CODED_SLICE_TRAIL_R,   // 1    NAL_UNIT_CODED_SLICE_TSA_N,     // 2  NAL_UNIT_CODED_SLICE_TLA,       // 3   // Current name in the spec: TSA_R    NAL_UNIT_CODED_SLICE_STSA_N,    // 4  NAL_UNIT_CODED_SLICE_STSA_R,    // 5  NAL_UNIT_CODED_SLICE_RADL_N,    // 6  NAL_UNIT_CODED_SLICE_DLP,       // 7 // Current name in the spec: RADL_R    NAL_UNIT_CODED_SLICE_RASL_N,    // 8  NAL_UNIT_CODED_SLICE_TFD,       // 9 // Current name in the spec: RASL_R  NAL_UNIT_RESERVED_10,  NAL_UNIT_RESERVED_11,  NAL_UNIT_RESERVED_12,  NAL_UNIT_RESERVED_13,  NAL_UNIT_RESERVED_14,  NAL_UNIT_RESERVED_15,  NAL_UNIT_CODED_SLICE_BLA,       // 16   // Current name in the spec: BLA_W_LP  NAL_UNIT_CODED_SLICE_BLANT,     // 17   // Current name in the spec: BLA_W_DLP  NAL_UNIT_CODED_SLICE_BLA_N_LP,  // 18  NAL_UNIT_CODED_SLICE_IDR,       // 19  // Current name in the spec: IDR_W_DLP  NAL_UNIT_CODED_SLICE_IDR_N_LP,  // 20  NAL_UNIT_CODED_SLICE_CRA,       // 21  NAL_UNIT_RESERVED_22,  NAL_UNIT_RESERVED_23,  NAL_UNIT_RESERVED_24,  NAL_UNIT_RESERVED_25,  NAL_UNIT_RESERVED_26,  NAL_UNIT_RESERVED_27,  NAL_UNIT_RESERVED_28,  NAL_UNIT_RESERVED_29,  NAL_UNIT_RESERVED_30,  NAL_UNIT_RESERVED_31,  NAL_UNIT_VPS,                   // 32  NAL_UNIT_SPS,                   // 33  NAL_UNIT_PPS,                   // 34  NAL_UNIT_ACCESS_UNIT_DELIMITER, // 35  NAL_UNIT_EOS,                   // 36  NAL_UNIT_EOB,                   // 37  NAL_UNIT_FILLER_DATA,           // 38  NAL_UNIT_SEI,                   // 39 Prefix SEI  NAL_UNIT_SEI_SUFFIX,            // 40 Suffix SEI  NAL_UNIT_RESERVED_41,  NAL_UNIT_RESERVED_42,  NAL_UNIT_RESERVED_43,  NAL_UNIT_RESERVED_44,  NAL_UNIT_RESERVED_45,  NAL_UNIT_RESERVED_46,  NAL_UNIT_RESERVED_47,  NAL_UNIT_UNSPECIFIED_48,  NAL_UNIT_UNSPECIFIED_49,  NAL_UNIT_UNSPECIFIED_50,  NAL_UNIT_UNSPECIFIED_51,  NAL_UNIT_UNSPECIFIED_52,  NAL_UNIT_UNSPECIFIED_53,  NAL_UNIT_UNSPECIFIED_54,  NAL_UNIT_UNSPECIFIED_55,  NAL_UNIT_UNSPECIFIED_56,  NAL_UNIT_UNSPECIFIED_57,  NAL_UNIT_UNSPECIFIED_58,  NAL_UNIT_UNSPECIFIED_59,  NAL_UNIT_UNSPECIFIED_60,  NAL_UNIT_UNSPECIFIED_61,  NAL_UNIT_UNSPECIFIED_62,  NAL_UNIT_UNSPECIFIED_63,  NAL_UNIT_INVALID,};


以下是nal_unit_header的描述,(nalUnitBuf[0]& 64) == 0  就是  NalUnitType  从0 到31的, NalUnitType 从32到64的,(nalUnitBuf[0] & 64)== 1, 在语法描述中有

forbidden_zero_bit 为 0,例如:NAL_UNIT_VPS  是32 , 0(forbidden_zero_bit)  100000(nal_unit_type),   0(nuh_reserved_zero_6bits), 所以NAL_UNIT_VPS的nalUnitBuf[0] 为64,。  通过 NalUnitType 得知,slice相关的(nalUnitBuf[0] & 64)== 0  , slice不相关的(nalUnitBuf[0] & 64)== 1

在slice中可能就有cabac_zero_word字节,不需要进行解码的。


nal_unit_header( ) {

Descriptor

     forbidden_zero_bit

f(1)

     nal_unit_type

u(6)

     nuh_reserved_zero_6bits

u(6)

     nuh_temporal_id_plus1

u(3)

}

 





convertPayloadToRBSP(nalUnitBuf, (nalUnitBuf[0] & 64) == 0);  函数就是去伪起始码,readNalUnitHeader 就是判断nalu的类型信息。

原创粉丝点击