Mercurial > mplayer.hg
annotate libmpcodecs/vf_sab.c @ 32282:606e4157cd4c
Split alloc and init of context so that parameters can be set in the context
instead of requireing being passed through function parameters. This also
makes sws work with AVOptions.
author | michael |
---|---|
date | Sun, 26 Sep 2010 19:33:57 +0000 |
parents | effad4f941ff |
children | 8fa2f43cb760 |
rev | line source |
---|---|
8100 | 1 /* |
26727 | 2 * Copyright (C) 2002 Michael Niedermayer <michaelni@gmx.at> |
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 */ | |
8100 | 20 |
21 #include <stdio.h> | |
22 #include <stdlib.h> | |
23 #include <string.h> | |
24 #include <inttypes.h> | |
25 #include <assert.h> | |
26 | |
17012 | 27 #include "config.h" |
28 #include "mp_msg.h" | |
8100 | 29 |
28594
df67d03dde3b
Convert HAVE_MALLOC_H into a 0/1 definition, fixes the warning:
diego
parents:
27754
diff
changeset
|
30 #if HAVE_MALLOC_H |
8100 | 31 #include <malloc.h> |
32 #endif | |
33 | |
26069
1318e956c092
FFmpeg now uses different (unified) #include paths.
diego
parents:
26006
diff
changeset
|
34 #include "libavutil/avutil.h" |
8100 | 35 #include "img_format.h" |
36 #include "mp_image.h" | |
37 #include "vf.h" | |
18861 | 38 #include "libswscale/swscale.h" |
10233
35f52ad860a0
vf_scale.h & related cleanup & some small warning fix by dominik
michael
parents:
9975
diff
changeset
|
39 #include "vf_scale.h" |
8100 | 40 |
41 | |
42 //===========================================================================// | |
43 | |
44 typedef struct FilterParam{ | |
45 float radius; | |
46 float preFilterRadius; | |
47 float strength; | |
48 float quality; | |
9494
543ab3909b78
sws_ prefix, more seperation between internal & external swscaler API
michael
parents:
8100
diff
changeset
|
49 struct SwsContext *preFilterContext; |
8100 | 50 uint8_t *preFilterBuf; |
51 int preFilterStride; | |
52 int distWidth; | |
53 int distStride; | |
54 int *distCoeff; | |
55 int colorDiffCoeff[512]; | |
56 }FilterParam; | |
57 | |
58 struct vf_priv_s { | |
59 FilterParam luma; | |
60 FilterParam chroma; | |
61 }; | |
62 | |
63 | |
64 /***************************************************************************/ | |
65 | |
66 //FIXME stupid code duplication | |
67 static void getSubSampleFactors(int *h, int *v, int format){ | |
68 switch(format){ | |
69 case IMGFMT_YV12: | |
70 case IMGFMT_I420: | |
71 *h=1; | |
72 *v=1; | |
73 break; | |
74 case IMGFMT_YVU9: | |
75 *h=2; | |
76 *v=2; | |
77 break; | |
78 case IMGFMT_444P: | |
79 *h=0; | |
80 *v=0; | |
81 break; | |
82 case IMGFMT_422P: | |
83 *h=1; | |
84 *v=0; | |
85 break; | |
86 case IMGFMT_411P: | |
87 *h=2; | |
88 *v=0; | |
89 break; | |
90 } | |
91 } | |
92 | |
93 static int allocStuff(FilterParam *f, int width, int height){ | |
94 int stride= (width+7)&~7; | |
95 SwsVector *vec; | |
96 SwsFilter swsF; | |
97 int i,x,y; | |
98 f->preFilterBuf= (uint8_t*)memalign(8, stride*height); | |
99 f->preFilterStride= stride; | |
100 | |
9494
543ab3909b78
sws_ prefix, more seperation between internal & external swscaler API
michael
parents:
8100
diff
changeset
|
101 vec = sws_getGaussianVec(f->preFilterRadius, f->quality); |
8100 | 102 swsF.lumH= swsF.lumV= vec; |
103 swsF.chrH= swsF.chrV= NULL; | |
9494
543ab3909b78
sws_ prefix, more seperation between internal & external swscaler API
michael
parents:
8100
diff
changeset
|
104 f->preFilterContext= sws_getContext( |
29164
228817b21ccf
Add algorithm flag (SWS_POINT) to sws_getContext call to avoid a crash.
diego
parents:
29064
diff
changeset
|
105 width, height, PIX_FMT_GRAY8, width, height, PIX_FMT_GRAY8, get_sws_cpuflags()|SWS_POINT, &swsF, NULL, NULL); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29164
diff
changeset
|
106 |
9494
543ab3909b78
sws_ prefix, more seperation between internal & external swscaler API
michael
parents:
8100
diff
changeset
|
107 sws_freeVec(vec); |
543ab3909b78
sws_ prefix, more seperation between internal & external swscaler API
michael
parents:
8100
diff
changeset
|
108 vec = sws_getGaussianVec(f->strength, 5.0); |
8100 | 109 for(i=0; i<512; i++){ |
110 double d; | |
111 int index= i-256 + vec->length/2; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29164
diff
changeset
|
112 |
8100 | 113 if(index<0 || index>=vec->length) d= 0.0; |
114 else d= vec->coeff[index]; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29164
diff
changeset
|
115 |
8100 | 116 f->colorDiffCoeff[i]= (int)(d/vec->coeff[vec->length/2]*(1<<12) + 0.5); |
117 } | |
9494
543ab3909b78
sws_ prefix, more seperation between internal & external swscaler API
michael
parents:
8100
diff
changeset
|
118 sws_freeVec(vec); |
543ab3909b78
sws_ prefix, more seperation between internal & external swscaler API
michael
parents:
8100
diff
changeset
|
119 vec = sws_getGaussianVec(f->radius, f->quality); |
8100 | 120 f->distWidth= vec->length; |
121 f->distStride= (vec->length+7)&~7; | |
122 f->distCoeff= (int32_t*)memalign(8, f->distWidth*f->distStride*sizeof(int32_t)); | |
123 | |
124 for(y=0; y<vec->length; y++){ | |
125 for(x=0; x<vec->length; x++){ | |
126 double d= vec->coeff[x] * vec->coeff[y]; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29164
diff
changeset
|
127 |
8100 | 128 f->distCoeff[x + y*f->distStride]= (int)(d*(1<<10) + 0.5); |
129 // if(y==vec->length/2) | |
130 // printf("%6d ", f->distCoeff[x + y*f->distStride]); | |
131 } | |
132 } | |
9494
543ab3909b78
sws_ prefix, more seperation between internal & external swscaler API
michael
parents:
8100
diff
changeset
|
133 sws_freeVec(vec); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29164
diff
changeset
|
134 |
8100 | 135 return 0; |
136 } | |
137 | |
30642
a972c1a4a012
cosmetics: Rename struct vf_instance_s --> vf_instance.
diego
parents:
30638
diff
changeset
|
138 static int config(struct vf_instance *vf, |
8100 | 139 int width, int height, int d_width, int d_height, |
140 unsigned int flags, unsigned int outfmt){ | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29164
diff
changeset
|
141 |
8100 | 142 int sw, sh; |
27754
08d18fe9da52
Change all occurrences of asm and __asm to __asm__, same as was done for FFmpeg.
diego
parents:
26727
diff
changeset
|
143 //__asm__ volatile("emms\n\t"); |
8100 | 144 allocStuff(&vf->priv->luma, width, height); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29164
diff
changeset
|
145 |
8100 | 146 getSubSampleFactors(&sw, &sh, outfmt); |
147 allocStuff(&vf->priv->chroma, width>>sw, height>>sh); | |
148 | |
149 return vf_next_config(vf,width,height,d_width,d_height,flags,outfmt); | |
150 } | |
151 | |
152 static void freeBuffers(FilterParam *f){ | |
9494
543ab3909b78
sws_ prefix, more seperation between internal & external swscaler API
michael
parents:
8100
diff
changeset
|
153 if(f->preFilterContext) sws_freeContext(f->preFilterContext); |
8100 | 154 f->preFilterContext=NULL; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29164
diff
changeset
|
155 |
8100 | 156 if(f->preFilterBuf) free(f->preFilterBuf); |
157 f->preFilterBuf=NULL; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29164
diff
changeset
|
158 |
8100 | 159 if(f->distCoeff) free(f->distCoeff); |
160 f->distCoeff=NULL; | |
161 } | |
162 | |
30642
a972c1a4a012
cosmetics: Rename struct vf_instance_s --> vf_instance.
diego
parents:
30638
diff
changeset
|
163 static void uninit(struct vf_instance *vf){ |
8100 | 164 if(!vf->priv) return; |
165 | |
166 freeBuffers(&vf->priv->luma); | |
167 freeBuffers(&vf->priv->chroma); | |
168 | |
169 free(vf->priv); | |
170 vf->priv=NULL; | |
171 } | |
172 | |
173 static inline void blur(uint8_t *dst, uint8_t *src, int w, int h, int dstStride, int srcStride, FilterParam *fp){ | |
174 int x, y; | |
175 FilterParam f= *fp; | |
176 const int radius= f.distWidth/2; | |
32136
effad4f941ff
Mark srcArray as const pointer to const data, fixes the warnings:
diego
parents:
30642
diff
changeset
|
177 const uint8_t* const srcArray[MP_MAX_PLANES] = {src}; |
29064
67c256364220
Consistently use MP_MAX_PLANES as size for plane pointer/stride arrays in libmpcodecs.
reimar
parents:
28594
diff
changeset
|
178 uint8_t *dstArray[MP_MAX_PLANES]= {f.preFilterBuf}; |
67c256364220
Consistently use MP_MAX_PLANES as size for plane pointer/stride arrays in libmpcodecs.
reimar
parents:
28594
diff
changeset
|
179 int srcStrideArray[MP_MAX_PLANES]= {srcStride}; |
67c256364220
Consistently use MP_MAX_PLANES as size for plane pointer/stride arrays in libmpcodecs.
reimar
parents:
28594
diff
changeset
|
180 int dstStrideArray[MP_MAX_PLANES]= {f.preFilterStride}; |
8100 | 181 |
9494
543ab3909b78
sws_ prefix, more seperation between internal & external swscaler API
michael
parents:
8100
diff
changeset
|
182 // f.preFilterContext->swScale(f.preFilterContext, srcArray, srcStrideArray, 0, h, dstArray, dstStrideArray); |
543ab3909b78
sws_ prefix, more seperation between internal & external swscaler API
michael
parents:
8100
diff
changeset
|
183 sws_scale(f.preFilterContext, srcArray, srcStrideArray, 0, h, dstArray, dstStrideArray); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29164
diff
changeset
|
184 |
8100 | 185 for(y=0; y<h; y++){ |
186 for(x=0; x<w; x++){ | |
187 int sum=0; | |
188 int div=0; | |
189 int dy; | |
190 const int preVal= f.preFilterBuf[x + y*f.preFilterStride]; | |
191 #if 0 | |
192 const int srcVal= src[x + y*srcStride]; | |
193 if((x/32)&1){ | |
194 dst[x + y*dstStride]= srcVal; | |
195 if(y%32==0) dst[x + y*dstStride]= 0; | |
196 continue; | |
197 } | |
198 #endif | |
199 if(x >= radius && x < w - radius){ | |
200 for(dy=0; dy<radius*2+1; dy++){ | |
201 int dx; | |
202 int iy= y+dy - radius; | |
203 if (iy<0) iy= -iy; | |
26006
ac00f0e343df
vf_sab mirrors coefficients past the edge of the picture instead of cropping:
diego
parents:
25221
diff
changeset
|
204 else if(iy>=h) iy= h+h-iy-1; |
8100 | 205 |
206 for(dx=0; dx<radius*2+1; dx++){ | |
207 const int ix= x+dx - radius; | |
208 int factor; | |
209 | |
210 factor= f.colorDiffCoeff[256+preVal - f.preFilterBuf[ix + iy*f.preFilterStride] ] | |
211 *f.distCoeff[dx + dy*f.distStride]; | |
212 sum+= src[ix + iy*srcStride] *factor; | |
213 div+= factor; | |
214 } | |
215 } | |
216 }else{ | |
217 for(dy=0; dy<radius*2+1; dy++){ | |
218 int dx; | |
219 int iy= y+dy - radius; | |
220 if (iy<0) iy= -iy; | |
26006
ac00f0e343df
vf_sab mirrors coefficients past the edge of the picture instead of cropping:
diego
parents:
25221
diff
changeset
|
221 else if(iy>=h) iy= h+h-iy-1; |
8100 | 222 |
223 for(dx=0; dx<radius*2+1; dx++){ | |
224 int ix= x+dx - radius; | |
225 int factor; | |
226 if (ix<0) ix= -ix; | |
26006
ac00f0e343df
vf_sab mirrors coefficients past the edge of the picture instead of cropping:
diego
parents:
25221
diff
changeset
|
227 else if(ix>=w) ix= w+w-ix-1; |
8100 | 228 |
229 factor= f.colorDiffCoeff[256+preVal - f.preFilterBuf[ix + iy*f.preFilterStride] ] | |
230 *f.distCoeff[dx + dy*f.distStride]; | |
231 sum+= src[ix + iy*srcStride] *factor; | |
232 div+= factor; | |
233 } | |
234 } | |
235 } | |
236 dst[x + y*dstStride]= (sum + div/2)/div; | |
237 } | |
238 } | |
239 } | |
240 | |
30642
a972c1a4a012
cosmetics: Rename struct vf_instance_s --> vf_instance.
diego
parents:
30638
diff
changeset
|
241 static int put_image(struct vf_instance *vf, mp_image_t *mpi, double pts){ |
8100 | 242 int cw= mpi->w >> mpi->chroma_x_shift; |
243 int ch= mpi->h >> mpi->chroma_y_shift; | |
244 | |
245 mp_image_t *dmpi=vf_get_image(vf->next,mpi->imgfmt, | |
246 MP_IMGTYPE_TEMP, MP_IMGFLAG_ACCEPT_STRIDE, | |
247 mpi->w,mpi->h); | |
248 | |
249 assert(mpi->flags&MP_IMGFLAG_PLANAR); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29164
diff
changeset
|
250 |
8100 | 251 blur(dmpi->planes[0], mpi->planes[0], mpi->w,mpi->h, dmpi->stride[0], mpi->stride[0], &vf->priv->luma); |
252 blur(dmpi->planes[1], mpi->planes[1], cw , ch , dmpi->stride[1], mpi->stride[1], &vf->priv->chroma); | |
253 blur(dmpi->planes[2], mpi->planes[2], cw , ch , dmpi->stride[2], mpi->stride[2], &vf->priv->chroma); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29164
diff
changeset
|
254 |
17906
20aca9baf5d8
passing pts through the filter layer (lets see if pts or cola comes out at the end)
michael
parents:
17367
diff
changeset
|
255 return vf_next_put_image(vf,dmpi, pts); |
8100 | 256 } |
257 | |
258 //===========================================================================// | |
259 | |
30642
a972c1a4a012
cosmetics: Rename struct vf_instance_s --> vf_instance.
diego
parents:
30638
diff
changeset
|
260 static int query_format(struct vf_instance *vf, unsigned int fmt){ |
8100 | 261 switch(fmt) |
262 { | |
263 case IMGFMT_YV12: | |
264 case IMGFMT_I420: | |
265 case IMGFMT_IYUV: | |
266 case IMGFMT_YVU9: | |
267 case IMGFMT_444P: | |
268 case IMGFMT_422P: | |
269 case IMGFMT_411P: | |
270 return vf_next_query_format(vf, fmt); | |
271 } | |
272 return 0; | |
273 } | |
274 | |
30638
a7b908875c14
Rename open() vf initialization function to vf_open().
diego
parents:
29263
diff
changeset
|
275 static int vf_open(vf_instance_t *vf, char *args){ |
8100 | 276 int e; |
277 | |
278 vf->config=config; | |
279 vf->put_image=put_image; | |
280 // vf->get_image=get_image; | |
281 vf->query_format=query_format; | |
282 vf->uninit=uninit; | |
283 vf->priv=malloc(sizeof(struct vf_priv_s)); | |
284 memset(vf->priv, 0, sizeof(struct vf_priv_s)); | |
285 | |
286 if(args==NULL) return 0; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29164
diff
changeset
|
287 |
8100 | 288 e=sscanf(args, "%f:%f:%f:%f:%f:%f", |
289 &vf->priv->luma.radius, | |
290 &vf->priv->luma.preFilterRadius, | |
291 &vf->priv->luma.strength, | |
292 &vf->priv->chroma.radius, | |
293 &vf->priv->chroma.preFilterRadius, | |
294 &vf->priv->chroma.strength | |
295 ); | |
296 | |
297 vf->priv->luma.quality = vf->priv->chroma.quality= 3.0; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29164
diff
changeset
|
298 |
8100 | 299 if(e==3){ |
300 vf->priv->chroma.radius= vf->priv->luma.radius; | |
301 vf->priv->chroma.preFilterRadius = vf->priv->luma.preFilterRadius; | |
302 vf->priv->chroma.strength= vf->priv->luma.strength; | |
303 }else if(e!=6) | |
304 return 0; | |
305 | |
306 // if(vf->priv->luma.radius < 0) return 0; | |
307 // if(vf->priv->chroma.radius < 0) return 0; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
29164
diff
changeset
|
308 |
8100 | 309 return 1; |
310 } | |
311 | |
25221 | 312 const vf_info_t vf_info_sab = { |
8100 | 313 "shape adaptive blur", |
314 "sab", | |
315 "Michael Niedermayer", | |
316 "", | |
30638
a7b908875c14
Rename open() vf initialization function to vf_open().
diego
parents:
29263
diff
changeset
|
317 vf_open, |
9593
e9a2af584986
Add the new -vf option wich is the same as vop in reverse order.
albeu
parents:
9494
diff
changeset
|
318 NULL |
8100 | 319 }; |
320 | |
321 //===========================================================================// |