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

pic_order_cnt_type=0的时候:

poc与frame_num没有直接的关系,是显式地出现在bit流中为pic_order_cnt_lsb(PicOderCntMsb 和 PicOderCntLsb分别代表的是POC的高位和低位。H.264中为了提高压缩效率,只对POC的低位进行编码传输,POC的高位不在码流中直接传输,而是通过别的语法元素推导得来。)
pic_order_cnt_lsb只是一个低位的poc,对应的高位PicOrderCntMsb不出现在bit流中,这个需要编码器或者解码器对pic_order_cnt_lsb的情况来进行PicOrderCntMsb的进位。其中MaxPicOrderCntLsb在SPS中可以得到,用于控制进位的。假定MaxPicOrderCntLsb=64,prevPicOrderCntMsb=0有如下情况:

      I   P   B...未出现mmco==5或IDR.....P B B P B B P B B
poc:    0   6   2                          60   56   58   2   62 0 6 2 4
总计 poc   0   6   2                          60   56   58   66 62 64 70 66   68

这里变量prevPicOrderCntLsb应该是以前参考帧的pic_order_cnt_lsb,对于pic_order_cnt_lsb=2的P,现在来计算它的poc, 此时prevPicOrderCntLsb=60,很明显满足条件prevPicOrderCntLsb>pic_order_cnt_lsb&&(prevPicOrderCntLsb-pic_order_cnt_lsb)>=64/2,
由于是参考帧所以其prevPicOrderCntMsb=prevPicOrderCntMsb+64=64,此时TopFiledOrderCnt=64+2=66;
      接着计算pic_order_cnt_lsb=62的B此时prevPicOrderCntMsb=64,而prevPicOrderCntLsb=2,很明显满足prevPicOrderCntLsb<pic_order_cnt_lsb&&(pic_order_cnt_lsb-prevPicOrderCntLsb)>=64/2,此时PicOrderCntMsb=prevPicOrderCntMsb-prevPicOrderCntLsb=64-2=62。由于不是参考帧所以prevPicOrderCntMsb还是保持为64,很明显prevPicOrderCntMsb应该是MaxPicOrderCntLsb的倍数。对于pic_order_cnt_lsb=0的B,上述两种情况都不满足,所以其PicOrderCntMsb=64。
      prevPicOrderCntMsb和prevPicOrderCntLsb在IDR或者mmco=5的时候选择性复位。这里如果考虑要场编码,则有如下情况:

      I   P   B...未出现mmco==5或IDR.....Pt   Pb   Bt   Bb   Bt Bb Pt Pb   Bt   Bb Bt Bb
poc:    0   6   2                          60   61   56   57   58 59 2 3 62   63 0     1
总计 poc   0   6   2                          60    56    58        66    62    64

Pt的poc为60的时候包含了mmco=5,由于他不是一个底场,所以prevPicOrderCntLsb就为60,如果出现在Pt的poc为61的时候包含了mmco=5,则prevPicOrderCntLsb=0;所以在帧编码的时候mmco=5只是复位prevPicOrderCntMsb,而prevPicOrderCntLsb应该不复位。而在场编码的时候mmco=5只有出现在底场的时候复位prevPicOrderCntMsb,prevPicOrderCntLsb为0。保证prevPicOrderCntLsb初始是从顶场开始,且为偶数开始(应该不是简单如此吧,应该还有深入原因,那位想通透的告诉我一声)

pic_order_cnt_type=1的时候:

考虑如下序列情况
        SPS中设置对于帧编码,offset_for_top_to_bottom_field=0;对于场编码           offset_for_top_to_bottom_field=1

序列1:    I    P    B 循环一
frame_num: 0    1    2   
poc:       0    4    2
                  P    B 循环二
frame_num:           2    3   
poc:                 8    6
                  P    B 循环三
frame_num:           3    4   
poc:             12    10

此时对于num_ref_frames_in_pic_order_cnt_cycle=1,num_ref_frames_in_pic_order_cnt_cycle表示IDR后一个循环内参考帧的总数.offset_for_ref_frame[0]=4,offset_for_ref_frame表示IDR后参考帧之间的偏移。

如果要计算poc=12的P帧的POC,如何得到呢?首先已经知道frame_num=3,num_ref_frames_in_pic_order_cnt_cycle=1,offset_for_ref_frame[0]=4,则可以得到
absFrameNum=3,picOrderCntCycleCnt =(3-1)/1=2;frameNumInPicOrderCntCycle=(3-1)%1=0;
expectedDeltaPerPicOrderCntCycle = 0
for( i = 0; i < num_ref_frames_in_pic_order_cnt_cycle; i++ )
expectedDeltaPerPicOrderCntCycle += offset_for_ref_frame[ i ]

