本文参考自http://wenku.baidu.com/link?url=ZPF0iSKzwLQg_8K02pnnd_-Zd6ISnsOGWsGYb98ucLkELZO4nOv-X-v2GKLzI3r0VMN4R0TC8cM6AQy7xOjDZ4AQJBYWT_-VOYlxQFCvaj_

视频编码顺序与视频的播放顺序,并不完全相同

视频编码时,如果采用了B帧编码,由于B帧很多时候都是双向预测得来的,这时会先编码B帧的后向预测图像(P帧),然后再进行B帧编码,

因此会把视频原来的播放顺序打乱,以新的编码顺序输出码流

而在解码断接收到码流后,需要把顺序还原成原本的播放顺序,以输出正确的视频

在编解码中,视频的播放顺序序号叫做POC(picture order count)

POC有两种类型:

1、把POC的低位编进码流内        (pic_order_cnt_type = 0)

2、依赖frame_num求解POC      (pic_order_cnt_type = 1)

对于第一种类型,POC的低位pic_order_cnt_lsb可以从码流内得到,而POC的高位PicOrderCntMsb则要求解码器自行计数

计数方式依赖于前一编码帧(PrevPicOrderCntMsb与PrevPicOrderCntLsb),代码如下

    // Calculate the MSBs of current pictureif( img->pic_order_cnt_lsb  <  img->PrevPicOrderCntLsb  &&  ( img->PrevPicOrderCntLsb - img->pic_order_cnt_lsb )  >=  ( MaxPicOrderCntLsb / 2 ) )img->PicOrderCntMsb = img->PrevPicOrderCntMsb + MaxPicOrderCntLsb;else if ( img->pic_order_cnt_lsb  >  img->PrevPicOrderCntLsb  &&( img->pic_order_cnt_lsb - img->PrevPicOrderCntLsb )  >  ( MaxPicOrderCntLsb / 2 ) )img->PicOrderCntMsb = img->PrevPicOrderCntMsb - MaxPicOrderCntLsb;elseimg->PicOrderCntMsb = img->PrevPicOrderCntMsb;

可以对比下图分析

如果序列内出现了mmco==5,
如果是场模式,并且出现在底场,PrevPicOrderCntMsb与PrevPicOrderCntLsb都要清零
如果出现在顶场,只需要清零PrevPicOrderCntMsb
如果mmco==5出现在帧模式,也是只清零PrevPicOrderCntMsb

另外如果出现了IDR,那么PrevPicOrderCntMsb与PrevPicOrderCntLsb都要清零

代码如下

    // 1stif(img->idr_flag){img->PrevPicOrderCntMsb = 0;img->PrevPicOrderCntLsb = 0;}else{if (img->last_has_mmco_5) {if (img->last_pic_bottom_field){img->PrevPicOrderCntMsb = 0;img->PrevPicOrderCntLsb = 0;}else{img->PrevPicOrderCntMsb = 0;img->PrevPicOrderCntLsb = img->toppoc;}}}

可以对比下图分析

对于第二种类型,是通过frame_num来计算得出POC
在解析步骤之前通过下图来分析一下帧序列结构

该序列分3个循环,

除开I帧外,每个循环有相同的结构其中frame_num是由解码器计数的,这里不在讨论范围内,直接拿来用,

另外有两个参数是从码流内(sps)获取:

num_ref_frames_in_pic_order_cnt_cycle    除I帧外,每个循环内有多少个参考帧(P帧)

offset_for_ref_frame[i]                             一个循环内参考帧之间的间隔

假设我们需要计算POC为42的B帧的poc值

有如下步骤:

1、判断IDR,mmco==5

2、根据frame_num获取AbsFrameNum,如果是B帧则需要减一

3、计算POC,其中又分为以下几个步骤:

  • 计算一个循环的长度,即offset_for_ref_frame[i]所有元素加起来,4+6+8 = 18
  • 计算AbsFrameNum所在循环的位置(9-1)/ 3 = 2 ,即第三个循环
  • 计算AbsFrameNum在循环内的偏移(9-1)%3 = 2,偏移2,即需要加上offset_for_ref_frame[0],offset_for_ref_frame[1]两个
  • 计算前两个循环的长度 2x18 = 36
  • 前两个循环长度加上偏移长度 36 + 4 + 6 = 46
  • 由于是B帧,最后要加上offset_for_non_ref_pic,offset_for_non_ref_pic = -2*(连续B帧的数量),而这里由于有多个连续B帧,所以取平均值2,即 offset_for_non_ref_pic = -2*2 = -4
  • 最后加上delta_pic_order_cnt[0] = 0,delta_pic_order_cnt[1] = 0 , 即POC = 42

代码如下:

  case 1: // POC MODE 1// 1stif(img->idr_flag){img->FrameNumOffset=0;     //  first pix of IDRGOP, img->delta_pic_order_cnt[0]=0;                        //ignore first deltaif(img->frame_num)  error("frame_num != 0 in idr pix", -1020);}else {if (img->last_has_mmco_5){img->PreviousFrameNumOffset = 0;img->PreviousFrameNum = 0;}if (img->frame_num<img->PreviousFrameNum){             //not first pix of IDRGOPimg->FrameNumOffset = img->PreviousFrameNumOffset + img->MaxFrameNum;}else {img->FrameNumOffset = img->PreviousFrameNumOffset;}}// 2ndif(active_sps->num_ref_frames_in_pic_order_cnt_cycle) img->AbsFrameNum = img->FrameNumOffset+img->frame_num;else img->AbsFrameNum=0;if(img->disposable_flag && img->AbsFrameNum>0)img->AbsFrameNum--;// 3rdimg->ExpectedDeltaPerPicOrderCntCycle=0;if(active_sps->num_ref_frames_in_pic_order_cnt_cycle)for(i=0;i<(int) active_sps->num_ref_frames_in_pic_order_cnt_cycle;i++)img->ExpectedDeltaPerPicOrderCntCycle += active_sps->offset_for_ref_frame[i];if(img->AbsFrameNum){img->PicOrderCntCycleCnt = (img->AbsFrameNum-1)/active_sps->num_ref_frames_in_pic_order_cnt_cycle;img->FrameNumInPicOrderCntCycle = (img->AbsFrameNum-1)%active_sps->num_ref_frames_in_pic_order_cnt_cycle;img->ExpectedPicOrderCnt = img->PicOrderCntCycleCnt*img->ExpectedDeltaPerPicOrderCntCycle;for(i=0;i<=(int)img->FrameNumInPicOrderCntCycle;i++)img->ExpectedPicOrderCnt += active_sps->offset_for_ref_frame[i];}else img->ExpectedPicOrderCnt=0;if(img->disposable_flag)img->ExpectedPicOrderCnt += active_sps->offset_for_non_ref_pic;if(img->field_pic_flag==0){           //frame piximg->toppoc = img->ExpectedPicOrderCnt + img->delta_pic_order_cnt[0];img->bottompoc = img->toppoc + active_sps->offset_for_top_to_bottom_field + img->delta_pic_order_cnt[1];img->ThisPOC = img->framepoc = (img->toppoc < img->bottompoc)? img->toppoc : img->bottompoc; // POC200301
    }else if (img->bottom_field_flag==0){  //top field img->ThisPOC = img->toppoc = img->ExpectedPicOrderCnt + img->delta_pic_order_cnt[0];} else{  //bottom fieldimg->ThisPOC = img->bottompoc = img->ExpectedPicOrderCnt + active_sps->offset_for_top_to_bottom_field + img->delta_pic_order_cnt[0];}img->framepoc=img->ThisPOC;img->PreviousFrameNum=img->frame_num;img->PreviousFrameNumOffset=img->FrameNumOffset;break;

  

计算POC还有一种类型,即没有B帧的,这种最简单,直接通过frame_num推导,

但是应该注意,在这种情况下不存在连续 的非参考图象(注释),且解码输出的顺序和显示输出顺序一致(注释),意思就是说不出现B帧,但可以出现非参考的P场,这也是为什么当 nal_ref_idc=0的时候

tempPicOrderCnt = 2 * ( FrameNumOffset + frame_num ) –1的情况。这里保证了参考场的POC始终为偶数,并且大于同帧的另外一个场

代码如下

  case 2: // POC MODE 2if(img->idr_flag) // IDR picture
    {img->FrameNumOffset=0;     //  first pix of IDRGOP, img->ThisPOC = img->framepoc = img->toppoc = img->bottompoc = 0;if(img->frame_num)  error("frame_num != 0 in idr pix", -1020);}else{if (img->last_has_mmco_5){img->PreviousFrameNum = 0;img->PreviousFrameNumOffset = 0;}if (img->frame_num<img->PreviousFrameNum)img->FrameNumOffset = img->PreviousFrameNumOffset + img->MaxFrameNum;else img->FrameNumOffset = img->PreviousFrameNumOffset;img->AbsFrameNum = img->FrameNumOffset+img->frame_num;if(img->disposable_flag)img->ThisPOC = (2*img->AbsFrameNum - 1);elseimg->ThisPOC = (2*img->AbsFrameNum);if (img->field_pic_flag==0)img->toppoc = img->bottompoc = img->framepoc = img->ThisPOC;else if (img->bottom_field_flag==0)img->toppoc = img->framepoc = img->ThisPOC;else img->bottompoc = img->framepoc = img->ThisPOC;}if (!img->disposable_flag)img->PreviousFrameNum=img->frame_num;img->PreviousFrameNumOffset=img->FrameNumOffset;break;

h.264的POC计算相关推荐

  1. H.264中POC类型之探讨

    有 B 图像的场合.POC 表示的是图像显示顺序.由于POC对于参考序列的初始化,重排序及标记关系重大,所以做了如下的分析,以下讨论情况是针对帧编码. pic_order_cnt_type=0的时候: ...

  2. h.264语法结构分析

    NAL Unit Stream Network Abstraction Layer,简称NAL. h.264把原始的yuv文件编码成码流文件,生成的码流文件就是NAL单元流(NAL unit Stre ...

  3. H.264 入门篇 - 01 (Bitstream)

    目录 1.H.264 比特流格式 1.1.起始字段 (Start Code) 1.2.NAL Unit 组成 1.2.1.NAL Unit Header 1.2.2.NAL Unit Payload ...

  4. h.264参考图像列表、解码图像缓存

    1.参考图像列表(reference picture list) 一般来说,h.264会把需要编码的图像分为三种类型:I.P.B,其中的B.P类型的图像由于采用了帧间编码的这种编码方式,而帧间编码又是 ...

  5. H.264参考帧列表、解码图像缓存

    1.参考图像列表(reference picture list) 一般来说,h.264会把需要编码的图像分为三种类型:I.P.B,其中的B.P类型的图像由于采用了帧间编码的这种编码方式,而帧间编码又是 ...

  6. 【H.264】H.264 解析 工具、web解析

    web h264-frame-viewer H264 PARSE 大神写的命令行程序. -H.264 解析 .SPS 解析.PPS 解析. 帧率计算 理论基础: [H.264]SPS 计算帧率 a W ...

  7. sad代价计算_转载:H.264帧内模式选择以及代价计算相关知识

    转自:http://blog.csdn.net/xingyu19871124/article/details/7721374 标签: h.264 优化 算法 c 测试 2012-07-06 10:57 ...

  8. H.264的DTS、PTS、frame_num、poc

    DTS与PTS: 先盗一张网图,解释DTS和PTS. DTS和PTS是解码端或者说播放器的概念,DTS是解码的顺序,PTS是显示的顺序.H264中,如果码流中不包含B帧,码流中所有帧的PTS=DTS. ...

  9. 十一、H.264的Slice Header解析

    GitHub代码地址:点击这里 H.264中的条带(Slice) 1. Slice的概念 我们已经知道,整个H.264的码流结构可以分为两层:网络抽象层NAL和视频编码层VCL.在NAL层,H.264 ...

最新文章

  1. java单例设计模式
  2. Python教程:import 、from import 及from import *
  3. js url传值中文乱码之解决之道
  4. android 判断是否是标点符号_Java 中文字符判断 中文标点符号判断
  5. css - clearfix-清除浮动
  6. centos7 致命错误:curl/curl.h:没有那个文件或目录 #include curl/curl.h
  7. 真正优秀的领导者,无非是做好这2件事
  8. java请求第三方接口
  9. Java List集合排序 Java8 List集合排序方法 Java Lambda集合排序
  10. 博科光纤交换机维护手册
  11. 阿里云CDN回源host理解
  12. UVAOJ 10098 Generating Fast
  13. 固定成本、可变成本、沉没成本、机会成本
  14. 回忆某图,如滔滔江水
  15. Innodb中的事务隔离级别和锁的关系
  16. mysql 1032 1062_MySQL 主从复制 ERROR-1032
  17. 基于Android的看小说APP源码Android本科毕业设计Android小说阅读器、小说APP源码
  18. 【C语言】fwrite 写如0X0A时,自动添加0X0D的解决方法
  19. Chrome浏览器中使用 iframe 嵌入网页导致视频不能全屏的问题解决方法
  20. 计算机老师的作文,电脑,我的好老师作文

热门文章

  1. Android国际化(多语言)实现,支持8.0
  2. 做一个略调皮的个人主页--相册与随笔篇
  3. 字符扫描剑指Offer读书笔记之第二章2字符替换Strut2教程-java教程
  4. HBase MetaStore和Compaction剖析
  5. Java基础学习总结(31)——Java思维导图
  6. Mac系统的JDK8默认安装路径
  7. CAS做单点登陆(SSO)——集成BIEE 11g
  8. iOS-项目打包为ipa文件
  9. 没有好看的 Terminal 怎么能够快乐地写代码
  10. BeautifulSoup安装及其应用