1 /*****************************************************************************
2 * deinterlace.c: VDPAU deinterlacing filter
3 *****************************************************************************
4 * Copyright (C) 2013 RĂ©mi Denis-Courmont
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation; either version 2.1 of the License, or
9 * (at your option) any later version.
11 * This program 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 Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
19 *****************************************************************************/
28 #include <vlc_common.h>
29 #include <vlc_plugin.h>
30 #include <vlc_filter.h>
31 #include "vlc_vdpau.h"
38 static picture_t *Deinterlace(filter_t *filter, picture_t *src)
40 filter_sys_t *sys = filter->p_sys;
41 mtime_t last_pts = sys->last_pts;
43 sys->last_pts = src->date;
45 vlc_vdp_video_field_t *f1 = src->context;
46 if (unlikely(f1 == NULL))
48 if (f1->structure != VDP_VIDEO_MIXER_PICTURE_STRUCTURE_FRAME)
49 return src; /* cannot deinterlace twice */
51 #ifdef VOUT_CORE_GETS_A_CLUE
52 picture_t *dst = filter_NewPicture(filter);
54 picture_t *dst = picture_NewFromFormat(&src->format);
57 return src; /* cannot deinterlace without copying fields */
59 vlc_vdp_video_field_t *f2 = vlc_vdp_video_copy(f1); // shallow copy
60 if (unlikely(f2 == NULL))
66 picture_CopyProperties(dst, src);
69 if (last_pts != VLC_TS_INVALID)
70 dst->date = (3 * src->date - last_pts) / 2;
72 if (filter->fmt_in.video.i_frame_rate != 0)
73 dst->date = src->date + ((filter->fmt_in.video.i_frame_rate_base
74 * CLOCK_FREQ) / filter->fmt_in.video.i_frame_rate);
75 dst->b_top_field_first = !src->b_top_field_first;
79 assert(src->p_next == NULL);
82 if (src->b_progressive || src->b_top_field_first)
84 f1->structure = VDP_VIDEO_MIXER_PICTURE_STRUCTURE_TOP_FIELD;
85 f2->structure = VDP_VIDEO_MIXER_PICTURE_STRUCTURE_BOTTOM_FIELD;
89 f1->structure = VDP_VIDEO_MIXER_PICTURE_STRUCTURE_BOTTOM_FIELD;
90 f2->structure = VDP_VIDEO_MIXER_PICTURE_STRUCTURE_TOP_FIELD;
93 src->b_progressive = true;
97 static int Open(vlc_object_t *obj)
99 filter_t *filter = (filter_t *)obj;
101 if (filter->fmt_in.video.i_chroma != VLC_CODEC_VDPAU_VIDEO_422
102 && filter->fmt_in.video.i_chroma != VLC_CODEC_VDPAU_VIDEO_420)
104 if (!video_format_IsSimilar(&filter->fmt_in.video, &filter->fmt_out.video))
107 filter_sys_t *sys = malloc(sizeof (*sys));
108 if (unlikely(sys == NULL))
111 /* NOTE: Only weave and bob are mandatory for the hardware to implement.
112 * The other modes and IVTC should be checked. */
114 sys->last_pts = VLC_TS_INVALID;
116 filter->pf_video_filter = Deinterlace;
118 filter->fmt_out.video.i_frame_rate *= 2;
122 static void Close(vlc_object_t *obj)
124 filter_t *filter = (filter_t *)obj;
125 filter_sys_t *sys = filter->p_sys;
131 set_description(N_("VDPAU deinterlacing filter"))
132 set_capability("video filter2", 0)
133 set_category(CAT_VIDEO)
134 set_subcategory(SUBCAT_VIDEO_VFILTER)
135 set_callbacks(Open, Close)
136 add_shortcut ("deinterlace")