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.
29 #include "img_format.h"
32 #include "libvo/fastmemcpy.h"
34 //===========================================================================//
47 /***************************************************************************/
50 static int config(struct vf_instance
* vf
,
51 int width
, int height
, int d_width
, int d_height
,
52 unsigned int flags
, unsigned int outfmt
){
54 return vf_next_config(vf
,width
,height
,d_width
,d_height
,flags
,outfmt
);
58 static void uninit(struct vf_instance
* vf
)
63 static inline int IsRGB(mp_image_t
*mpi
)
65 return mpi
->imgfmt
== IMGFMT_RGB
;
68 static inline int IsYUY2(mp_image_t
*mpi
)
70 return mpi
->imgfmt
== IMGFMT_YUY2
;
77 static int put_image(struct vf_instance
* vf
, mp_image_t
*mpi
, double pts
){
78 int cw
= mpi
->w
>> mpi
->chroma_x_shift
;
79 int ch
= mpi
->h
>> mpi
->chroma_y_shift
;
80 int W
= mpi
->w
, H
= mpi
->h
;
81 const unsigned char *prvp
, *prvpp
, *prvpn
, *prvpnn
, *prvppp
, *prvp4p
, *prvp4n
;
82 const unsigned char *srcp_saved
;
83 const unsigned char *srcp
, *srcpp
, *srcpn
, *srcpnn
, *srcppp
, *srcp3p
, *srcp3n
, *srcp4p
, *srcp4n
;
84 unsigned char *dstp
, *dstp_saved
;
89 int n
= vf
->priv
->frame
++;
90 int val
, hi
, lo
, w
, h
;
93 int threshold
= vf
->priv
->thresh
;
94 int order
= vf
->priv
->order
;
95 int map
= vf
->priv
->map
;
96 int sharp
= vf
->priv
->sharp
;
97 int twoway
= vf
->priv
->twoway
;
98 mp_image_t
*dmpi
, *pmpi
;
100 if(!vf
->priv
->do_deinterlace
)
101 return vf_next_put_image(vf
, mpi
, pts
);
103 dmpi
=vf_get_image(vf
->next
,mpi
->imgfmt
,
104 MP_IMGTYPE_IP
, MP_IMGFLAG_ACCEPT_STRIDE
,
106 pmpi
=vf_get_image(vf
->next
,mpi
->imgfmt
,
107 MP_IMGTYPE_TEMP
, MP_IMGFLAG_ACCEPT_STRIDE
,
111 for (z
=0; z
<mpi
->num_planes
; z
++) {
112 if (z
== 0) plane
= PLANAR_Y
;
113 else if (z
== 1) plane
= PLANAR_U
;
114 else plane
= PLANAR_V
;
116 h
= plane
== PLANAR_Y
? H
: ch
;
117 w
= plane
== PLANAR_Y
? W
: cw
;
119 srcp
= srcp_saved
= mpi
->planes
[z
];
120 src_pitch
= mpi
->stride
[z
];
121 psrc_pitch
= pmpi
->stride
[z
];
122 dstp
= dstp_saved
= dmpi
->planes
[z
];
123 dst_pitch
= dmpi
->stride
[z
];
124 srcp
= srcp_saved
+ (1-order
) * src_pitch
;
125 dstp
= dstp_saved
+ (1-order
) * dst_pitch
;
127 for (y
=0; y
<h
; y
+=2) {
128 fast_memcpy(dstp
, srcp
, w
);
133 // Copy through the lines that will be missed below.
134 fast_memcpy(dstp_saved
+ order
*dst_pitch
, srcp_saved
+ (1-order
)*src_pitch
, w
);
135 fast_memcpy(dstp_saved
+ (2+order
)*dst_pitch
, srcp_saved
+ (3-order
)*src_pitch
, w
);
136 fast_memcpy(dstp_saved
+ (h
-2+order
)*dst_pitch
, srcp_saved
+ (h
-1-order
)*src_pitch
, w
);
137 fast_memcpy(dstp_saved
+ (h
-4+order
)*dst_pitch
, srcp_saved
+ (h
-3-order
)*src_pitch
, w
);
138 /* For the other field choose adaptively between using the previous field
139 or the interpolant from the current field. */
141 prvp
= pmpi
->planes
[z
] + 5*psrc_pitch
- (1-order
)*psrc_pitch
;
142 prvpp
= prvp
- psrc_pitch
;
143 prvppp
= prvp
- 2*psrc_pitch
;
144 prvp4p
= prvp
- 4*psrc_pitch
;
145 prvpn
= prvp
+ psrc_pitch
;
146 prvpnn
= prvp
+ 2*psrc_pitch
;
147 prvp4n
= prvp
+ 4*psrc_pitch
;
148 srcp
= srcp_saved
+ 5*src_pitch
- (1-order
)*src_pitch
;
149 srcpp
= srcp
- src_pitch
;
150 srcppp
= srcp
- 2*src_pitch
;
151 srcp3p
= srcp
- 3*src_pitch
;
152 srcp4p
= srcp
- 4*src_pitch
;
153 srcpn
= srcp
+ src_pitch
;
154 srcpnn
= srcp
+ 2*src_pitch
;
155 srcp3n
= srcp
+ 3*src_pitch
;
156 srcp4n
= srcp
+ 4*src_pitch
;
157 dstp
= dstp_saved
+ 5*dst_pitch
- (1-order
)*dst_pitch
;
158 for (y
= 5 - (1-order
); y
<= h
- 5 - (1-order
); y
+=2)
160 for (x
= 0; x
< w
; x
++)
162 if ((threshold
== 0) || (n
== 0) ||
163 (abs((int)prvp
[x
] - (int)srcp
[x
]) > threshold
) ||
164 (abs((int)prvpp
[x
] - (int)srcpp
[x
]) > threshold
) ||
165 (abs((int)prvpn
[x
] - (int)srcpn
[x
]) > threshold
))
178 else if (IsYUY2(mpi
) == 1)
188 if (plane
== PLANAR_Y
) dstp
[x
] = 235;
199 else if (IsYUY2(mpi
))
201 hi
= (x
& 1) ? 240 : 235;
206 hi
= (plane
== PLANAR_Y
) ? 235 : 240;
213 valf
= + 0.526*((int)srcpp
[x
] + (int)srcpn
[x
])
214 + 0.170*((int)srcp
[x
] + (int)prvp
[x
])
215 - 0.116*((int)srcppp
[x
] + (int)srcpnn
[x
] + (int)prvppp
[x
] + (int)prvpnn
[x
])
216 - 0.026*((int)srcp3p
[x
] + (int)srcp3n
[x
])
217 + 0.031*((int)srcp4p
[x
] + (int)srcp4n
[x
] + (int)prvp4p
[x
] + (int)prvp4n
[x
]);
219 valf
= + 0.526*((int)srcpp
[x
] + (int)srcpn
[x
])
220 + 0.170*((int)prvp
[x
])
221 - 0.116*((int)prvppp
[x
] + (int)prvpnn
[x
])
222 - 0.026*((int)srcp3p
[x
] + (int)srcp3n
[x
])
223 + 0.031*((int)prvp4p
[x
] + (int)prvp4p
[x
]);
224 if (valf
> hi
) valf
= hi
;
225 else if (valf
< lo
) valf
= lo
;
226 dstp
[x
] = (int) valf
;
231 val
= (8*((int)srcpp
[x
] + (int)srcpn
[x
]) + 2*((int)srcp
[x
] + (int)prvp
[x
]) -
232 (int)(srcppp
[x
]) - (int)(srcpnn
[x
]) -
233 (int)(prvppp
[x
]) - (int)(prvpnn
[x
])) >> 4;
235 val
= (8*((int)srcpp
[x
] + (int)srcpn
[x
]) + 2*((int)prvp
[x
]) -
236 (int)(prvppp
[x
]) - (int)(prvpnn
[x
])) >> 4;
237 if (val
> hi
) val
= hi
;
238 else if (val
< lo
) val
= lo
;
248 prvp
+= 2*psrc_pitch
;
249 prvpp
+= 2*psrc_pitch
;
250 prvppp
+= 2*psrc_pitch
;
251 prvpn
+= 2*psrc_pitch
;
252 prvpnn
+= 2*psrc_pitch
;
253 prvp4p
+= 2*psrc_pitch
;
254 prvp4n
+= 2*psrc_pitch
;
256 srcpp
+= 2*src_pitch
;
257 srcppp
+= 2*src_pitch
;
258 srcp3p
+= 2*src_pitch
;
259 srcp4p
+= 2*src_pitch
;
260 srcpn
+= 2*src_pitch
;
261 srcpnn
+= 2*src_pitch
;
262 srcp3n
+= 2*src_pitch
;
263 srcp4n
+= 2*src_pitch
;
267 srcp
= mpi
->planes
[z
];
268 dstp
= pmpi
->planes
[z
];
269 for (y
=0; y
<h
; y
++) {
270 fast_memcpy(dstp
, srcp
, w
);
276 return vf_next_put_image(vf
,dmpi
, pts
);
279 //===========================================================================//
281 static int query_format(struct vf_instance
* vf
, unsigned int fmt
){
287 return vf_next_query_format(vf
, fmt
);
292 static int control(struct vf_instance
* vf
, int request
, void* data
){
295 case VFCTRL_GET_DEINTERLACE
:
296 *(int*)data
= vf
->priv
->do_deinterlace
;
298 case VFCTRL_SET_DEINTERLACE
:
299 vf
->priv
->do_deinterlace
= *(int*)data
;
302 return vf_next_control (vf
, request
, data
);
305 static int vf_open(vf_instance_t
*vf
, char *args
){
309 vf
->put_image
=put_image
;
310 vf
->query_format
=query_format
;
312 vf
->priv
=malloc(sizeof(struct vf_priv_s
));
313 memset(vf
->priv
, 0, sizeof(struct vf_priv_s
));
319 vf
->priv
->thresh
= 10;
321 vf
->priv
->twoway
= 0;
322 vf
->priv
->do_deinterlace
=1;
326 sscanf(args
, "%d:%d:%d:%d:%d",
327 &vf
->priv
->thresh
, &vf
->priv
->map
,
328 &vf
->priv
->order
, &vf
->priv
->sharp
,
331 if (vf
->priv
->order
> 1) vf
->priv
->order
= 1;
336 const vf_info_t vf_info_kerndeint
= {
337 "Kernel Deinterlacer",
345 //===========================================================================//