[vlc-devel] [PATCH 1/2] vout: add vout_Drain()
Rémi Denis-Courmont
remi at remlab.net
Wed Mar 15 15:44:20 CET 2017
On March 15, 2017 4:33:30 PM GMT+02:00, Thomas Guillem <thomas at gllm.fr> wrote:
>vout_Drain() asks the vout thread to drain its queued pictures. This
>function
>will wait for the last picture to be displayed.
>
>Refs #18105
>---
>src/video_output/control.c | 33 +++++++++++++++++++++++++++++++--
> src/video_output/control.h | 4 ++++
> src/video_output/video_output.c | 28 ++++++++++++++++++++++++++++
> src/video_output/vout_control.h | 5 +++++
> src/video_output/vout_internal.h | 1 +
> 5 files changed, 69 insertions(+), 2 deletions(-)
>
>diff --git a/src/video_output/control.c b/src/video_output/control.c
>index bbdb8948eb..078c510450 100644
>--- a/src/video_output/control.c
>+++ b/src/video_output/control.c
>@@ -64,6 +64,7 @@ void vout_control_Init(vout_control_t *ctrl)
> ctrl->is_dead = false;
> ctrl->can_sleep = true;
> ctrl->is_processing = false;
>+ ctrl->is_draining = false;
> ARRAY_INIT(ctrl->cmd);
> }
>
>@@ -98,15 +99,21 @@ void vout_control_WaitEmpty(vout_control_t *ctrl)
> vlc_mutex_unlock(&ctrl->lock);
> }
>
>-void vout_control_Push(vout_control_t *ctrl, vout_control_cmd_t *cmd)
>+static void vout_control_PushLocked(vout_control_t *ctrl,
>+ vout_control_cmd_t *cmd)
> {
>- vlc_mutex_lock(&ctrl->lock);
> if (!ctrl->is_dead) {
> ARRAY_APPEND(ctrl->cmd, *cmd);
> vlc_cond_signal(&ctrl->wait_request);
> } else {
> vout_control_cmd_Clean(cmd);
> }
>+}
>+
>+void vout_control_Push(vout_control_t *ctrl, vout_control_cmd_t *cmd)
>+{
>+ vlc_mutex_lock(&ctrl->lock);
>+ vout_control_PushLocked(ctrl, cmd);
> vlc_mutex_unlock(&ctrl->lock);
> }
>
>@@ -176,6 +183,28 @@ void vout_control_PushString(vout_control_t *ctrl,
>int type, const char *string)
> vout_control_Push(ctrl, &cmd);
> }
>
>+void vout_control_Drained(vout_control_t *ctrl)
>+{
>+ vlc_mutex_lock(&ctrl->lock);
>+ ctrl->is_draining = false;
>+ vlc_cond_broadcast(&ctrl->wait_acknowledge);
>+ vlc_mutex_unlock(&ctrl->lock);
>+}
>+
>+void vout_control_Drain(vout_control_t *ctrl)
>+{
>+ vout_control_cmd_t cmd;
>+
>+ vout_control_cmd_Init(&cmd, VOUT_CONTROL_DRAIN);
>+
>+ vlc_mutex_lock(&ctrl->lock);
>+ ctrl->is_draining = true;
>+ vout_control_PushLocked(ctrl, &cmd);
>+ while (ctrl->is_draining && !ctrl->is_dead)
>+ vlc_cond_wait(&ctrl->wait_acknowledge, &ctrl->lock);
>+ vlc_mutex_unlock(&ctrl->lock);
>+}
>+
> int vout_control_Pop(vout_control_t *ctrl, vout_control_cmd_t *cmd,
> mtime_t deadline)
> {
>diff --git a/src/video_output/control.h b/src/video_output/control.h
>index 14eec3468d..c41a444aa6 100644
>--- a/src/video_output/control.h
>+++ b/src/video_output/control.h
>@@ -48,6 +48,7 @@ enum {
>
> VOUT_CONTROL_PAUSE,
> VOUT_CONTROL_FLUSH, /* time */
>+ VOUT_CONTROL_DRAIN, /* void */
> VOUT_CONTROL_STEP, /* time_ptr */
>
> VOUT_CONTROL_FULLSCREEN, /* bool */
>@@ -115,6 +116,7 @@ typedef struct {
> bool is_dead;
> bool can_sleep;
> bool is_processing;
>+ bool is_draining;
> DECL_ARRAY(vout_control_cmd_t) cmd;
> } vout_control_t;
>
>@@ -124,6 +126,7 @@ void vout_control_Clean(vout_control_t *);
>
> /* controls outside of the vout thread */
> void vout_control_WaitEmpty(vout_control_t *);
>+void vout_control_Drain(vout_control_t *);
>
> void vout_control_Push(vout_control_t *, vout_control_cmd_t *);
> void vout_control_PushVoid(vout_control_t *, int type);
>@@ -138,5 +141,6 @@ void vout_control_Wake(vout_control_t *);
> /* control inside of the vout thread */
>int vout_control_Pop(vout_control_t *, vout_control_cmd_t *, mtime_t
>deadline);
> void vout_control_Dead(vout_control_t *);
>+void vout_control_Drained(vout_control_t *);
>
> #endif
>diff --git a/src/video_output/video_output.c
>b/src/video_output/video_output.c
>index 155d6a9e30..16e3704f7c 100644
>--- a/src/video_output/video_output.c
>+++ b/src/video_output/video_output.c
>@@ -332,6 +332,11 @@ void vout_Flush(vout_thread_t *vout, mtime_t date)
> vout_control_WaitEmpty(&vout->p->control);
> }
>
>+void vout_Drain(vout_thread_t *vout)
>+{
>+ vout_control_Drain(&vout->p->control);
>+}
>+
> bool vout_IsEmpty(vout_thread_t *vout)
> {
> picture_t *picture = picture_fifo_Peek(vout->p->decoder_fifo);
>@@ -1067,6 +1072,25 @@ static int ThreadDisplayPicture(vout_thread_t
>*vout, mtime_t *deadline)
> const mtime_t date = mdate();
>const mtime_t render_delay = vout_chrono_GetHigh(&vout->p->render) +
>VOUT_MWAIT_TOLERANCE;
>
>+ if (vout->p->draining && vout->p->displayed.next == NULL)
>+ {
>+ /* We reached the last picture to display */
>+ if (vout->p->displayed.date <= VLC_TS_INVALID
>+ || vout->p->displayed.date + render_delay <= date)
>+ {
>+ /* Notify the input (the caller of vout_Drain()) that the
>vout is
>+ * drained */
>+ vout_control_Drained(&vout->p->control);
>+ }
>+ else
>+ {
>+ /* Wait a little more before notifying the input, this
>function
>+ * will be called again after the deadline. */
>+ *deadline = vout->p->displayed.date + render_delay;
>+ }
>+ return VLC_EGENERIC;
>+ }
>+
> bool drop_next_frame = frame_by_frame;
> mtime_t date_next = VLC_TS_INVALID;
> if (!paused && vout->p->displayed.next) {
>@@ -1450,6 +1474,7 @@ static void ThreadInit(vout_thread_t *vout)
> vout->p->is_late_dropped = var_InheritBool(vout, "drop-late-frames");
> vout->p->pause.is_on = false;
> vout->p->pause.date = VLC_TS_INVALID;
>+ vout->p->draining = false;
>
>vout_chrono_Init(&vout->p->render, 5, 10000); /* Arbitrary initial time
>*/
> }
>@@ -1571,6 +1596,9 @@ static int ThreadControl(vout_thread_t *vout,
>vout_control_cmd_t cmd)
> case VOUT_CONTROL_FLUSH:
> ThreadFlush(vout, false, cmd.u.time);
> break;
>+ case VOUT_CONTROL_DRAIN:
>+ vout->p->draining = true;
>+ break;
> case VOUT_CONTROL_STEP:
> ThreadStep(vout, cmd.u.time_ptr);
> break;
>diff --git a/src/video_output/vout_control.h
>b/src/video_output/vout_control.h
>index 25bae8e9aa..e12b8eb169 100644
>--- a/src/video_output/vout_control.h
>+++ b/src/video_output/vout_control.h
>@@ -50,6 +50,11 @@ void vout_GetResetStatistic( vout_thread_t *p_vout,
>unsigned *pi_displayed,
> */
> void vout_Flush( vout_thread_t *p_vout, mtime_t i_date );
>
>+/**
>+ * This function will wait for all queued pictures to be displayed.
>+ */
>+void vout_Drain( vout_thread_t *p_vout );
>+
> /*
>* Cancel the vout, if cancel is true, it won't return any pictures
>after this
> * call.
>diff --git a/src/video_output/vout_internal.h
>b/src/video_output/vout_internal.h
>index fec54f38eb..b441786089 100644
>--- a/src/video_output/vout_internal.h
>+++ b/src/video_output/vout_internal.h
>@@ -74,6 +74,7 @@ struct vout_thread_sys_t
> /* Thread & synchronization */
> vlc_thread_t thread;
> bool dead;
>+ bool draining;
> vout_control_t control;
>
> /* */
>--
>2.11.0
>
>_______________________________________________
>vlc-devel mailing list
>To unsubscribe or modify your subscription options:
>https://mailman.videolan.org/listinfo/vlc-devel
Fine With me but I fear this sort of thing is not to the liking of the ES output buffering code.
--
Rémi Denis-Courmont
More information about the vlc-devel
mailing list