X264 中的x264_macroblock_cache_load 的问题2

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

1h->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);

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

(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;

         这里有点让我看不懂,71315 好理解,71315 左上 参考块都确定,这里不写右上 (71315 右上 0 右上 是不同的,宏块编码顺序和块的编码顺序也是一样的,0 右上 右上角 的宏块,而71315 右上 右边 的宏块。右边 的宏块总是在左边 的宏块 之后编码 。如下图宏块1 宏块2 之前编码 宏块3 宏块2 之后编码 。)

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

                                         0   1   
                                         2   3 

       3 11 有点让人看不懂,3 11 左上 右上 参考块都确定,为什么和71315 放一起呢? 如果看下编码顺序就不难发现了, 3 右上 4 ,而 4 是在 3 之后编码 。所以 3右上 参考块是 不确定的 ,也就将 3 71315 放在一起了。(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;

          6912 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 );

  (1w * (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 )
应该就是这个了。

你可能感兴趣的:(cache,百度,each,DST)