您的位置:首页 > 其它

X264 中的x264_macroblock_cache_load 的问题2

2010-08-06 15:16 267 查看

X264 中的x264_macroblock_cache_load 的问题2



2008-12-04 14:53

摘自百度快照 http://mawnja.blog.163.com/blog/static/21206198200874780810/


memcpy

( &h
->mb.pic.p_fdec
[i][-1-FDEC_STRIDE
], &plane_fdec
[-1-i_stride
], w
*3/2
+1

);

这里为什么拷贝 w
*3/2
+1

个数据?h->mb.pic.p_fdec
[i][-1-FDEC_STRIDE
]里面应该只能拷贝1
个值。

解答:

memcpy
() 函数,里面参数是指针。&h
->mb.pic.p_fdec
[i][-1-FDEC_STRIDE
] 只是个首地址。对这毕书P212页,图8-22看(注意:图上只画了4*4的块,而这里操作的是16*16宏块) ,对于Y(U、V的类似)宏块需要上面1
行共需要25个数据,需要左边1
列共16个数据。

h->mb.pic.p_fdec
[i][-1-FDEC_STRIDE
] 对应M,
memcpy
( &h
->mb.pic.p_fdec
[i][-1-FDEC_STRIDE
], &plane_fdec
[-1-i_stride
], w
*3/2
+1

);
是取上面1
行25个数据。

for( j = 0; j < w
; j++ )

h->mb.pic.p_fdec
[i][-1
+j*FDEC_STRIDE] = plane_fdec[-1
+j*i_stride]; 是取左边1
列16个数据

0(M) 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
x x x x x x x x x x x x x x x x

2 x x x x x x x x x x x x x x x x

3 x x x x x x x x x x x x x x x x

4 x x x x x x x x x x x x x x x x

5 x x x x x x x x x x x x x x x x

6 x x x x x x x x x x x x x x x x

7 x x x x x x x x x x x x x x x x

8 x x x x x x x x x x x x x x x x

9 x x x x x x x x x x x x x x x x

10 x x x x x x x x x x x x x x x x

11 x x x x x x x x x x x x x x x x

12 x x x x x x x x x x x x x x x x

13 x x x x x x x x x x x x x x x x

14 x x x x x x x x x x x x x x x x

15 x x x x x x x x x x x x x x x x

16 x x x x x x x x x x x x x x x x

另一个问题

unsigned int i_neighbour8[4]; /* neighbours of each 8x8 or 4x4 block that are available */

unsigned int i_neighbour4[16]; /* at the time the block is coded */

......................................................................................

h->mb.i_neighbour4[0] =

h->mb.i_neighbour8[0] = (h->mb.i_neighbour & (MB_TOP|MB_LEFT|MB_TOPLEFT))

| ((h->mb.i_neighbour & MB_TOP) ? MB_TOPRIGHT : 0);

h->mb.i_neighbour4[4] =

h->mb.i_neighbour4[1
] = MB_LEFT

| ((h->mb.i_neighbour & MB_TOP) ? (MB_TOP|MB_TOPLEFT|MB_TOPRIGHT) : 0);

h->mb.i_neighbour4[2] =

h->mb.i_neighbour4[8] =

h->mb.i_neighbour4[10] =

h->mb.i_neighbour8[2] = MB_TOP|MB_TOPRIGHT

| ((h->mb.i_neighbour & MB_LEFT) ? (MB_LEFT|MB_TOPLEFT) : 0);

h->mb.i_neighbour4[3] =

h->mb.i_neighbour4[7] =

h->mb.i_neighbour4[11] =

h->mb.i_neighbour4[13] =

h->mb.i_neighbour4[15] =

h->mb.i_neighbour8[3] = MB_LEFT|MB_TOP|MB_TOPLEFT;

h->mb.i_neighbour4[5] =

h->mb.i_neighbour8[1
] = MB_LEFT | (h->mb.i_neighbour & MB_TOPRIGHT)

| ((h->mb.i_neighbour & MB_TOP) ? MB_TOP|MB_TOPLEFT : 0);

h->mb.i_neighbour4[6] =

h->mb.i_neighbour4[9] =

h->mb.i_neighbour4[12] =

h->mb.i_neighbour4[14] = MB_LEFT|MB_TOP|MB_TOPLEFT|MB_TOPRIGHT;

从注释看h->mb.i_neighbour8[]表示可参考的相邻块状态(这个懂,不管它),h->mb.i_neighbour4[]表示当前编码的块,那么我想h->mb.i_neighbour4[0]到h->mb.i_neighbour4[15]值应该是一样的
,都表示该块有没有被编码,这里为什么不赋一样的值?

解答:
这里不是表示当前编码的块,而是表示的位置信息
,这个从赋值关系中可以看出来

先对照宏块里面块的编码数序看

0 1
4 5

2 3 6 7

8 9 12 13

10 11 14 15

1
)h->mb.i_neighbour4[0
] =

h->mb.i_neighbour8[0] = (h->mb.i_neighbour & (MB_TOP|MB_LEFT|MB_TOPLEFT))

