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;
94 dst->b_progressive = true;
98 static int Open(vlc_object_t *obj)
100 filter_t *filter = (filter_t *)obj;
102 if (filter->fmt_in.video.i_chroma != VLC_CODEC_VDPAU_VIDEO_420
103 && filter->fmt_in.video.i_chroma != VLC_CODEC_VDPAU_VIDEO_422
104 && filter->fmt_in.video.i_chroma != VLC_CODEC_VDPAU_VIDEO_444)
106 if (!video_format_IsSimilar(&filter->fmt_in.video, &filter->fmt_out.video))
109 filter_sys_t *sys = malloc(sizeof (*sys));
110 if (unlikely(sys == NULL))
113 /* NOTE: Only weave and bob are mandatory for the hardware to implement.
114 * The other modes and IVTC should be checked. */
116 sys->last_pts = VLC_TS_INVALID;
118 filter->pf_video_filter = Deinterlace;
120 filter->fmt_out.video.i_frame_rate *= 2;
124 static void Close(vlc_object_t *obj)
126 filter_t *filter = (filter_t *)obj;
127 filter_sys_t *sys = filter->p_sys;
133 set_description(N_("VDPAU deinterlacing filter"))
134 set_capability("video filter2", 0)
135 set_category(CAT_VIDEO)
136 set_subcategory(SUBCAT_VIDEO_VFILTER)
137 set_callbacks(Open, Close)
138 add_shortcut ("deinterlace")