x264 代码中的一个坑 和 指针;

开源代码就是开源代码,不是工程代码;
今天在看x264的 x264_cqm_init 这个函数的代码时,发现里面有个坑;

先来看下 x264_h 里面有这样几个变量:

 

/* quantization matrix for decoding, [cqm][qp%6][coef] */
    int             (*dequant4_mf[4])[16];   /* [4][6][16] */
    int             (*dequant8_mf[2])[64];   /* [2][6][64] */
    /* quantization matrix for trellis, [cqm][qp][coef] */
    int             (*unquant4_mf[4])[16];   /* [4][52][16] */
    int             (*unquant8_mf[2])[64];   /* [2][52][64] */
    /* quantization matrix for deadzone */
    uint16_t        (*quant4_mf[4])[16];     /* [4][52][16] */
    uint16_t        (*quant8_mf[2])[64];     /* [2][52][64] */
    uint16_t        (*quant4_bias[4])[16];   /* [4][52][16] */
    uint16_t        (*quant8_bias[2])[64];   /* [2][52][64] */


在 x264_cqm_init 中 有这样的代码;

for( int i = 0; i < 4 + num_8x8_lists; i++ )
    {
        int size = i<4 ? 16 : 64;
        int j;
        for( j = (i<4 ? 0 : 4); j < i; j++ )
            if( !memcmp( h->pps->scaling_list[i], h->pps->scaling_list[j], size*sizeof(uint8_t) ) )
                break;
        if( j < i )
        {
            h->  quant4_mf[i] = h->  quant4_mf[j];
            h->dequant4_mf[i] = h->dequant4_mf[j];
            h->unquant4_mf[i] = h->unquant4_mf[j];
        }
        else
        {
            CHECKED_MALLOC(udctcoef (*)[16], h->  quant4_mf[i], (QP_MAX+1)*size*sizeof(udctcoef) );//实际跟踪发现,i会等于4;而 quant4_mf 长度明确定义为4,这岂不是越界了?我准备怀疑我的C语言水平了
            CHECKED_MALLOC(int (*)[16], h->dequant4_mf[i],  6*size*sizeof(int) );
            CHECKED_MALLOC(int (*)[16], h->unquant4_mf[i], (QP_MAX+1)*size*sizeof(int) );
        }
        .
        .
        .
     }

在后面对 h->quant4_mf 的访问过程如下

h->quant4_mf[i_list][q][i] = j = SHIFT(quant4_mf[i_list][q%6][i], q/6 - 1);


其中 i_list 范围是 0-3;这里的做法和定义是一致的;

经过仔细地研究代码,发现奥秘是,在上面分配内存的过程中,在一个循环内,实际上是先后给 unquant4_mf[4] 和 unquant8_mf[2] 申请内存和设置内存地址;
num_8x8_lists 实际是 2, 也就是循环的前4次是处理 unquant4_mf[4], 后两次是处理 unquant8_mf[2];
这也就是在 x264_h 相关变量这么定义的原因;
对于其余几个类似变量也是同样的情形。

所以,x264_h 结构体里面的定义 有些地方还真不是可以随便改动的,弄不好就会踩到坑;

这里也同时提示了 指针的特殊用法;

{
	unsigned char v3[2][2][3][4] = 
	{
		{
			{{1,2,3,4},{5,6,7,8},{9,10,11,12}},
			{{13,14,15,16},{17,18,19,20},{21,22,23,24}}
		},
		{
			{{1,2,3,4},{5,6,7,8},{9,10,11,12}},
			{{13,14,15,16},{17,18,19,20},{21,22,23,24}}
		}
	};

	unsigned char (*p3[2])[2][3][4];
	//here
	//p3[0] = p[1] = 0xcccccccc

	int d0 = 1;//0-1
	p3[d0] = (unsigned char (*)[2][3][4])v3[0];

	int d1/*0-1*/, d2/*0-2*/, d3/*0-3*/;

	//visit [1][2][3]
	d1 = 1, d2 = 2, d3 = 3;
	printf("p3[%d][0][%d][%d][%d]=%d\n", d0, d1, d2, d3, p3[d0][0][d1][d2][d3]);
	//or printf("p3[%d][0][%d][%d][%d]=%d\n", d0, d1, d2, d3, (*p3[d0])[d1][d2][d3]);

	//visit [1][3][2], offset = 1*3*4 + 3*4 + 2; actually visit v3[1][0][0][2]
	d1 = 1, d2 = 3,	d3 = 2;	
	printf("p3[%d][0][%d][%d][%d]=%d\n", d0, d1, d2, d3, p3[d0][0][d1][d2][d3]);
	//or printf("p3[%d][0][%d][%d][%d]=%d\n", d0, d1, d2, d3, (*p3[d0])[d1][d2][d3]);
	
	//usage in x264
	int 16x = 64;
	unsigned char (*p4[4])[16];
	p4[3] = malloc(16 * 16x);
	
	//visit p4[3][2][5], offset is 2*15 + 5;
	printf("p4[3][2][5]=%d\n", p4[3][2][5]);
	
}



 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值