2 Original AVISynth Filter Copyright (C) 2003 Donald A. Graft
3 Adapted to MPlayer by Tobias Diedrich
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
32 #include "img_format.h"
35 #include "libvo/fastmemcpy.h"
37 //===========================================================================//
50 /***************************************************************************/
53 static int config(struct vf_instance_s
* vf
,
54 int width
, int height
, int d_width
, int d_height
,
55 unsigned int flags
, unsigned int outfmt
){
57 return vf_next_config(vf
,width
,height
,d_width
,d_height
,flags
,outfmt
);
61 static void uninit(struct vf_instance_s
* vf
)
66 static inline int IsRGB(mp_image_t
*mpi
)
68 return mpi
->imgfmt
== IMGFMT_RGB
;
71 static inline int IsYUY2(mp_image_t
*mpi
)
73 return mpi
->imgfmt
== IMGFMT_YUY2
;
80 static int put_image(struct vf_instance_s
* vf
, mp_image_t
*mpi
, double pts
){
81 int cw
= mpi
->w
>> mpi
->chroma_x_shift
;
82 int ch
= mpi
->h
>> mpi
->chroma_y_shift
;
83 int W
= mpi
->w
, H
= mpi
->h
;
84 const unsigned char *prvp
, *prvpp
, *prvpn
, *prvpnn
, *prvppp
, *prvp4p
, *prvp4n
;
85 const unsigned char *srcp_saved
;
86 const unsigned char *srcp
, *srcpp
, *srcpn
, *srcpnn
, *srcppp
, *srcp3p
, *srcp3n
, *srcp4p
, *srcp4n
;
87 unsigned char *dstp
, *dstp_saved
;
92 int n
= vf
->priv
->frame
++;
93 int val
, hi
, lo
, w
, h
;
96 int threshold
= vf
->priv
->thresh
;
97 int order
= vf
->priv
->order
;
98 int map
= vf
->priv
->map
;
99 int sharp
= vf
->priv
->sharp
;
100 int twoway
= vf
->priv
->twoway
;
101 mp_image_t
*dmpi
, *pmpi
;
103 if(!vf
->priv
->do_deinterlace
)
104 return vf_next_put_image(vf
, mpi
, pts
);
106 dmpi
=vf_get_image(vf
->next
,mpi
->imgfmt
,
107 MP_IMGTYPE_IP
, MP_IMGFLAG_ACCEPT_STRIDE
,
109 pmpi
=vf_get_image(vf
->next
,mpi
->imgfmt
,
110 MP_IMGTYPE_TEMP
, MP_IMGFLAG_ACCEPT_STRIDE
,
114 for (z
=0; z
<mpi
->num_planes
; z
++) {
115 if (z
== 0) plane
= PLANAR_Y
;
116 else if (z
== 1) plane
= PLANAR_U
;
117 else plane
= PLANAR_V
;
119 h
= plane
== PLANAR_Y
? H
: ch
;
120 w
= plane
== PLANAR_Y
? W
: cw
;
122 srcp
= srcp_saved
= mpi
->planes
[z
];
123 src_pitch
= mpi
->stride
[z
];
124 psrc_pitch
= pmpi
->stride
[z
];
125 dstp
= dstp_saved
= dmpi
->planes
[z
];
126 dst_pitch
= dmpi
->stride
[z
];
127 srcp
= srcp_saved
+ (1-order
) * src_pitch
;
128 dstp
= dstp_saved
+ (1-order
) * dst_pitch
;
130 for (y
=0; y
<h
; y
+=2) {
131 memcpy(dstp
, srcp
, w
);
136 // Copy through the lines that will be missed below.
137 memcpy(dstp_saved
+ order
*dst_pitch
, srcp_saved
+ (1-order
)*src_pitch
, w
);
138 memcpy(dstp_saved
+ (2+order
)*dst_pitch
, srcp_saved
+ (3-order
)*src_pitch
, w
);
139 memcpy(dstp_saved
+ (h
-2+order
)*dst_pitch
, srcp_saved
+ (h
-1-order
)*src_pitch
, w
);
140 memcpy(dstp_saved
+ (h
-4+order
)*dst_pitch
, srcp_saved
+ (h
-3-order
)*src_pitch
, w
);
141 /* For the other field choose adaptively between using the previous field
142 or the interpolant from the current field. */
144 prvp
= pmpi
->planes
[z
] + 5*psrc_pitch
- (1-order
)*psrc_pitch
;
145 prvpp
= prvp
- psrc_pitch
;
146 prvppp
= prvp
- 2*psrc_pitch
;
147 prvp4p
= prvp
- 4*psrc_pitch
;
148 prvpn
= prvp
+ psrc_pitch
;
149 prvpnn
= prvp
+ 2*psrc_pitch
;
150 prvp4n
= prvp
+ 4*psrc_pitch
;
151 srcp
= srcp_saved
+ 5*src_pitch
- (1-order
)*src_pitch
;
152 srcpp
= srcp
- src_pitch
;
153 srcppp
= srcp
- 2*src_pitch
;
154 srcp3p
= srcp
- 3*src_pitch
;
155 srcp4p
= srcp
- 4*src_pitch
;
156 srcpn
= srcp
+ src_pitch
;
157 srcpnn
= srcp
+ 2*src_pitch
;
158 srcp3n
= srcp
+ 3*src_pitch
;
159 srcp4n
= srcp
+ 4*src_pitch
;
160 dstp
= dstp_saved
+ 5*dst_pitch
- (1-order
)*dst_pitch
;
161 for (y
= 5 - (1-order
); y
<= h
- 5 - (1-order
); y
+=2)
163 for (x
= 0; x
< w
; x
++)
165 if ((threshold
== 0) || (n
== 0) ||
166 (abs((int)prvp
[x
] - (int)srcp
[x
]) > threshold
) ||
167 (abs((int)prvpp
[x
] - (int)srcpp
[x
]) > threshold
) ||
168 (abs((int)prvpn
[x
] - (int)srcpn
[x
]) > threshold
))
181 else if (IsYUY2(mpi
) == 1)
191 if (plane
== PLANAR_Y
) dstp
[x
] = 235;
202 else if (IsYUY2(mpi
))
204 hi
= (x
& 1) ? 240 : 235;
209 hi
= (plane
== PLANAR_Y
) ? 235 : 240;
216 valf
= + 0.526*((int)srcpp
[x
] + (int)srcpn
[x
])
217 + 0.170*((int)srcp
[x
] + (int)prvp
[x
])
218 - 0.116*((int)srcppp
[x
] + (int)srcpnn
[x
] + (int)prvppp
[x
] + (int)prvpnn
[x
])
219 - 0.026*((int)srcp3p
[x
] + (int)srcp3n
[x
])
220 + 0.031*((int)srcp4p
[x
] + (int)srcp4n
[x
] + (int)prvp4p
[x
] + (int)prvp4n
[x
]);
222 valf
= + 0.526*((int)srcpp
[x
] + (int)srcpn
[x
])
223 + 0.170*((int)prvp
[x
])
224 - 0.116*((int)prvppp
[x
] + (int)prvpnn
[x
])
225 - 0.026*((int)srcp3p
[x
] + (int)srcp3n
[x
])
226 + 0.031*((int)prvp4p
[x
] + (int)prvp4p
[x
]);
227 if (valf
> hi
) valf
= hi
;
228 else if (valf
< lo
) valf
= lo
;
229 dstp
[x
] = (int) valf
;
234 val
= (8*((int)srcpp
[x
] + (int)srcpn
[x
]) + 2*((int)srcp
[x
] + (int)prvp
[x
]) -
235 (int)(srcppp
[x
]) - (int)(srcpnn
[x
]) -
236 (int)(prvppp
[x
]) - (int)(prvpnn
[x
])) >> 4;
238 val
= (8*((int)srcpp
[x
] + (int)srcpn
[x
]) + 2*((int)prvp
[x
]) -
239 (int)(prvppp
[x
]) - (int)(prvpnn
[x
])) >> 4;
240 if (val
> hi
) val
= hi
;
241 else if (val
< lo
) val
= lo
;
251 prvp
+= 2*psrc_pitch
;
252 prvpp
+= 2*psrc_pitch
;
253 prvppp
+= 2*psrc_pitch
;
254 prvpn
+= 2*psrc_pitch
;
255 prvpnn
+= 2*psrc_pitch
;
256 prvp4p
+= 2*psrc_pitch
;
257 prvp4n
+= 2*psrc_pitch
;
259 srcpp
+= 2*src_pitch
;
260 srcppp
+= 2*src_pitch
;
261 srcp3p
+= 2*src_pitch
;
262 srcp4p
+= 2*src_pitch
;
263 srcpn
+= 2*src_pitch
;
264 srcpnn
+= 2*src_pitch
;
265 srcp3n
+= 2*src_pitch
;
266 srcp4n
+= 2*src_pitch
;
270 srcp
= mpi
->planes
[z
];
271 dstp
= pmpi
->planes
[z
];
272 for (y
=0; y
<h
; y
++) {
273 memcpy(dstp
, srcp
, w
);
279 return vf_next_put_image(vf
,dmpi
, pts
);
282 //===========================================================================//
284 static int query_format(struct vf_instance_s
* vf
, unsigned int fmt
){
290 return vf_next_query_format(vf
, fmt
);
295 static int control(struct vf_instance_s
* vf
, int request
, void* data
){
298 case VFCTRL_GET_DEINTERLACE
:
299 *(int*)data
= vf
->priv
->do_deinterlace
;
301 case VFCTRL_SET_DEINTERLACE
:
302 vf
->priv
->do_deinterlace
= *(int*)data
;
305 return vf_next_control (vf
, request
, data
);
308 static int open(vf_instance_t
*vf
, char* args
){
312 vf
->put_image
=put_image
;
313 vf
->query_format
=query_format
;
315 vf
->priv
=malloc(sizeof(struct vf_priv_s
));
316 memset(vf
->priv
, 0, sizeof(struct vf_priv_s
));
322 vf
->priv
->thresh
= 10;
324 vf
->priv
->twoway
= 0;
325 vf
->priv
->do_deinterlace
=1;
329 sscanf(args
, "%d:%d:%d:%d:%d",
330 &vf
->priv
->thresh
, &vf
->priv
->map
,
331 &vf
->priv
->order
, &vf
->priv
->sharp
,
334 if (vf
->priv
->order
> 1) vf
->priv
->order
= 1;
339 vf_info_t vf_info_kerndeint
= {
340 "Kernel Deinterlacer",
348 //===========================================================================//