Outline:
1、 CFG文件中有关可变尺寸宏块模式的相关选项
2、 7种宏块模式对应的数值常量
3、 7种宏块模式被分成宏块和亚宏块
4、 如何对宏块和亚宏块的运动估计,采用一个共同的函数来处理
5、 遗留问题
1、CFG文件中有关可变尺寸宏块模式的相关选项
############################################################################### #Encoder Control
###############################################################################
…
InterSearch16x16 = 1 # Inter block search 16x16 (0=disable, 1=enable)
InterSearch16x8 = 1 # Inter block search 16x8 (0=disable, 1=enable)
InterSearch8x16 = 1 # Inter block search 8x16 (0=disable, 1=enable)
InterSearch8x8 = 1 # Inter block search 8x8 (0=disable, 1=enable)
InterSearch8x4 = 1 # Inter block search 8x4 (0=disable, 1=enable)
InterSearch4x8 = 1 # Inter block search 4x8 (0=disable, 1=enable)
InterSearch4x4 = 1 # Inter block search 4x4 (0=disable, 1=enable)
解释:
各种宏块尺寸可以在程序外部进行选择。
…
2、 7种宏块模式对应的数值常量
各种宏块模式对应的数值常量如下:
16×16-1 16×8-2 8×16-3 8×8-4 8×4-5 4×8-6 4×4-7
以上的数值常量的rdopt.c的encode_one_macroblock()中的valid[]数组和mode变量中会用到,另外在mv_search.c的PartitionMotionSearch()中的blocktype变量也会用到。
3、 7种宏块模式被分成宏块和亚宏块
16x16, 16x8, 8x16(,8×8)被称为宏块级,而8×8,8×4,4×8,4×4被称为亚宏块级。
所用到的函数是:encode_one_macroblock(),rdopt.c
该函数的作用是编码一个宏块(包括帧间、帧内、帧内预测的方式)。
其中重要的程序段如下:
…
//宏块级运动估计
//===== MOTION ESTIMATION FOR 16x16, 16x8, 8x16 BLOCKS =====
for (min_cost=1<<20, best_mode=1, mode=1; mode<4; mode++)
{
if (valid[mode])//对应于程序外部(即CFG文件中)的设置
{
//对于16×16,MB只分一个块;对于16×8和8×16,MB被分成两个块
for (cost=0, block=0; block<(mode==1?1:2); block++)
{
//块匹配!!!lambda_motion用来求运动矢量消耗的码率
PartitionMotionSearch (mode, block, lambda_motion);
…
//亚宏块级运动估计
if (valid[P8x8])
{
…
//===== LOOP OVER POSSIBLE CODING MODES FOR 8x8 SUB-PARTITION =====
for (min_cost8x8=(1<<20), min_rdcost=1e30, index=(bframe?0:1); index<5; index++)
{
if (valid[mode=b8_mode_table[index]])//b8_mode_table[6] = {0, 4, 5, 6, 7};
{
curr_cbp_blk = 0;
if (mode==0) //--- Direct Mode ---
{
…
} // if (mode==0)
else
{
//--- motion estimation for all reference frames ---
PartitionMotionSearch (mode, block, lambda_motion);
…
NOTE:从上面程序段中可以看出JM8.5中对7种宏块模式是采用全部遍历的方式,所以导致的计算复杂度很高。
4、 如何对宏块和亚宏块的运动估计,采用一个共同的函数来处理
从3中的程序可以看到,对于宏块和亚宏块级的运动估计,都采用了一个共同的函数:PartitionMotionSearch(), mv_search.c
其中重要的程序段如下:
……
//各种宏块模式下的子块的起始偏移量,相对4*4块来讲,这有利于运动矢量的存放
//[5]表示宏块的类型,[4]表示各种类型下的子块序号,最多子块情况为P8X8模式下有4个
static int bx0[5][4] = {{0,0,0,0}, {0,0,0,0}, {0,0,0,0}, {0,2,0,0}, {0,2,0,2}};
static int by0[5][4] = {{0,0,0,0}, {0,0,0,0}, {0,2,0,0}, {0,0,0,0}, {0,0,2,2}};
……
int parttype = (blocktype<4?blocktype:4);//亚宏块的parttype都设为4
//step_?是用来求4*4块级别的步长,
//由于parttype和blocktype的区别使得两组步长之间存在微妙的差异,为下面的循环做好了铺垫
int step_h0 = (input->blc_size[ parttype][0]>>2);
int step_v0 = (input->blc_size[ parttype][1]>>2);
int step_h = (input->blc_size[blocktype][0]>>2);
int step_v = (input->blc_size[blocktype][1]>>2);
……
//===== LOOP OVER SUB MACRO BLOCK partitions
//这里对于亚宏块的循环是自适应的,
//假如小于8*8块尺寸时,自动采取循环
for (v=by0[parttype][block8x8]; v<by0[parttype][block8x8]+step_v0; v+=step_v)
{
pic_block_y = img->block_y + v;
for (h=bx0[parttype][block8x8]; h<bx0[parttype][block8x8]+step_h0; h+=step_h)
{
……
<script src="http://pagead2.googlesyndication.com/pagead/show_ads.js" type=text/javascript> </script>
发表于 @ 2004年11月08日 15:37:00|评论(10 )|编辑
新一篇: JM8.5中的多参考帧问题 | 旧一篇: H.264码流结构
- 1500元三大java项目特训特惠班
- 周末班和脱产班 itcastbbs、供应链、进销存三大项目

- Linux 日志文件系统剖析大全
- 典型的文件系统 日志文件系统的未来

评论
# guest 发表于2005-08-24 15:10:00 IP: 211.100.4.*-
在mv_search.c中函数SetMotionVectorPredictor的一段代码该如何理解,谢谢了!
if (mb_y > 0)
{
if (mb_x < 8) // first column of 8x8 blocks
{
if (mb_y==8)
{
if (blockshape_x == 16) block_c.available = 0;
else block_c.available &= 1;
}
else
{
if (mb_x+blockshape_x != 8) block_c.available &= 1;
else block_c.available = 0;
}
}
else
{
if (mb_x+blockshape_x != 16) block_c.available &= 1;
else block_c.available = 0;
}
}
# autumn 发表于2005-10-19 10:32:00 IP: 211.100.21.*-
李老师:您好
您说原来做过帧内预测,这里想请教一个问题:
我现在是在看JM的intra帧内预测,我发现在在编I帧时,其实最主要就在encode_one_macroblock ()中给mode= mb_mode_table[index]赋值,index 分别为0~8时对mode应着0, 1, 2, 3, P8x8, I16MB, I4MB, I8MB, IPCM.然后在mode为I16MB, I4MB, I8MB, IPCM时,进入函数compute_mode_RD_cost(),这个函数应该就是在编I帧最消耗时间的地方,我觉得应该是在I16MB, I4MB, I8MB, IPCM中选择一种模式,是这样吗?
在函数compute_mode_RD_cost()中有"mb_type=mode",而在I片中mb_type的定义好象和I16MB, I4MB, I8MB, IPCM对应不上,I16MB, I4MB, I8MB, IPCM到底代表什么意义呢?能否说一下compute_mode_RD_cost()方面的信息.
希望得到您的解答,非常感谢!
# blueautumn2000 发表于2005-10-19 15:17:00 IP: 211.100.21.*-
李老师:您好
您说原来做过帧内预测,这里想请教一个问题:
我现在是在看JM的intra帧内预测,我发现在在编I帧时,其实最主要就在encode_one_macroblock ()中给mode= mb_mode_table[index]赋值,index 分别为0~8时对mode应着0, 1, 2, 3, P8x8, I16MB, I4MB, I8MB, IPCM.然后在mode为I16MB, I4MB, I8MB, IPCM时,进入函数compute_mode_RD_cost(),这个函数应该就是在编I帧最消耗时间的地方,我觉得应该是在I16MB, I4MB, I8MB, IPCM中选择一种模式,是这样吗?
而函数中有"mb_type=mode",而在I片中mb_type的定义好象和I16MB, I4MB, I8MB, IPCM对应不上,I16MB, I4MB, I8MB, IPCM到底代表什么意义呢?
希望得到您的解答,非常感谢!
# 李世平 发表于2005-10-25 14:54:00 IP: 211.100.21.*-
to blueautumn2000 ,你好,
我估计你看的是jm90之后的版本,我以前看的是jm86不包含亮度8x8,不过我估计整个编码框架应该还是一致的。
1、jm86中是RDCost_for_macroblocks()这个函数来处理宏块层模式之间的选择,我猜测和你说的compute_mode_RD_cost()函数一致,这个函数内部又调用了各种帧内块(i4x4,i16x16)的模式选择,从局部来讲,帧内模式选择中最耗时的时i4x4的9中预测模式的选择,从帧内来讲,可以说耗时部分都集中在RDCost_for_macroblocks函数中
2、jm86中,是有个表进行转换的,这个问题我估计你看仔细一点就能找到原因。
# olive 发表于2006-01-06 19:47:00 IP: 218.249.179.*-
李老师你好:
我在jm里面的encoder.cfg里面将rdoptimazation选择为with losses时,在编码调试的时候,发现亮度的PSNR值一下子降下去了。是不是编码端模拟丢包了?
谢谢你,李老师。
# xletow 发表于2006-04-27 21:58:00 IP: 218.81.158.*-
李先生:
你好,当mode=2是,宏块对应2个16X8的子块儿,也就是每一块对应1个运动矢量。我单步执行时,发现是8个,有人说是为了编程方便采用每4X4块一个矢量存放,这8个是相等的,且为了后续的滤波,这是怎么回事呢?谢谢!
# jsdadong 发表于2006-04-28 11:36:00 IP: 61.183.67.*-
Mr. lee:
你好!
JM86以后的版本是否已经禁止使用了LA-RDO?设置文件中的lossrateA好像已经没什么作用了。
另外,JM86中的LA-RDO好像也不完善,设置lossrateA为任何值,结果竟然都一样!
是否是这样的呢?
# 李世平 发表于2006-04-29 10:08:00 IP: 192.168.8.*-
to olive :
不清楚
TO xletow
是这样的,
原因就是为了编程实现上的方便。
to jsdadong :
对的,loss mode rdo在jm86中就没有完整实现的。
# joy 发表于2008-05-07 10:19:45 IP: 158.132.21.*-
李先生您好:
请问在解码时,一个宏块有几个运动矢量?是每个4*4对应一个,还是8*8,还是一个宏块只有一个?
谢谢您!
2008-06-05 23:15:52作者回复-
每个4*4对应一个
# qu 发表于2008-05-12 16:23:13 IP: 219.149.11.*-
您好,您能详细解释一下PNGARG宏的定义及实现方法吗?我给你的icebug@126.com信箱发了邮件,期盼您能够回复。非常感谢