summaryrefslogtreecommitdiffstats
path: root/libmpcodecs/vf_hqdn3d.c
diff options
context:
space:
mode:
authorlorenm <lorenm@b3059339-0415-0410-9bf9-f77b7e298cf2>2005-10-06 06:05:38 +0000
committerlorenm <lorenm@b3059339-0415-0410-9bf9-f77b7e298cf2>2005-10-06 06:05:38 +0000
commit3f9760f8e0b1d6725a90c9bab33f34aa916531ef (patch)
tree5b9e48389174223971c1f8792a2252a7136e97a0 /libmpcodecs/vf_hqdn3d.c
parentd05960762c030ca867f5b324dde7a6239d090357 (diff)
downloadmpv-3f9760f8e0b1d6725a90c9bab33f34aa916531ef.tar.bz2
mpv-3f9760f8e0b1d6725a90c9bab33f34aa916531ef.tar.xz
hqdn3d: 2.5x faster temporal-only, 1.6x faster spatial-only.
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@16683 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'libmpcodecs/vf_hqdn3d.c')
-rw-r--r--libmpcodecs/vf_hqdn3d.c77
1 files changed, 76 insertions, 1 deletions
diff --git a/libmpcodecs/vf_hqdn3d.c b/libmpcodecs/vf_hqdn3d.c
index ce59d0f66e..4a3168f132 100644
--- a/libmpcodecs/vf_hqdn3d.c
+++ b/libmpcodecs/vf_hqdn3d.c
@@ -73,6 +73,68 @@ static inline unsigned int LowPassMul(unsigned int PrevMul, unsigned int CurrMul
return CurrMul + Coef[d];
}
+static void deNoiseTemporal(
+ unsigned char *Frame, // mpi->planes[x]
+ unsigned char *FrameDest, // dmpi->planes[x]
+ unsigned short *FrameAnt,
+ int W, int H, int sStride, int dStride,
+ int *Temporal)
+{
+ int X, Y;
+ int PixelDst;
+
+ for (Y = 0; Y < H; Y++){
+ for (X = 0; X < W; X++){
+ PixelDst = LowPassMul(FrameAnt[X]<<8, Frame[X]<<16, Temporal);
+ FrameAnt[X] = ((PixelDst+0x1000007F)/256);
+ FrameDest[X]= ((PixelDst+0x10007FFF)/65536);
+ }
+ Frame += sStride;
+ FrameDest += dStride;
+ FrameAnt += W;
+ }
+}
+
+static void deNoiseSpacial(
+ unsigned char *Frame, // mpi->planes[x]
+ unsigned char *FrameDest, // dmpi->planes[x]
+ unsigned int *LineAnt, // vf->priv->Line (width bytes)
+ int W, int H, int sStride, int dStride,
+ int *Horizontal, int *Vertical)
+{
+ int X, Y;
+ int sLineOffs = 0, dLineOffs = 0;
+ unsigned int PixelAnt;
+ int PixelDst;
+
+ /* First pixel has no left nor top neightbour. */
+ PixelDst = LineAnt[0] = PixelAnt = Frame[0]<<16;
+ FrameDest[0]= ((PixelDst+0x10007FFF)/65536);
+
+ /* Fist line has no top neightbour, only left. */
+ for (X = 1; X < W; X++){
+ PixelDst = LineAnt[X] = LowPassMul(PixelAnt, Frame[X]<<16, Horizontal);
+ FrameDest[X]= ((PixelDst+0x10007FFF)/65536);
+ }
+
+ for (Y = 1; Y < H; Y++){
+ unsigned int PixelAnt;
+ sLineOffs += sStride, dLineOffs += dStride;
+ /* First pixel on each line doesn't have previous pixel */
+ PixelAnt = Frame[sLineOffs]<<16;
+ PixelDst = LineAnt[0] = LowPassMul(LineAnt[0], PixelAnt, Vertical);
+ FrameDest[dLineOffs]= ((PixelDst+0x10007FFF)/65536);
+
+ for (X = 1; X < W; X++){
+ int PixelDst;
+ /* The rest are normal */
+ PixelAnt = LowPassMul(PixelAnt, Frame[sLineOffs+X]<<16, Horizontal);
+ PixelDst = LineAnt[X] = LowPassMul(LineAnt[X], PixelAnt, Vertical);
+ FrameDest[dLineOffs+X]= ((PixelDst+0x10007FFF)/65536);
+ }
+ }
+}
+
static void deNoise(unsigned char *Frame, // mpi->planes[x]
unsigned char *FrameDest, // dmpi->planes[x]
unsigned int *LineAnt, // vf->priv->Line (width bytes)
@@ -95,6 +157,17 @@ static void deNoise(unsigned char *Frame, // mpi->planes[x]
}
}
+ if(!Horizontal[0] && !Vertical[0]){
+ deNoiseTemporal(Frame, FrameDest, FrameAnt,
+ W, H, sStride, dStride, Temporal);
+ return;
+ }
+ if(!Temporal[0]){
+ deNoiseSpacial(Frame, FrameDest, LineAnt,
+ W, H, sStride, dStride, Horizontal, Vertical);
+ return;
+ }
+
/* First pixel has no left nor top neightbour. Only previous frame */
LineAnt[0] = PixelAnt = Frame[0]<<16;
PixelDst = LowPassMul(FrameAnt[0]<<8, PixelAnt, Temporal);
@@ -194,12 +267,14 @@ static void PrecalcCoefs(int *Ct, double Dist25)
Gamma = log(0.25) / log(1.0 - Dist25/255.0 - 0.00001);
- for (i = -256*16; i < 256*16; i++)
+ for (i = -255*16; i <= 255*16; i++)
{
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);
}
+
+ Ct[0] = (Dist25 != 0);
}