+ if (vout->p->spu_blend &&
+ vout->p->spu_blend->fmt_out.video.i_chroma != fmt_spu.i_chroma) {
+ filter_DeleteBlend(vout->p->spu_blend);
+ vout->p->spu_blend = NULL;
+ vout->p->spu_blend_chroma = 0;
+ }
+ if (!vout->p->spu_blend && vout->p->spu_blend_chroma != fmt_spu.i_chroma) {
+ vout->p->spu_blend_chroma = fmt_spu.i_chroma;
+ vout->p->spu_blend = filter_NewBlend(VLC_OBJECT(vout), &fmt_spu);
+ if (!vout->p->spu_blend)
+ msg_Err(vout, "Failed to create blending filter, OSD/Subtitles will not work");
+ }
+ }
+
+ subpicture_t *subpic = spu_Render(vout->p->spu,
+ subpicture_chromas, &fmt_spu,
+ &vd->source,
+ render_subtitle_date, render_osd_date,
+ do_snapshot);
+ /*
+ * Perform rendering
+ *
+ * We have to:
+ * - be sure to end up with a direct buffer.
+ * - blend subtitles, and in a fast access buffer
+ */
+ bool is_direct = vout->p->decoder_pool == vout->p->display_pool;
+ picture_t *todisplay = filtered;
+ if (do_early_spu && 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);
+ }
+ subpicture_Delete(subpic);
+ subpic = NULL;
+ }
+
+ 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;
+ }
+
+ /* 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, todisplay);
+
+ /* Render the direct buffer */
+ vout_UpdateDisplaySourceProperties(vd, &todisplay->format);
+ if (sys->display.use_dr) {
+ vout_display_Prepare(vd, todisplay, subpic);
+ } else {
+ 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;
+ }