则expectedDeltaPerPicOrderCntCycle =4;
expectedPicOrderCnt = picOrderCntCycleCnt * expectedDeltaPerPicOrderCntCycle
for( i = 0; i <= frameNumInPicOrderCntCycle; i++ )
expectedPicOrderCnt = expectedPicOrderCnt + offset_for_ref_frame[ i ]
则expectedPicOrderCnt =12;可以得到
由于是P-slice,此时slice header中
delta_pic_order_cnt[ 0 ]=0;delta_pic_order_cnt[ 1 ]=0;
TopFieldOrderCnt = 12;BottomFieldOrderCnt = 12;

序列2:    I    P    B     B    循环一
frame_num: 0    1    2     2
poc:       0    6    2     4
                  P    B     B    循环二
frame_num:           2    3     3   
poc:                 12    8     10
                  P    B     B    循环三
frame_num:           3    4     4
poc:             18    14 16

此时
对于
num_ref_frames_in_pic_order_cnt_cycle=1,
offset_for_ref_frame[0]=6。
如果要计算poc=16的B帧的POC,如何得到呢?首先已经知道frame_num=4,num_ref_frames_in_pic_order_cnt_cycle=1,offset_for_ref_frame[0]=6,则可以得到
absFrameNum=4-1(因为是B帧不用于参考),picOrderCntCycleCnt =(3-1)/1=2;frameNumInPicOrderCntCycle=(3-1)%1=0;
expectedDeltaPerPicOrderCntCycle =6;
由于offset_for_non_ref_pic=-2*(连续B帧的数量);这里应该是-4
expectedPicOrderCnt =14;可以得到,
此时slice_header中delta_pic_order_cnt[ 0 ]=2,delta_pic_order_cnt[ 1 ]=0;
TopFieldOrderCnt = 16;BottomFieldOrderCnt = 16;

序列2:    I    P    B     P     B B P B B B    循环一
frame_num: 0    1    2     2     3 3 3 4 4 4
poc:       0    4    2     10 6 8 18 12   14   16

P    B     P     B B P B B B    循环二
frame_num:           4    5     5     6 6 6 7 7 7   
poc:                 22    20 28 24 26 36 30   32   34
                  P    B     P     B B P B B B    循环三
frame_num:           7    8     8     9 9 9 10 10   10
poc:             40    38 46 42 44 54   48 50   52
此时
对于
num_ref_frames_in_pic_order_cnt_cycle=3,
offset_for_ref_frame[3]={4,6,8}。
如果要计算poc=54的P帧的POC,如何得到呢?首先已经知道frame_num=9,num_ref_frames_in_pic_order_cnt_cycle=3,offset_for_ref_frame[3]={4,6,8},则可以得到
absFrameNum=9,picOrderCntCycleCnt =(9-1)/3=2;frameNumInPicOrderCntCycle=(9-1)%3=2;
expectedDeltaPerPicOrderCntCycle =18;
expectedPicOrderCnt =18*2+4+6+8=54;可以得到,
此时slice_header中delta_pic_order_cnt[ 0 ]=0,delta_pic_order_cnt[ 1 ]=0;
TopFieldOrderCnt = 54;BottomFieldOrderCnt = 54;
如果要计算poc=50的B帧的POC,如何得到呢?由于是B帧
absFrameNum=10-1=9,picOrderCntCycleCnt =(9-1)/3=2;frameNumInPicOrderCntCycle=(9-1)%3=2;
由于连续B帧数目是变化的取平均值为2,此时offset_for_non_ref_pic=-4,
expectedPicOrderCnt =18*2+4+6+8-4=50;此时slice_header中delta_pic_order_cnt[ 0 ]=0,delta_pic_order_cnt[ 1 ]=0;

pic_order_cnt_type=2的时候:

poc是由frame_num推导出来的,这个比较简单,但是应该注意,在这种情况下不存在连续的非参考图象(注释),且解码输出的顺序和显示输出顺序一致(注释),意思就是说不出现B帧,但可以出现非参考的P场,这也是为什么当nal_ref_idc=0的时候tempPicOrderCnt = 2 * ( FrameNumOffset + frame_num ) – 1的情况。这里保证了参考场的POC始终为偶数,并且大于同帧的另外一个场。

综合三种poc的,类型2应该是最省bit的,因为直接从frame_num获得,但是序列方式限制最大
类型1,只需要一定的bit量sps标志出一些信息还在slice header中表示poc的变化,但是比类型0要节省bit,但是其序列并不是随意的,要周期变化;对于类型0因为要对poc的 lsb进行编码所以用到的bit最多,优点是序列可以随意。

