作者:jogh.264   参考代码 JM86
一·参数说明
这一节阐述的是encoder.cfg 中的参数对编码过程的影响
要注意的是encoder.cfg 中的参数跟input 结构体中的变量是一一对应的
 
?  StartFrame:从视频流的第几帧开始编码
?  FramesToBeEncoded:指明了除去 B帧后将要被编码的帧数
input->no_frames = FramesToBeEncoded
?  FrameSkip:指明了编码过程中跳过的帧数,中间有 B 帧也算跳过一帧。
?  NumberBFrames:相邻 I、P帧或相邻的 P帧之间的 B 帧个数,必须有
                         NumberBFrames< FrameSkip
input->successive_Bframe = NumberBFrames
?  IntraPeriod:I 帧出现的频率。若 IntraPeriod="3",则每 3 帧(不含 B 帧)中有一 I 帧;
           IntraPeriod="0" 时只有第一帧是 I 帧。
?  IDRIntraEnable:此值为1时每个 I帧都是 IDR,否则只有第一个 I帧是 IDR。
 
举例:在 StartFrame="0"
         FramesToBeEncoded="5"
         FrameSkip="3"
         NumberBFrames="2"
         IntraPeriod="3"
         IDRIntraEnable="1"
       的情况下编码情况如下,其中红色代表 IDR 帧 
表 1
视频流  0  1  2  3  4  5 6 7 8 9 10 11 12 13 14  15  16  17
编码流  I  B  B    P  B B   P B B   I B B    P  
编码顺序  0  2  3    1  5 6   4 8 9   7 11 12    10  
二·pic_order_cnt_type 为 0 的情况
这种情况下显式的计算 POC
(1)  编码端 I 帧或 P 帧 toppoc 的计算
这个过程在 main()函数的组循环
    “for (img->number=0; img->number < input->no_frames; img->number++){ }”
中实现
z  IntraPeriod或 IDRIntraEnable 为零时
这种情况下只有第一个 I 帧是 IDR 帧,比较简单。对于 I帧或 P 帧,其顶场的 POC 为
          (img->number) * (2*(input->successive_Bframe+1)) z  IntraPeriod和 IDRIntraEnable 都不为零时
这种情况下每个 I 帧都是 IDR 帧,其 POC 必须设置为零, I帧出现的频率为 IntraPeriod,
故其 toppoc为
    (img->number % input->intra_period) * (2*(input->successive_Bframe+1))
z  说明:
原程序中使用了宏定义 IMG_NUMBER
    “#define IMG_NUMBER (img->number - start_frame_no_in_this_IGOP)”
通过搜start_frame_no_in_this_IGOP可知这个变量在NumberOfFrameInSecondIGOP为0
(encoder_main.cfg 中就是这样设置的)时恒为 0,故有
           IMG_NUMBER = img->number
(2)  编码端 B帧 POC 的计算
由表一可知,在编完一 I 帧或 P 帧之后才开始对它前面的 B帧进行编码
 
  for (img->number=0; img->number < input->no_frames; img->number++)
  {
  ……I,P 帧编码……
  if ((input->successive_Bframe != 0) && (IMG_NUMBER > 0))  
{
    ……
    for(img->b_frame_to_code=1; img->b_frame_to_code<=input->successive_Bframe;   
                                                  img->b_frame_to_code++)
   {
   }
 
z  IntraPeriod或 IDRIntraEnable 为零时toppoc 等于
     2+(img->number-1) * (2*(input->successive_Bframe+1)) 
       +2* (img->b_frame_to_code-1)
a)  第一个 2 指得是 IDR 的两个场;
b)  img->number要减一是因为要对当前帧(img->number)前面的 B帧进行编码;
 
z  IntraPeriod和 IDRIntraEnable 都不为零时 toppoc等于
    2+(img->number % input->intra_period-1) * (2*(input->successive_Bframe+1))
    +2* (img->b_frame_to_code-1)
IDR 帧前面
(3)  toppoc 到 pic_order_cnt_lsb 的转化
        img->pic_order_cnt_lsb
       =img->toppoc &
        ~((((unsigned int)( –1)) << (log2_max_pic_order_cnt_lsb_minus4+4)))
 
z  (unsigned int)(-1)的十六进制形式是 0xffffffff,即它的每一位都是 1;
z  log2_max_pic_order_cnt_lsb_minus4+4是图象数目(包括 B 帧)最大值的位数 z  当 toppoc >0时,img->pic_order_cnt_lsb=img->toppoc
当 toppoc <0时,img->pic_order_cnt_lsb= max_pic_order_cnt+ img->toppoc
其中 max_pic_order_cnt=1<<( log2_max_pic_order_cnt_lsb_minus4+4)
z  疑问:
不知道 toppoc 到 pic_order_cnt_lsb 这个过程有什么意义;
POC 的值会从 0 变到很大,为什么不对它进行熵编码;
(4)  解码端 toppoc 的恢复
  此过程在函数 decode_poc 中执行。其思想是对于 IDR 前的 B 帧
            Toppoc = pic_order_cnt_lsb - max_pic_order_cnt
否则 
               Toppoc = pic_order_cnt_lsb
是否减去 max_pic_order_cnt 由变量 PicOrderCntMsb 决定,对于 IDR 前的 B 帧
           PicOrderCntMsb = (– max_pic_order_cnt)
否则
           PicOrderCntMsb = 0
到这就不难理解 PicOrderCntMsb 的含义了, PicOrderCntMsb 反映了 toppoc的值是否小于 0。
至于另外两个参数:PrevPicOrderCntMsb 总是为 0;PrevPicOrderCntLsb 在当前图象是 IDR
或 IDR 前(视频流中)的 B 帧时为0,否则等于前一图象(编码序列中)的 PicOrderCntLsb。 
三·pic_order_cnt_type 为 1 的情况
这种情况下通过 frame_num来计算 POC
(1)frame_num 简介
参考《毕厚杰》7.3.4 节中 frame_num 条款的解释,对于表 1 中的图象序列,其 frame_num     
的值参考如下:
 
