Commit 1b658e10 authored by Steve Lhomme's avatar Steve Lhomme
Browse files

vdpau: implement draining of extra pictures in deinterlacer

We no longer return pictures chained using vlc_picture_chain_AppendChain().

The original code was returning the source picture, with a few metadata changed
and a secondary picture attached.

The secondary picture, with a different date, is prepared during the drain. We
keep a reference to the primary picture while waiting for the drain. This kept
picture is released during a Flush or on Close.

The last_pts that was used locally when chaining picture is kept as
prev_last_pts to generate the secondary picture(s) during the drain.
parent 8a97b7a8
......@@ -34,12 +34,14 @@
typedef struct
{
vlc_tick_t last_pts;
vlc_tick_t prev_last_pts;
picture_t *last_pic;
} filter_sys_t;
static picture_t *Deinterlace(filter_t *filter, picture_t *src)
{
filter_sys_t *sys = filter->p_sys;
vlc_tick_t last_pts = sys->last_pts;
sys->prev_last_pts = sys->last_pts;
sys->last_pts = src->date;
......@@ -49,66 +51,88 @@ static picture_t *Deinterlace(filter_t *filter, picture_t *src)
if (f1->structure != VDP_VIDEO_MIXER_PICTURE_STRUCTURE_FRAME)
return src; /* cannot deinterlace twice */
sys->last_pic = picture_Hold(src);
src->i_nb_fields = 1;
if (src->b_progressive || src->b_top_field_first)
f1->structure = VDP_VIDEO_MIXER_PICTURE_STRUCTURE_TOP_FIELD;
else
f1->structure = VDP_VIDEO_MIXER_PICTURE_STRUCTURE_BOTTOM_FIELD;
src->b_progressive = true;
return src;
}
static picture_t *Drain(filter_t *filter)
{
filter_sys_t *sys = filter->p_sys;
if (sys->last_pic == NULL) // second drain call
return NULL;
const picture_t *src = sys->last_pic;
vlc_vdp_video_field_t *f1 = VDPAU_FIELD_FROM_PICCTX(src->context);
#ifdef VOUT_CORE_GETS_A_CLUE
picture_t *dst = filter_NewPicture(filter);
#else
picture_t *dst = picture_NewFromFormat(&src->format);
#endif
if (dst == NULL)
return src; /* cannot deinterlace without copying fields */
goto error; /* cannot deinterlace without copying fields */
vlc_vdp_video_field_t *f2 = vlc_vdp_video_copy(f1); // shallow copy
if (unlikely(f2 == NULL))
{
picture_Release(dst);
return src;
dst = NULL;
goto error;
}
picture_CopyProperties(dst, src);
dst->context = &f2->context;
if (last_pts != VLC_TICK_INVALID)
dst->date = (3 * src->date - last_pts) / 2;
if (sys->prev_last_pts != VLC_TICK_INVALID)
dst->date = (3 * src->date - sys->prev_last_pts) / 2;
else
if (filter->fmt_in.video.i_frame_rate != 0)
dst->date = src->date + vlc_tick_from_samples(filter->fmt_in.video.i_frame_rate_base
,filter->fmt_in.video.i_frame_rate);
dst->b_top_field_first = !src->b_top_field_first;
dst->i_nb_fields = 1;
src->i_nb_fields = 1;
assert(!picture_HasChainedPics(src));
vlc_picture_chain_AppendChain( src, dst );
if (src->b_progressive || src->b_top_field_first)
{
f1->structure = VDP_VIDEO_MIXER_PICTURE_STRUCTURE_TOP_FIELD;
f2->structure = VDP_VIDEO_MIXER_PICTURE_STRUCTURE_BOTTOM_FIELD;
}
else
{
f1->structure = VDP_VIDEO_MIXER_PICTURE_STRUCTURE_BOTTOM_FIELD;
f2->structure = VDP_VIDEO_MIXER_PICTURE_STRUCTURE_TOP_FIELD;
}
src->b_progressive = true;
dst->b_progressive = true;
return src;
error :
picture_Release(sys->last_pic);
sys->last_pic = NULL;
return dst;
}
static void Flush(filter_t *filter)
{
filter_sys_t *sys = filter->p_sys;
if (sys->last_pic)
{
picture_Release(sys->last_pic);
sys->last_pic = NULL;
}
sys->last_pts = VLC_TICK_INVALID;
sys->prev_last_pts = VLC_TICK_INVALID;
}
static void Close(filter_t *filter)
{
Flush(filter);
vlc_video_context_Release(filter->vctx_out);
}
static const struct vlc_filter_operations filter_ops = {
.filter_video = Deinterlace, .close = Close,
.filter_video = Deinterlace, .drain_video = Drain, .close = Close,
.flush = Flush,
};
......@@ -132,6 +156,7 @@ static int Open(filter_t *filter)
* The other modes and IVTC should be checked. */
sys->last_pts = VLC_TICK_INVALID;
sys->prev_last_pts = VLC_TICK_INVALID;
filter->ops = &filter_ops;
filter->p_sys = sys;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment