H.264编解码技术[原始积累二]

来源:互联网 发布:淘宝电商差评怎么回复 编辑:程序博客网 时间:2024/05/01 02:29

 poc的计算

 

POC :picture order count;代表显示顺序。

Frame num:代表参考帧的解码顺序,。如果是帧编码,则总为偶数,步长为2

当不存在b帧时,编码顺序,即播放顺序。解码收放到buffer list中即可。

当存在b帧时,由于b帧需要参考前向帧,导致编码顺序和播放顺序不一致。

例如:一个GOP的结构为I0 P1 B3 P4, 这些为播放顺序,编码顺序为I0,P1,P4,B3,其中,B3参考的尾P1,P4的重建帧?。假设B3的参考帧为P1\P4;解码顺序为为:I0 P1P4 B3;因为码流中B3的残差需要加上解码后P1,P4的信息才能解码。B3解码后,reorder然后再放到buffer list中去显示。

但是,非参考帧的frame num = 参考帧的frame num+1,所以如果有连续非参考帧,如连续几个B B,则这几个B帧的frame num相同。

POC和frame num存在一定的对于关系,当pic_order_cnt_type= 1,2时,可以通过frame num计算得到POC

一个简单的视频序列如表1和表2所以,表1按图像顺序,表2编码顺序。

表1 按图像顺序的视频序列


表2 按编码顺序的视频序列


Poc用于表示图像的播放顺序,另外,在图像帧间参考解码时,表示参考帧的初始序号。

本处主要讲述帧间预测解码时,参考帧初始序号的计算:

1、  当当前帧为idr帧,或本帧的memory_manage_contorl_operation=5(表示清空参考帧队列,和idr有着相同的效果),则当前帧的poc=0;poc表示相对于idr帧的序号。

2、  在sps参数集中,有一个pic_order_cnt_type句法元素,影响着poc的计算。

a.当pic_order_cnt_type=0时:

输入为picOrderCntMsb,最终的poc=picOrderCntMsb+picOrderCntLsb, picOrderCntLsb可以从码流中获得,所以主要计算picOrderCntMsb。

通过当前帧的picOrderCntLsb和前一图像的prePicOrderCntMsb来计算获得。

 

过程:

当前帧为idr帧时(或,memory_manage_control_operation=5),picOrderCntMsb=0。

如果(picOrderCntLsb<prePicOrderCntLsb)&&( prePicOrderCntLsb- picOrderCntLsb>=MaxPicOderCntLsb/2)则表示picOrderCntLsb真实值超过了MaxPicOderCntLsb发生了溢出,则picOrderCntMsb=prePicOrderCntMsb+MaxPicOderCntLsb。

如果(picOrderCntLsb>prePicOrderCntLsb)&&( picOrderCntLsb- PrePicOrderCntLsb>=MaxPicOderCntLsb/2)则表示,PrePicOrderCntLsb的值曾经

超过了MaxPicOderCntLsb发生了溢出,测picOrderCntMsb=prePicOrderCntMsb- MaxPicOderCntLsb;此时发生了乱序。

  其它情况,picOrderCntMsb=prePicOrderCntMsb;

 

流程图:

总结:根据前一帧的PicOrderCntMsb 、PicOrderCntLsb计算当前帧的PicOrderCntMsb。其中有进位,概念。当PicOrderCntLsb大于MaxOrderCntLsb时PicOrderCntLsb重新计数,此时PicOrderCntMsb+=MaxOrderCntLsb(自己的猜测)

b.当pic_order_cnt_flag=1时:

此处的基本思想是,poc循环周期计数,其周期为num_ref_frames_in_pic_order_cnt_cycle在sps参数中指定,offset_for_ref_frames_num[i]也是参数集中指定的num_ref_frames_in_pic_order_cnt_cycle是它的大小。

absFrameNum为绝对帧号;absFrameNum = frameNumOffset + framNum

frameNumOffset =frameNumCycCount*frameNumMax,可以看出frameNum为相对帧号,有一个变化的周期。周期为frameNumMax。

picOrderCntCycCnt和picOrderCntInCyc分别表示absFrameNum对num_ref_frames_in_pic_order_cnt_cycle的模和求余。

expectDeltaPerPicOrderCntCycle为offset_ref_frames[i]的和

expecPicOrderCnt=expectDeltaPerPicOrderCntCycle*picOrderCntCycCnt+

TopFieldOrderCnt = expectedPicOrderCnt +delta_pic_order_cnt[ 0 ]

 

流程图:

 

总结:

Pic_order_cnt_type=1时,比较复杂,用于有多个参考帧的情况下。根据前一帧的FrameNumOffset以及前一帧和本帧的序号对比来决定本帧的frameNumOffset,根据sps中的num_ref_frames_in_pic_order_cnt和offset_for_ref_frame[i]参数来确定expectPicOrderCnt,然后在根据帧,场调节参数最终得到POC

 

当pic_order_cnt_flag=2时,这种只适用于单参考帧的情况,可以看出是1类型的简化。流程图为:

本文所有的流程图源于:http://blog.csdn.net/newthinker_wei/article/details/8784720

 

参考网站:http://blog.csdn.net/yu_yuan_1314/article/details/9003664


Slice(片头)包含的句法:

Pic_order_cnt_type=1条件下poc的计算。


num_ref_frames_in_pic_order_cnt_cycle表示一个poc中,除了IDR外p b帧结构中参考帧的数量。

offset_for_ref_frame[]表示每个循环结构中,参考帧之间的偏移。

序列:  I       P      B     B    P      B     B     P      B     B  (为编码顺序=解码顺序)

                   I      B     B     P      B     B     P     B     B    P (为播放顺序)

                   0     2      4     6      8      10     12   14  16   18

Num_ref_frames_in_pic_order_cnt_cycle=1,每次循环中参考帧p出现的次数为1

Offset_for_ref_frame[0]=6,p帧离i帧的偏移为6(在播放顺序中看)

 

I P B P B B P B B BP B P B B P B B B P B P B B P B B B

I B   P B B        P B B B   PB PB B P B B B P B P B B P B B B P

0    4           10              18

Num_ref_frames_in_pic_order_cnt_cycle=3

Offset_for_ref_frame[3]={4,6 ,8}  //I P P P相邻参考帧之间的差值.只需要分析第一个循环结构即可。

 

分析:由于frame num表示参考帧的编号,非参考帧的编号为参考帧的编号+1,

I       P      B    B     P      B     B    P      B     B

0      1     2      2      3      4       4     5      6     6

absFrameNum

absFrameNum代表参考帧的frame num,它本身忽略了非参考帧。

Num_ref_frames_in_pic_order_cnt_cycle+Offset_for_ref_frame描述了非参考帧的信息。

所以通过absFrameNum 和 num_ref_frames_in_pic_order_cnt_cycle能知道循环次数,Offset_for_ref_frame能知道每个循环中的信息。由这些信息能推到出来poc.

 

参考:http://www.rosoo.net/a/201412/17178.html

 


0 0
原创粉丝点击