表 2
视频流  0  1  2  4  5 6 8 9 10 12 13 14  16
编码流  I  B  B  P  B B P B B I B B P
编码顺序  0  2  3  1  5 6 4 8 9  7 11 12  10
frame_num  0  2  2  1  3 3 2 1 1  0 2 2 1
poc  0  2  4  6  8 10 12 -4 -2 0 2 4 6
 
(2)算法思想以及其解码端的实现
z  对于 IDR 帧,poc = 0;
z  对于 I 帧或P 帧
      poc = frame_num*2*(input->successive_Bframe+1)
或  
      poc = 2*(input->successive_Bframe+1)
           + (frame_num – 1)*2*(input->successive_Bframe+1) 解码端实现
      poc = img->ExpectedPicOrderCnt
           + img->delta_pic_order_cnt[0]   (在 I,P 帧下为 0)
z  对于 I 帧或P 帧之前的 B 帧(视频流中)
            poc = (frame_num – 1)*2*(input->successive_Bframe+1)
           – 2*(input->successive_Bframe+1 – img->b_frame_to_code)

      poc = 2*(input->successive_Bframe+1)
           + (frame_num – 1 – 1)*2*(input->successive_Bframe+1)
           + 2*( img->b_frame_to_code – 1)
           – 2*input->successive_Bframe
解码端的实现
      poc = img->ExpectedPicOrderCnt
           + img->delta_pic_order_cnt[0]
           + active_sps->offset_for_non_ref_pic
z  变量说明
a)  其中 img->b_frame_to_code请参见标题一·(2)
b)  img->disposable_flag = (nalu->nal_reference_idc = = 0),而 nal_reference_idc 只在 B 帧时
为0,即img->disposable_flag只在B帧时为1。这也是在B帧情况下img->AbsFrameNum
要比 I 帧或P 帧多减去一个 1 的原因。
c)  其它变量参见下面小题;
(3)编码端参数设置
a)  img->num_ref_frames_in_pic_order_cnt_cycle:
    这个参数在 init_poc( )函数中设置为 1 后就再没改动过;
b)  img->offset_for_ref_frame[0]  :
   在 StoredBPictures为0 时等于 2*(input->successive_Bframe+1);
c)  img->offset_for_ref_frame[1]  :
   没什么用,264 头文件中不会保存此变量;
d)  img->delta_pic_order_cnt[0]  :
   这个变量只对 B 帧有用,等于 2*(img->b_frame_to_code –1);  对于 I 帧或 P 帧,  
         其值为 0;
e)  active_sps->offset_for_non_ref_pic:
   只对 B 帧有用,在 StoredBPictures 为0 时等于–2*input->successive_Bframe,

264中 POC的计算方法相关推荐

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

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

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

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

  3. 考究Hadoop中split的计算方法

    Hadoop中block块大小和split切片大小会影响到MapReduce程序在运行过程中的效率.map的个数.在本文中,以经典入门案例WordCount为例,通过debug的方式跟踪源代码,来分析 ...

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

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

  5. H.264中的I_PCM模式

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

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

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

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

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

  8. mysql key_len_浅谈mysql explain中key_len的计算方法

    mysql的explain命令可以分析sql的性能,其中有一项是key_len(索引的长度)的统计.本文将分析mysql explain中key_len的计算方法. 1.创建测试表及数据 CREATE ...

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

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

最新文章

  1. slub object 内存布局
  2. 回到顶部最简单的JQuery实现代码
  3. vs2013 无法打开 源 文件 SDKDDKVer.h
  4. 十一届蓝桥杯国赛 本质上升序列-dp
  5. shell入门(一)
  6. ASP.NET MVC:mvc pattern
  7. 华南理工会计学计算机答案,2020华工会计学原理平时作业答案
  8. AMS1117手册解析
  9. 02web前端笔试题
  10. python5.2、输出格式控制 - 摄氏-华氏温度换算
  11. oracle dba_hist_sql,从dba_hist_sqlstat视图中查找过去时段最占用资源的会话
  12. 苹果企业开发账号申请三步走
  13. struts2架构网站漏洞修复详情与利用漏洞修复方案
  14. 经常喝茶、喝咖啡与喝白开水的人,身体都怎么样了?老实跟你说
  15. U8采购入库单API接口示例(参照采购到货)
  16. 尚在人间,何处不青春
  17. 程序猿的自救 从零备考NSCA/CSCS 2 阻力运动生物力学
  18. 前端加密方法sha256.js源码+用法(亲测可用)
  19. 【方案】去哪儿网徐磊:如何利用开源技术构建日处理130亿+的实时日志平台?...
  20. shell脚本中-eq、-ne、-gt、-ge、-lt、-le

热门文章

  1. 第六节:框架搭建之EF的Fluent Api模式的使用流程
  2. 美团科技 Java工程师_美团Java工程师面试题(2018秋招)
  3. *【POJ - 2796】 Feel Good (前缀和优化+单调栈维护)
  4. 【牛客 - 272B】Xor Path(树上操作,路径异或值)
  5. 【HDU - 1009 】FatMouse' Trade (贪心)
  6. 【HDU - 1455】Sticks (dfs + 剪枝)
  7. 对short类型,输出结果不一样?
  8. java word转html 乱码 poi,java word转html poi
  9. php 字符串比较的规则,PHP字符串比较函数strcmp()与strcasecmp()的用法介绍
  10. java面向方面编程_面向方面编程的介绍----基本概念