Mercurial > mplayer.hg
annotate libmpcodecs/vf_smartblur.c @ 23011:365eef1fc4f0
Disable caching of rotated glyphs.
The following commits will add perspective distortion to the glyphs rotated
with \frx and \fry. Somewhere along the way correct caching of such glyphs
will become impossible, but in the end everything will be fine.
author | eugeni |
---|---|
date | Fri, 20 Apr 2007 22:49:48 +0000 |
parents | bf1fbe97cc40 |
children | f8d4f8eff72b |
rev | line source |
---|---|
8106 | 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 | |
17367
401b440a6d76
Update licensing information: The FSF changed postal address.
diego
parents:
17012
diff
changeset
|
16 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
8106 | 17 */ |
18 | |
19 #include <stdio.h> | |
20 #include <stdlib.h> | |
21 #include <string.h> | |
22 #include <inttypes.h> | |
23 #include <assert.h> | |
24 | |
17012 | 25 #include "config.h" |
26 #include "mp_msg.h" | |
8106 | 27 |
28 #ifdef HAVE_MALLOC_H | |
29 #include <malloc.h> | |
30 #endif | |
31 | |
21778
bf1fbe97cc40
Fix build with shared libavutil. Approved by Diego.
rathann
parents:
19870
diff
changeset
|
32 #ifdef USE_LIBAVUTIL_SO |
bf1fbe97cc40
Fix build with shared libavutil. Approved by Diego.
rathann
parents:
19870
diff
changeset
|
33 #include <ffmpeg/avutil.h> |
bf1fbe97cc40
Fix build with shared libavutil. Approved by Diego.
rathann
parents:
19870
diff
changeset
|
34 #else |
19870
1e5cf11e8b1f
Use PIX_FMT_* instead of IMGFMT_* when calling sws_getContext()
lucabe
parents:
18861
diff
changeset
|
35 #include "avutil.h" |
21778
bf1fbe97cc40
Fix build with shared libavutil. Approved by Diego.
rathann
parents:
19870
diff
changeset
|
36 #endif |
8106 | 37 #include "img_format.h" |
38 #include "mp_image.h" | |
39 #include "vf.h" | |
17012 | 40 #include "libvo/fastmemcpy.h" |
18861 | 41 #include "libswscale/swscale.h" |
10233
35f52ad860a0
vf_scale.h & related cleanup & some small warning fix by dominik
michael
parents:
9975
diff
changeset
|
42 #include "vf_scale.h" |
8106 | 43 |
44 //===========================================================================// | |
45 | |
46 typedef struct FilterParam{ | |
47 float radius; | |
48 float strength; | |
49 int threshold; | |
50 float quality; | |
9494
543ab3909b78
sws_ prefix, more seperation between internal & external swscaler API
michael
parents:
8263
diff
changeset
|
51 struct SwsContext *filterContext; |
8106 | 52 }FilterParam; |
53 | |
54 struct vf_priv_s { | |
55 FilterParam luma; | |
56 FilterParam chroma; | |
57 }; | |
58 | |
59 | |
60 /***************************************************************************/ | |
61 | |
62 //FIXME stupid code duplication | |
63 static void getSubSampleFactors(int *h, int *v, int format){ | |
64 switch(format){ | |
65 case IMGFMT_YV12: | |
66 case IMGFMT_I420: | |
67 *h=1; | |
68 *v=1; | |
69 break; | |
70 case IMGFMT_YVU9: | |
71 *h=2; | |
72 *v=2; | |
73 break; | |
74 case IMGFMT_444P: | |
75 *h=0; | |
76 *v=0; | |
77 break; | |
78 case IMGFMT_422P: | |
79 *h=1; | |
80 *v=0; | |
81 break; | |
82 case IMGFMT_411P: | |
83 *h=2; | |
84 *v=0; | |
85 break; | |
86 } | |
87 } | |
88 | |
89 static int allocStuff(FilterParam *f, int width, int height){ | |
90 SwsVector *vec; | |
91 SwsFilter swsF; | |
92 | |
9494
543ab3909b78
sws_ prefix, more seperation between internal & external swscaler API
michael
parents:
8263
diff
changeset
|
93 vec = sws_getGaussianVec(f->radius, f->quality); |
543ab3909b78
sws_ prefix, more seperation between internal & external swscaler API
michael
parents:
8263
diff
changeset
|
94 sws_scaleVec(vec, f->strength); |
8106 | 95 vec->coeff[vec->length/2]+= 1.0 - f->strength; |
96 swsF.lumH= swsF.lumV= vec; | |
97 swsF.chrH= swsF.chrV= NULL; | |
9494
543ab3909b78
sws_ prefix, more seperation between internal & external swscaler API
michael
parents:
8263
diff
changeset
|
98 f->filterContext= sws_getContext( |
19870
1e5cf11e8b1f
Use PIX_FMT_* instead of IMGFMT_* when calling sws_getContext()
lucabe
parents:
18861
diff
changeset
|
99 width, height, PIX_FMT_GRAY8, width, height, PIX_FMT_GRAY8, get_sws_cpuflags(), &swsF, NULL, NULL); |
8106 | 100 |
9494
543ab3909b78
sws_ prefix, more seperation between internal & external swscaler API
michael
parents:
8263
diff
changeset
|
101 sws_freeVec(vec); |
8106 | 102 |
103 return 0; | |
104 } | |
105 | |
106 static int config(struct vf_instance_s* vf, | |
107 int width, int height, int d_width, int d_height, | |
108 unsigned int flags, unsigned int outfmt){ | |
109 | |
110 int sw, sh; | |
111 | |
112 allocStuff(&vf->priv->luma, width, height); | |
113 | |
114 getSubSampleFactors(&sw, &sh, outfmt); | |
115 allocStuff(&vf->priv->chroma, width>>sw, height>>sh); | |
116 | |
117 return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt); | |
118 } | |
119 | |
120 static void freeBuffers(FilterParam *f){ | |
9494
543ab3909b78
sws_ prefix, more seperation between internal & external swscaler API
michael
parents:
8263
diff
changeset
|
121 if(f->filterContext) sws_freeContext(f->filterContext); |
8106 | 122 f->filterContext=NULL; |
123 } | |
124 | |
125 static void uninit(struct vf_instance_s* vf){ | |
126 if(!vf->priv) return; | |
127 | |
128 freeBuffers(&vf->priv->luma); | |
129 freeBuffers(&vf->priv->chroma); | |
130 | |
131 free(vf->priv); | |
132 vf->priv=NULL; | |
133 } | |
134 | |
135 static inline void blur(uint8_t *dst, uint8_t *src, int w, int h, int dstStride, int srcStride, FilterParam *fp){ | |
136 int x, y; | |
137 FilterParam f= *fp; | |
138 uint8_t *srcArray[3]= {src, NULL, NULL}; | |
139 uint8_t *dstArray[3]= {dst, NULL, NULL}; | |
140 int srcStrideArray[3]= {srcStride, 0, 0}; | |
141 int dstStrideArray[3]= {dstStride, 0, 0}; | |
142 | |
9494
543ab3909b78
sws_ prefix, more seperation between internal & external swscaler API
michael
parents:
8263
diff
changeset
|
143 sws_scale(f.filterContext, srcArray, srcStrideArray, 0, h, dstArray, dstStrideArray); |
8106 | 144 |
145 if(f.threshold > 0){ | |
146 for(y=0; y<h; y++){ | |
147 for(x=0; x<w; x++){ | |
148 const int orig= src[x + y*srcStride]; | |
149 const int filtered= dst[x + y*dstStride]; | |
150 const int diff= orig - filtered; | |
151 | |
152 if(diff > 0){ | |
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 }else{ | |
159 if(-diff > 2*f.threshold){ | |
160 dst[x + y*dstStride]= orig; | |
161 }else if(-diff > f.threshold){ | |
162 dst[x + y*dstStride]= filtered + diff + f.threshold; | |
163 } | |
164 } | |
165 } | |
166 } | |
167 }else if(f.threshold < 0){ | |
168 for(y=0; y<h; y++){ | |
169 for(x=0; x<w; x++){ | |
170 const int orig= src[x + y*srcStride]; | |
171 const int filtered= dst[x + y*dstStride]; | |
172 const int diff= orig - filtered; | |
173 | |
174 if(diff > 0){ | |
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 }else{ | |
181 if(diff < 2*f.threshold){ | |
182 }else if(diff < f.threshold){ | |
183 dst[x + y*dstStride]= orig - diff + f.threshold; | |
184 }else | |
185 dst[x + y*dstStride]= orig; | |
186 } | |
187 } | |
188 } | |
189 } | |
190 } | |
191 | |
17906
20aca9baf5d8
passing pts through the filter layer (lets see if pts or cola comes out at the end)
michael
parents:
17367
diff
changeset
|
192 static int put_image(struct vf_instance_s* vf, mp_image_t *mpi, double pts){ |
8106 | 193 int cw= mpi->w >> mpi->chroma_x_shift; |
194 int ch= mpi->h >> mpi->chroma_y_shift; | |
16154
abe49bc12544
when threshold != 0 the dest image must be readable
reimar
parents:
14542
diff
changeset
|
195 FilterParam *f= &vf->priv; |
8106 | 196 |
197 mp_image_t *dmpi=vf_get_image(vf->next,mpi->imgfmt, | |
16154
abe49bc12544
when threshold != 0 the dest image must be readable
reimar
parents:
14542
diff
changeset
|
198 MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE| |
abe49bc12544
when threshold != 0 the dest image must be readable
reimar
parents:
14542
diff
changeset
|
199 (f->threshold) ? MP_IMGFLAG_READABLE : 0, |
8106 | 200 mpi->w,mpi->h); |
201 | |
202 assert(mpi->flags&MP_IMGFLAG_PLANAR); | |
203 | |
204 blur(dmpi->planes[0], mpi->planes[0], mpi->w,mpi->h, dmpi->stride[0], mpi->stride[0], &vf->priv->luma); | |
205 blur(dmpi->planes[1], mpi->planes[1], cw , ch , dmpi->stride[1], mpi->stride[1], &vf->priv->chroma); | |
206 blur(dmpi->planes[2], mpi->planes[2], cw , ch , dmpi->stride[2], mpi->stride[2], &vf->priv->chroma); | |
207 | |
17906
20aca9baf5d8
passing pts through the filter layer (lets see if pts or cola comes out at the end)
michael
parents:
17367
diff
changeset
|
208 return vf_next_put_image(vf,dmpi, pts); |
8106 | 209 } |
210 | |
211 //===========================================================================// | |
212 | |
213 static int query_format(struct vf_instance_s* vf, unsigned int fmt){ | |
214 switch(fmt) | |
215 { | |
216 case IMGFMT_YV12: | |
217 case IMGFMT_I420: | |
218 case IMGFMT_IYUV: | |
219 case IMGFMT_YVU9: | |
220 case IMGFMT_444P: | |
221 case IMGFMT_422P: | |
222 case IMGFMT_411P: | |
223 return vf_next_query_format(vf, fmt); | |
224 } | |
225 return 0; | |
226 } | |
227 | |
228 static int open(vf_instance_t *vf, char* args){ | |
229 int e; | |
230 | |
231 vf->config=config; | |
232 vf->put_image=put_image; | |
233 // vf->get_image=get_image; | |
234 vf->query_format=query_format; | |
235 vf->uninit=uninit; | |
236 vf->priv=malloc(sizeof(struct vf_priv_s)); | |
237 memset(vf->priv, 0, sizeof(struct vf_priv_s)); | |
238 | |
239 if(args==NULL) return 0; | |
240 | |
241 e=sscanf(args, "%f:%f:%d:%f:%f:%d", | |
242 &vf->priv->luma.radius, | |
243 &vf->priv->luma.strength, | |
244 &vf->priv->luma.threshold, | |
245 &vf->priv->chroma.radius, | |
246 &vf->priv->chroma.strength, | |
247 &vf->priv->chroma.threshold | |
248 ); | |
249 | |
250 vf->priv->luma.quality = vf->priv->chroma.quality= 3.0; | |
251 | |
252 if(e==3){ | |
253 vf->priv->chroma.radius= vf->priv->luma.radius; | |
254 vf->priv->chroma.strength= vf->priv->luma.strength; | |
255 vf->priv->chroma.threshold = vf->priv->luma.threshold; | |
256 }else if(e!=6) | |
257 return 0; | |
258 | |
259 return 1; | |
260 } | |
261 | |
262 vf_info_t vf_info_smartblur = { | |
263 "smart blur", | |
264 "smartblur", | |
265 "Michael Niedermayer", | |
266 "", | |
9593
e9a2af584986
Add the new -vf option wich is the same as vop in reverse order.
albeu
parents:
9494
diff
changeset
|
267 open, |
e9a2af584986
Add the new -vf option wich is the same as vop in reverse order.
albeu
parents:
9494
diff
changeset
|
268 NULL |
8106 | 269 }; |
270 | |
271 //===========================================================================// |