]> git.sesse.net Git - vlc/blob - modules/video_filter/hqdn3d.h
decoder: do not mix and match condidition variable and mutex pairings
[vlc] / modules / video_filter / hqdn3d.h
1 /*
2  * Copyright (C) 2003 Daniel Moreno <comac@comac.darktech.org>
3  *
4  * This file is part of MPlayer.
5  *
6  * MPlayer is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * MPlayer is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with MPlayer; if not, write to the Free Software Foundation, Inc.,
18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19  */
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <inttypes.h>
25 #include <math.h>
26
27 #define PARAM1_DEFAULT 4.0
28 #define PARAM2_DEFAULT 3.0
29 #define PARAM3_DEFAULT 6.0
30
31 //===========================================================================//
32
33 struct vf_priv_s {
34         int Coefs[4][512*16];
35         unsigned int *Line;
36         unsigned short *Frame[3];
37 };
38
39
40 /***************************************************************************/
41
42 static /*inline*/ unsigned int LowPassMul(unsigned int PrevMul, unsigned int CurrMul, int* Coef){
43 //    int dMul= (PrevMul&0xFFFFFF)-(CurrMul&0xFFFFFF);
44     int dMul= PrevMul-CurrMul;
45     unsigned int d=((dMul+0x10007FF)>>12);
46     return CurrMul + Coef[d];
47 }
48
49 static void deNoiseTemporal(
50                     unsigned char *Frame,        // mpi->planes[x]
51                     unsigned char *FrameDest,    // dmpi->planes[x]
52                     unsigned short *FrameAnt,
53                     int W, int H, int sStride, int dStride,
54                     int *Temporal)
55 {
56     long X, Y;
57     unsigned int PixelDst;
58
59     for (Y = 0; Y < H; Y++){
60         for (X = 0; X < W; X++){
61             PixelDst = LowPassMul(FrameAnt[X]<<8, Frame[X]<<16, Temporal);
62             FrameAnt[X] = ((PixelDst+0x1000007F)>>8);
63             FrameDest[X]= ((PixelDst+0x10007FFF)>>16);
64         }
65         Frame += sStride;
66         FrameDest += dStride;
67         FrameAnt += W;
68     }
69 }
70
71 static void deNoiseSpacial(
72                     unsigned char *Frame,        // mpi->planes[x]
73                     unsigned char *FrameDest,    // dmpi->planes[x]
74                     unsigned int *LineAnt,       // vf->priv->Line (width bytes)
75                     int W, int H, int sStride, int dStride,
76                     int *Horizontal, int *Vertical)
77 {
78     long X, Y;
79     long sLineOffs = 0, dLineOffs = 0;
80     unsigned int PixelAnt;
81     unsigned int PixelDst;
82
83     /* First pixel has no left nor top neighbor. */
84     PixelDst = LineAnt[0] = PixelAnt = Frame[0]<<16;
85     FrameDest[0]= ((PixelDst+0x10007FFF)>>16);
86
87     /* First line has no top neighbor, only left. */
88     for (X = 1; X < W; X++){
89         PixelDst = LineAnt[X] = LowPassMul(PixelAnt, Frame[X]<<16, Horizontal);
90         FrameDest[X]= ((PixelDst+0x10007FFF)>>16);
91     }
92
93     for (Y = 1; Y < H; Y++){
94         unsigned int PixelAnt;
95         sLineOffs += sStride, dLineOffs += dStride;
96         /* First pixel on each line doesn't have previous pixel */
97         PixelAnt = Frame[sLineOffs]<<16;
98         PixelDst = LineAnt[0] = LowPassMul(LineAnt[0], PixelAnt, Vertical);
99         FrameDest[dLineOffs]= ((PixelDst+0x10007FFF)>>16);
100
101         for (X = 1; X < W; X++){
102             unsigned int PixelDst;
103             /* The rest are normal */
104             PixelAnt = LowPassMul(PixelAnt, Frame[sLineOffs+X]<<16, Horizontal);
105             PixelDst = LineAnt[X] = LowPassMul(LineAnt[X], PixelAnt, Vertical);
106             FrameDest[dLineOffs+X]= ((PixelDst+0x10007FFF)>>16);
107         }
108     }
109 }
110
111 static void deNoise(unsigned char *Frame,        // mpi->planes[x]
112                     unsigned char *FrameDest,    // dmpi->planes[x]
113                     unsigned int *LineAnt,      // vf->priv->Line (width bytes)
114                     unsigned short **FrameAntPtr,
115                     int W, int H, int sStride, int dStride,
116                     int *Horizontal, int *Vertical, int *Temporal)
117 {
118     long X, Y;
119     long sLineOffs = 0, dLineOffs = 0;
120     unsigned int PixelAnt;
121     unsigned int PixelDst;
122     unsigned short* FrameAnt=(*FrameAntPtr);
123
124     if(!FrameAnt){
125         (*FrameAntPtr)=FrameAnt=malloc(W*H*sizeof(unsigned short));
126         for (Y = 0; Y < H; Y++){
127             unsigned short* dst=&FrameAnt[Y*W];
128             unsigned char* src=Frame+Y*sStride;
129             for (X = 0; X < W; X++) dst[X]=src[X]<<8;
130         }
131     }
132
133     if(!Horizontal[0] && !Vertical[0]){
134         deNoiseTemporal(Frame, FrameDest, FrameAnt,
135                         W, H, sStride, dStride, Temporal);
136         return;
137     }
138     if(!Temporal[0]){
139         deNoiseSpacial(Frame, FrameDest, LineAnt,
140                        W, H, sStride, dStride, Horizontal, Vertical);
141         return;
142     }
143
144     /* First pixel has no left nor top neighbor. Only previous frame */
145     LineAnt[0] = PixelAnt = Frame[0]<<16;
146     PixelDst = LowPassMul(FrameAnt[0]<<8, PixelAnt, Temporal);
147     FrameAnt[0] = ((PixelDst+0x1000007F)>>8);
148     FrameDest[0]= ((PixelDst+0x10007FFF)>>16);
149
150     /* First line has no top neighbor. Only left one for each pixel and
151      * last frame */
152     for (X = 1; X < W; X++){
153         LineAnt[X] = PixelAnt = LowPassMul(PixelAnt, Frame[X]<<16, Horizontal);
154         PixelDst = LowPassMul(FrameAnt[X]<<8, PixelAnt, Temporal);
155         FrameAnt[X] = ((PixelDst+0x1000007F)>>8);
156         FrameDest[X]= ((PixelDst+0x10007FFF)>>16);
157     }
158
159     for (Y = 1; Y < H; Y++){
160         unsigned int PixelAnt;
161         unsigned short* LinePrev=&FrameAnt[Y*W];
162         sLineOffs += sStride, dLineOffs += dStride;
163         /* First pixel on each line doesn't have previous pixel */
164         PixelAnt = Frame[sLineOffs]<<16;
165         LineAnt[0] = LowPassMul(LineAnt[0], PixelAnt, Vertical);
166         PixelDst = LowPassMul(LinePrev[0]<<8, LineAnt[0], Temporal);
167         LinePrev[0] = ((PixelDst+0x1000007F)>>8);
168         FrameDest[dLineOffs]= ((PixelDst+0x10007FFF)>>16);
169
170         for (X = 1; X < W; X++){
171             unsigned int PixelDst;
172             /* The rest are normal */
173             PixelAnt = LowPassMul(PixelAnt, Frame[sLineOffs+X]<<16, Horizontal);
174             LineAnt[X] = LowPassMul(LineAnt[X], PixelAnt, Vertical);
175             PixelDst = LowPassMul(LinePrev[X]<<8, LineAnt[X], Temporal);
176             LinePrev[X] = ((PixelDst+0x1000007F)>>8);
177             FrameDest[dLineOffs+X]= ((PixelDst+0x10007FFF)>>16);
178         }
179     }
180 }
181
182
183 //===========================================================================//
184
185 static void PrecalcCoefs(int *Ct, double Dist25)
186 {
187     int i;
188     double Gamma, Simil, C;
189
190     Gamma = log(0.25) / log(1.0 - Dist25/255.0 - 0.00001);
191
192     for (i = -255*16; i <= 255*16; i++)
193     {
194         Simil = 1.0 - abs(i) / (16*255.0);
195         C = pow(Simil, Gamma) * 65536.0 * (double)i / 16.0;
196         Ct[16*256+i] = (C<0) ? (C-0.5) : (C+0.5);
197     }
198
199     Ct[0] = (Dist25 != 0);
200 }
201
202
203 //===========================================================================//