现在的位置: 首页 > 综合 > 正文

x264中的菱形搜索算法研究

2013年02月21日 ⁄ 综合 ⁄ 共 3109字 ⁄ 字号 评论关闭

case X264_ME_DIA:

        i = 0;

        do

        {

            DIA1_ITER( bmx, bmy ); 菱形搜索算法

            if( (bmx == omx) & (bmy == omy) )避免搜索重复循环

                break;

            if( !CHECK_MVRANGE(bmx, bmy) )检查是否越界

                break;

        } while( ++i < i_me_range );

        break;

#define DIA1_ITER( mx, my )\

{\

    omx = mx; omy = my;\ omx,omy为旧的MV

    COST_MV_X4( 0,-1, 0,1, -1,0, 1,0 );\ 调用COST_MV_X4计算小菱形的4个顶点的cost,并与中心点比较出最小的cost点  

}

#define COST_MV_X4( m0x, m0y, m1x, m1y, m2x, m2y, m3x, m3y )\

{\

    uint8_t *pix_base = p_fref + omx + omy*m->i_stride[0];\找到具体像素点

    h->pixf.fpelcmp_x4[i_pixel]( m->p_fenc[0],\函数调用,后面详细讲

        pix_base + (m0x) + (m0y)*m->i_stride[0],\

        pix_base + (m1x) + (m1y)*m->i_stride[0],\

        pix_base + (m2x) + (m2y)*m->i_stride[0],\

        pix_base + (m3x) + (m3y)*m->i_stride[0],\

        m->i_stride[0], costs );\

    costs[0] += BITS_MVD( omx+(m0x), omy+(m0y) );\

    costs[1] += BITS_MVD( omx+(m1x), omy+(m1y) );\

    costs[2] += BITS_MVD( omx+(m2x), omy+(m2y) );\

    costs[3] += BITS_MVD( omx+(m3x), omy+(m3y) );\

    COPY3_IF_LT( bcost, costs[0], bmx, omx+(m0x), bmy, omy+(m0y) );\

    COPY3_IF_LT( bcost, costs[1], bmx, omx+(m1x), bmy, omy+(m1y) );\

    COPY3_IF_LT( bcost, costs[2], bmx, omx+(m2x), bmy, omy+(m2y) );\

    COPY3_IF_LT( bcost, costs[3], bmx, omx+(m3x), bmy, omy+(m3y) );\

如果计算出的代价costs[]比原来预测的的代价bcost小的话,则将bcost赋值为costs[],并改变运动矢量omx+(m0x),omy+(m0y)

}

 

pixel.h

x264_pixel_cmp_x4_t fpelcmp_x4[7]; x264_pixel_cmp_x4_t其实就是一函数指针

typedef void (*x264_pixel_cmp_x4_t) ( uint8_t *, uint8_t *, uint8_t *, uint8_t *, uint8_t *, int, int[4] );

x264_pixel_cmp_x3_t satd_x3[7];         x264_pixel_cmp_x4_t satd_x4[7];

  encoder.c

memcpy( h->pixf.fpelcmp_x4, satd ? h->pixf.satd_x4 : h->pixf.sad_x4, sizeof(h->pixf.fpelcmp_x4) );

就是说fpelcmp_x4要么用的是satd_x4算法,要么是sad_x4算法

整象素搜索用SAD,而亚象素用SATD,帧内模式选择要用SATD

static void x264_pixel_sad_x4_##size( uint8_t *fenc, uint8_t *pix0, uint8_t *pix1, uint8_t *pix2, uint8_t *pix3, int i_stride, int scores[4] )\

{\

    scores[0] = x264_pixel_sad_##size( fenc, FENC_STRIDE, pix0, i_stride );\

    scores[1] = x264_pixel_sad_##size( fenc, FENC_STRIDE, pix1, i_stride );\

    scores[2] = x264_pixel_sad_##size( fenc, FENC_STRIDE, pix2, i_stride );\

    scores[3] = x264_pixel_sad_##size( fenc, FENC_STRIDE, pix3, i_stride );\

}

针对不同块大小的SAD

PIXEL_SAD_C( x264_pixel_sad_16x16, 16, 16 )

PIXEL_SAD_C( x264_pixel_sad_16x8,  16,  8 )

PIXEL_SAD_C( x264_pixel_sad_8x16,   8, 16 )

PIXEL_SAD_C( x264_pixel_sad_8x8,    8,  8 )

PIXEL_SAD_C( x264_pixel_sad_8x4,    8,  4 )

PIXEL_SAD_C( x264_pixel_sad_4x8,    4,  8 )

PIXEL_SAD_C( x264_pixel_sad_4x4,    4,  4 )

#define PIXEL_SAD_C( name, lx, ly ) \

static int name( uint8_t *pix1, int i_stride_pix1,  \

                 uint8_t *pix2, int i_stride_pix2 ) \

                                                 
\

    int i_sum = 0;                                  \

    int x, y;                                      
\

    for( y = 0; y < ly; y++ )                       \

                                                
\

        for( x = 0; x < lx; x++ )                   \

                                                
\

            i_sum += abs( pix1[x] - pix2[x] );      \具体计算差值当前帧和重构帧

                                                
\

        pix1 += i_stride_pix1;                      \

        pix2 += i_stride_pix2;                      \

                                                
\

    return i_sum;                                   \

}

抱歉!评论已关闭.