H264H265视频编解码算法文章汇总
怎样解析一帧图像的Slice结构,目前测试的码流都是帧编码全部是I帧,一个图像序列(尤其是I帧和IDR帧)的Slice结构是怎样的?
1.Slice的概念
-
H.264的码流结构可以分为两层:
-
网络抽象层NAL:用于传输的二进制码流包
-
视频编码层VCL:保存原始视频的图像数据
-
-
H.264的条带:Slice
-
表示视频图像数据的NAL Unit包含的语法元素
-
IDR Slice NAL type: 5
-
non-IDR Slice NAL type: 1
-
一个Slice包含了一帧图像的全部或部分数据,换言之,一帧的视频图像可以编码为1个或多个Slice,每个Slice至少要包含一个宏块最多能包含整帧图像的数据,在不同的编码实现中,同一帧图像所组成的Slice数目不一定相同,一帧图像本来编码为1个Slice,修改编码配置可能分为多个Slice进行编码
-
一个Slice:
- 包含某一帧的全部或部分数据
-
定义Slice的意义:
-
防止误码的扩散
-
不同的slice之间,其解码操作独立;
-
某一个slice的解码过程所参考的数据(例如预测编码)不能越过slice的边界
-
如果一个Slice中产生误码,此误码只产生在Slice之内,不会影响相应的Slice的解码正常进行
2.Slice的类型
-
根据码流中不同的数据类型,H.264标准中共定义了5总Slice类型:
-
I slice: 帧内编码的条带;I slice可以不依赖其他数据进行解码,因此不能包含P slice(宏块)或B slice(宏块)
-
P slice: 单向帧间编码的条带;也可包含I slice(宏块),并不在少数,若采用I Slice使用最少的代价,就会使用I Slice(宏块)
-
B slice: 双向帧间编码的条带;也可包含I slice(宏块),并不在少数,若采用I Slice使用最少的代价,就会使用I Slice(宏块)
-
SI slice: 切换I条带,用于扩展档次中码流切换使用;
-
SP slice: 切换P条带,用于扩展档次中码流切换使用;
-
S表示Switch切换的意思
3.Slice的组成
![](https://img.haomeiwen.com/i4193251/16d4baced1c0c09f.png)
-
Slice Header: 保存Slice的总体信息
-
Slice Body: 一组连续的宏块结构(或者宏块跳过信息)
-
image.png
first_mb_in_slice:大多数情况下一帧图像被编码成一个Slice,这一帧的Slice的第一个宏块自然就是这一帧的左上角的数据了这个值为0
slice_type:slice的类型,在Nal Unit中只区分了type为5或1,IDR帧或非IDR帧,非IDR帧可能会有好多种slice,可通过以下表格判断,slice_type specifies the coding type of the slice according to Table 7-6.,前面0,1,2,3,4五个数值即可区分
![](https://img.haomeiwen.com/i4193251/8cfd825eb1b74880.png)
pic_parameter_set_id:依赖于哪一个pps的值
colour_plane_id:当前处理的是哪一个颜色分量,只有在YUV三个分量分开处理的时候才有效,为0,1,2的时候分别表示Y,U,V三个分量
frame_num:和pic_order_cnt_lsb都是表示度量当前帧顺序的序号,只不过两者表示的含义不一样,差距主要体现在帧间编码上,携带了P帧或B帧的时候,研究帧间编码的时候详细解答
field_pic_flag:在frame_mbs_only_flag为假的时候才存在,也就是非帧编码的时候才存在,表示当前Slice是帧编码还是场编码,标志位也称为场编码标志位,为1,当前Slice按照场编码来处理,为0,按帧编码处理
bottom_field_flag:底场标志位,为1表示处理的是顶场和底场中的底场,为0,表示顶场
idr_pic_id:如果为IDR slice,需要idr_pic_id,如果IDR被编码为了多个Slice,每个Slice的idr_pic_id必须一样,取值范围为0~65535之间
pic_order_cnt_lsb:度量图像顺序的标号
下面暂时忽略
![](https://img.haomeiwen.com/i4193251/560190613477b131.png)
进行帧间编码时会用到
![](https://img.haomeiwen.com/i4193251/3103fab2b06822d3.png)
slice_qp_delta:计算当前Slice的初始量化参数值,pps中的参数pic_init_qp_minus26表示一个pps管理的一个gop的整体初始量化参数,加上26表示每一个pic_init_qp的值,到了每一个Slice之中,可以通过slice_qp_delta进行调整,slice_qp_delta有更强的灵活性
后面的对示例中I帧的视频解析是不需要的,保留字段
![](https://img.haomeiwen.com/i4193251/7dca665f435a95d7.png)
代码中还需要定义dec_ref_pic_marking( ),目前例子中解析的是IDR帧,只包含两个语法元素就可以了
no_output_of_prior_pics_flag
long_term_reference_flag
若解析非IDR帧,还需要以下元素
![](https://img.haomeiwen.com/i4193251/1c327f4f9982b9cb.png)
当sps中的separate_colour_plane_flag = = 1时存在元素colour_plane_id
frame_num的长度取决于sps中log2_max_frame_num_minus4
网友评论