JM8.5中的7种宏块模式问题

本文解析了H.264编码中宏块模式的配置选项及其对应的数值常量,并介绍了宏块与亚宏块的划分方式及运动估计的处理方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Outline:

1、  CFG文件中有关可变尺寸宏块模式的相关选项

2、  7种宏块模式对应的数值常量

3、  7种宏块模式被分成宏块和亚宏块

4、  如何对宏块和亚宏块的运动估计,采用一个共同的函数来处理

5、  遗留问题

 

 

1CFG文件中有关可变尺寸宏块模式的相关选项

############################################################################### #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×161     16×82       8×163       8×84    8×45     4×86      4×47 

以上的数值常量的rdopt.cencode_one_macroblock()中的valid[]数组和mode变量中会用到另外在mv_search.cPartitionMotionSearch()中的blocktype变量也会用到。

 

3、   7种宏块模式被分成宏块和亚宏块

16x16, 16x8, 8x16(,8×8)被称为宏块级,而8×88×44×84×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信箱发了邮件,期盼您能够回复。非常感谢
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值