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 )
应该就是这个了。
相关文章推荐
- X264 中的x264_macroblock_cache_load 的问题
- x264_macroblock_cache_load()函数分析
- x264_macroblock_cache_load()函数分析
- x264_macroblock_cache_load分析
- x264 - x264_macroblock_cache_load
- x264_macroblock_cache_load分析
- x264_macroblock_cache_load()
- 对x264_macroblock_cache_load的理解
- x264 - x264_macroblock_cache_load
- x264_macroblock_cache_init 的分析
- EDMA使用中遇到cache一致性的问题
- TimesTen cache to oracle的问题
- Direct3D: TextureLoad.FromStream的问题.
- fedora 14 安装VM tools 问题:Even if the module were to compile successfully, it would not load into the running kernel.
- 在配置load balance时,真实的ip在apache log 中无法记录的问题
- 通过load值查服务器问题
- jquery判断图像是否加载完毕【解决读取缓存不调用load方法的问题】
- "FoxitReaderOCX.ocx failed to load" 问题解决方案
- cache和命中率的问题
- x264代码剖析(十四):核心算法之宏块编码函数x264_macroblock_encode()