一·参数说明 
这一节阐述的是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_co de=1; img->b_frame_to_co de<=input->successive_Bframe;    
img->b_frame_to_co de++) 

}

z  IntraPeriod或 IDRIntraEnable 为零时toppoc 等于 
2+(img->number-1) * (2*(input->successive_Bframe+1))  
+2* (img->b_frame_to_co de-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_co de-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_co de) 
或 
poc = 2*(input->successive_Bframe+1) 
+ (frame_num – 1 – 1)*2*(input->successive_Bframe+1) 
+ 2*( img->b_frame_to_co de – 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_co de请参见标题一·(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_co de –1);  对于 I 帧或 P 帧,   
其值为 0; 
e)  active_sps->offset_for_non_ref_pic: 
只对 B 帧有用,在 StoredBPictures 为0 时等于–2*input->successive_Bframe,

/
(1) 文件操作参数:#Files

InputFile ="silent.yuv" #输入序列,YUV 4:2:0 
FramesToBeEncoded = 30  #编码图象帧数 
SourceWidth = 352       #图象宽度,必须是16像素的倍数 
SourceHeight = 288      #图象高度,必须是16像素的倍数 
TraceFile = "silent_enc2.txt" #跟踪文件 
ReconFile = "silent_rec_RD2.yuv" #恢复文件 
OutFile = "silent.26l" #输出文件

(2) 编码控制参数: #Encoder Control

IntraPeriod = 0 #I帧的周期(0=只有第一帧为I帧) 
QPFirstFrame = 15 #第一帧量化步长(0-31) 
QPRemainingFrame = 25 #其它帧量化步长(0-31) 
FrameSkip = 0 #输出图象采样间隔(如2表示每三帧取一帧) 
MVResolution = 1 #运动矢量精度:0:1/4像素精度,1:1/8像素精度 
UseHamard = 0 #Hadamard变换(0=无效,1=有效) 
SearchRange = 16 #最大搜索范围 
NumberRefereceFrames = 1 #用于帧间预测的参考帧数(1-5) 
MbLineIntraUpdate = 0 #错误鲁棒性0:无效,N:每N帧进行一次帧内编码GOB 
InterSearch16x16 = 1 #帧间搜索块16x16大小(0=无效,1=有效) 
InterSearch16x8 = 1 #帧间搜索块16x8大小(0=无效,1=有效) 
InterSearch8x16 = 1 #帧间搜索块8x16大小(0=无效,1=有效) 
InterSearch8x8 = 1 #帧间搜索块8x8大小(0=无效,1=有效) 
InterSearch8x4 = 1 #帧间搜索块8x4大小(0=无效,1=有效) 
InterSearch4x8 = 1 #帧间搜索块4x8大小(0=无效,1=有效) 
InterSearch4x4 = 1 #帧间搜索块4x4大小(0=无效,1=有效)

(3) 定义输入参数结构体InputParameters 
typedef struct 

int no_frames; //编码帧数 
int qp0; //第一帧量化步长 
int qpN; //其余帧量化步长 
int jumpd; //输出图象采样间隔(如2表示每三帧取一帧) 
int mv_res; //运动矢量精度:0:1/4像素精度1:1/8像素精度 
int hadamard; //0:普通1:利用4x4Hadamard变换,计算绝对变换误差 
int search_range; //搜索范围 - 基于16x16块整像素搜索,搜索窗是以预测矢量为中心,对于8x8和4x4块的搜索范围是基于16x16块的1/2

int no_multpred; //1:仅以前一帧做参考,2:以前一帧或大前帧,最多5个参考帧 
int img_width; //图象宽度 
int img_height; //图象高度 
int yuv_format; //YUV采样比(0=4:0:0,1=4:2:0,2=4:2:2,3=4:4:4) 
int color_depth; //每个像素所需的位数,一般为8bit/pel 
int intra_upd; //错误鲁棒性(0:无效,N:每N帧进行一次帧内编码GOB) 
int blc_size[8][2]; //帧间搜索的不同大小块数组 
int slice_mode; //片编码模式 
int UseConstrainedIntraPred; //0:帧间宏块采用帧内预测 1:无效 
int infile_header; //输出文件的头信息长度 
char infile[100]; //YUV4:2:0输入文件 
char outfile[100]; //H26L压缩输出码流 
char ReconFile[100]; //重建图象文件 
char TraceFile[100]; //跟踪输出文件 
int intra_period; //帧内编码周期 
//B pictures 
int successive_Bframe; //B帧编码数目 
int pqB; //B帧编码量化步长 
//SP Pictures 
int sp_periodicity; //SP帧周期 
int qpsp; //SP帧预测误差量化步长 
int qpsp_psed; //SP帧预测量化步长 
int InterSearch16x16; //搜索块大小 
int InterSearch16x8; 
int InterSearch8x16; 
int InterSearch8x8; 
int InterSearch8x4; 
int InterSearch4x8; 
int InterSearch4x4; 
}InputParameters;

JM、H.264中一些参数的设置和含义相关推荐

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

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

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

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

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

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

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

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

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

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

  6. H.264中的I_PCM模式

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

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

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

  8. H.264中的熵编码算法(主讲指数哥伦布编码)

    以下文章参考于殷文杰的博客. https://yinwenjie.blog.csdn.net/article/details/52301584 1 熵编码基本概念 1)"熵"这一概 ...

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

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

最新文章

  1. QGC添加显示多架无人机飞行轨迹
  2. 细思极恐!未来百万人将下岗十大职业将消失
  3. [导入]二叉树(C#数据结构四)
  4. 【转】wordpress/wp-includes目录文件概述
  5. php sorcket_PHP: Sockets - Manual
  6. java蓝桥杯 试题-基础练习-十六进制转八进制
  7. Windows Server 2012 R2安装体验
  8. 【C语言】数据结构C语言版 实验5 递归
  9. 为何要使用大数据可视化平台
  10. 设计模式09-组合模式
  11. java oom分析_JAVA各种OOM代码示例与解决方法
  12. android版here地图下载,HERE WeGo地图安卓版
  13. 第二次作业-语言和文法
  14. referenced before assignment
  15. 用CMSS指令提高串口群发短信的效率
  16. 海康摄像机3D PTZ功能,拍照功能
  17. 二十三、正则表达式中的“r”含义
  18. webView加载全景图
  19. 关于云ERP系统的错误看法
  20. 服务器如何数据备份?

热门文章

  1. Elsevier latex模板 三级标题斜体改直体
  2. 《管理办法》正式施行,银保机构消费者个人信息保护圈重点!
  3. 修改远程服务器的登录密码
  4. 关于数据库中的一些概念
  5. 单例模式中懒汉式和饿汉式实现
  6. JS中DOM元素的操作
  7. 【最长回文子串】Manacher算法详解
  8. 如何明晰定位与责任_认清自己的责任——定位在哪里就要对哪里负责
  9. 多线程编程(一):加减计算
  10. unique_lock与lock_guard区别