x264_analyse_update_cache 内部各种函数注释

 

转载于:http://blog.sina.com.cn/s/blog_6938cd0501011qk1.html


x264_analyse_update_cache <wbr>内部各种函数注释


staticinlinevoidx264_mb_cache_mv_p8x8(x264_t*h,x264_mb_analysis_t*a,inti)

{

constintx=2*(i%2);

constinty=2*(i/2);

 

switch(h->mb.i_sub_partition[i])//之前应该有一个遍历i的循环

{

caseD_L0_8x8:

x264_macroblock_cache_mv_ptr(h,x,y,2,2,0,a->l0.me8x8[i].mv);

break;

caseD_L0_8x4:

x264_macroblock_cache_mv_ptr(h,x,y+0,2,1,0,a->l0.me8x4[i][0].mv);//me8x4[i][0]第一维应该是表示16*16的第几个8*8块,而第二维的[0]应该是表示是8*4的上半块,如果是[1]表示的就是下半块了。

x264_macroblock_cache_mv_ptr(h,x,y+1,2,1,0,a->l0.me8x4[i][1].mv);

break;

caseD_L0_4x8:

x264_macroblock_cache_mv_ptr(h,x+0,y,1,2,0,a->l0.me4x8[i][0].mv);

x264_macroblock_cache_mv_ptr(h,x+1,y,1,2,0,a->l0.me4x8[i][1].mv);

break;

caseD_L0_4x4:

x264_macroblock_cache_mv_ptr(h,x+0,y+0,1,1,0,a->l0.me4x4[i][0].mv);

x264_macroblock_cache_mv_ptr(h,x+1,y+0,1,1,0,a->l0.me4x4[i][1].mv);

x264_macroblock_cache_mv_ptr(h,x+0,y+1,1,1,0,a->l0.me4x4[i][2].mv);

x264_macroblock_cache_mv_ptr(h,x+1,y+1,1,1,0,a->l0.me4x4[i][3].mv);

break;

default:

x264_log(h,X264_LOG_ERROR,"internalerror\n");

break;

}

}


x264_macroblock_cache_mv_ptr(h,x+0,y+0,1,1,0,a->l0.me4x4[i][0].mv);

#definex264_macroblock_cache_mv_ptr(a,x,y,w,h,l,mv)x264_macroblock_cache_mv(a,x,y,w,h,l,*(uint32_t*)mv)//转换指针类型并取其值

staticALWAYS_INLINEvoidx264_macroblock_cache_mv(x264_t*h,intx,inty,intwidth,intheight,inti_list,uint32_tmv)

{

x264_macroblock_cache_rect4(&h->mb.cache.mv[i_list][X264_SCAN8_0+x+8*y],width,height,mv);//x,y用来对luma进行偏移

}

#defineX264_SCAN8_0(4+1*8)//SCAN8里的第一个LUMA

#defineWORD_SIZEsizeof(void*)//sizeof(void*)==sizeof(int(*)(void))就是四字节了

staticALWAYS_INLINEvoidx264_macroblock_cache_rect4(void*dst,intwidth,intheight,uint32_tval)

{

intdy;

if(width==1||WORD_SIZE<8){

for(dy=0;dy<height;dy++)

{

((uint32_t*)dst)[8*dy+0]=val;//这里看width最多是4,都是赋同一个值(mv),所以是给一个方阵全赋一个值,因为dst是从luma开始,所以这里就是SCAN8LUMA的那个方阵没错了

if(width>=2)((uint32_t*)dst)[8*dy+1]=val;

if(width==4)((uint32_t*)dst)[8*dy+2]=val;

if(width==4)((uint32_t*)dst)[8*dy+3]=val;

}

}

else

{

uint64_tval64=val+((uint64_t)val<<32);//uint64_t64int(其实是长整型)

for(dy=0;dy<height;dy++)

{

((uint64_t*)dst)[4*dy+0]=val64;

if(width==4)((uint64_t*)dst)[4*dy+1]=val64;

}

}

}


 

 

voidx264_mb_load_mv_direct8x8(x264_t*h,intidx)

{//idx48x8ID,下面

constintx=2*(idx%2);

constinty=2*(idx/2);//这个处理和之后x264_macroblock_cache_intra8x8_pred里的处理结果是一样的

x264_macroblock_cache_ref(h,x,y,2,2,0,h->mb.cache.direct_ref[0][idx]);//list0

x264_macroblock_cache_ref(h,x,y,2,2,1,h->mb.cache.direct_ref[1][idx]);//list1

 

*(uint64_t*)h->mb.cache.mv[0][x264_scan8[idx*4]]=

*(uint64_t*)h->mb.cache.direct_mv[0][x264_scan8[idx*4]];这里代码原理类似x264_macroblock_cache_intra8x8_pred//因是三维数组,且最后一维有二个元素,故一个L32位,一次COPY两个就是64,注意这里之所以能肆无忌殚地扩容指针,是因为最后一维是[2]

 

*(uint64_t*)h->mb.cache.mv[0][x264_scan8[idx*4]+8]=

*(uint64_t*)h->mb.cache.direct_mv[0][x264_scan8[idx*4]+8];//+8换一行

 

*(uint64_t*)h->mb.cache.mv[1][x264_scan8[idx*4]]=

*(uint64_t*)h->mb.cache.direct_mv[1][x264_scan8[idx*4]];

 

*(uint64_t*)h->mb.cache.mv[1][x264_scan8[idx*4]+8]=

*(uint64_t*)h->mb.cache.direct_mv[1][x264_scan8[idx*4]+8];

}//idx=0是左上块,idx=1是右上块,一次COPY一个块,包括mvx,y,以此类推

int8_tdirect_ref[2][48];

 

int16_tmv[2][X264_SCAN8_SIZE][2]

int16_tdirect_mv[2][48][2];

 


staticALWAYS_INLINEvoidx264_macroblock_cache_ref(x264_t*h,intx,inty,intwidth,intheight,inti_list,uint8_tref)

{

x264_macroblock_cache_rect1(&h->mb.cache.ref[i_list][X264_SCAN8_0+x+8*y],width,height,ref);//一次y偏移8就移动到了下一行的luma

}//从函数名看是存参考帧,这里的widthheight应该是以4*4MB为单位的,如16*8的分块,则width=4,height=2

 

staticALWAYS_INLINEvoidx264_macroblock_cache_rect1(void*dst,intwidth,intheight,uint8_tval)

{

if(width==4)//16x1616x8

{

uint32_tval2=val*0x01010101;//一次四个字节就是四个unsignedchar也就是一个int

((uint32_t*)dst)[0]=val2;//通过改变指针类型,增大移动长度,一条语句赋值一行,然后[2]指针往下移动了32*264位,正是下一行(8x8=64

if(height>=2)((uint32_t*)dst)[2]=val2;

if(height==4)((uint32_t*)dst)[4]=val2;

if(height==4)((uint32_t*)dst)[6]=val2;

}//这样一次赋完luma块,这里的luma8x4x4

else//2//8x16

{

uint32_tval2=val*0x0101;//一次四个字节

((uint16_t*)dst)[0]=val2;

if(height>=2)((uint16_t*)dst)[4]=val2;

if(height==4)((uint16_t*)dst)[8]=val2;

if(height==4)((uint16_t*)dst)[12]=val2;

}//只有一半,故赋半行即可

}

int8_tref[2][48];


 

 

x264_macroblock_cache_intra8x8_pred(h,2*(i&1),2*(i>>1),

a->i_predict8x8[i]);

 

staticALWAYS_INLINEvoidx264_macroblock_cache_intra8x8_pred(x264_t*h,intx,inty,inti_mode)

{

int8_t*cache=&h->mb.cache.intra4x4_pred_mode[X264_SCAN8_0+x+8*y];

cache[0]=cache[1]=cache[8]=cache[9]=i_mode;//x=0,y=0LUMA方阵中的第一个8x8块,(2,0)luma方阵第二个(右上),(0,2是第三个(左下)(2,2)是第四个右下,根据之前i0,1,2,3在函数的参数列表里作了处理

}

int8_tintra4x4_pred_mode[48];

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值