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.
34 #include "img_format.h"
39 //===========================================================================//
41 typedef struct FilterParam
{
47 FilterParam lumaParam
;
48 FilterParam chromaParam
;
52 /***************************************************************************/
55 static int config(struct vf_instance_s
* vf
,
56 int width
, int height
, int d_width
, int d_height
,
57 unsigned int flags
, unsigned int outfmt
){
59 return vf_next_config(vf
,width
,height
,d_width
,d_height
,flags
,outfmt
);
62 static inline void blur(uint8_t *dst
, uint8_t *src
, int w
, int radius
, int dstStep
, int srcStep
){
64 const int length
= radius
*2 + 1;
65 const int inv
= ((1<<16) + length
/2)/length
;
69 for(x
=0; x
<radius
; x
++){
70 sum
+= src
[x
*srcStep
]<<1;
72 sum
+= src
[radius
*srcStep
];
74 for(x
=0; x
<=radius
; x
++){
75 sum
+= src
[(radius
+x
)*srcStep
] - src
[(radius
-x
)*srcStep
];
76 dst
[x
*dstStep
]= (sum
*inv
+ (1<<15))>>16;
79 for(; x
<w
-radius
; x
++){
80 sum
+= src
[(radius
+x
)*srcStep
] - src
[(x
-radius
-1)*srcStep
];
81 dst
[x
*dstStep
]= (sum
*inv
+ (1<<15))>>16;
85 sum
+= src
[(2*w
-radius
-x
-1)*srcStep
] - src
[(x
-radius
-1)*srcStep
];
86 dst
[x
*dstStep
]= (sum
*inv
+ (1<<15))>>16;
90 static inline void blur2(uint8_t *dst
, uint8_t *src
, int w
, int radius
, int power
, int dstStep
, int srcStep
){
91 uint8_t temp
[2][4096];
92 uint8_t *a
= temp
[0], *b
=temp
[1];
95 blur(a
, src
, w
, radius
, 1, srcStep
);
96 for(; power
>2; power
--){
98 blur(b
, a
, w
, radius
, 1, 1);
102 blur(dst
, a
, w
, radius
, dstStep
, 1);
106 dst
[i
*dstStep
]= a
[i
];
111 dst
[i
*dstStep
]= src
[i
*srcStep
];
115 static void hBlur(uint8_t *dst
, uint8_t *src
, int w
, int h
, int dstStride
, int srcStride
, int radius
, int power
){
118 if(radius
==0 && dst
==src
) return;
121 blur2(dst
+ y
*dstStride
, src
+ y
*srcStride
, w
, radius
, power
, 1, 1);
125 //FIXME optimize (x before y !!!)
126 static void vBlur(uint8_t *dst
, uint8_t *src
, int w
, int h
, int dstStride
, int srcStride
, int radius
, int power
){
129 if(radius
==0 && dst
==src
) return;
132 blur2(dst
+ x
, src
+ x
, h
, radius
, power
, dstStride
, srcStride
);
136 static int put_image(struct vf_instance_s
* vf
, mp_image_t
*mpi
, double pts
){
137 int cw
= mpi
->w
>> mpi
->chroma_x_shift
;
138 int ch
= mpi
->h
>> mpi
->chroma_y_shift
;
140 mp_image_t
*dmpi
=vf_get_image(vf
->next
,mpi
->imgfmt
,
141 MP_IMGTYPE_TEMP
, MP_IMGFLAG_ACCEPT_STRIDE
| MP_IMGFLAG_READABLE
,
144 assert(mpi
->flags
&MP_IMGFLAG_PLANAR
);
146 hBlur(dmpi
->planes
[0], mpi
->planes
[0], mpi
->w
,mpi
->h
,
147 dmpi
->stride
[0], mpi
->stride
[0], vf
->priv
->lumaParam
.radius
, vf
->priv
->lumaParam
.power
);
148 hBlur(dmpi
->planes
[1], mpi
->planes
[1], cw
,ch
,
149 dmpi
->stride
[1], mpi
->stride
[1], vf
->priv
->chromaParam
.radius
, vf
->priv
->chromaParam
.power
);
150 hBlur(dmpi
->planes
[2], mpi
->planes
[2], cw
,ch
,
151 dmpi
->stride
[2], mpi
->stride
[2], vf
->priv
->chromaParam
.radius
, vf
->priv
->chromaParam
.power
);
153 vBlur(dmpi
->planes
[0], dmpi
->planes
[0], mpi
->w
,mpi
->h
,
154 dmpi
->stride
[0], dmpi
->stride
[0], vf
->priv
->lumaParam
.radius
, vf
->priv
->lumaParam
.power
);
155 vBlur(dmpi
->planes
[1], dmpi
->planes
[1], cw
,ch
,
156 dmpi
->stride
[1], dmpi
->stride
[1], vf
->priv
->chromaParam
.radius
, vf
->priv
->chromaParam
.power
);
157 vBlur(dmpi
->planes
[2], dmpi
->planes
[2], cw
,ch
,
158 dmpi
->stride
[2], dmpi
->stride
[2], vf
->priv
->chromaParam
.radius
, vf
->priv
->chromaParam
.power
);
160 return vf_next_put_image(vf
,dmpi
, pts
);
163 //===========================================================================//
165 static int query_format(struct vf_instance_s
* vf
, unsigned int fmt
){
175 return vf_next_query_format(vf
, fmt
);
180 static int open(vf_instance_t
*vf
, char* args
){
184 vf
->put_image
=put_image
;
185 // vf->get_image=get_image;
186 vf
->query_format
=query_format
;
187 vf
->priv
=malloc(sizeof(struct vf_priv_s
));
188 memset(vf
->priv
, 0, sizeof(struct vf_priv_s
));
190 if(args
==NULL
) return 0;
192 e
=sscanf(args
, "%d:%d:%d:%d",
193 &vf
->priv
->lumaParam
.radius
,
194 &vf
->priv
->lumaParam
.power
,
195 &vf
->priv
->chromaParam
.radius
,
196 &vf
->priv
->chromaParam
.power
200 vf
->priv
->chromaParam
.radius
= vf
->priv
->lumaParam
.radius
;
201 vf
->priv
->chromaParam
.power
= vf
->priv
->lumaParam
.power
;
205 if(vf
->priv
->lumaParam
.radius
< 0) return 0;
206 if(vf
->priv
->chromaParam
.radius
< 0) return 0;
211 const vf_info_t vf_info_boxblur
= {
214 "Michael Niedermayer",
220 //===========================================================================//