H.264中POC类型之探讨相关推荐

  1. H.264 中很有用的一些概念

    Q:PSNR 峰值信噪比 是根据它来取qp是不是? A:不是 和QP没有直接关系但是QP的选择会影响到PSNR Q: 如果不用率失真最优化,为什么选择SATD+delta×r(mv,mode)作为模式 ...

  2. H.264中的一些易混淆概念

    Q:PSNR 峰值信噪比 Q:是根据它来取qp是不是? A:不是, 和QP没有直接关系, 但是QP的选择会影响到PSNR Q: 如果不用率失真最优化, 为什么选择SATD+delta×r(mv,mod ...

  3. H.264中IDR帧和I帧区别

    IDR(Instantaneous Decoding Refresh)--即时解码刷新.       I和IDR帧都是使用帧内预测的.它们都是同一个东西而已,在编码和解码中为了方便,要首个I帧和其他I ...

  4. H.264中的SPamp;amp;SI帧技术简述

    H.264中的SP&SI帧技术简述 1           应用背景(详细可见文献[1,2])        流间切换.随机接入.错误恢复.快进快退.拼接 2           SP/SI帧 ...

  5. H.264 中 SAD SATD及常见知识点

    H264标准只定义了码流的格式编码器实现是各公司自己的事,只要形成的码流符合标准就行解码器必须按照这个格式来,这样任何符合标准的码流都可以解出来 Q:什么是SAD,SAE,SATD,SSD,SSE,M ...

  6. 八、H.264中的熵编码基本方法、指数哥伦布编码

    GitHub代码地址:点击这里 本节视频免费 1. H.264中的熵编码基本方法 在成功从NAL Unit中获取到语法元素的码流之后,接下来就是对语法元素的码流进行解析.根据我们在前面的博文中所讲述的 ...

  7. H.264中的I_PCM模式

    H.264中的I_PCM模式 I_PCM是一种帧内编码模式,在该模式下,编码器直接传输图像的像素值,而不经过预测和变换.在一些特殊的情况下,特别是图像内容不规则或者量化参数非常低时,该模式比常规的操作 ...

  8. 【H.264/AVC视频编解码技术详解】八、 熵编码算法(2):H.264中的熵编码基本方法、指数哥伦布编码

    <H.264/AVC视频编解码技术详解>视频教程已经在"CSDN学院"上线,视频中详述了H.264的背景.标准协议和实现,并通过一个实战工程的形式对H.264的标准进行 ...

  9. 从下象棋的角度来类比浅析H.264中的像素残差和运动矢量残差

    我酷爱下象棋,经常沉迷其中,不好啊,最近下定决心,尽量少下象棋. 现从下象棋的角度来类比浅析H.264中的像素残差和运动矢量残差. 第一帧: 双方把象棋摆放好,准备开始下,这个画面就是第一帧; (对应 ...

最新文章

  1. 欧盟调查或拖累进程 高通收购NXP一波三折
  2. 一维数组去重处理法二(C语言)
  3. 董明珠自媒体:格力口罩今日开售 上午预约下午抢购
  4. python+flask搭建CNN在线识别手写中文网站
  5. AtCoder Beginner Contest 185
  6. 浅谈ASP.NET客户端回调
  7. iPhone企业应用实例分析之四:技术要点分析(1)
  8. Spring学习之整合Activiti(一)
  9. Vue SSR服务端渲染 vue预渲染
  10. 【VulnHub靶场】——HARRYPOTTER第二部: NAGINI
  11. Pytorch中iter(dataloader)的使用
  12. PMP证书现在还值得考吗?
  13. js 空数组直接赋值与push
  14. 7月7日云栖精选夜读:专访 | 杨强教授谈CCAI、深度学习泡沫与人工智能入门
  15. 服务器tomcat成功运行但是无法在外网访问的解决办法
  16. php pageoffice安装,senman
  17. #企业要求程序员统一电脑桌面,网友:桌面壁纸都不配拥有?
  18. 清华博士生导师亲授:高考志愿计算机/AI专业填报指南
  19. 是否似曾相识?每个开发人员都犯过的15个错误
  20. 小米5 摄像头技术规格

热门文章

  1. sql server 数据库忘记sa账户密码/ 无管理员账户解决办法
  2. 一步步编写操作系统 25 cpu的保护模式
  3. html中点击照片时放大缩小,基于jquery实现一张图片点击鼠标放大再点缩小
  4. linux中sybase删除数据库,Linux_Sybase ASE数据库的常见问题解答,1 数据库占用磁盘空间的形式 - phpStudy...
  5. 【JS 逆向百例】webpack 改写实战,G 某游戏 RSA 加密
  6. java await signal_【Java并发008】原理层面:ReentrantLock中 await()、signal()/signalAll()全解析...
  7. 【HDU - 1559】最大子矩阵 (二维前缀和裸题)
  8. 【CodeForces - 215A】Bicycle Chain (水题)
  9. java的方法调用中分不清_java中不太清晰的知识点
  10. java基本数据类型存储,JAVA - 基本数据类型的存储空间长度