Mercurial > mplayer.hg
annotate libmpcodecs/vf_hqdn3d.c @ 9593:e9a2af584986
Add the new -vf option wich is the same as vop in reverse order.
Syntax is we decided, so you can give the nomes or not with both
vop and vf. vf take precedence over vop.
author | albeu |
---|---|
date | Sat, 15 Mar 2003 18:01:02 +0000 |
parents | 85fa92f14e99 |
children | 5f98b89262c4 |
rev | line source |
---|---|
9441 | 1 /* |
2 Copyright (C) 2003 Daniel Moreno <comac@comac.darktech.org> | |
3 | |
4 This program is free software; you can redistribute it and/or modify | |
5 it under the terms of the GNU General Public License as published by | |
6 the Free Software Foundation; either version 2 of the License, or | |
7 (at your option) any later version. | |
8 | |
9 This program is distributed in the hope that it will be useful, | |
10 but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 GNU General Public License for more details. | |
13 | |
14 You should have received a copy of the GNU General Public License | |
15 along with this program; if not, write to the Free Software | |
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
17 */ | |
18 | |
19 #include <stdio.h> | |
20 #include <stdlib.h> | |
21 #include <string.h> | |
22 #include <inttypes.h> | |
23 #include <math.h> | |
24 | |
25 #include "../config.h" | |
26 #include "../mp_msg.h" | |
27 | |
28 #ifdef HAVE_MALLOC_H | |
29 #include <malloc.h> | |
30 #endif | |
31 | |
32 #include "img_format.h" | |
33 #include "mp_image.h" | |
34 #include "vf.h" | |
35 #include "../libvo/fastmemcpy.h" | |
36 | |
37 #define PARAM1_DEFAULT 4.0 | |
38 #define PARAM2_DEFAULT 3.0 | |
39 #define PARAM3_DEFAULT 6.0 | |
40 | |
41 //===========================================================================// | |
42 | |
43 struct vf_priv_s { | |
44 int Coefs[4][512*16]; | |
45 unsigned int *Line; | |
46 unsigned short *Frame[3]; | |
47 }; | |
48 | |
49 | |
50 /***************************************************************************/ | |
51 | |
52 static void uninit(struct vf_instance_s* vf){ | |
53 if(vf->priv->Line){free(vf->priv->Line);vf->priv->Line=NULL;} | |
54 if(vf->priv->Frame[0]){free(vf->priv->Frame[0]);vf->priv->Frame[0]=NULL;} | |
55 if(vf->priv->Frame[1]){free(vf->priv->Frame[1]);vf->priv->Frame[1]=NULL;} | |
56 if(vf->priv->Frame[2]){free(vf->priv->Frame[2]);vf->priv->Frame[2]=NULL;} | |
57 } | |
58 | |
59 static int config(struct vf_instance_s* vf, | |
60 int width, int height, int d_width, int d_height, | |
61 unsigned int flags, unsigned int outfmt){ | |
62 | |
63 uninit(vf); | |
64 vf->priv->Line = malloc(width*sizeof(int)); | |
65 | |
66 return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt); | |
67 } | |
68 | |
69 static inline unsigned int LowPassMul(unsigned int PrevMul, unsigned int CurrMul, int* Coef){ | |
70 // int dMul= (PrevMul&0xFFFFFF)-(CurrMul&0xFFFFFF); | |
71 int dMul= PrevMul-CurrMul; | |
72 int d=((dMul+0x10007FF)/(65536/16)); | |
73 return CurrMul + Coef[d]; | |
74 } | |
75 | |
76 static void deNoise(unsigned char *Frame, // mpi->planes[x] | |
77 unsigned char *FrameDest, // dmpi->planes[x] | |
78 unsigned int *LineAnt, // vf->priv->Line (width bytes) | |
79 unsigned short **FrameAntPtr, | |
80 int W, int H, int sStride, int dStride, | |
81 int *Horizontal, int *Vertical, int *Temporal) | |
82 { | |
83 int X, Y; | |
84 int sLineOffs = 0, dLineOffs = 0; | |
85 unsigned int PixelAnt; | |
86 int PixelDst; | |
87 unsigned short* FrameAnt=(*FrameAntPtr); | |
88 | |
89 if(!FrameAnt){ | |
90 (*FrameAntPtr)=FrameAnt=malloc(W*H*sizeof(unsigned short)); | |
91 for (Y = 0; Y < H; Y++){ | |
92 unsigned short* dst=&FrameAnt[Y*W]; | |
93 unsigned char* src=Frame+Y*sStride; | |
94 for (X = 0; X < W; X++) dst[X]=src[X]<<8; | |
95 } | |
96 } | |
97 | |
98 /* First pixel has no left nor top neightbour. Only previous frame */ | |
99 LineAnt[0] = PixelAnt = Frame[0]<<16; | |
100 PixelDst = LowPassMul(FrameAnt[0]<<8, PixelAnt, Temporal); | |
101 FrameAnt[0] = ((PixelDst+0x1000007F)/256); | |
102 FrameDest[0]= ((PixelDst+0x10007FFF)/65536); | |
103 | |
104 /* Fist line has no top neightbour. Only left one for each pixel and | |
105 * last frame */ | |
106 for (X = 1; X < W; X++){ | |
107 LineAnt[X] = PixelAnt = LowPassMul(PixelAnt, Frame[X]<<16, Horizontal); | |
108 PixelDst = LowPassMul(FrameAnt[X]<<8, PixelAnt, Temporal); | |
109 FrameAnt[X] = ((PixelDst+0x1000007F)/256); | |
110 FrameDest[X]= ((PixelDst+0x10007FFF)/65536); | |
111 } | |
112 | |
113 for (Y = 1; Y < H; Y++){ | |
114 unsigned int PixelAnt; | |
115 unsigned short* LinePrev=&FrameAnt[Y*W]; | |
116 sLineOffs += sStride, dLineOffs += dStride; | |
117 /* First pixel on each line doesn't have previous pixel */ | |
118 PixelAnt = Frame[sLineOffs]<<16; | |
119 LineAnt[0] = LowPassMul(LineAnt[0], PixelAnt, Vertical); | |
120 PixelDst = LowPassMul(LinePrev[0]<<8, LineAnt[0], Temporal); | |
121 LinePrev[0] = ((PixelDst+0x1000007F)/256); | |
122 FrameDest[dLineOffs]= ((PixelDst+0x10007FFF)/65536); | |
123 | |
124 for (X = 1; X < W; X++){ | |
125 int PixelDst; | |
126 /* The rest are normal */ | |
127 PixelAnt = LowPassMul(PixelAnt, Frame[sLineOffs+X]<<16, Horizontal); | |
128 LineAnt[X] = LowPassMul(LineAnt[X], PixelAnt, Vertical); | |
129 PixelDst = LowPassMul(LinePrev[X]<<8, LineAnt[X], Temporal); | |
130 LinePrev[X] = ((PixelDst+0x1000007F)/256); | |
131 FrameDest[dLineOffs+X]= ((PixelDst+0x10007FFF)/65536); | |
132 } | |
133 } | |
134 } | |
135 | |
136 | |
137 static int put_image(struct vf_instance_s* vf, mp_image_t *mpi){ | |
138 int cw= mpi->w >> mpi->chroma_x_shift; | |
139 int ch= mpi->h >> mpi->chroma_y_shift; | |
140 int W = mpi->w, H = mpi->h; | |
141 | |
142 mp_image_t *dmpi=vf_get_image(vf->next,mpi->imgfmt, | |
143 MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE, | |
144 mpi->w,mpi->h); | |
145 | |
146 if(!dmpi) return 0; | |
147 | |
148 deNoise(mpi->planes[0], dmpi->planes[0], | |
149 vf->priv->Line, &vf->priv->Frame[0], W, H, | |
150 mpi->stride[0], dmpi->stride[0], | |
151 vf->priv->Coefs[0], | |
152 vf->priv->Coefs[0], | |
153 vf->priv->Coefs[1]); | |
154 deNoise(mpi->planes[1], dmpi->planes[1], | |
155 vf->priv->Line, &vf->priv->Frame[1], cw, ch, | |
156 mpi->stride[1], dmpi->stride[1], | |
157 vf->priv->Coefs[2], | |
158 vf->priv->Coefs[2], | |
159 vf->priv->Coefs[3]); | |
160 deNoise(mpi->planes[2], dmpi->planes[2], | |
161 vf->priv->Line, &vf->priv->Frame[2], cw, ch, | |
162 mpi->stride[2], dmpi->stride[2], | |
163 vf->priv->Coefs[2], | |
164 vf->priv->Coefs[2], | |
165 vf->priv->Coefs[3]); | |
166 | |
167 return vf_next_put_image(vf,dmpi); | |
168 } | |
169 | |
170 //===========================================================================// | |
171 | |
172 static int query_format(struct vf_instance_s* vf, unsigned int fmt){ | |
173 switch(fmt) | |
174 { | |
175 case IMGFMT_YV12: | |
176 case IMGFMT_I420: | |
177 case IMGFMT_IYUV: | |
178 case IMGFMT_YVU9: | |
179 case IMGFMT_444P: | |
180 case IMGFMT_422P: | |
181 case IMGFMT_411P: | |
182 return vf_next_query_format(vf, fmt); | |
183 } | |
184 return 0; | |
185 } | |
186 | |
187 | |
188 #define ABS(A) ( (A) > 0 ? (A) : -(A) ) | |
189 | |
190 static void PrecalcCoefs(int *Ct, double Dist25) | |
191 { | |
192 int i; | |
193 double Gamma, Simil, C; | |
194 | |
195 Gamma = log(0.25) / log(1.0 - Dist25/255.0 - 0.00001); | |
196 | |
197 for (i = -256*16; i < 256*16; i++) | |
198 { | |
199 Simil = 1.0 - ABS(i) / (16*255.0); | |
200 C = pow(Simil, Gamma) * 65536.0 * (double)i / 16.0; | |
201 Ct[16*256+i] = (C<0) ? (C-0.5) : (C+0.5); | |
202 } | |
203 } | |
204 | |
205 | |
206 static int open(vf_instance_t *vf, char* args){ | |
207 double LumSpac, LumTmp, ChromSpac, ChromTmp; | |
208 double Param1, Param2, Param3, Param4; | |
209 | |
210 vf->config=config; | |
211 vf->put_image=put_image; | |
212 vf->query_format=query_format; | |
213 vf->uninit=uninit; | |
214 vf->priv=malloc(sizeof(struct vf_priv_s)); | |
215 memset(vf->priv, 0, sizeof(struct vf_priv_s)); | |
216 | |
217 if (args) | |
218 { | |
219 switch(sscanf(args, "%lf:%lf:%lf:%lf", | |
220 &Param1, &Param2, &Param3, &Param4 | |
221 )) | |
222 { | |
223 case 0: | |
224 LumSpac = PARAM1_DEFAULT; | |
225 LumTmp = PARAM3_DEFAULT; | |
226 | |
227 ChromSpac = PARAM2_DEFAULT; | |
228 ChromTmp = LumTmp * ChromSpac / LumSpac; | |
229 break; | |
230 | |
231 case 1: | |
232 LumSpac = Param1; | |
233 LumTmp = PARAM3_DEFAULT * Param1 / PARAM1_DEFAULT; | |
234 | |
235 ChromSpac = PARAM2_DEFAULT * Param1 / PARAM1_DEFAULT; | |
236 ChromTmp = LumTmp * ChromSpac / LumSpac; | |
237 break; | |
238 | |
239 case 2: | |
240 LumSpac = Param1; | |
241 LumTmp = PARAM3_DEFAULT * Param1 / PARAM1_DEFAULT; | |
242 | |
243 ChromSpac = Param2; | |
244 ChromTmp = LumTmp * ChromSpac / LumSpac; | |
245 break; | |
246 | |
247 case 3: | |
248 LumSpac = Param1; | |
249 LumTmp = Param3; | |
250 | |
251 ChromSpac = Param2; | |
252 ChromTmp = LumTmp * ChromSpac / LumSpac; | |
253 break; | |
254 | |
255 case 4: | |
256 LumSpac = Param1; | |
257 LumTmp = Param3; | |
258 | |
259 ChromSpac = Param2; | |
260 ChromTmp = Param4; | |
261 break; | |
262 | |
263 default: | |
264 LumSpac = PARAM1_DEFAULT; | |
265 LumTmp = PARAM3_DEFAULT; | |
266 | |
267 ChromSpac = PARAM2_DEFAULT; | |
268 ChromTmp = LumTmp * ChromSpac / LumSpac; | |
269 } | |
270 } | |
271 else | |
272 { | |
273 LumSpac = PARAM1_DEFAULT; | |
274 LumTmp = PARAM3_DEFAULT; | |
275 | |
276 ChromSpac = PARAM2_DEFAULT; | |
277 ChromTmp = LumTmp * ChromSpac / LumSpac; | |
278 } | |
279 | |
280 PrecalcCoefs(vf->priv->Coefs[0], LumSpac); | |
281 PrecalcCoefs(vf->priv->Coefs[1], LumTmp); | |
282 PrecalcCoefs(vf->priv->Coefs[2], ChromSpac); | |
283 PrecalcCoefs(vf->priv->Coefs[3], ChromTmp); | |
284 | |
285 return 1; | |
286 } | |
287 | |
288 vf_info_t vf_info_hqdn3d = { | |
289 "High Quality 3D Denoiser", | |
290 "hqdn3d", | |
291 "Daniel Moreno & A'rpi", | |
292 "", | |
9593
e9a2af584986
Add the new -vf option wich is the same as vop in reverse order.
albeu
parents:
9441
diff
changeset
|
293 open, |
e9a2af584986
Add the new -vf option wich is the same as vop in reverse order.
albeu
parents:
9441
diff
changeset
|
294 NULL |
9441 | 295 }; |
296 | |
297 //===========================================================================// |