引言 H.264相对于以前的标准,采用了多参考帧的技术,提高了编码器的性能,但也增加了实现的复杂度,在理解上也加大了难度。下面是我近来参阅一些资料的总结; frame_num:标志片的解码顺序,当前图像是IDR(立即刷新图像)时,设置为0;相对于前面一个参考帧(解码顺序),增加1; POC:picture ordercount的缩写,标志片的播放顺序,IDR图像的第一个场的POC为0;POC由片头信息得出,根据pic_order_cnt_type有三种计算方法; Type0:TopFieldOrderCnt=POCMsb+POCLsb POCLsb由片头提供,即pic_order_cnt_lsb;当pic_order_cnt_lsb溢出时,POCMsb增加;delta_pic_order_cnt指示顶场和低场POC的变化,默认值为0; 例: 播放顺序:IBPBPBPB… B帧不作参考帧,则POC相对于前面的一个参考帧增加2;
Type1: 在序列参数集中设置一个POC预期值,若POC的值有变化,则只传送相对变化值;序列参数集规定了POC循环的参考帧数目;对于一帧图像,计算POC预期值如下: 1. 2. 3. 4. TopFieldOrderCount=expectedPOC+delta_pic_order_cnt[0] BottomFieldOrderCount=expectedPOC+delta_pic_order_cnt[1](if field_pic = 1) 例1: 播放顺序:IBPBPBPB… B帧不作参考帧,一个POC循环中有一个参考帧,offset_for_non_ref_pic=-2,offset to nextref frame=4
例2: 播放顺序:IBPBPBPB… B帧不作参考帧,一个POC循环中有一个参考帧,offset_for_non_ref_pic=-4,offset to nextref frame=6
Type2: 播放顺序与解码顺序相同;POC由frame_num直接得到 if(used for ref) else set TopPOC and/or BottomPOC to(2*frame_num-1) 参考帧重排序 由于在解码每个MB时,都要用到参考帧的索引ref_idx_l0或ref_idx_l1。可能发生这样的情况,有个参考帧(短期参考帧或者长期参考帧)对于解码一个图像特别有用,但是这个参考帧在缺省的队列中并不位于索引值为0的位置,所以编码大的索引值需要花费多的比特。参考帧的重排序可以使这个参考帧位于索引值比较小的位置,以节省编码比特数。 下面我们以list0的重排序为例来说明 如果ref_pic_list_reordering_flag非0,则进入重排序的循环,直到ref_pic_list_reordering_flag为3时为止。 短期参考帧重排序(short-term): 初始化一个指针refIdxL0使其指向参考帧索引值0,abs_diff_pic_num_minus1是相对于预测参考帧的偏移量,对于第一次重排序操作,预测参考帧就是当前图像,对于后续的重排序操作,预测图像就是最近重排序的图像; if(reordering_of_pic_nums_idc==0) elseif(reordering_of_pic_nums_idc==1) elseif(reordering_of_pic_nums_idc==2) else 得到remapped_pic后,就将remapped_pic移至索引值为refIdxL0的位置,同时更新refIdxL0,并将后面的图像向后移动一个位置; 长期参考帧重排序(long-term): 例: list0的缺省顺序是: 157,155,153,1,3 初始化predicted_pic=158,refIdxL0=0 1. remapped_pic=158-5=153 重排序如下: 153,157,155,1,3 更新remapped_pic=153,refIdxL0=1 (abcjennifer) |