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., 675 Mass Ave, Cambridge, MA 02139, USA.
32 #include "img_format.h"
35 #include "libvo/fastmemcpy.h"
37 //===========================================================================//
49 /***************************************************************************/
52 static int config(struct vf_instance_s
* vf
,
53 int width
, int height
, int d_width
, int d_height
,
54 unsigned int flags
, unsigned int outfmt
){
56 return vf_next_config(vf
,width
,height
,d_width
,d_height
,flags
,outfmt
);
60 static void uninit(struct vf_instance_s
* vf
)
65 static inline int IsRGB(mp_image_t
*mpi
)
67 return mpi
->imgfmt
== IMGFMT_RGB
;
70 static inline int IsYUY2(mp_image_t
*mpi
)
72 return mpi
->imgfmt
== IMGFMT_YUY2
;
79 static int put_image(struct vf_instance_s
* vf
, mp_image_t
*mpi
, double pts
){
80 int cw
= mpi
->w
>> mpi
->chroma_x_shift
;
81 int ch
= mpi
->h
>> mpi
->chroma_y_shift
;
82 int W
= mpi
->w
, H
= mpi
->h
;
83 const unsigned char *prvp
, *prvpp
, *prvpn
, *prvpnn
, *prvppp
, *prvp4p
, *prvp4n
;
84 const unsigned char *srcp_saved
;
85 const unsigned char *srcp
, *srcpp
, *srcpn
, *srcpnn
, *srcppp
, *srcp3p
, *srcp3n
, *srcp4p
, *srcp4n
;
86 unsigned char *dstp
, *dstp_saved
;
91 int n
= vf
->priv
->frame
++;
92 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
;
102 mp_image_t
*dmpi
=vf_get_image(vf
->next
,mpi
->imgfmt
,
103 MP_IMGTYPE_IP
, MP_IMGFLAG_ACCEPT_STRIDE
,
105 mp_image_t
*pmpi
=vf_get_image(vf
->next
,mpi
->imgfmt
,
106 MP_IMGTYPE_TEMP
, MP_IMGFLAG_ACCEPT_STRIDE
,
110 for (z
=0; z
<mpi
->num_planes
; z
++) {
111 if (z
== 0) plane
= PLANAR_Y
;
112 else if (z
== 1) plane
= PLANAR_U
;
113 else plane
= PLANAR_V
;
115 h
= plane
== PLANAR_Y
? H
: ch
;
116 w
= plane
== PLANAR_Y
? W
: cw
;
118 srcp
= srcp_saved
= mpi
->planes
[z
];
119 src_pitch
= mpi
->stride
[z
];
120 psrc_pitch
= pmpi
->stride
[z
];
121 dstp
= dstp_saved
= dmpi
->planes
[z
];
122 dst_pitch
= dmpi
->stride
[z
];
123 srcp
= srcp_saved
+ (1-order
) * src_pitch
;
124 dstp
= dstp_saved
+ (1-order
) * dst_pitch
;
126 for (y
=0; y
<h
; y
+=2) {
127 memcpy(dstp
, srcp
, w
);
132 // Copy through the lines that will be missed below.
133 memcpy(dstp_saved
+ order
*dst_pitch
, srcp_saved
+ (1-order
)*src_pitch
, w
);
134 memcpy(dstp_saved
+ (2+order
)*dst_pitch
, srcp_saved
+ (3-order
)*src_pitch
, w
);
135 memcpy(dstp_saved
+ (h
-2+order
)*dst_pitch
, srcp_saved
+ (h
-1-order
)*src_pitch
, w
);
136 memcpy(dstp_saved
+ (h
-4+order
)*dst_pitch
, srcp_saved
+ (h
-3-order
)*src_pitch
, w
);
137 /* For the other field choose adaptively between using the previous field
138 or the interpolant from the current field. */
140 prvp
= pmpi
->planes
[z
] + 5*psrc_pitch
- (1-order
)*psrc_pitch
;
141 prvpp
= prvp
- psrc_pitch
;
142 prvppp
= prvp
- 2*psrc_pitch
;
143 prvp4p
= prvp
- 4*psrc_pitch
;
144 prvpn
= prvp
+ psrc_pitch
;
145 prvpnn
= prvp
+ 2*psrc_pitch
;
146 prvp4n
= prvp
+ 4*psrc_pitch
;
147 srcp
= srcp_saved
+ 5*src_pitch
- (1-order
)*src_pitch
;
148 srcpp
= srcp
- src_pitch
;
149 srcppp
= srcp
- 2*src_pitch
;
150 srcp3p
= srcp
- 3*src_pitch
;
151 srcp4p
= srcp
- 4*src_pitch
;
152 srcpn
= srcp
+ src_pitch
;
153 srcpnn
= srcp
+ 2*src_pitch
;
154 srcp3n
= srcp
+ 3*src_pitch
;
155 srcp4n
= srcp
+ 4*src_pitch
;
156 dstp
= dstp_saved
+ 5*dst_pitch
- (1-order
)*dst_pitch
;
157 for (y
= 5 - (1-order
); y
<= h
- 5 - (1-order
); y
+=2)
159 for (x
= 0; x
< w
; x
++)
161 if ((threshold
== 0) || (n
== 0) ||
162 (abs((int)prvp
[x
] - (int)srcp
[x
]) > threshold
) ||
163 (abs((int)prvpp
[x
] - (int)srcpp
[x
]) > threshold
) ||
164 (abs((int)prvpn
[x
] - (int)srcpn
[x
]) > threshold
))
177 else if (IsYUY2(mpi
) == 1)
187 if (plane
== PLANAR_Y
) dstp
[x
] = 235;
198 else if (IsYUY2(mpi
))
200 hi
= (x
& 1) ? 240 : 235;
205 hi
= (plane
== PLANAR_Y
) ? 235 : 240;
212 valf
= + 0.526*((int)srcpp
[x
] + (int)srcpn
[x
])
213 + 0.170*((int)srcp
[x
] + (int)prvp
[x
])
214 - 0.116*((int)srcppp
[x
] + (int)srcpnn
[x
] + (int)prvppp
[x
] + (int)prvpnn
[x
])
215 - 0.026*((int)srcp3p
[x
] + (int)srcp3n
[x
])
216 + 0.031*((int)srcp4p
[x
] + (int)srcp4n
[x
] + (int)prvp4p
[x
] + (int)prvp4n
[x
]);
218 valf
= + 0.526*((int)srcpp
[x
] + (int)srcpn
[x
])
219 + 0.170*((int)prvp
[x
])
220 - 0.116*((int)prvppp
[x
] + (int)prvpnn
[x
])
221 - 0.026*((int)srcp3p
[x
] + (int)srcp3n
[x
])
222 + 0.031*((int)prvp4p
[x
] + (int)prvp4p
[x
]);
223 if (valf
> hi
) valf
= hi
;
224 else if (valf
< lo
) valf
= lo
;
225 dstp
[x
] = (int) valf
;
230 val
= (8*((int)srcpp
[x
] + (int)srcpn
[x
]) + 2*((int)srcp
[x
] + (int)prvp
[x
]) -
231 (int)(srcppp
[x
]) - (int)(srcpnn
[x
]) -
232 (int)(prvppp
[x
]) - (int)(prvpnn
[x
])) >> 4;
234 val
= (8*((int)srcpp
[x
] + (int)srcpn
[x
]) + 2*((int)prvp
[x
]) -
235 (int)(prvppp
[x
]) - (int)(prvpnn
[x
])) >> 4;
236 if (val
> hi
) val
= hi
;
237 else if (val
< lo
) val
= lo
;
247 prvp
+= 2*psrc_pitch
;
248 prvpp
+= 2*psrc_pitch
;
249 prvppp
+= 2*psrc_pitch
;
250 prvpn
+= 2*psrc_pitch
;
251 prvpnn
+= 2*psrc_pitch
;
252 prvp4p
+= 2*psrc_pitch
;
253 prvp4n
+= 2*psrc_pitch
;
255 srcpp
+= 2*src_pitch
;
256 srcppp
+= 2*src_pitch
;
257 srcp3p
+= 2*src_pitch
;
258 srcp4p
+= 2*src_pitch
;
259 srcpn
+= 2*src_pitch
;
260 srcpnn
+= 2*src_pitch
;
261 srcp3n
+= 2*src_pitch
;
262 srcp4n
+= 2*src_pitch
;
266 srcp
= mpi
->planes
[z
];
267 dstp
= pmpi
->planes
[z
];
268 for (y
=0; y
<h
; y
++) {
269 memcpy(dstp
, srcp
, w
);
275 return vf_next_put_image(vf
,dmpi
, pts
);
278 //===========================================================================//
280 static int query_format(struct vf_instance_s
* vf
, unsigned int fmt
){
286 return vf_next_query_format(vf
, fmt
);
291 static int open(vf_instance_t
*vf
, char* args
){
292 double LumSpac
, LumTmp
, ChromSpac
, ChromTmp
;
293 double Param1
, Param2
, Param3
;
296 vf
->put_image
=put_image
;
297 vf
->query_format
=query_format
;
299 vf
->priv
=malloc(sizeof(struct vf_priv_s
));
300 memset(vf
->priv
, 0, sizeof(struct vf_priv_s
));
306 vf
->priv
->thresh
= 10;
308 vf
->priv
->twoway
= 0;
312 sscanf(args
, "%d:%d:%d:%d:%d",
313 &vf
->priv
->thresh
, &vf
->priv
->map
,
314 &vf
->priv
->order
, &vf
->priv
->sharp
,
317 if (vf
->priv
->order
> 1) vf
->priv
->order
= 1;
322 vf_info_t vf_info_kerndeint
= {
323 "Kernel Deinterlacer",
331 //===========================================================================//