JM中的一些问题总结

关于JM93的compute_colocated函数

1、为什么用到RSD这个宏?
#define RSD(x) ((x&2) ? (x|1) : (x&(~1)))
关于这个宏的使用协议中是否有相应的说明?
2、storable_picture结构体中ref_idx, re_pic_id, ref_id有什么区别?
int  ***    ref_idx;       //!< reference picture   [ list ][subblock_x][subblock_y]
int64 ***    ref_pic_id;    //!< reference picture identifier [ list ][subblock_x][subblock_y]
                             //   (not  simply index)
int64 ***    ref_id;    //!< reference picture identifier [ list ][subblock_x][subblock_y]
3、 compute_coloated (Mbuffer.c)函数中  下面这一段在协议中是否相应部分 ?

p->moving_block[i][j] =

!((!p->is_long_term &&((p->ref_idx[LIST_0][i][j] == 0) &&

(abs(p->mv[LIST_0][i][j][0])>>1 == 0) &&

(abs(p->mv[LIST_0][i][j][1])>>1 == 0))) ||

((p->ref_idx[LIST_0][i][j] == -1) &&

(p->ref_idx[LIST_1][i][j] == 0) &&

(abs(p->mv[LIST_1][i][j][0])>>1 == 0) &&

(abs(p->mv[LIST_1][i][j][1])>>1 == 0)));

解答:RSD的作用是计算对应坐标
如下图(借用标准的图6-10)
当direct_8x8_inference_flag==1时,
0、1、2、3的mv, 都要用0的mv
4、5、6、7的mv, 都要用5的mv
8、9、10、11的mv, 都要用10的mv
12、13、14、15的mv, 都要用15的mv

通过RSD对每个4x4块的坐标计算
对0、1、2、3的坐标, RSD计算的结果是0的坐标
对4、5、6、7的坐标, RSD计算的结果是5的坐标
对8、9、10、11的坐标, RSD计算的结果是10的坐标
对12、13、14、15的坐标, RSD计算的结果是15的坐标

 

JM 代码中宏块类型宏定义的说明 #define P8x8 8 #define I4MB 9 #define I16MB 10 #define IBLOCK 11 #define SI4MB 12 #define MAXMODE 15 #define IPCM 14

这些是宏块类型的一个集合概念。这些类型的定义主要是代码作者本人对算法结构的安排,在标准中是找不到的。但它们与标准(200503版)的7-11、7-12、7-13、7-14四个表里的 mb_type 有对应关系。这四个表里的 mb_type 是实际码流里的宏块类型。JM 解码器在解码时候会把那些实际的宏块类型转换成上面那些宏定义。也就是按具体宏块类型把宏块进行归类。想了解更详细,请看 JM 解码器里的 interpret_mb_mode_I、 interpret_mb_mode_P、interpret_mb_mode_B 三个函数。在这三个函数以前,mb_type 是实际的值(也就是四个表格里的mb_type),经过这三个函数的解析,就变成上面的这些宏定义的类型了。例如:#define I16MB 10 表示宏块为帧内16*16,其实对应的是表7-11第三行到倒数第二行的所有宏块,因为这些宏块都是帧内16*16类型。本来从码流中读出来的他们的 mb_type 值本来是 1 到 24 (即在进入interpret_mb_mode_I 函数前),但经过 interpret_mb_mode_I 函数解析之后,这些宏块的 mb_type 值都被改变成了 10。其他宏定义也是同样道理。 【注】:以上过程仅为 JM 处理过程。其他H.264代码可能并非如此,这主要决定于算法流程

 

 

如何设置JM编码器分片参数

总是有很多人问片和片组怎么设置,其实编码配置文件写得很清楚。
SliceMode             =  0   # Slice mode (0=off 1=fixed #mb in slice 2=fixed #bytes in slice 3=use callback)
正如注释所说:
值为 0,表示不采用分片。也就是一个片组为一个片,如果不采用片组那么就是一幅图像为一个片。
值为 1,表示将每 SliceArgument 个宏块分为一个片;
值为 2,表示将每 SliceArgument 个字节分为一个片。(我没有试过这种方式,但我猜测可能这只是一个参考值,并不可能真的按这样分。实际分可能是按照多少个宏块的字节数加起来最接近这个设定值就将多少个宏块分为一个片);
值为 3,我也不知道是什么意思,猜测可能是根据解码器或者其他什么的反馈信息来确定。这样根据反馈信息可以更好适应不同网络环境下抗错能力。
SliceArgument         = 50   # Slice argument (Arguments to modes 1 and 2 above)
正如注释所说:
该参数是与上面的参数联合使用。即如果 SliceMode = 1,该参数表示将多少个 MB 分为一个片;如果 SliceMode = 2,该参数表示将近似多少个字节分为一个片。
num_slice_groups_minus1 = 0  # Number of Slice Groups Minus 1, 0 == no FMO, 1 == two slice groups, etc.
正如注释所说:
值为 0 表示不采用 FMO ,也就是不采用片组;值为 1 表示一幅图像分两个片组;依此类推。
SliceGroupConfigFileName          = "sg0conf.cfg"   # Used for slice_group_map_type 0, 2, 6
正如注释所说:
当采用 0、2、6 种片组组织形式时,该参数所指定的文件来决定一个片组的起止宏块号;

另外,提醒大家时刻清楚的是:
H.264 是先对一幅图像分片组,然后在每个片组中再分片。在 JM 中一幅图像可以只分片,而不启用片组(也就是不启用 FMO),此时一幅图像默认为一个片组。

 

2011年5月9日18:51:41

帧内模式的预测

在JM代码中有一个mostProbableMode的变量, 这个变量表示的是和帧内模式预测有关,mostProbableMode的值是按下面的方法得到的: most probable mode(MPM)左边相邻块A和上边相邻块B 的预测模式中的较小的

这样,如果当前的模式和MPM是一样的,这样我们只需要要用一位来标示这个就行了,而不用传输具体的模式了.

理解listX数组

对于listX可以这么理解StorablePicture *listX[6][ref_frame]; 66个参考列表,ref_frame是参考帧的数目,每一个listX[i][j]中存的是StorablePicture*指针

所以我们可以这么理解,listX是6个列表, 每一个列表中存放的是一个指针(StorablePicture**), 该指针指向一个内存区域, 这个内存区域存储是该表中参考帧, 但是我们不直接存参考帧, 我们在这儿存储的是参考帧的指针(StorablePicture*)

至于6个列表中到底存放了多少个参考帧, 这个是由数组lsitXsize决定的, 这个lsitXsize[6]数组就是用来存储对应列表大小的

 

posted @ 2012-07-31 15:09  Mr.Rico  阅读(...)  评论(...编辑  收藏