19 |
#define SIGN(X) (((X)>0)?1:-1) |
#define SIGN(X) (((X)>0)?1:-1) |
20 |
#endif |
#endif |
21 |
|
|
22 |
|
#ifndef RSHIFT |
23 |
|
#define RSHIFT(a,b) ((a) > 0 ? ((a) + (1<<((b)-1)))>>(b) : ((a) + (1<<((b)-1))-1)>>(b)) |
24 |
|
#endif |
25 |
|
|
26 |
|
/* assume b>0 */ |
27 |
|
#ifndef ROUNDED_DIV |
28 |
|
#define ROUNDED_DIV(a,b) (((a)>0 ? (a) + ((b)>>1) : (a) - ((b)>>1))/(b)) |
29 |
|
#endif |
30 |
|
|
31 |
|
|
32 |
/* This is borrowed from decoder.c */ |
/* This is borrowed from decoder.c */ |
33 |
static __inline int gmc_sanitize(int value, int quarterpel, int fcode) |
static __inline int gmc_sanitize(int value, int quarterpel, int fcode) |
641 |
/* i2s and i2ss are only needed for num_wp == 3, etc. */ |
/* i2s and i2ss are only needed for num_wp == 3, etc. */ |
642 |
|
|
643 |
/* the 'ss' values are in 1/16 pel resolution */ |
/* the 'ss' values are in 1/16 pel resolution */ |
644 |
gmc->i1ss = 16*gmc->Ws + ((gmc->W-gmc->Ws)*(gmc->r*gmc->i0s) + gmc->Ws*(gmc->r*gmc->i1s - 16*gmc->W)) / gmc->W; |
gmc->i1ss = 16*gmc->Ws + ROUNDED_DIV(((gmc->W-gmc->Ws)*(gmc->r*gmc->i0s) + gmc->Ws*(gmc->r*gmc->i1s - 16*gmc->W)),gmc->W); |
645 |
gmc->j1ss = ((gmc->W - gmc->Ws)*(gmc->r*gmc->j0s) + gmc->Ws*gmc->r*gmc->j1s) / gmc->W; |
gmc->j1ss = ROUNDED_DIV( ((gmc->W - gmc->Ws)*(gmc->r*gmc->j0s) + gmc->Ws*gmc->r*gmc->j1s) ,gmc->W ); |
646 |
|
|
647 |
// gmc->i2ss = ((gmc->H - gmc->Hs)*(gmc->r*gmc->i0s) + gmc->Hs*(gmc->r*gmc->i2s)) / gmc->H; |
// gmc->i2ss = ROUNDED_DIV( ((gmc->H - gmc->Hs)*(gmc->r*gmc->i0s) + gmc->Hs*(gmc->r*gmc->i2s)), gmc->H); |
648 |
// gmc->j2ss = 16*gmc->Hs + ((gmc->H-gmc->Hs)*(gmc->r*gmc->j0s) + gmc->Ws*(gmc->r*gmc->j2s - 16*gmc->H)) / gmc->H; |
// gmc->j2ss = 16*gmc->Hs + ROUNDED_DIV( ((gmc->H-gmc->Hs)*(gmc->r*gmc->j0s) + gmc->Ws*(gmc->r*gmc->j2s - 16*gmc->H)), gmc->H); |
649 |
|
|
650 |
return; |
return; |
651 |
} |
} |
842 |
pGMC->v[J*stride2+I] = (uint8_t)C00; /* output 1 V-pixel */ |
pGMC->v[J*stride2+I] = (uint8_t)C00; /* output 1 V-pixel */ |
843 |
} |
} |
844 |
|
|
845 |
|
/* The average vector is rounded from 1/s-pel to 1/2 or 1/4 using the '//' operator*/ |
846 |
|
|
847 |
|
avgMV.x = RSHIFT( avgMV.x, (sigma+7-quarterpel) ); |
848 |
|
avgMV.y = RSHIFT( avgMV.y, (sigma+7-quarterpel) ); |
849 |
|
|
850 |
/* The average vector is rounded from 1/s-pel to 1/2 or 1/4 */ |
/* ^^^^ this is the way MS Reference Software does it */ |
|
if (quarterpel) |
|
|
{ /* >>8 because of 256 terms in sum, >>(sigma-2) to obtain 1/4th-pel */ |
|
|
avgMV.x = ( (avgMV.x + (1<<(sigma+5)) )>>(sigma+6) ); |
|
|
avgMV.y = ( (avgMV.y + (1<<(sigma+5)) )>>(sigma+6) ); |
|
|
} |
|
|
else |
|
|
{ /* >>8 because of 256 terms in sum, >>(sigma-1) to obtain 1/2th-pel */ |
|
|
avgMV.x = ( (avgMV.x + (1<<(sigma+6)))>>(sigma+7) ); |
|
|
avgMV.y = ( (avgMV.y + (1<<(sigma+6)))>>(sigma+7) ); |
|
|
} /* TODO: Check if this is correct way of rounding */ |
|
851 |
|
|
852 |
return avgMV; /* clipping to fcode area is done outside! */ |
return avgMV; /* clipping to fcode area is done outside! */ |
853 |
} |
} |