2 * Original AVISynth Filter Copyright (C) 2003 Donald A. Graft
3 * Adapted to MPlayer by Tobias Diedrich
5 * This file is part of MPlayer.
7 * MPlayer is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * MPlayer is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License along
18 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
35 #include "img_format.h"
38 #include "libvo/fastmemcpy.h"
40 //===========================================================================//
53 /***************************************************************************/
56 static int config(struct vf_instance_s
* vf
,
57 int width
, int height
, int d_width
, int d_height
,
58 unsigned int flags
, unsigned int outfmt
){
60 return vf_next_config(vf
,width
,height
,d_width
,d_height
,flags
,outfmt
);
64 static void uninit(struct vf_instance_s
* vf
)
69 static inline int IsRGB(mp_image_t
*mpi
)
71 return mpi
->imgfmt
== IMGFMT_RGB
;
74 static inline int IsYUY2(mp_image_t
*mpi
)
76 return mpi
->imgfmt
== IMGFMT_YUY2
;
83 static int put_image(struct vf_instance_s
* vf
, mp_image_t
*mpi
, double pts
){
84 int cw
= mpi
->w
>> mpi
->chroma_x_shift
;
85 int ch
= mpi
->h
>> mpi
->chroma_y_shift
;
86 int W
= mpi
->w
, H
= mpi
->h
;
87 const unsigned char *prvp
, *prvpp
, *prvpn
, *prvpnn
, *prvppp
, *prvp4p
, *prvp4n
;
88 const unsigned char *srcp_saved
;
89 const unsigned char *srcp
, *srcpp
, *srcpn
, *srcpnn
, *srcppp
, *srcp3p
, *srcp3n
, *srcp4p
, *srcp4n
;
90 unsigned char *dstp
, *dstp_saved
;
95 int n
= vf
->priv
->frame
++;
96 int val
, hi
, lo
, w
, h
;
99 int threshold
= vf
->priv
->thresh
;
100 int order
= vf
->priv
->order
;
101 int map
= vf
->priv
->map
;
102 int sharp
= vf
->priv
->sharp
;
103 int twoway
= vf
->priv
->twoway
;
104 mp_image_t
*dmpi
, *pmpi
;
106 if(!vf
->priv
->do_deinterlace
)
107 return vf_next_put_image(vf
, mpi
, pts
);
109 dmpi
=vf_get_image(vf
->next
,mpi
->imgfmt
,
110 MP_IMGTYPE_IP
, MP_IMGFLAG_ACCEPT_STRIDE
,
112 pmpi
=vf_get_image(vf
->next
,mpi
->imgfmt
,
113 MP_IMGTYPE_TEMP
, MP_IMGFLAG_ACCEPT_STRIDE
,
117 for (z
=0; z
<mpi
->num_planes
; z
++) {
118 if (z
== 0) plane
= PLANAR_Y
;
119 else if (z
== 1) plane
= PLANAR_U
;
120 else plane
= PLANAR_V
;
122 h
= plane
== PLANAR_Y
? H
: ch
;
123 w
= plane
== PLANAR_Y
? W
: cw
;
125 srcp
= srcp_saved
= mpi
->planes
[z
];
126 src_pitch
= mpi
->stride
[z
];
127 psrc_pitch
= pmpi
->stride
[z
];
128 dstp
= dstp_saved
= dmpi
->planes
[z
];
129 dst_pitch
= dmpi
->stride
[z
];
130 srcp
= srcp_saved
+ (1-order
) * src_pitch
;
131 dstp
= dstp_saved
+ (1-order
) * dst_pitch
;
133 for (y
=0; y
<h
; y
+=2) {
134 fast_memcpy(dstp
, srcp
, w
);
139 // Copy through the lines that will be missed below.
140 fast_memcpy(dstp_saved
+ order
*dst_pitch
, srcp_saved
+ (1-order
)*src_pitch
, w
);
141 fast_memcpy(dstp_saved
+ (2+order
)*dst_pitch
, srcp_saved
+ (3-order
)*src_pitch
, w
);
142 fast_memcpy(dstp_saved
+ (h
-2+order
)*dst_pitch
, srcp_saved
+ (h
-1-order
)*src_pitch
, w
);
143 fast_memcpy(dstp_saved
+ (h
-4+order
)*dst_pitch
, srcp_saved
+ (h
-3-order
)*src_pitch
, w
);
144 /* For the other field choose adaptively between using the previous field
145 or the interpolant from the current field. */
147 prvp
= pmpi
->planes
[z
] + 5*psrc_pitch
- (1-order
)*psrc_pitch
;
148 prvpp
= prvp
- psrc_pitch
;
149 prvppp
= prvp
- 2*psrc_pitch
;
150 prvp4p
= prvp
- 4*psrc_pitch
;
151 prvpn
= prvp
+ psrc_pitch
;
152 prvpnn
= prvp
+ 2*psrc_pitch
;
153 prvp4n
= prvp
+ 4*psrc_pitch
;
154 srcp
= srcp_saved
+ 5*src_pitch
- (1-order
)*src_pitch
;
155 srcpp
= srcp
- src_pitch
;
156 srcppp
= srcp
- 2*src_pitch
;
157 srcp3p
= srcp
- 3*src_pitch
;
158 srcp4p
= srcp
- 4*src_pitch
;
159 srcpn
= srcp
+ src_pitch
;
160 srcpnn
= srcp
+ 2*src_pitch
;
161 srcp3n
= srcp
+ 3*src_pitch
;
162 srcp4n
= srcp
+ 4*src_pitch
;
163 dstp
= dstp_saved
+ 5*dst_pitch
- (1-order
)*dst_pitch
;
164 for (y
= 5 - (1-order
); y
<= h
- 5 - (1-order
); y
+=2)
166 for (x
= 0; x
< w
; x
++)
168 if ((threshold
== 0) || (n
== 0) ||
169 (abs((int)prvp
[x
] - (int)srcp
[x
]) > threshold
) ||
170 (abs((int)prvpp
[x
] - (int)srcpp
[x
]) > threshold
) ||
171 (abs((int)prvpn
[x
] - (int)srcpn
[x
]) > threshold
))
184 else if (IsYUY2(mpi
) == 1)
194 if (plane
== PLANAR_Y
) dstp
[x
] = 235;
205 else if (IsYUY2(mpi
))
207 hi
= (x
& 1) ? 240 : 235;
212 hi
= (plane
== PLANAR_Y
) ? 235 : 240;
219 valf
= + 0.526*((int)srcpp
[x
] + (int)srcpn
[x
])
220 + 0.170*((int)srcp
[x
] + (int)prvp
[x
])
221 - 0.116*((int)srcppp
[x
] + (int)srcpnn
[x
] + (int)prvppp
[x
] + (int)prvpnn
[x
])
222 - 0.026*((int)srcp3p
[x
] + (int)srcp3n
[x
])
223 + 0.031*((int)srcp4p
[x
] + (int)srcp4n
[x
] + (int)prvp4p
[x
] + (int)prvp4n
[x
]);
225 valf
= + 0.526*((int)srcpp
[x
] + (int)srcpn
[x
])
226 + 0.170*((int)prvp
[x
])
227 - 0.116*((int)prvppp
[x
] + (int)prvpnn
[x
])
228 - 0.026*((int)srcp3p
[x
] + (int)srcp3n
[x
])
229 + 0.031*((int)prvp4p
[x
] + (int)prvp4p
[x
]);
230 if (valf
> hi
) valf
= hi
;
231 else if (valf
< lo
) valf
= lo
;
232 dstp
[x
] = (int) valf
;
237 val
= (8*((int)srcpp
[x
] + (int)srcpn
[x
]) + 2*((int)srcp
[x
] + (int)prvp
[x
]) -
238 (int)(srcppp
[x
]) - (int)(srcpnn
[x
]) -
239 (int)(prvppp
[x
]) - (int)(prvpnn
[x
])) >> 4;
241 val
= (8*((int)srcpp
[x
] + (int)srcpn
[x
]) + 2*((int)prvp
[x
]) -
242 (int)(prvppp
[x
]) - (int)(prvpnn
[x
])) >> 4;
243 if (val
> hi
) val
= hi
;
244 else if (val
< lo
) val
= lo
;
254 prvp
+= 2*psrc_pitch
;
255 prvpp
+= 2*psrc_pitch
;
256 prvppp
+= 2*psrc_pitch
;
257 prvpn
+= 2*psrc_pitch
;
258 prvpnn
+= 2*psrc_pitch
;
259 prvp4p
+= 2*psrc_pitch
;
260 prvp4n
+= 2*psrc_pitch
;
262 srcpp
+= 2*src_pitch
;
263 srcppp
+= 2*src_pitch
;
264 srcp3p
+= 2*src_pitch
;
265 srcp4p
+= 2*src_pitch
;
266 srcpn
+= 2*src_pitch
;
267 srcpnn
+= 2*src_pitch
;
268 srcp3n
+= 2*src_pitch
;
269 srcp4n
+= 2*src_pitch
;
273 srcp
= mpi
->planes
[z
];
274 dstp
= pmpi
->planes
[z
];
275 for (y
=0; y
<h
; y
++) {
276 fast_memcpy(dstp
, srcp
, w
);
282 return vf_next_put_image(vf
,dmpi
, pts
);
285 //===========================================================================//
287 static int query_format(struct vf_instance_s
* vf
, unsigned int fmt
){
293 return vf_next_query_format(vf
, fmt
);
298 static int control(struct vf_instance_s
* vf
, int request
, void* data
){
301 case VFCTRL_GET_DEINTERLACE
:
302 *(int*)data
= vf
->priv
->do_deinterlace
;
304 case VFCTRL_SET_DEINTERLACE
:
305 vf
->priv
->do_deinterlace
= *(int*)data
;
308 return vf_next_control (vf
, request
, data
);
311 static int open(vf_instance_t
*vf
, char* args
){
315 vf
->put_image
=put_image
;
316 vf
->query_format
=query_format
;
318 vf
->priv
=malloc(sizeof(struct vf_priv_s
));
319 memset(vf
->priv
, 0, sizeof(struct vf_priv_s
));
325 vf
->priv
->thresh
= 10;
327 vf
->priv
->twoway
= 0;
328 vf
->priv
->do_deinterlace
=1;
332 sscanf(args
, "%d:%d:%d:%d:%d",
333 &vf
->priv
->thresh
, &vf
->priv
->map
,
334 &vf
->priv
->order
, &vf
->priv
->sharp
,
337 if (vf
->priv
->order
> 1) vf
->priv
->order
= 1;
342 const vf_info_t vf_info_kerndeint
= {
343 "Kernel Deinterlacer",
351 //===========================================================================//