shithub: libvpx

ref: 5f320d010f4b7b20e79d5b1d7633b751a5968daf
dir: /vp8/common/maskingmv.c/

View raw version
/*
 ============================================================================
 Name        : maskingmv.c
 Author      : jimbankoski
 Version     :
 Copyright   : Your copyright notice
 Description : Hello World in C, Ansi-style
 ============================================================================
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
extern unsigned int vp8_sad16x16_sse3(
    unsigned char *src_ptr,
    int  src_stride,
    unsigned char *ref_ptr,
    int  ref_stride,
    int  max_err);

extern void vp8_sad16x16x3_sse3(
    unsigned char *src_ptr,
    int  src_stride,
    unsigned char *ref_ptr,
    int  ref_stride,
    int  *results);

extern int vp8_growmaskmb_sse3(
    unsigned char *om,
    unsigned char *nm);

extern void vp8_makemask_sse3(
    unsigned char *y,
    unsigned char *u,
    unsigned char *v,
    unsigned char *ym,
    int yp,
    int uvp,
    int ys,
    int us,
    int vs,
    int yt,
    int ut,
    int vt);

unsigned int vp8_sad16x16_unmasked_wmt(
    unsigned char *src_ptr,
    int  src_stride,
    unsigned char *ref_ptr,
    int  ref_stride,
    unsigned char *mask);

unsigned int vp8_sad16x16_masked_wmt(
    unsigned char *src_ptr,
    int  src_stride,
    unsigned char *ref_ptr,
    int  ref_stride,
    unsigned char *mask);

unsigned int vp8_masked_predictor_wmt(
    unsigned char *masked,
    unsigned char *unmasked,
    int  src_stride,
    unsigned char *dst_ptr,
    int  dst_stride,
    unsigned char *mask);
unsigned int vp8_masked_predictor_uv_wmt(
    unsigned char *masked,
    unsigned char *unmasked,
    int  src_stride,
    unsigned char *dst_ptr,
    int  dst_stride,
    unsigned char *mask);
unsigned int vp8_uv_from_y_mask(
    unsigned char *ymask,
    unsigned char *uvmask);
int yp=16;
unsigned char sxy[]=
{
40,40,40,60,60,60,60,40,40,40,40,60,60,60,60,40,80,120,120,90,90,90,90,90,80,120,120,90,90,90,90,90,
40,40,40,60,60,60,60,40,40,40,40,60,60,60,60,40,80,120,120,90,90,90,90,90,80,120,120,90,90,90,90,90,
40,40,60,60,60,60,40,40,40,40,60,60,60,60,40,40,80,120,120,90,90,90,90,90,80,120,120,90,90,90,90,90,
40,40,60,60,60,60,40,40,40,40,60,60,60,60,40,40,80,120,120,90,90,90,90,90,80,120,120,90,90,90,90,90,
40,60,60,60,60,40,40,40,40,60,60,60,60,40,40,40,80,120,120,90,90,90,90,90,80,120,120,90,90,90,90,90,
60,60,60,60,40,40,40,40,60,60,60,60,40,40,40,40,80,120,120,90,90,90,90,90,80,120,120,90,90,90,90,90,
60,60,60,60,40,40,40,40,60,60,60,60,40,40,40,40,80,120,120,90,90,90,90,90,80,120,120,90,90,90,90,90,
60,60,60,60,40,40,40,40,60,60,60,60,40,40,40,40,80,120,120,90,90,90,90,90,80,120,120,90,90,90,90,90,
40,60,60,60,60,40,40,40,40,60,60,60,60,40,40,40,80,120,120,90,90,90,90,90,80,120,120,90,90,90,90,90,
40,60,60,60,60,40,40,40,40,60,60,60,60,40,40,40,80,120,120,90,90,90,90,90,80,120,120,90,90,90,90,90,
40,40,60,60,60,60,40,40,40,40,60,60,60,60,40,40,80,120,120,90,90,90,90,90,80,120,120,90,90,90,90,90,
40,40,60,60,60,60,40,40,40,40,60,60,60,60,40,40,80,120,120,90,90,90,90,90,80,120,120,90,90,90,90,90,
40,40,40,60,60,60,60,40,40,40,40,60,60,60,60,40,80,120,120,90,90,90,90,90,80,120,120,90,90,90,90,90,
40,40,40,60,60,60,60,40,40,40,40,60,60,60,60,40,80,120,120,90,90,90,90,90,80,120,120,90,90,90,90,90,
40,40,40,60,60,60,60,40,40,40,40,60,60,60,60,40,80,120,120,90,90,90,90,90,80,120,120,90,90,90,90,90,
40,40,40,60,60,60,60,40,40,40,40,60,60,60,60,40,80,120,120,90,90,90,90,90,80,120,120,90,90,90,90,90
};

unsigned char sts[]=
{
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
};
unsigned char str[]=
{
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
};

unsigned char y[]=
{
40,40,40,60,60,60,60,40,40,40,40,60,60,60,60,40,
40,40,40,60,60,60,60,40,40,40,40,60,60,60,60,40,
40,40,60,60,60,60,40,40,40,40,60,60,60,60,40,40,
40,40,60,60,60,60,40,40,40,40,60,60,60,60,40,40,
40,60,60,60,60,40,40,40,40,60,60,60,60,40,40,40,
60,60,60,60,40,40,40,40,60,60,60,60,40,40,40,40,
60,60,60,60,40,40,40,40,60,60,60,60,40,40,40,40,
60,60,60,60,40,40,40,40,60,60,60,60,40,40,40,40,
40,60,60,60,60,40,40,40,40,60,60,60,60,40,40,40,
40,60,60,60,60,40,40,40,40,60,60,60,60,40,40,40,
40,40,60,60,60,60,40,40,40,40,60,60,60,60,40,40,
40,40,60,60,60,60,40,40,40,40,60,60,60,60,40,40,
40,40,40,60,60,60,60,40,40,40,40,60,60,60,60,40,
40,40,40,60,60,60,60,40,40,40,40,60,60,60,60,40,
40,40,40,60,60,60,60,40,40,40,40,60,60,60,60,40,
40,40,40,60,60,60,60,40,40,40,40,60,60,60,60,40
};
int uvp=8;
unsigned char u[]=
{
90,80,70,70,90,90,90,17,
90,80,70,70,90,90,90,17,
84,70,70,90,90,90,17,17,
84,70,70,90,90,90,17,17,
80,70,70,90,90,90,17,17,
90,80,70,70,90,90,90,17,
90,80,70,70,90,90,90,17,
90,80,70,70,90,90,90,17
};

unsigned char v[]=
{
80,80,80,80,80,80,80,80,
80,80,80,80,80,80,80,80,
80,80,80,80,80,80,80,80,
80,80,80,80,80,80,80,80,
80,80,80,80,80,80,80,80,
80,80,80,80,80,80,80,80,
80,80,80,80,80,80,80,80,
80,80,80,80,80,80,80,80
};

unsigned char ym[256];
unsigned char uvm[64];
typedef struct
{
    unsigned char y;
    unsigned char yt;
    unsigned char u;
    unsigned char ut;
    unsigned char v;
    unsigned char vt;
    unsigned char use;
} COLOR_SEG_ELEMENT;

/*
COLOR_SEG_ELEMENT segmentation[]=
{
    { 60,4,80,17,80,10, 1},
    { 40,4,15,10,80,10, 1},
};
*/

COLOR_SEG_ELEMENT segmentation[]=
{
    { 79,44,92,44, 237,60, 1},
};

unsigned char pixel_mask(unsigned char y,unsigned char u,unsigned char v,
                COLOR_SEG_ELEMENT sgm[],
                int c)
{
    COLOR_SEG_ELEMENT *s=sgm;
    unsigned char m =0;
    int i;
    for(i=0;i<c;i++,s++)
        m |= ( abs(y-s->y)< s->yt &&
               abs(u-s->u)< s->ut &&
               abs(v-s->v)< s->vt ? 255 : 0 );

    return m;
}
int neighbors[256][8];
int makeneighbors(void)
{
    int i,j;
    for(i=0;i<256;i++)
    {
        int r=(i>>4),c=(i&15);
        int ni=0;
        for(j=0;j<8;j++)
            neighbors[i][j]=i;
        for(j=0;j<256;j++)
        {
            int nr=(j>>4),nc=(j&15);
            if(abs(nr-r)<2&&abs(nc-c)<2)
              neighbors[i][ni++]=j;
        }
    }
    return 0;
}
void grow_ymask(unsigned char *ym)
{
    unsigned char nym[256];
    int i,j;

    for(i=0;i<256;i++)
    {
        nym[i]=ym[i];
        for(j=0;j<8;j++)
        {
            nym[i]|=ym[neighbors[i][j]];
        }
    }
    for(i=0;i<256;i++)
        ym[i]=nym[i];
}
void make_mb_mask(unsigned char *y, unsigned char *u, unsigned char *v,
                  unsigned char *ym, unsigned char *uvm,
                  int yp, int uvp,
                  COLOR_SEG_ELEMENT sgm[],
                  int count)
{
    int r,c;
    unsigned char *oym = ym;

    memset(ym,20,256);
    for(r=0;r<8;r++,uvm+=8,u+=uvp,v+=uvp,y+=(yp+yp),ym+=32)
        for(c=0;c<8;c++)
        {
            int y1=y[c<<1];
            int u1=u[c];
            int v1=v[c];
            int m = pixel_mask(y1,u1,v1,sgm,count);
            uvm[c] = m;
            ym[c<<1] = uvm[c];// = pixel_mask(y[c<<1],u[c],v[c],sgm,count);
            ym[(c<<1)+1] = pixel_mask(y[1+(c<<1)],u[c],v[c],sgm,count);
            ym[(c<<1)+16] = pixel_mask(y[yp+(c<<1)],u[c],v[c],sgm,count);
            ym[(c<<1)+17] = pixel_mask(y[1+yp+(c<<1)],u[c],v[c],sgm,count);
        }
    grow_ymask(oym);
}

int masked_sad(unsigned char *src, int p, unsigned char *dst, int dp,
               unsigned char *ym )
{
    int i,j;
    unsigned sad = 0;
    for(i=0;i<16;i++,src+=p,dst+=dp,ym+=16)
        for(j=0;j<16;j++)
            if(ym[j])
                sad+= abs(src[j]-dst[j]);

    return sad;
}

int compare_masks(unsigned char *sym, unsigned char *ym)
{
    int i,j;
    unsigned sad = 0;
    for(i=0;i<16;i++,sym += 16,ym+=16)
        for(j=0;j<16;j++)
            sad+= (sym[j]!=ym[j]?1:0);

    return sad;
}
int unmasked_sad(unsigned char *src, int p, unsigned char *dst, int dp,
               unsigned char *ym)
{
    int i,j;
    unsigned sad = 0;
    for(i=0;i<16;i++,src+=p,dst+=dp,ym+=16)
        for(j=0;j<16;j++)
            if(!ym[j])
                sad+= abs(src[j]-dst[j]);

    return sad;
}
int masked_motion_search( unsigned char *y, unsigned char *u, unsigned char *v,
                          int yp, int uvp,
                          unsigned char *dy, unsigned char *du, unsigned char *dv,
                          int dyp, int duvp,
                          COLOR_SEG_ELEMENT sgm[],
                          int count,
                          int *mi,
                          int *mj,
                          int *ui,
                          int *uj,
                          int *wm)
{
    int i,j;

    unsigned char ym[256];
    unsigned char uvm[64];
    unsigned char dym[256];
    unsigned char duvm[64];
    unsigned int e = 0 ;
    int beste=256;
    int bmi=-32,bmj=-32;
    int bui=-32,buj=-32;
    int beste1=256;
    int bmi1=-32,bmj1=-32;
    int bui1=-32,buj1=-32;
    int obeste;

    // first try finding best mask and then unmasked
    beste = 0xffffffff;

    // find best unmasked mv
    for(i=-32;i<32;i++)
    {
        unsigned char *dyz = i*dyp + dy;
        unsigned char *duz = i/2*duvp + du;
        unsigned char *dvz = i/2*duvp + dv;
        for(j=-32;j<32;j++)
        {
            // 0,0  masked destination
            make_mb_mask(dyz+j,duz+j/2, dvz+j/2, dym, duvm, dyp, duvp,sgm,count);

            e = unmasked_sad(y, yp, dyz+j, dyp, dym );

            if(e<beste)
            {
                bui=i;
                buj=j;
                beste=e;
            }
        }
    }
    //bui=0;buj=0;
    // best mv masked destination
    make_mb_mask(dy+bui*dyp+buj,du+bui/2*duvp+buj/2, dv+bui/2*duvp+buj/2,
                 dym, duvm, dyp, duvp,sgm,count);

    obeste = beste;
    beste = 0xffffffff;

    // find best masked
    for(i=-32;i<32;i++)
    {
        unsigned char *dyz = i*dyp + dy;
        for(j=-32;j<32;j++)
        {
            e = masked_sad(y, yp, dyz+j, dyp, dym );

            if(e<beste)
            {
                bmi=i;
                bmj=j;
                beste=e;
            }
        }
    }
    beste1=beste+obeste;
    bmi1=bmi;bmj1=bmj;
    bui1=bui;buj1=buj;

    beste = 0xffffffff;
    // source mask
    make_mb_mask(y,u, v, ym, uvm, yp, uvp,sgm,count);

    // find best mask
    for(i=-32;i<32;i++)
    {
        unsigned char *dyz = i*dyp + dy;
        unsigned char *duz = i/2*duvp + du;
        unsigned char *dvz = i/2*duvp + dv;
        for(j=-32;j<32;j++)
        {
            // 0,0  masked destination
            make_mb_mask(dyz+j,duz+j/2, dvz+j/2, dym, duvm, dyp, duvp,sgm,count);

            e = compare_masks(ym, dym);

            if(e<beste)
            {
                bmi=i;
                bmj=j;
                beste=e;
            }
        }
    }


    // best mv masked destination
    make_mb_mask(dy+bmi*dyp+bmj,du+bmi/2*duvp+bmj/2, dv+bmi/2*duvp+bmj/2,
                 dym, duvm, dyp, duvp,sgm,count);

    obeste = masked_sad(y, yp, dy+bmi*dyp+bmj, dyp, dym );

    beste = 0xffffffff;

    // find best unmasked mv
    for(i=-32;i<32;i++)
    {
        unsigned char *dyz = i*dyp + dy;
        for(j=-32;j<32;j++)
        {
            e = unmasked_sad(y, yp, dyz+j, dyp, dym );

            if(e<beste)
            {
                bui=i;
                buj=j;
                beste=e;
            }
        }
    }
    beste += obeste;


    if(beste<beste1)
    {
        *mi = bmi;
        *mj = bmj;
        *ui = bui;
        *uj = buj;
        *wm = 1;
    }
    else
    {
        *mi = bmi1;
        *mj = bmj1;
        *ui = bui1;
        *uj = buj1;
        *wm = 0;

    }
    return 0;
}

int predict(unsigned char *src, int p, unsigned char *dst, int dp,
            unsigned char *ym, unsigned char *prd )
{
    int i,j;
    for(i=0;i<16;i++,src+=p,dst+=dp,ym+=16, prd+=16)
        for(j=0;j<16;j++)
            prd[j]=(ym[j] ? src[j]:dst[j]);
    return 0;
}

int fast_masked_motion_search( unsigned char *y, unsigned char *u, unsigned char *v,
                          int yp, int uvp,
                          unsigned char *dy, unsigned char *du, unsigned char *dv,
                          int dyp, int duvp,
                          COLOR_SEG_ELEMENT sgm[],
                          int count,
                          int *mi,
                          int *mj,
                          int *ui,
                          int *uj,
                          int *wm)
{
    int i,j;

    unsigned char ym[256];
    unsigned char ym2[256];
    unsigned char uvm[64];
    unsigned char dym2[256];
    unsigned char dym[256];
    unsigned char duvm[64];
    unsigned int e = 0 ;
    int beste=256;
    int bmi=-32,bmj=-32;
    int bui=-32,buj=-32;
    int beste1=256;
    int bmi1=-32,bmj1=-32;
    int bui1=-32,buj1=-32;
    int obeste;

    // first try finding best mask and then unmasked
    beste = 0xffffffff;

#if 0
    for(i=0;i<16;i++)
    {
        unsigned char *dy = i*yp + y;
        for(j=0;j<16;j++)
            printf("%2x",dy[j]);
        printf("\n");
    }
    printf("\n");

    for(i=-32;i<48;i++)
    {
        unsigned char *dyz = i*dyp + dy;
        for(j=-32;j<48;j++)
            printf("%2x",dyz[j]);
        printf("\n");
    }
#endif

    // find best unmasked mv
    for(i=-32;i<32;i++)
    {
        unsigned char *dyz = i*dyp + dy;
        unsigned char *duz = i/2*duvp + du;
        unsigned char *dvz = i/2*duvp + dv;
        for(j=-32;j<32;j++)
        {
            // 0,0  masked destination
            vp8_makemask_sse3(dyz+j,duz+j/2, dvz+j/2, dym, dyp, duvp,
                              sgm[0].y,sgm[0].u,sgm[0].v,
                              sgm[0].yt,sgm[0].ut,sgm[0].vt);

            vp8_growmaskmb_sse3(dym,dym2);

            e = vp8_sad16x16_unmasked_wmt(y, yp, dyz+j, dyp, dym2 );

            if(e<beste)
            {
                bui=i;
                buj=j;
                beste=e;
            }
        }
    }
    //bui=0;buj=0;
    // best mv masked destination

    vp8_makemask_sse3(dy+bui*dyp+buj,du+bui/2*duvp+buj/2, dv+bui/2*duvp+buj/2,
                      dym, dyp, duvp,
                      sgm[0].y,sgm[0].u,sgm[0].v,
                      sgm[0].yt,sgm[0].ut,sgm[0].vt);

    vp8_growmaskmb_sse3(dym,dym2);

    obeste = beste;
    beste = 0xffffffff;

    // find best masked
    for(i=-32;i<32;i++)
    {
        unsigned char *dyz = i*dyp + dy;
        for(j=-32;j<32;j++)
        {
            e = vp8_sad16x16_masked_wmt(y, yp, dyz+j, dyp, dym2 );
            if(e<beste)
            {
                bmi=i;
                bmj=j;
                beste=e;
            }
        }
    }
    beste1=beste+obeste;
    bmi1=bmi;bmj1=bmj;
    bui1=bui;buj1=buj;

    // source mask
    vp8_makemask_sse3(y,u, v,
                        ym, yp, uvp,
                        sgm[0].y,sgm[0].u,sgm[0].v,
                        sgm[0].yt,sgm[0].ut,sgm[0].vt);

    vp8_growmaskmb_sse3(ym,ym2);

    // find best mask
    for(i=-32;i<32;i++)
    {
        unsigned char *dyz = i*dyp + dy;
        unsigned char *duz = i/2*duvp + du;
        unsigned char *dvz = i/2*duvp + dv;
        for(j=-32;j<32;j++)
        {
            // 0,0  masked destination
            vp8_makemask_sse3(dyz+j,duz+j/2, dvz+j/2, dym, dyp, duvp,
                              sgm[0].y,sgm[0].u,sgm[0].v,
                              sgm[0].yt,sgm[0].ut,sgm[0].vt);

            vp8_growmaskmb_sse3(dym,dym2);

            e = compare_masks(ym2, dym2);

            if(e<beste)
            {
                bmi=i;
                bmj=j;
                beste=e;
            }
        }
    }

    vp8_makemask_sse3(dy+bmi*dyp+bmj,du+bmi/2*duvp+bmj/2, dv+bmi/2*duvp+bmj/2,
                      dym, dyp, duvp,
                      sgm[0].y,sgm[0].u,sgm[0].v,
                      sgm[0].yt,sgm[0].ut,sgm[0].vt);

    vp8_growmaskmb_sse3(dym,dym2);

    obeste = vp8_sad16x16_masked_wmt(y, yp, dy+bmi*dyp+bmj, dyp, dym2 );

    beste = 0xffffffff;

    // find best unmasked mv
    for(i=-32;i<32;i++)
    {
        unsigned char *dyz = i*dyp + dy;
        for(j=-32;j<32;j++)
        {
            e = vp8_sad16x16_unmasked_wmt(y, yp, dyz+j, dyp, dym2 );

            if(e<beste)
            {
                bui=i;
                buj=j;
                beste=e;
            }
        }
    }
    beste += obeste;

    if(beste<beste1)
    {
        *mi = bmi;
        *mj = bmj;
        *ui = bui;
        *uj = buj;
        *wm = 1;
    }
    else
    {
        *mi = bmi1;
        *mj = bmj1;
        *ui = bui1;
        *uj = buj1;
        *wm = 0;
        beste=beste1;

    }
    return beste;
}

int predict_all(unsigned char *ym, unsigned char *um, unsigned char *vm,
                int ymp, int uvmp,
                unsigned char *yp, unsigned char *up, unsigned char *vp,
                int ypp, int uvpp,
                COLOR_SEG_ELEMENT sgm[],
                int count,
                int mi,
                int mj,
                int ui,
                int uj,
                int wm)
{
    int i,j;
    unsigned char dym[256];
    unsigned char dym2[256];
    unsigned char duvm[64];
    unsigned char *yu=ym,*uu=um, *vu=vm;

    unsigned char *dym3=dym2;

    ym+=mi*ymp+mj;
    um+=mi/2*uvmp+mj/2;
    vm+=mi/2*uvmp+mj/2;

    yu+=ui*ymp+uj;
    uu+=ui/2*uvmp+uj/2;
    vu+=ui/2*uvmp+uj/2;

    // best mv masked destination
    if(wm)
        vp8_makemask_sse3(ym,um, vm, dym, ymp, uvmp,
                              sgm[0].y,sgm[0].u,sgm[0].v,
                              sgm[0].yt,sgm[0].ut,sgm[0].vt);
    else
        vp8_makemask_sse3(yu,uu, vu, dym, ymp, uvmp,
                              sgm[0].y,sgm[0].u,sgm[0].v,
                              sgm[0].yt,sgm[0].ut,sgm[0].vt);

    vp8_growmaskmb_sse3(dym,dym2);
    vp8_masked_predictor_wmt(ym,yu,ymp,yp,ypp,dym3);
    vp8_uv_from_y_mask(dym3,duvm);
    vp8_masked_predictor_uv_wmt(um,uu,uvmp,up,uvpp,duvm);
    vp8_masked_predictor_uv_wmt(vm,vu,uvmp,vp,uvpp,duvm);

    return 0;
}

unsigned char f0p[1280*720*3/2];
unsigned char f1p[1280*720*3/2];
unsigned char prd[1280*720*3/2];
unsigned char msk[1280*720*3/2];


int mainz(int argc, char *argv[]) {

    FILE *f=fopen(argv[1],"rb");
    FILE *g=fopen(argv[2],"wb");
    int w=atoi(argv[3]),h=atoi(argv[4]);
    int y_stride=w,uv_stride=w/2;
    int r,c;
    unsigned char *f0=f0p,*f1=f1p,*t;
    unsigned char ym[256],uvm[64];
    unsigned char ym2[256],uvm2[64];
    unsigned char ym3[256],uvm3[64];
    int a,b;

    COLOR_SEG_ELEMENT last={ 20,20,20,20, 230,20, 1},best;
#if 0
    makeneighbors();
    COLOR_SEG_ELEMENT segmentation[]=
    {
        { 60,4,80,17,80,10, 1},
        { 40,4,15,10,80,10, 1},
    };
    make_mb_mask(y, u, v,ym2,uvm2,16,8,segmentation,1);

    vp8_makemask_sse3(y,u,v,ym, (int) 16,(int) 8,
                      (int) segmentation[0].y,(int) segmentation[0].u,(int) segmentation[0].v,
                      segmentation[0].yt,segmentation[0].ut,segmentation[0].vt);

    vp8_growmaskmb_sse3(ym,ym3);

    a = vp8_sad16x16_masked_wmt(str,16,sts,16,ym3);
    b = vp8_sad16x16_unmasked_wmt(str,16,sts,16,ym3);

    vp8_masked_predictor_wmt(str,sts,16,ym,16,ym3);

    vp8_uv_from_y_mask(ym3,uvm3);

    return 4;
#endif
    makeneighbors();


    memset(prd,128,w*h*3/2);

    fread(f0,w*h*3/2,1,f);

    while(!feof(f))
    {
        unsigned char *ys=f1,*yd=f0,*yp=prd;
        unsigned char *us=f1+w*h,*ud=f0+w*h,*up=prd+w*h;
        unsigned char *vs=f1+w*h*5/4,*vd=f0+w*h*5/4,*vp=prd+w*h*5/4;
        fread(f1,w*h*3/2,1,f);

        ys+=32*y_stride;yd+=32*y_stride;yp+=32*y_stride;
        us+=16*uv_stride;ud+=16*uv_stride;up+=16*uv_stride;
        vs+=16*uv_stride;vd+=16*uv_stride;vp+=16*uv_stride;
        for(r=32;r<h-32;r+=16,
            ys+=16*w,yd+=16*w,yp+=16*w,
            us+=8*uv_stride,ud+=8*uv_stride,up+=8*uv_stride,
            vs+=8*uv_stride,vd+=8*uv_stride,vp+=8*uv_stride)
        {
            for(c=32;c<w-32;c+=16)
            {
                int mi,mj,ui,uj,wm;
                int bmi,bmj,bui,buj,bwm;
                unsigned char ym[256];

                if(vp8_sad16x16_sse3( ys+c,y_stride, yd+c,y_stride,0xffff) == 0)
                    bmi=bmj=bui=buj=bwm=0;
                else
                {
                    COLOR_SEG_ELEMENT cs[5];
                    int j;
                    unsigned int beste=0xfffffff;
                    unsigned int bestj=0;

                    // try color from last mb segmentation
                    cs[0] = last;

                    // try color segs from 4 pixels in mb recon as segmentation
                    cs[1].y = yd[c + y_stride + 1];cs[1].u = ud[c/2 + uv_stride];
                    cs[1].v = vd[c/2 + uv_stride];
                    cs[1].yt = cs[1].ut = cs[1].vt = 20;
                    cs[2].y = yd[c + w + 14];
                    cs[2].u = ud[c/2 + uv_stride+7];
                    cs[2].v = vd[c/2 + uv_stride+7];
                    cs[2].yt = cs[2].ut = cs[2].vt = 20;
                    cs[3].y = yd[c + w*14 + 1];
                    cs[3].u = ud[c/2 + uv_stride*7];
                    cs[3].v = vd[c/2 + uv_stride*7];
                    cs[3].yt = cs[3].ut = cs[3].vt = 20;
                    cs[4].y = yd[c + w*14 + 14];
                    cs[4].u = ud[c/2 + uv_stride*7+7];
                    cs[4].v = vd[c/2 + uv_stride*7+7];
                    cs[4].yt = cs[4].ut = cs[4].vt = 20;

                    for(j=0;j<5;j++)
                    {
                        int e;

                        e = fast_masked_motion_search(
                           ys+c, us+c/2, vs+c/2, y_stride, uv_stride,
                           yd+c, ud+c/2, vd+c/2, y_stride, uv_stride,
                           &cs[j], 1, &mi,&mj,&ui,&uj,&wm);

                        if(e<beste)
                        {
                            bmi=mi;bmj=mj;bui=ui;buj=uj,bwm=wm;
                            bestj=j;
                            beste=e;
                        }
                    }
                    best = cs[bestj];
                    //best = segmentation[0];
                    last = best;
                }
                predict_all(yd+c, ud+c/2, vd+c/2, w, uv_stride,
                            yp+c, up+c/2, vp+c/2, w, uv_stride,
                            &best, 1, bmi,bmj,bui,buj,bwm);

            }
        }
        fwrite(prd,w*h*3/2,1,g);
        t=f0;
        f0=f1;
        f1=t;

    }
    fclose(f);
    fclose(g);
	return;
}