| ((h->mb.i_neighbour & MB_TOP) ? MB_TOPRIGHT : 0);

0
的左
、上
、左上
、右上
参考块都不确定.但是为什么把

TOPRIGHT单独列出来呢,如上图位置关系,0块就是当TOP有效时,TOPRIGHT才有效。以下同理。

(2)

h->mb.i_neighbour4[4
] =

h->mb.i_neighbour4[1

] = MB_LEFT

| ((h->mb.i_neighbour & MB_TOP) ? (MB_TOP|MB_TOPLEFT|MB_TOPRIGHT) : 0);

4
1



参考块确定,而上
、左上
、右上
参考块都不确定

(3)
h->mb.i_neighbour4[2
] =

h->mb.i_neighbour4[8
] =

h->mb.i_neighbour4[10
] =

h->mb.i_neighbour8[2
] = MB_TOP|MB_TOPRIGHT

| ((h->mb.i_neighbour & MB_LEFT) ? (MB_LEFT|MB_TOPLEFT) : 0);

2、
8、
10

上、
右上
参考块确定,而左
、左上
参考块都不确定

(4)
h->mb.i_neighbour4[3
] =

h->mb.i_neighbour4[7
] =

h->mb.i_neighbour4[11
] =

h->mb.i_neighbour4[13
] =

h->mb.i_neighbour4[15
] =

h->mb.i_neighbour8[3
] = MB_LEFT|MB_TOP|MB_TOPLEFT;

这里有点让我看不懂,7
、13
、15
好理解,7
、13
、15左



左上

参考块都确定,这里不写右上
(7
、13
、15

的右上

和0的
右上

是不同的,宏块编码顺序和块的编码顺序也是一样的,0

右上

是右上角
的宏块,而7
、13
、15
的右上

是右边
的宏块。右边
的宏块总是在左边
的宏块

之后编码

。如下图宏块1



宏块2
之前编码

,宏块3

宏块2
之后编码

。)

附宏块的编码顺序(和块是一样的)

0 1

2 3

3

11
有点让人看不懂,3

11左



左上

右上

参考块都确定,为什么和7
、13
、15
放一起呢? 如果看下编码顺序就不难发现了,

3
右上

4
,而
4
是在
3
之后编码
。所以
3右上
参考块是

不确定的
,也就将
3
和7
、13
、15

放在一起了。(11
同理
)

(5)
h->mb.i_neighbour4[5
] =

h->mb.i_neighbour8[1
] = MB_LEFT | (h->mb.i_neighbour & MB_TOPRIGHT)

| ((h->mb.i_neighbour & MB_TOP) ? MB_TOP|MB_TOPLEFT : 0);

5

参考块确定,上

左上

右上
参考块都不确定

(6)
h->mb.i_neighbour4[6
] =

h->mb.i_neighbour4[9
] =

h->mb.i_neighbour4[12
] =

h->mb.i_neighbour4[14
] = MB_LEFT|MB_TOP|MB_TOPLEFT|MB_TOPRIGHT;

6
、9
、12、
14
的左
、上
、左上
、右上
参考块都确定

3 另一个问题

来自264乐园的兄弟“遥远”,问我

h->mc.copy[i?PIXEL_8x8:PIXEL_16x16]( h->mb.pic.p_fenc[i], FENC_STRIDE,

&h
->fenc->plane[i][ w
* (i_mb_x + i_mb_y * i_stride)
], i_stride, w
);

1
w
* (i_mb_x + i_mb_y * i_stride)
不明白为什么要* w

( 这只考虑i=0情况,即Y情况,U、V类似)

(2)h->mc.copy这个函数定义在哪?

解答:

1
)汗一个,刚开始我也没弄懂,真是惭愧。i_stride=240
是像素点Y的步长,所以这里坐标表示的是像素点Y的位置,

(i_mb_x + i_mb_y * i_stride)
是每个像素点Y位置的索引,w
* (i_mb_x + i_mb_y * i_stride)

是每个宏块Y的索引.

(2)根据h->mc.copy找 copy定义 ,发现带5个参数,直接搜索copy,会发现好多带6个参数,那是不对的,是其他的copy函数。这时要利用i?PIXEL_8x8:PIXEL_16x16这个信息,我找到了

pf->copy[PIXEL_16x16] = mc_copy_w16;

pf->copy[PIXEL_8x8] = mc_copy_w8;

pf->copy[PIXEL_4x4] = mc_copy_w4;

再根据其中一个

pf->copy[PIXEL_16x16] = mc_copy_w16;

我找到了

#define MC_COPY( name, a ) /

static void name( uint8_t *src, int i_src, /

uint8_t *dst, int i_dst, int i_height ) /

{ /

int y; /

for( y = 0; y < i_height; y++ ) /

{ /

memcpy
( dst, src, a ); /

src += i_src; /

dst += i_dst; /

} /

}

MC_COPY( mc_copy_w4, 4 )

MC_COPY( mc_copy_w8, 8 )

MC_COPY( mc_copy_w16, 16 )

应该就是这个了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: