HEVC函数入门(24)——比特流

本文介绍了HEVC编码中的比特流处理,包括VCL、NAL层的概念,详细讲解了NAL单元的结构、转换规则以及在HEVC编码器中的实现过程,如NALUnit、OutputNALUnit、AccessUnit等关键类的作用。此外,还提到了NALU在网络传输中的字节流和分组流两种形式。
摘要由CSDN通过智能技术生成

NB_vol_1的博文在比特流之前讲了去方块滤波和SAO,这个部分我打算放到后面,这里先看一下比特流。本文整理自http://blog.csdn.net/nb_vol_1/article/details/55057213
在讲比特流之前先了解下VCL和NAL,HEVC编码分成两个层次,高层处理编码具体细节的被称为VCL(视频编码层)、底层处理比特流的被称为NAL(网络适配层)。预测编码、变换、量化、环路滤波以及熵编码都属于VCL。而处理比特流封装细节的部分则属于NAL。
VCLU
编码之后的数据要在网络上传输,必须按照一定的格式进行封装成报文,这样的数据报文被称为nal unit简称NALU。一个NALU包含了一个参数集或者一个SS(slice segment)的数据;包含一个参数集或者其他信息的NALU被称为non-VCLU;包含一个SS的压缩数据的NALU被称为VCLU。
HEVC规定一副图像中的VCLU具有相同的时域重要性及与其他图像的时域依赖关系。
NALU可以包含一个SS的压缩数据、vps、sps、pps、补充增强信息(SEI)、也可以为定界、序列结束、比特流结束、填充数据等
NALU的结构如下,它包含NALU头部(2字节)和NALU载荷(称为RBSP,整数字节)。
注意,RBSP和压缩的数据(SODB)是有区别的。SODB通过下面方式转换成RBSP:
1、把下面的字节流进行转换:
0x000000 ——> 0x00000300
0x000001 ——> 0x00000301
0x000002 ——> 0x00000302
0x000003 ——> 0x00000303
因为,0x000001是NALU的起始码,0x000000是NALU的结束码,0x000002是预留码,对0x000003进行替换是为了避免与0x0000030X(0x00000300,0x00000301,0x00000302,0x00000303)冲突。
2、如果转换之后的SODB不足整数个字节,那么在后面填充比特0,直到包含整数个字节。
3、最后可能会加入16个比特的0作为填充比特。
NALU的头部:
1比特的forbidden_zero_bit(固定的0比特)
6比特的nal_unit_type(NALU类型)
6比特的nuh_layer_id(当前应该取0,非0值用于3D视频等)
3比特的nuh_temporal_id_plus1,该值减去1表示NALU所在时域层的标识号temporalId,不能为0,temporalId表示NALU的时域层级,根据temporalId可以确定图像的重要性,配合nal_unit_type就可以实现视频流的时域分级。
关于上文出现的一些缩写和概念可以参考我以前的博文:
http://blog.csdn.net/qq_21747841/article/details/73332394
http://blog.csdn.net/qq_21747841/article/details/75224344
Access Unit
HEVC中引入了接入单元(Access Unit,AU)的概念,一个AU表示多个按照顺序(解码顺序)排列的NALU,这些NALU刚好可以解码生成一个图像。
AU可以看作压缩视频比特流的基本单位,即压缩的视频流由多个按顺序排列的AU组成。
一个AU应该包含一幅图像的所有VCLU,还可以包含non-VCLU。一个AU可以从定界NALU、SEI类型的NALU或者第一个SS的NALU开始,可以用最后一个SS的NALU、序列结束NALU或者比特流结束NALU来结束。
一般情况下,一个AU不包含下面类型的NALU:参数集,保留VCL、填充、保留non-VCLU、未明确等。
NALU在网络上的传输
NALU在网上传输的时候分为两种类型:
1、字节流。
NALU生成字节流的过程如下:
(1)在每个NALU前面插入3字节的起始码start_code_prefix_one_3bytes,其值为0x000001
(2)如果NALU的类型为:VPS_NUT,SPS_NUT,PPS_NUT或者解码顺序为一个AU的第一个NALU,则在其起始码前再插入一个zero_byte,值为0x00
(3)在视频首个NALU的起始码(可能包含zero_byte)前插入leading_zero_8bits,值是0x00
(4)根据需要可在每个NALU后增加trailing_zero_8bits,值是0x00,作为填充数据。
2、分组流。使用RTP、RTMP等协议,把NALU直接作为网络分组的有效载荷。
比特流在HEVC中的实现
这里是重点,因为之前都是看的帧内帧间的实现,这里要重新找它的位置,这里是在编码的入口TAppEncTop搜索m_nalUnitType找到的。
HEVC中的实现:
1、NALUnit表示一个NALU头部

/**
 * Represents a single NALunit header and the associated RBSPayload
 */
// NAL单元头部 
struct NALUnit
{
  // NAL单元的类型 
  NalUnitType m_nalUnitType; ///< nal_unit_type
  UInt        m_temporalId;  ///< temporal_id
  UInt        m_nuhLayerId;  ///< nuh_layer_id

  /** construct an NALunit structure with given header values. */
   // 构造函数
  NALUnit(
    NalUnitType nalUnitType,
    Int         temporalId = 0,
    Int         nuhLayerId = 0)
    :m_nalUnitType (nalUnitType)
    ,m_temporalId  (temporalId)
    ,m_nuhLayerId  (nuhLayerId)
  {}

  /** default constru
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值