[MPlayer-dev-eng] [PATCH] denoise3d increaed precission
Arpi
arpi at thot.banki.hu
Sun Feb 9 15:36:23 CET 2003
Hi,
I've spent some (too much) time optimizing denoise3d.c, and especially
increasing the precission of the calculations, since i can see accumulated
rounding errors on the screen sometimes.
The reason is simple. The main equation it uses is LowPass, after cleanup:
#define LowPass(Prev, Curr, Coef) (Curr + Coef[Prev - Curr])
Curr is the current pixel, (Prev - Curr) is the difference from
left/top/previousframe pixel. SO teh crrection factor (Coeff[]) depends
on the pixel difference, which is often a small number, mostly in -5..+5
range. It means quite high rounding errors (+-0.5 compared to +-5)...
Ok, i've changed it to use 16.16 fixed point and 16 times bigger Coeff[]
table. Patch for testing/optinions/etc:
( do not commit this because it's freezee, and it may be slower or even
buggy at some contexts )
Index: vf_denoise3d.c
===================================================================
RCS file: /cvsroot/mplayer/main/libmpcodecs/vf_denoise3d.c,v
retrieving revision 1.4
diff -u -r1.4 vf_denoise3d.c
--- vf_denoise3d.c 9 Feb 2003 12:51:59 -0000 1.4
+++ vf_denoise3d.c 9 Feb 2003 14:30:11 -0000
@@ -41,8 +41,8 @@
//===========================================================================//
struct vf_priv_s {
- int Coefs[4][512];
- unsigned char *Line;
+ int Coefs[4][512*16];
+ unsigned int *Line;
mp_image_t *pmpi;
};
@@ -55,7 +55,7 @@
unsigned int flags, unsigned int outfmt){
if(vf->priv->Line) free(vf->priv->Line);
- vf->priv->Line = malloc(width);
+ vf->priv->Line = malloc(width*sizeof(int));
vf->priv->pmpi=NULL;
// vf->default_caps &= !VFCAP_ACCEPT_STRIDE;
@@ -68,46 +68,57 @@
free(vf->priv->Line);
}
-#define LowPass(Prev, Curr, Coef) (Curr + Coef[Prev - Curr])
+static inline unsigned int LowPassMul(unsigned int PrevMul, unsigned int CurrMul, int* Coef){
+// int dMul= (PrevMul&0xFFFFFF)-(CurrMul&0xFFFFFF);
+ int dMul= PrevMul-CurrMul;
+ int d=((dMul+0x10007FF)/(65536/16));
+ return CurrMul + Coef[d];
+}
+
+static inline unsigned char LowPassMulPix(unsigned int PrevMul, unsigned int CurrMul, int* Coef){
+ int x=LowPassMul(PrevMul,CurrMul,Coef);
+ unsigned int r=((x+0x10007FFF)/65536);
+ return r; // & 0xFF;
+}
static void deNoise(unsigned char *Frame, // mpi->planes[x]
unsigned char *FramePrev, // pmpi->planes[x]
unsigned char *FrameDest, // dmpi->planes[x]
- unsigned char *LineAnt, // vf->priv->Line (width bytes)
+ unsigned int *LineAnt, // vf->priv->Line (width bytes)
int W, int H, int sStride, int pStride, int dStride,
int *Horizontal, int *Vertical, int *Temporal)
{
int X, Y;
int sLineOffs = 0, pLineOffs = 0, dLineOffs = 0;
- unsigned char PixelAnt;
+ unsigned int PixelAnt;
/* First pixel has no left nor top neightbour. Only previous frame */
- LineAnt[0] = PixelAnt = Frame[0];
- FrameDest[0] = LowPass(FramePrev[0], LineAnt[0], Temporal);
+ LineAnt[0] = PixelAnt = Frame[0]<<16;
+ FrameDest[0] = LowPassMulPix(FramePrev[0]<<16, PixelAnt, Temporal);
/* Fist line has no top neightbour. Only left one for each pixel and
* last frame */
for (X = 1; X < W; X++)
{
- PixelAnt = LowPass(PixelAnt, Frame[X], Horizontal);
+ PixelAnt = LowPassMul(PixelAnt, Frame[X]<<16, Horizontal);
LineAnt[X] = PixelAnt;
- FrameDest[X] = LowPass(FramePrev[X], LineAnt[X], Temporal);
+ FrameDest[X] = LowPassMulPix(FramePrev[X]<<16, LineAnt[X], Temporal);
}
for (Y = 1; Y < H; Y++)
{
sLineOffs += sStride, pLineOffs += pStride, dLineOffs += dStride;
/* First pixel on each line doesn't have previous pixel */
- PixelAnt = Frame[sLineOffs];
- LineAnt[0] = LowPass(LineAnt[0], PixelAnt, Vertical);
- FrameDest[dLineOffs] = LowPass(FramePrev[pLineOffs], LineAnt[0], Temporal);
+ PixelAnt = Frame[sLineOffs]<<16;
+ LineAnt[0] = LowPassMul(LineAnt[0], PixelAnt, Vertical);
+ FrameDest[dLineOffs] = LowPassMulPix(FramePrev[pLineOffs]<<16, LineAnt[0], Temporal);
for (X = 1; X < W; X++)
{
/* The rest are normal */
- PixelAnt = LowPass(PixelAnt, Frame[sLineOffs+X], Horizontal);
- LineAnt[X] = LowPass(LineAnt[X], PixelAnt, Vertical);
- FrameDest[dLineOffs+X] = LowPass(FramePrev[pLineOffs+X], LineAnt[X], Temporal);
+ PixelAnt = LowPassMul(PixelAnt, Frame[sLineOffs+X]<<16, Horizontal);
+ LineAnt[X] = LowPassMul(LineAnt[X], PixelAnt, Vertical);
+ FrameDest[dLineOffs+X] = LowPassMulPix(FramePrev[pLineOffs+X]<<16, LineAnt[X], Temporal);
}
}
}
@@ -129,21 +140,21 @@
deNoise(mpi->planes[0], vf->priv->pmpi->planes[0], dmpi->planes[0],
vf->priv->Line, W, H,
mpi->stride[0], vf->priv->pmpi->stride[0], dmpi->stride[0],
- vf->priv->Coefs[0] + 256,
- vf->priv->Coefs[0] + 256,
- vf->priv->Coefs[1] + 256);
+ vf->priv->Coefs[0],
+ vf->priv->Coefs[0],
+ vf->priv->Coefs[1]);
deNoise(mpi->planes[1], vf->priv->pmpi->planes[1], dmpi->planes[1],
vf->priv->Line, cw, ch,
mpi->stride[1], vf->priv->pmpi->stride[1], dmpi->stride[1],
- vf->priv->Coefs[2] + 256,
- vf->priv->Coefs[2] + 256,
- vf->priv->Coefs[3] + 256);
+ vf->priv->Coefs[2],
+ vf->priv->Coefs[2],
+ vf->priv->Coefs[3]);
deNoise(mpi->planes[2], vf->priv->pmpi->planes[2], dmpi->planes[2],
vf->priv->Line, cw, ch,
mpi->stride[2], vf->priv->pmpi->stride[2], dmpi->stride[2],
- vf->priv->Coefs[2] + 256,
- vf->priv->Coefs[2] + 256,
- vf->priv->Coefs[3] + 256);
+ vf->priv->Coefs[2],
+ vf->priv->Coefs[2],
+ vf->priv->Coefs[3]);
vf->priv->pmpi=dmpi; // save reference image
return vf_next_put_image(vf,dmpi);
@@ -176,12 +187,11 @@
Gamma = log(0.25) / log(1.0 - Dist25/255.0);
- for (i = -256; i <= 255; i++)
+ for (i = -256*16; i < 256*16; i++)
{
- Simil = 1.0 - ABS(i) / 255.0;
-// Ct[256+i] = lround(pow(Simil, Gamma) * (double)i);
- C = pow(Simil, Gamma) * (double)i;
- Ct[256+i] = (C<0) ? (C-0.5) : (C+0.5);
+ Simil = 1.0 - ABS(i) / (16*255.0);
+ C = pow(Simil, Gamma) * 65536.0 * (double)i / 16.0;
+ Ct[16*256+i] = (C<0) ? (C-0.5) : (C+0.5);
}
}
A'rpi / Astral & ESP-team
--
Developer of MPlayer, the Movie Player for Linux - http://www.MPlayerHQ.hu
"However, many people beg for its inclusion in Debian. Why?" - Gabucino
"Because having new software in Debian is good." - Josselin Mouette
"Because having good software in Debian is new." - Gabucino
More information about the MPlayer-dev-eng
mailing list