bool is_direct = vout->p->decoder_pool == vout->p->display_pool;
picture_t *todisplay = filtered;
if (do_early_spu && subpic) {
- todisplay = picture_pool_Get(vout->p->private_pool);
- if (todisplay) {
- VideoFormatCopyCropAr(&todisplay->format, &filtered->format);
- picture_Copy(todisplay, filtered);
- if (vout->p->spu_blend)
- picture_BlendSubpicture(todisplay, vout->p->spu_blend, subpic);
+ picture_t *blent = picture_pool_Get(vout->p->private_pool);
+ if (blent) {
+ VideoFormatCopyCropAr(&blent->format, &filtered->format);
+ picture_Copy(blent, filtered);
+ if (vout->p->spu_blend
+ && picture_BlendSubpicture(blent, vout->p->spu_blend, subpic)) {
+ picture_Release(todisplay);
+ todisplay = blent;
+ } else
+ picture_Release(blent);
}
- picture_Release(filtered);
subpicture_Delete(subpic);
subpic = NULL;
-
- if (!todisplay)
- return VLC_EGENERIC;
}
- picture_t *direct;
- if (!is_direct && todisplay) {
- direct = picture_pool_Get(vout->p->display_pool);
- if (direct) {
- VideoFormatCopyCropAr(&direct->format, &todisplay->format);
- picture_Copy(direct, todisplay);
+ assert(vout_IsDisplayFiltered(vd) == !sys->display.use_dr);
+ if (sys->display.use_dr && !is_direct) {
+ picture_t *direct = picture_pool_Get(vout->p->display_pool);
+ if (!direct) {
+ picture_Release(todisplay);
+ if (subpic)
+ subpicture_Delete(subpic);
+ return VLC_EGENERIC;
}
- picture_Release(todisplay);
- } else {
- direct = todisplay;
- }
- if (!direct) {
- if (subpic)
- subpicture_Delete(subpic);
- return VLC_EGENERIC;
+ /* The display uses direct rendering (no conversion), but its pool of
+ * pictures is not usable by the decoder (too few, too slow or
+ * subject to invalidation...). Since there are no filters, copying
+ * pictures from the decoder to the output is unavoidable. */
+ VideoFormatCopyCropAr(&direct->format, &todisplay->format);
+ picture_Copy(direct, todisplay);
+ picture_Release(todisplay);
+ todisplay = direct;
}
/*
* Take a snapshot if requested
*/
if (do_snapshot)
- vout_snapshot_Set(&vout->p->snapshot, &vd->source, direct);
+ vout_snapshot_Set(&vout->p->snapshot, &vd->source, todisplay);
/* Render the direct buffer */
- assert(vout_IsDisplayFiltered(vd) == !sys->display.use_dr);
- vout_UpdateDisplaySourceProperties(vd, &direct->format);
+ vout_UpdateDisplaySourceProperties(vd, &todisplay->format);
if (sys->display.use_dr) {
- vout_display_Prepare(vd, direct, subpic);
+ vout_display_Prepare(vd, todisplay, subpic);
} else {
- sys->display.filtered = vout_FilterDisplay(vd, direct);
+ sys->display.filtered = vout_FilterDisplay(vd, todisplay);
if (sys->display.filtered) {
if (!do_dr_spu && !do_early_spu && vout->p->spu_blend && subpic)
picture_BlendSubpicture(sys->display.filtered, vout->p->spu_blend, subpic);
vout_display_Prepare(vd, sys->display.filtered, do_dr_spu ? subpic : NULL);
}
if (!do_dr_spu && subpic)
+ {
subpicture_Delete(subpic);
+ subpic = NULL;
+ }
if (!sys->display.filtered)
return VLC_EGENERIC;
}
msg_Warn(vout, "picture is late (%lld ms)", delay / 1000);
#endif
if (!is_forced)
- mwait(direct->date);
+ mwait(todisplay->date);
/* Display the direct buffer returned by vout_RenderPicture */
vout->p->displayed.date = mdate();
vout_display_Display(vd,
sys->display.filtered ? sys->display.filtered
- : direct,
+ : todisplay,
subpic);
sys->display.filtered = NULL;
return VLC_SUCCESS;
}
-static int ThreadDisplayPicture(vout_thread_t *vout,
- bool now, mtime_t *deadline)
+static int ThreadDisplayPicture(vout_thread_t *vout, mtime_t *deadline)
{
+ bool now = !deadline;
bool is_late_dropped = vout->p->is_late_dropped && !vout->p->pause.is_on && !now;
bool first = !vout->p->displayed.current;
if (first && ThreadDisplayPreparePicture(vout, true, is_late_dropped)) /* FIXME not sure it is ok */
refresh = date_refresh <= date;
if (!first && !refresh && !drop) {
- if (date_next != VLC_TS_INVALID && date_refresh != VLC_TS_INVALID)
- *deadline = __MIN(date_next, date_refresh);
- else if (date_next != VLC_TS_INVALID)
- *deadline = date_next;
- else if (date_refresh != VLC_TS_INVALID)
- *deadline = date_refresh;
+ if (!now) {
+ if (date_next != VLC_TS_INVALID && date_refresh != VLC_TS_INVALID)
+ *deadline = __MIN(date_next, date_refresh);
+ else if (date_next != VLC_TS_INVALID)
+ *deadline = date_next;
+ else if (date_refresh != VLC_TS_INVALID)
+ *deadline = date_refresh;
+ }
return VLC_EGENERIC;
}
vlc_mutex_lock(&vout->p->picture_lock);
*deadline = VLC_TS_INVALID;
- for (;;) {
- if (ThreadDisplayPicture(vout, false, deadline))
+ for (;;)
+ if (ThreadDisplayPicture(vout, deadline))
break;
- }
const bool picture_interlaced = vout->p->displayed.is_interlaced;
if (vout->p->step.last <= VLC_TS_INVALID)
vout->p->step.last = vout->p->displayed.timestamp;
- mtime_t dummy;
- if (ThreadDisplayPicture(vout, true, &dummy))
+ if (ThreadDisplayPicture(vout, NULL))
return;
vout->p->step.timestamp = vout->p->displayed.timestamp;