x264_scan8分析

common/common.h

x264_scan8这个表格储存的是什么资料。开始的时候,的确让人费解,越看越糊涂。
在很多地方都直接或者间接通过这个表格来保存资料。比如:

h->mb.cache.intra4x4_pred_mode[x264_scan8[0] - 8] = h->mb.intra4x4_pred_mode[i_top_xy][0];
h->mb.cache.intra4x4_pred_mode[x264_scan8[1] - 8] = h->mb.intra4x4_pred_mode[i_top_xy][1];
h->mb.cache.intra4x4_pred_mode[x264_scan8[4] - 8] = h->mb.intra4x4_pred_mode[i_top_xy][2];
h->mb.cache.intra4x4_pred_mode[x264_scan8[5] - 8] = h->mb.intra4x4_pred_mode[i_top_xy][3];

x264_scan8分析 - 加菲 -  .

 

x264_scan8分析 - 加菲 -  .

 


很多地方都是通过x264_scan8找到数组的下标,那么这个x264_scan8表格是如何定义的呢,

x264_scan8分析 - 加菲 -  .

 

我们看
static const int x264_scan8[16+2*4] =
{
     /* Luma */
     4+1*8, 5+1*8, 4+2*8, 5+2*8,
     6+1*8, 7+1*8, 6+2*8, 7+2*8,
     4+3*8, 5+3*8, 4+4*8, 5+4*8,
     6+3*8, 7+3*8, 6+4*8, 7+4*8,

     /* Cb */
     1+1*8, 2+1*8,
     1+2*8, 2+2*8,
     /* Cr */
     1+4*8, 2+4*8,
     1+5*8, 2+5*8,
};
/*
    0 1 2 3 4 5 6 7
0
1    B B    L L L L
2    B B    L L L L
3              L L L L
4    R R    L L L L
5    R R
*/
 
x264_scan8分析 - 加菲 -  .
 
 
 
        首先,这是一个表格,存储的是4x4块的YUV420的3分量的扫描序号。
        其次,不要试图把它和实际的样点联系起来。
 
        这个图的每一个小格,与一个4x4块对应,灰色的块,每个小格对应一个4x4块,就代表4x4个“4x4块”,正好是一个宏块(16x16像素)的亮度块(16x16)。
 
      黄色的2行2列,共4个小格,代表2x2个“4x4块”(色度Cb块)。
 

x264_scan8分析 - 加菲 -  .

        YcbCr取样时,色度是水平和垂直方向都是二取一,所以,这个4x4色度块对应于宏块的8x8个像素。也就是说,对于一个宏块(16x16像素),它的Y分量是16x16个字节,色度Cb,水平方向,两个像素样点,共用一个色度值,垂直方向也是二个样点共用一个色度值,也就是,4个亮度值,对应于一个Cb和一个Cr。

 
所以,这个表格存储了一整个宏块的信息,但是单位是4x4块。
 
一般来说,各种预测只关心左边和上边的块,确切的说,包括:左边、上边、左上、右上。上述表格把这些位置都空了下来,就是用来存放这些信息的。
 
但是,这个表格到底怎么来用呢?光是这个表格好像起不到作用。应该有一个实际存4x4块的个“东西”,比如,一个一维的数组,或者一个结构体数组,这个数组里的每个元素都是4x4块,这些块除了一个宏块的4x4个“4x4块”外,还有它的左邻近和上邻近“4x4块”,这样,我们利用这个表来得到结构体数组的下标,转换成平面相对位置。
 
        从图上看,这个扫描共有6X8=48个数据(包括空格,图中最后两行无用),实际上YUV420只有16+8=24个4x4块(16个亮度值,4个Cb色度值和4个Cr色度值),那么其他的空间用来干什么呢。

        事实上,第0行,第0列,第3列,第3行都有空块.这些空块用来存储什么呢,通过分析,用来存储当前宏块的top宏块,left宏块的邻近像素,比如:
        x264_scan8[0],代表第一个Luma的扫描,扫描序为12,位于上图表格的(4,1)处;
        x264_scan8[1],代表第二个Luma的扫描,扫描序为13,位于上图表格的(5,1)处;
        x264_scan8[4],代表第三个Luma的扫描,扫描序为14,位于上图表格的(6,1)处;
        x264_scan8[5],代表第四个Luma的扫描,扫描序为15,位于上图表格的(7,1)处;
 
        所以:
        x264_scan8[0]
        x264_scan8[1]
        x264_scan8[4]
        x264_scan8[5]
        代表整个宏块的第一行的4X4块的扫描序号
 
        由于我们在帧内亮度,色度预测,帧间运动矢量预测的时候,都要运用top,left侧的子块做Left,top,或者中值预测。所以上面空出来的扫描序号用来存储top,或者left宏块的边缘子块(4X4)扫描。比如(4,0)~(7,0)存储当前
宏块的top宏块下边缘的扫描(对Luma)。其他的Cb,Cr分量依次类推。
到此x264_scan8表格分析完成,结论:存储的是当前宏块各个分量4X4块在8X6表格中的扫描序号。
 
x264_scan8分析 - 加菲 -  .
 
x264_scan8分析 - 加菲 -  .
 ----------------------
 
      从图上看,这个扫描共有6X8=48个数据(包括空格,图中最后两行无用),实际上YUV420只有16+8=24个4X4块,那么其他的空间用来干什么呢。
        事实上,第0行,第0列,第3列,第3行都有空块.这些空块用来存储什么呢,通过分析,用来存储当前宏块的top宏块,left宏块的4X4子块的扫描,比如x264_scan8[0],代表第一个Luma的扫描,扫描序为12,
位于上图表格的(4,1)处,(5,1)处是第二个Luma,扫描序为13,位于x264_scan8[1],(6,1)处这时候扫描序号是14,位于x264_scan8[4],
(7,1)扫描序号是15位于x264_scan8[5].所以x264_scan8[0],x264_scan8[1],x264_scan8[4],x264_scan8[5],代表整个宏块的
第一行的4X4块的扫描序号,由于我们在帧内亮度,色度预测,帧间运动矢量预测的时候,都要运用top,left侧的子块
做Left,top,或者中值预测.所以上面空出来的扫描序号用来存储top,或者left宏块的边缘子块(4X4)扫描。比如(4,0)~(7,0)存储当前
宏块的top宏块下边缘的扫描(对Luma)。其他的Cb,Cr分量依次类推。
到此x264_scan8表格分析完成,结论:存储的是当前宏块各个分量4X4块在8X6表格中的扫描序号。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值