• 5_9 __3 scan8分析


    大体上将一个宏块的编码过程跟下来

    上面分析完事宏块位置问题,下面看一个宏块的编码过程。

     

    Macroblock.h中的一个编码过程

        h->dctf.sub4x4_dct( dct4x4, p_src, p_dst );  //mutiply two parameter matrix

     

        nz = x264_quant_4x4( h, dct4x4, i_qp, ctx_cat_plane[DCT_LUMA_4x4][p], 1, p, idx );

        h->mb.cache.non_zero_count[x264_scan8[p*16+idx]] = nz;

        if( nz )

    {         

    h->mb.i_cbp_luma |= 1<<(idx>>2);

            h->zigzagf.scan_4x4( h->dct.luma4x4[p*16+idx], dct4x4 );

            h->quantf.dequant_4x4( dct4x4, h->dequant4_mf[p?CQM_4IC:CQM_4IY], i_qp );

            h->dctf.add4x4_idct( p_dst, dct4x4 );

    }

     

    首先分析第一个 dct变换

    h->dctf.sub4x4_dct( dct4x4, p_src, p_dst );  

     

    x264_dct_init( h->param.cpu, &h->dctf ); 初始化命令行

    void x264_dct_init( int cpu, x264_dct_function_t *dctf )  函数

     

    所谓的蝶形  dct就是宏块内容  第一个和第二个都是h里面的全局内容

    static void sub4x4_dct( dctcoef dct[16], pixel *pix1, pixel *pix2 )

    {

        dctcoef d[16];

        dctcoef tmp[16];

     

    //get the residual block

        pixel_sub_wxh( d, 4, pix1, FENC_STRIDE, pix2, FDEC_STRIDE );

     

    这里d里面存放的已经是残差了。其实就是进行了AXA的过程

    两个矩阵为

     

    1  1  1  1 1  2  1  1

    2  1     -1 -2       X        1  1 -1 -2

    1 -1 -1  1  1 -1 -1    2 1 -2  2 -1 1 -2 1  -1

     

        for( int i = 0; i < 4; i++ )

        {

            int s03 = d[i*4+0] + d[i*4+3];

            int s12 = d[i*4+1] + d[i*4+2];

            int d03 = d[i*4+0] - d[i*4+3];

            int d12 = d[i*4+1] - d[i*4+2];

        

    0i

            tmp[0*4+i] =   s03 +   s12;

            1i

    tmp[1*4+i] = 2*d03 +   d12;

           3i

    tmp[2*4+i] =   s03 -   s12;

            4i

    tmp[3*4+i] =   d03 - 2*d12;

        }

     

        for( int i = 0; i < 4; i++ )

        {

            int s03 = tmp[i*4+0] + tmp[i*4+3];

            int s12 = tmp[i*4+1] + tmp[i*4+2];

            int d03 = tmp[i*4+0] - tmp[i*4+3];

            int d12 = tmp[i*4+1] - tmp[i*4+2];

     

            dct[i*4+0] =   s03 +   s12;

            dct[i*4+1] = 2*d03 +   d12;

            dct[i*4+2] =   s03 -   s12;

            dct[i*4+3] =   d03 - 2*d12;

        }

    }

     

     

     pixel_sub_wxh( d, 4, pix1, FENC_STRIDE, pix2, FDEC_STRIDE );

    d为空的像素数组 最后就是将残差放入到这个数组里面返回然后对其进行编码

    static inline void pixel_sub_wxh( dctcoef *diff, int i_size,

                                      pixel *pix1, int i_pix1, pixel *pix2, int i_pix2 )

    {

        for( int y = 0; y < i_size; y++ )

        {

            for( int x = 0; x < i_size; x++ )

                diff[x + y*i_size] = pix1[x] - pix2[x];

            pix1 += i_pix1;

            pix2 += i_pix2;

        }

    }

     

     

     

     

     

    /* Scan8 organization:

     *    0 1 2 3 4 5 6 7

     * 0  DY    y y y y y

     * 1        y Y Y Y Y

     * 2        y Y Y Y Y

     * 3        y Y Y Y Y

     * 4        y Y Y Y Y

     * 5  DU    u u u u u

     * 6        u U U U U

     * 7        u U U U U

     * 8        u U U U U

     * 9        u U U U U

     * 10 DV    v v v v v

     * 11       v V V V V

     * 12       v V V V V

     * 13       v V V V V

     * 14       v V V V V

     * DY/DU/DV are for luma/chroma DC.

     */

    已经改变了 不是以前那个48矩阵了,这里给出的是这个样子的。

     

    h->mb.cache.non_zero_count[x264_scan8[p*16+idx]] = nz;

    这句是对于编码量化后,对于缓存中非0系数的统计。可以看出当前块编码完成之后要对于非0个数进行缓存。将idx和 x264_scan8[p*16+idx]打印出来的

    p == 0 的时候也就是色度的时候

     0  1    2   3   4   5   6   7   8   9  10  11 12 13 14 15

    12 13 20 21 14 15 22 23 28 29  36 37 30 31 38 39

     

    P==1打印不出来

    不过可以对照前面那个图可以看出 如果p==1就是16+idxidx0也就是16+0

    16+1 。。。 16+16

    x264_scan8[16] = 52

    对照上面那个图看看应该刚好对应上

    16  17

    52   53

    http://wmnmtm.blog.163.com/blog/static/3824571420118175553244/

    这时老版本里面的 但是那个方格图像坐标可以对比着看

     

    ALIGNED_16( uint8_t non_zero_count[X264_SCAN8_SIZE] );

    static const uint8_t x264_scan8[16*3 + 3] =

    {

        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,

        4+ 6*8, 5+ 6*8, 4+ 7*8, 5+ 7*8,

        6+ 6*8, 7+ 6*8, 6+ 7*8, 7+ 7*8,

        4+ 8*8, 5+ 8*8, 4+ 9*8, 5+ 9*8,

        6+ 8*8, 7+ 8*8, 6+ 9*8, 7+ 9*8,

        4+11*8, 5+11*8, 4+12*8, 5+12*8,

        6+11*8, 7+11*8, 6+12*8, 7+12*8,

        4+13*8, 5+13*8, 4+14*8, 5+14*8,

        6+13*8, 7+13*8, 6+14*8, 7+14*8,

        0+ 0*8, 0+ 5*8, 0+10*8

    };

     

    分析的不是很完整。。。。

     

     

     

     

     

  • 相关阅读:
    mysql的触发器
    数据库面试题
    数据库面试(1)
    eclipse里maven项目An error occurred while filtering resources解决办法
    Missing artifact com.github.pagehelper:pagehelper:jar:3.4.2-fix的解决方法
    淘淘商城学习
    spring Security简介
    ElasticSearch学习
    在Visual Studio中使用FFTW库
    FFTW程序Demo
  • 原文地址:https://www.cnblogs.com/hatreds/p/2491741.html
Copyright © 2020-2023  润新知