2 * Copyright (C) 2002 Michael Niedermayer <michaelni@gmx.at>
4 * This file is part of MPlayer.
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.
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.
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.
28 #include "img_format.h"
33 //===========================================================================//
35 typedef struct FilterParam
{
41 FilterParam lumaParam
;
42 FilterParam chromaParam
;
46 /***************************************************************************/
49 static int config(struct vf_instance
*vf
,
50 int width
, int height
, int d_width
, int d_height
,
51 unsigned int flags
, unsigned int outfmt
){
53 return vf_next_config(vf
,width
,height
,d_width
,d_height
,flags
,outfmt
);
56 static inline void blur(uint8_t *dst
, uint8_t *src
, int w
, int radius
, int dstStep
, int srcStep
){
58 const int length
= radius
*2 + 1;
59 const int inv
= ((1<<16) + length
/2)/length
;
63 for(x
=0; x
<radius
; x
++){
64 sum
+= src
[x
*srcStep
]<<1;
66 sum
+= src
[radius
*srcStep
];
68 for(x
=0; x
<=radius
; x
++){
69 sum
+= src
[(radius
+x
)*srcStep
] - src
[(radius
-x
)*srcStep
];
70 dst
[x
*dstStep
]= (sum
*inv
+ (1<<15))>>16;
73 for(; x
<w
-radius
; x
++){
74 sum
+= src
[(radius
+x
)*srcStep
] - src
[(x
-radius
-1)*srcStep
];
75 dst
[x
*dstStep
]= (sum
*inv
+ (1<<15))>>16;
79 sum
+= src
[(2*w
-radius
-x
-1)*srcStep
] - src
[(x
-radius
-1)*srcStep
];
80 dst
[x
*dstStep
]= (sum
*inv
+ (1<<15))>>16;
84 static inline void blur2(uint8_t *dst
, uint8_t *src
, int w
, int radius
, int power
, int dstStep
, int srcStep
){
85 uint8_t temp
[2][4096];
86 uint8_t *a
= temp
[0], *b
=temp
[1];
89 blur(a
, src
, w
, radius
, 1, srcStep
);
90 for(; power
>2; power
--){
92 blur(b
, a
, w
, radius
, 1, 1);
96 blur(dst
, a
, w
, radius
, dstStep
, 1);
100 dst
[i
*dstStep
]= a
[i
];
105 dst
[i
*dstStep
]= src
[i
*srcStep
];
109 static void hBlur(uint8_t *dst
, uint8_t *src
, int w
, int h
, int dstStride
, int srcStride
, int radius
, int power
){
112 if(radius
==0 && dst
==src
) return;
115 blur2(dst
+ y
*dstStride
, src
+ y
*srcStride
, w
, radius
, power
, 1, 1);
119 //FIXME optimize (x before y !!!)
120 static void vBlur(uint8_t *dst
, uint8_t *src
, int w
, int h
, int dstStride
, int srcStride
, int radius
, int power
){
123 if(radius
==0 && dst
==src
) return;
126 blur2(dst
+ x
, src
+ x
, h
, radius
, power
, dstStride
, srcStride
);
130 static int put_image(struct vf_instance
*vf
, mp_image_t
*mpi
, double pts
){
131 int cw
= mpi
->w
>> mpi
->chroma_x_shift
;
132 int ch
= mpi
->h
>> mpi
->chroma_y_shift
;
134 mp_image_t
*dmpi
=vf_get_image(vf
->next
,mpi
->imgfmt
,
135 MP_IMGTYPE_TEMP
, MP_IMGFLAG_ACCEPT_STRIDE
| MP_IMGFLAG_READABLE
,
138 assert(mpi
->flags
&MP_IMGFLAG_PLANAR
);
140 hBlur(dmpi
->planes
[0], mpi
->planes
[0], mpi
->w
,mpi
->h
,
141 dmpi
->stride
[0], mpi
->stride
[0], vf
->priv
->lumaParam
.radius
, vf
->priv
->lumaParam
.power
);
142 hBlur(dmpi
->planes
[1], mpi
->planes
[1], cw
,ch
,
143 dmpi
->stride
[1], mpi
->stride
[1], vf
->priv
->chromaParam
.radius
, vf
->priv
->chromaParam
.power
);
144 hBlur(dmpi
->planes
[2], mpi
->planes
[2], cw
,ch
,
145 dmpi
->stride
[2], mpi
->stride
[2], vf
->priv
->chromaParam
.radius
, vf
->priv
->chromaParam
.power
);
147 vBlur(dmpi
->planes
[0], dmpi
->planes
[0], mpi
->w
,mpi
->h
,
148 dmpi
->stride
[0], dmpi
->stride
[0], vf
->priv
->lumaParam
.radius
, vf
->priv
->lumaParam
.power
);
149 vBlur(dmpi
->planes
[1], dmpi
->planes
[1], cw
,ch
,
150 dmpi
->stride
[1], dmpi
->stride
[1], vf
->priv
->chromaParam
.radius
, vf
->priv
->chromaParam
.power
);
151 vBlur(dmpi
->planes
[2], dmpi
->planes
[2], cw
,ch
,
152 dmpi
->stride
[2], dmpi
->stride
[2], vf
->priv
->chromaParam
.radius
, vf
->priv
->chromaParam
.power
);
154 return vf_next_put_image(vf
,dmpi
, pts
);
157 //===========================================================================//
159 static int query_format(struct vf_instance
*vf
, unsigned int fmt
){
169 return vf_next_query_format(vf
, fmt
);
174 static int vf_open(vf_instance_t
*vf
, char *args
){
178 vf
->put_image
=put_image
;
179 // vf->get_image=get_image;
180 vf
->query_format
=query_format
;
181 vf
->priv
=malloc(sizeof(struct vf_priv_s
));
182 memset(vf
->priv
, 0, sizeof(struct vf_priv_s
));
184 if(args
==NULL
) return 0;
186 e
=sscanf(args
, "%d:%d:%d:%d",
187 &vf
->priv
->lumaParam
.radius
,
188 &vf
->priv
->lumaParam
.power
,
189 &vf
->priv
->chromaParam
.radius
,
190 &vf
->priv
->chromaParam
.power
194 vf
->priv
->chromaParam
.radius
= vf
->priv
->lumaParam
.radius
;
195 vf
->priv
->chromaParam
.power
= vf
->priv
->lumaParam
.power
;
199 if(vf
->priv
->lumaParam
.radius
< 0) return 0;
200 if(vf
->priv
->chromaParam
.radius
< 0) return 0;
205 const vf_info_t vf_info_boxblur
= {
208 "Michael Niedermayer",
214 //===========================================================================//