Mercurial > mplayer.hg
comparison libmpcodecs/vf_smartblur.c @ 8106:7aa3dba949f1
smartblur
author | michael |
---|---|
date | Mon, 04 Nov 2002 20:39:27 +0000 |
parents | |
children | 442ea8b6733c |
comparison
equal
deleted
inserted
replaced
8105:057c9c3f3312 | 8106:7aa3dba949f1 |
---|---|
1 /* | |
2 Copyright (C) 2002 Michael Niedermayer <michaelni@gmx.at> | |
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 <assert.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 #include "../postproc/swscale.h" | |
37 | |
38 //===========================================================================// | |
39 | |
40 typedef struct FilterParam{ | |
41 float radius; | |
42 float strength; | |
43 int threshold; | |
44 float quality; | |
45 SwsContext *filterContext; | |
46 }FilterParam; | |
47 | |
48 struct vf_priv_s { | |
49 FilterParam luma; | |
50 FilterParam chroma; | |
51 }; | |
52 | |
53 | |
54 /***************************************************************************/ | |
55 | |
56 //FIXME stupid code duplication | |
57 static void getSubSampleFactors(int *h, int *v, int format){ | |
58 switch(format){ | |
59 case IMGFMT_YV12: | |
60 case IMGFMT_I420: | |
61 *h=1; | |
62 *v=1; | |
63 break; | |
64 case IMGFMT_YVU9: | |
65 *h=2; | |
66 *v=2; | |
67 break; | |
68 case IMGFMT_444P: | |
69 *h=0; | |
70 *v=0; | |
71 break; | |
72 case IMGFMT_422P: | |
73 *h=1; | |
74 *v=0; | |
75 break; | |
76 case IMGFMT_411P: | |
77 *h=2; | |
78 *v=0; | |
79 break; | |
80 } | |
81 } | |
82 | |
83 static int allocStuff(FilterParam *f, int width, int height){ | |
84 SwsVector *vec; | |
85 SwsFilter swsF; | |
86 | |
87 vec = getGaussianVec(f->radius, f->quality); | |
88 scaleVec(vec, f->strength); | |
89 vec->coeff[vec->length/2]+= 1.0 - f->strength; | |
90 swsF.lumH= swsF.lumV= vec; | |
91 swsF.chrH= swsF.chrV= NULL; | |
92 f->filterContext= getSwsContext( | |
93 width, height, IMGFMT_Y8, width, height, IMGFMT_Y8, 0, &swsF, NULL); | |
94 | |
95 freeVec(vec); | |
96 | |
97 return 0; | |
98 } | |
99 | |
100 static int config(struct vf_instance_s* vf, | |
101 int width, int height, int d_width, int d_height, | |
102 unsigned int flags, unsigned int outfmt){ | |
103 | |
104 int sw, sh; | |
105 | |
106 allocStuff(&vf->priv->luma, width, height); | |
107 | |
108 getSubSampleFactors(&sw, &sh, outfmt); | |
109 allocStuff(&vf->priv->chroma, width>>sw, height>>sh); | |
110 | |
111 return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt); | |
112 } | |
113 | |
114 static void freeBuffers(FilterParam *f){ | |
115 if(f->filterContext) freeSwsContext(f->filterContext); | |
116 f->filterContext=NULL; | |
117 } | |
118 | |
119 static void uninit(struct vf_instance_s* vf){ | |
120 if(!vf->priv) return; | |
121 | |
122 freeBuffers(&vf->priv->luma); | |
123 freeBuffers(&vf->priv->chroma); | |
124 | |
125 free(vf->priv); | |
126 vf->priv=NULL; | |
127 } | |
128 | |
129 static inline void blur(uint8_t *dst, uint8_t *src, int w, int h, int dstStride, int srcStride, FilterParam *fp){ | |
130 int x, y; | |
131 FilterParam f= *fp; | |
132 uint8_t *srcArray[3]= {src, NULL, NULL}; | |
133 uint8_t *dstArray[3]= {dst, NULL, NULL}; | |
134 int srcStrideArray[3]= {srcStride, 0, 0}; | |
135 int dstStrideArray[3]= {dstStride, 0, 0}; | |
136 | |
137 f.filterContext->swScale(f.filterContext, srcArray, srcStrideArray, 0, h, dstArray, dstStrideArray); | |
138 | |
139 if(f.threshold > 0){ | |
140 for(y=0; y<h; y++){ | |
141 for(x=0; x<w; x++){ | |
142 const int orig= src[x + y*srcStride]; | |
143 const int filtered= dst[x + y*dstStride]; | |
144 const int diff= orig - filtered; | |
145 | |
146 if(diff > 0){ | |
147 if(diff > 2*f.threshold){ | |
148 dst[x + y*dstStride]= orig; | |
149 }else if(diff > f.threshold){ | |
150 dst[x + y*dstStride]= filtered + diff - f.threshold; | |
151 } | |
152 }else{ | |
153 if(-diff > 2*f.threshold){ | |
154 dst[x + y*dstStride]= orig; | |
155 }else if(-diff > f.threshold){ | |
156 dst[x + y*dstStride]= filtered + diff + f.threshold; | |
157 } | |
158 } | |
159 } | |
160 } | |
161 }else if(f.threshold < 0){ | |
162 for(y=0; y<h; y++){ | |
163 for(x=0; x<w; x++){ | |
164 const int orig= src[x + y*srcStride]; | |
165 const int filtered= dst[x + y*dstStride]; | |
166 const int diff= orig - filtered; | |
167 | |
168 if(diff > 0){ | |
169 if(diff > -2*f.threshold){ | |
170 }else if(diff > -f.threshold){ | |
171 dst[x + y*dstStride]= orig - diff - f.threshold; | |
172 }else | |
173 dst[x + y*dstStride]= orig; | |
174 }else{ | |
175 if(diff < 2*f.threshold){ | |
176 }else if(diff < f.threshold){ | |
177 dst[x + y*dstStride]= orig - diff + f.threshold; | |
178 }else | |
179 dst[x + y*dstStride]= orig; | |
180 } | |
181 } | |
182 } | |
183 } | |
184 } | |
185 | |
186 static int put_image(struct vf_instance_s* vf, mp_image_t *mpi){ | |
187 int cw= mpi->w >> mpi->chroma_x_shift; | |
188 int ch= mpi->h >> mpi->chroma_y_shift; | |
189 | |
190 mp_image_t *dmpi=vf_get_image(vf->next,mpi->imgfmt, | |
191 MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE, | |
192 mpi->w,mpi->h); | |
193 | |
194 assert(mpi->flags&MP_IMGFLAG_PLANAR); | |
195 | |
196 blur(dmpi->planes[0], mpi->planes[0], mpi->w,mpi->h, dmpi->stride[0], mpi->stride[0], &vf->priv->luma); | |
197 blur(dmpi->planes[1], mpi->planes[1], cw , ch , dmpi->stride[1], mpi->stride[1], &vf->priv->chroma); | |
198 blur(dmpi->planes[2], mpi->planes[2], cw , ch , dmpi->stride[2], mpi->stride[2], &vf->priv->chroma); | |
199 | |
200 return vf_next_put_image(vf,dmpi); | |
201 } | |
202 | |
203 //===========================================================================// | |
204 | |
205 static int query_format(struct vf_instance_s* vf, unsigned int fmt){ | |
206 switch(fmt) | |
207 { | |
208 case IMGFMT_YV12: | |
209 case IMGFMT_I420: | |
210 case IMGFMT_IYUV: | |
211 case IMGFMT_YVU9: | |
212 case IMGFMT_444P: | |
213 case IMGFMT_422P: | |
214 case IMGFMT_411P: | |
215 return vf_next_query_format(vf, fmt); | |
216 } | |
217 return 0; | |
218 } | |
219 | |
220 static int open(vf_instance_t *vf, char* args){ | |
221 int e; | |
222 | |
223 vf->config=config; | |
224 vf->put_image=put_image; | |
225 // vf->get_image=get_image; | |
226 vf->query_format=query_format; | |
227 vf->uninit=uninit; | |
228 vf->priv=malloc(sizeof(struct vf_priv_s)); | |
229 memset(vf->priv, 0, sizeof(struct vf_priv_s)); | |
230 | |
231 if(args==NULL) return 0; | |
232 | |
233 e=sscanf(args, "%f:%f:%d:%f:%f:%d", | |
234 &vf->priv->luma.radius, | |
235 &vf->priv->luma.strength, | |
236 &vf->priv->luma.threshold, | |
237 &vf->priv->chroma.radius, | |
238 &vf->priv->chroma.strength, | |
239 &vf->priv->chroma.threshold | |
240 ); | |
241 | |
242 vf->priv->luma.quality = vf->priv->chroma.quality= 3.0; | |
243 | |
244 if(e==3){ | |
245 vf->priv->chroma.radius= vf->priv->luma.radius; | |
246 vf->priv->chroma.strength= vf->priv->luma.strength; | |
247 vf->priv->chroma.threshold = vf->priv->luma.threshold; | |
248 }else if(e!=6) | |
249 return 0; | |
250 | |
251 return 1; | |
252 } | |
253 | |
254 vf_info_t vf_info_smartblur = { | |
255 "smart blur", | |
256 "smartblur", | |
257 "Michael Niedermayer", | |
258 "", | |
259 open | |
260 }; | |
261 | |
262 //===========================================================================// |