+static int ThreadManage(vout_thread_t *vout,
+ mtime_t *deadline,
+ vout_interlacing_support_t *interlacing,
+ vout_postprocessing_support_t *postprocessing)
+{
+ vlc_mutex_lock(&vout->p->picture_lock);
+
+ *deadline = VLC_TS_INVALID;
+ bool has_displayed = !ThreadDisplayPicture(vout, vout->p->step.is_requested, deadline);
+
+ if (has_displayed) {
+ vout->p->step.timestamp = vout->p->displayed.timestamp;
+ if (vout->p->step.last <= VLC_TS_INVALID)
+ vout->p->step.last = vout->p->step.timestamp;
+ }
+ if (vout->p->step.is_requested) {
+ if (!has_displayed && !vout->p->b_picture_empty) {
+ picture_t *peek = picture_fifo_Peek(vout->p->decoder_fifo);
+ if (peek)
+ picture_Release(peek);
+ if (!peek) {
+ vout->p->b_picture_empty = true;
+ vlc_cond_signal(&vout->p->picture_wait);
+ }
+ }
+ if (has_displayed) {
+ vout->p->step.is_requested = false;
+ vlc_cond_signal(&vout->p->picture_wait);
+ }
+ }
+
+ const int picture_qtype = vout->p->displayed.qtype;
+ const bool picture_interlaced = vout->p->displayed.is_interlaced;
+
+ vlc_mutex_unlock(&vout->p->picture_lock);
+
+ /* Post processing */
+ vout_SetPostProcessingState(vout, postprocessing, picture_qtype);
+
+ /* Deinterlacing */
+ vout_SetInterlacingState(vout, interlacing, picture_interlaced);
+
+ if (vout_ManageWrapper(vout)) {
+ /* A fatal error occurred, and the thread must terminate
+ * immediately, without displaying anything - setting b_error to 1
+ * causes the immediate end of the main while() loop. */
+ // FIXME pf_end
+ return VLC_EGENERIC;
+ }
+ return VLC_SUCCESS;
+}
+
+static void ThreadDisplayOsdTitle(vout_thread_t *vout)
+{
+ if (!vout->p->title.show || !vout->p->title.value)
+ return;
+
+ vlc_assert_locked(&vout->p->change_lock);
+
+ const mtime_t start = mdate();
+ const mtime_t stop = start +
+ INT64_C(1000) * vout->p->title.timeout;
+
+ if (stop > start)
+ vout_ShowTextAbsolute(vout, DEFAULT_CHAN,
+ vout->p->title.value, NULL,
+ vout->p->title.position,
+ 30 + vout->fmt_in.i_width
+ - vout->fmt_in.i_visible_width
+ - vout->fmt_in.i_x_offset,
+ 20 + vout->fmt_in.i_y_offset,
+ start, stop);
+
+ free(vout->p->title.value);
+ vout->p->title.value = NULL;
+}
+
+static void ThreadChangeFilter(vout_thread_t *vout)
+{
+ /* Check for "video filter2" changes */
+ vlc_mutex_lock(&vout->p->vfilter_lock);
+ if (vout->p->psz_vf2) {
+ es_format_t fmt;
+
+ es_format_Init(&fmt, VIDEO_ES, vout->fmt_render.i_chroma);
+ fmt.video = vout->fmt_render;
+ filter_chain_Reset(vout->p->p_vf2_chain, &fmt, &fmt);
+
+ if (filter_chain_AppendFromString(vout->p->p_vf2_chain,
+ vout->p->psz_vf2) < 0)
+ msg_Err(vout, "Video filter chain creation failed");
+
+ free(vout->p->psz_vf2);
+ vout->p->psz_vf2 = NULL;
+ }
+ vlc_mutex_unlock(&vout->p->vfilter_lock);
+}
+