x264 - ssd_mb

来源:互联网 发布:诚殷网络web渗透培训 编辑:程序博客网 时间:2024/06/06 18:18

In summary, ssd_mb is used to calc

squared sum of residual of mb mainly,

including Y, U, V three planes.


static inline int ssd_mb( x264_t *h )
{
    //  PIXEL_16X16 = 0, chroma_size = 3
    int chroma_size = h->luma2chroma_pixel[PIXEL_16x16];
    // calc two chroma blocks' ssd
    int chroma_ssd = ssd_plane(h, chroma_size, 1, 0, 0) + ssd_plane(h, chroma_size, 2, 0, 0);
    // multiply mb.i_chroma_lambda2_offset
    chroma_ssd = ((uint64_t)chroma_ssd * h->mb.i_chroma_lambda2_offset + 128) >> 8;
    // calc Y's ssd, return sum(Yssd Ussd, Vssd)
    return ssd_plane(h, PIXEL_16x16, 0, 0, 0) + chroma_ssd;
}

static inline int ssd_plane( x264_t *h, int size, int p, int x, int y )
{
    ALIGNED_16( static pixel zero[16] ) = {0};
    int satd = 0;
    pixel *fdec = h->mb.pic.p_fdec[p] + x + y*FDEC_STRIDE;
    pixel *fenc = h->mb.pic.p_fenc[p] + x + y*FENC_STRIDE;
    if( p == 0 && h->mb.i_psy_rd )
    {
        // calc Y plane's satd
        /* If the plane is smaller than 8x8, we can't do an SA8D; this probably isn't a big problem. */
        if( size <= PIXEL_8x8 )
        {
            // for size <= PIXEL_8X8
            // calc satd of ac
            // h->pixf.hadamard_ac = x264_pixel_hadamard_ac_16x16
            // HADAMARD_AC( 16, 16 )
           
uint64_t fdec_acs = h->pixf.hadamard_ac[size]( fdec, FDEC_STRIDE );
            uint64_t fenc_acs = cached_hadamard( h, size, x, y );
            satd = abs((int32_t)fdec_acs - (int32_t)fenc_acs)
                 + abs((int32_t)(fdec_acs>>32) - (int32_t)(fenc_acs>>32));
            satd >>= 1;
        }
        else
        {   // calc satd of dc
            int dc = h->pixf.sad[size]( fdec, FDEC_STRIDE, zero, 0 ) >> 1;
            satd = abs(h->pixf.satd[size]( fdec, FDEC_STRIDE, zero, 0 ) - dc - cached_satd( h, size, x, y ));
        }
        // adjust satd
        satd = (satd * h->mb.i_psy_rd * h->mb.i_psy_rd_lambda + 128) >> 8;
    }
   
    // h->pixf.ssd[0] = x264_pixel_ssd_16x16, calc sum ( (srcpixel - predict_pixel) * (srcpixel - predict_pixe))
    // i.e. calc squared sum of residual of 16x16 block
    // h->pixf.ssd[3] = x264_pixel_ssd_8x8, calc squared sum of residual of 8x8 block

   
    return h->pixf.ssd[size](fenc, FENC_STRIDE, fdec, FDEC_STRIDE) + satd;
}


// actually calc squared sum of residual of mb
#define PIXEL_SSD_C( name, lx, ly ) \
static int name( pixel *pix1, intptr_t i_stride_pix1,  \
                 pixel *pix2, intptr_t i_stride_pix2 ) \
{                                                   \
    int i_sum = 0;                                  \
    for( int y = 0; y < ly; y++ )                   \
    {                                               \
        for( int x = 0; x < lx; x++ )               \
        {                                           \
            int d = pix1[x] - pix2[x];              \
            i_sum += d*d;                           \
        }                                           \
        pix1 += i_stride_pix1;                      \
        pix2 += i_stride_pix2;                      \
    }                                               \
    return i_sum;                                   \
}
PIXEL_SSD_C( x264_pixel_ssd_16x16, 16, 16 )
PIXEL_SSD_C( x264_pixel_ssd_16x8,  16,  8 )
PIXEL_SSD_C( x264_pixel_ssd_8x16,   8, 16 )
PIXEL_SSD_C( x264_pixel_ssd_8x8,    8,  8 )
PIXEL_SSD_C( x264_pixel_ssd_8x4,    8,  4 )
PIXEL_SSD_C( x264_pixel_ssd_4x16,   4, 16 )
PIXEL_SSD_C( x264_pixel_ssd_4x8,    4,  8 )
PIXEL_SSD_C( x264_pixel_ssd_4x4,    4,  4 )

0 0
原创粉丝点击