X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fvideo_output%2Fvideo_output.c;h=3876ccd0afd852de79e614de3098951f305ba4ef;hb=cb21f5e9cac205dd0219581a9591e8c1cbbc2b4c;hp=35e7a184c18b15d93c3a2b44dbe93ed32c692362;hpb=1e5b4699eb66d5f5367aaa9ce1a50e090674d844;p=vlc diff --git a/src/video_output/video_output.c b/src/video_output/video_output.c index 35e7a184c1..3876ccd0af 100644 --- a/src/video_output/video_output.c +++ b/src/video_output/video_output.c @@ -971,59 +971,63 @@ static int ThreadDisplayRenderPicture(vout_thread_t *vout, bool is_forced) 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; } @@ -1045,13 +1049,13 @@ static int ThreadDisplayRenderPicture(vout_thread_t *vout, bool is_forced) 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; @@ -1060,9 +1064,9 @@ static int ThreadDisplayRenderPicture(vout_thread_t *vout, bool is_forced) 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 */ @@ -1104,12 +1108,14 @@ static int ThreadDisplayPicture(vout_thread_t *vout, 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; } @@ -1132,10 +1138,9 @@ static void ThreadManage(vout_thread_t *vout, 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; @@ -1246,8 +1251,7 @@ static void ThreadStep(vout_thread_t *vout, mtime_t *duration) 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;