[vlc-devel] [PATCH 11/11] input: move vout start/stop handling in resource
Thomas Guillem
thomas at gllm.fr
Tue Jun 30 17:27:22 CEST 2020
The start state is now know by the input resource and protected with its lock.
Move vout_StopDisplay() and vout_ChangeSource() to input/resource.c since the
execution of these functions depend on the start state.
---
src/input/decoder.c | 51 +++++++++++++++++---------------------------
src/input/resource.c | 41 ++++++++++++++++++++++++++++++-----
src/input/resource.h | 5 +++--
3 files changed, 59 insertions(+), 38 deletions(-)
diff --git a/src/input/decoder.c b/src/input/decoder.c
index ed7cb6803b8..ec3711cc685 100644
--- a/src/input/decoder.c
+++ b/src/input/decoder.c
@@ -128,7 +128,6 @@ struct vlc_input_decoder_t
vout_thread_t *p_vout;
enum vlc_vout_order vout_order;
- bool vout_thread_started;
/* -- Theses variables need locking on read *and* write -- */
/* Preroll */
@@ -463,26 +462,21 @@ static int ModuleThread_UpdateVideoFormat( decoder_t *p_dec, vlc_video_context *
return -1;
}
}
- if (p_owner->vout_thread_started)
- {
- int res = vout_ChangeSource(p_owner->p_vout, &p_dec->fmt_out.video);
- if (res == 0)
- // the display/thread is started and can handle the new source format
- return 0;
- }
vout_configuration_t cfg = {
.vout = p_owner->p_vout, .clock = p_owner->p_clock, .fmt = &p_dec->fmt_out.video,
.mouse_event = MouseEvent, .mouse_opaque = p_dec,
};
+ bool started;
vout_thread_t *p_vout =
- input_resource_RequestVout(p_owner->p_resource, vctx, &cfg, NULL);
+ input_resource_RequestVout(p_owner->p_resource, vctx, &cfg, NULL, &started);
if (p_vout != NULL)
{
- p_owner->vout_thread_started = true;
- decoder_Notify(p_owner, on_vout_started, p_vout, p_owner->vout_order);
+ if (started)
+ decoder_Notify(p_owner, on_vout_started, p_vout, p_owner->vout_order);
return 0;
}
+
return -1;
}
@@ -543,7 +537,7 @@ static int CreateVoutIfNeeded(vlc_input_decoder_t *p_owner)
enum vlc_vout_order order;
const vout_configuration_t cfg = { .vout = p_vout, .fmt = NULL };
- p_vout = input_resource_RequestVout( p_owner->p_resource, NULL, &cfg, &order );
+ p_vout = input_resource_RequestVout( p_owner->p_resource, NULL, &cfg, &order, NULL );
vlc_mutex_lock( &p_owner->lock );
p_owner->p_vout = p_vout;
@@ -663,7 +657,6 @@ static subpicture_t *ModuleThread_NewSpuBuffer( decoder_t *p_dec,
vout_Release(p_owner->p_vout);
p_owner->p_vout = NULL; // the DecoderThread should not use the old vout anymore
- p_owner->vout_thread_started = false;
vlc_mutex_unlock( &p_owner->lock );
}
return NULL;
@@ -684,7 +677,6 @@ static subpicture_t *ModuleThread_NewSpuBuffer( decoder_t *p_dec,
p_owner->i_spu_channel);
vout_Release(p_owner->p_vout);
p_owner->p_vout = NULL; // the DecoderThread should not use the old vout anymore
- p_owner->vout_thread_started = false;
}
enum vlc_vout_order channel_order;
@@ -702,7 +694,6 @@ static subpicture_t *ModuleThread_NewSpuBuffer( decoder_t *p_dec,
}
p_owner->p_vout = p_vout;
- p_owner->vout_thread_started = true;
p_owner->vout_order = channel_order;
vlc_mutex_unlock(&p_owner->lock);
@@ -1021,7 +1012,7 @@ static void ModuleThread_QueueCc( decoder_t *p_videodec, block_t *p_cc,
static int ModuleThread_PlayVideo( vlc_input_decoder_t *p_owner, picture_t *p_picture )
{
decoder_t *p_dec = &p_owner->dec;
- vout_thread_t *p_vout = p_owner->vout_thread_started ? p_owner->p_vout : NULL;
+ vout_thread_t *p_vout = p_owner->p_vout;
if( p_picture->date == VLC_TICK_INVALID )
/* FIXME: VLC_TICK_INVALID -- verify video_output */
@@ -1482,12 +1473,12 @@ static void DecoderThread_Flush( vlc_input_decoder_t *p_owner )
}
else if( p_dec->fmt_out.i_cat == VIDEO_ES )
{
- if( p_owner->p_vout && p_owner->vout_thread_started )
+ if( p_owner->p_vout )
vout_FlushAll( p_owner->p_vout );
}
else if( p_dec->fmt_out.i_cat == SPU_ES )
{
- if( p_owner->p_vout && p_owner->vout_thread_started )
+ if( p_owner->p_vout )
{
assert( p_owner->i_spu_channel != VOUT_SPU_CHANNEL_INVALID );
vout_FlushSubpictureChannel( p_owner->p_vout, p_owner->i_spu_channel );
@@ -1796,7 +1787,6 @@ CreateDecoder( vlc_object_t *p_parent,
p_owner->cbs_userdata = cbs_userdata;
p_owner->p_aout = NULL;
p_owner->p_vout = NULL;
- p_owner->vout_thread_started = false;
p_owner->i_spu_channel = VOUT_SPU_CHANNEL_INVALID;
p_owner->i_spu_order = 0;
p_owner->p_sout = p_sout;
@@ -1973,15 +1963,16 @@ static void DeleteDecoder( vlc_input_decoder_t *p_owner )
if (vout != NULL)
{
- if( p_owner->vout_thread_started)
- {
- /* Reset the cancel state that was set before joining the
- * decoder thread */
- vout_StopDisplay(vout);
- p_owner->vout_thread_started = false;
+ /* Hold the vout since PutVout will likely release it and a
+ * last reference is needed for notify callbacks */
+ vout_Hold(vout);
+
+ bool stopped;
+ input_resource_PutVout(p_owner->p_resource, vout, &stopped);
+ if (stopped)
decoder_Notify(p_owner, on_vout_stopped, vout);
- }
- input_resource_PutVout(p_owner->p_resource, vout);
+
+ vout_Release(vout);
}
break;
}
@@ -1995,7 +1986,6 @@ static void DeleteDecoder( vlc_input_decoder_t *p_owner )
vout_UnregisterSubpictureChannel( p_owner->p_vout,
p_owner->i_spu_channel );
vout_Release(p_owner->p_vout);
- p_owner->vout_thread_started = false;
}
break;
}
@@ -2157,7 +2147,7 @@ void vlc_input_decoder_Delete( vlc_input_decoder_t *p_owner )
*
* This unblocks the thread, allowing the decoder module to join all its
* worker threads (if any) and the decoder thread to terminate. */
- if( p_dec->fmt_in.i_cat == VIDEO_ES && p_owner->p_vout != NULL && p_owner->vout_thread_started )
+ if( p_dec->fmt_in.i_cat == VIDEO_ES && p_owner->p_vout != NULL )
{
if (p_owner->out_pool)
picture_pool_Cancel( p_owner->out_pool, true );
@@ -2303,8 +2293,7 @@ void vlc_input_decoder_Flush( vlc_input_decoder_t *p_owner )
* after being unstuck. */
vlc_mutex_lock( &p_owner->lock );
- if( p_owner->dec.fmt_out.i_cat == VIDEO_ES
- && p_owner->p_vout && p_owner->vout_thread_started )
+ if( p_owner->dec.fmt_out.i_cat == VIDEO_ES && p_owner->p_vout )
vout_FlushAll( p_owner->p_vout );
vlc_mutex_unlock( &p_owner->lock );
}
diff --git a/src/input/resource.c b/src/input/resource.c
index b82d04a2897..04d554c1d48 100644
--- a/src/input/resource.c
+++ b/src/input/resource.c
@@ -48,6 +48,7 @@ struct vout_resource
{
vout_thread_t *vout;
enum vlc_vout_order order;
+ bool started;
struct vlc_list node;
};
@@ -105,6 +106,7 @@ vout_resource_Create(vout_thread_t *vout)
if (unlikely(vout_rsc == NULL))
return NULL;
+ vout_rsc->started = false;
vout_rsc->vout = vout;
return vout_rsc;
}
@@ -376,12 +378,21 @@ void input_resource_SetInput( input_resource_t *p_resource, input_thread_t *p_in
}
static void input_resource_PutVoutLocked(input_resource_t *p_resource,
- vout_thread_t *vout)
+ vout_thread_t *vout, bool *stopped)
{
assert(vout != NULL);
struct vout_resource *vout_rsc = resource_GetVoutRsc(p_resource, vout);
assert(vout_rsc != NULL);
+ if (stopped != NULL)
+ *stopped = vout_rsc->started;
+
+ if (vout_rsc->started)
+ {
+ vout_StopDisplay(vout_rsc->vout);
+ vout_rsc->started = false;
+ }
+
if (vout_rsc == resource_GetFirstVoutRsc(p_resource))
{
assert(p_resource->vout_rsc_free == NULL || p_resource->vout_rsc_free == vout_rsc);
@@ -403,10 +414,10 @@ static void input_resource_PutVoutLocked(input_resource_t *p_resource,
}
void input_resource_PutVout(input_resource_t *p_resource,
- vout_thread_t *vout)
+ vout_thread_t *vout, bool *stopped)
{
vlc_mutex_lock( &p_resource->lock );
- input_resource_PutVoutLocked( p_resource, vout );
+ input_resource_PutVoutLocked( p_resource, vout, stopped );
vlc_mutex_unlock( &p_resource->lock );
}
@@ -455,11 +466,15 @@ RequestVoutRsc(input_resource_t *p_resource)
vout_thread_t *input_resource_RequestVout(input_resource_t *p_resource,
vlc_video_context *vctx,
const vout_configuration_t *cfg,
- enum vlc_vout_order *order)
+ enum vlc_vout_order *order,
+ bool *started)
{
vlc_mutex_lock( &p_resource->lock );
struct vout_resource *vout_rsc = NULL;
+ if (started != NULL)
+ *started = false;
+
vout_configuration_t dcfg = *cfg;
if (dcfg.vout == NULL)
{
@@ -490,8 +505,19 @@ vout_thread_t *input_resource_RequestVout(input_resource_t *p_resource,
return dcfg.vout;
}
+ if (vout_rsc->started)
+ {
+ assert(cfg->vout != NULL);
+ int ret = vout_ChangeSource(dcfg.vout, dcfg.fmt);
+ if (ret == 0)
+ {
+ vlc_mutex_unlock(&p_resource->lock);
+ return dcfg.vout;
+ }
+ }
+
if (vout_Request(&dcfg, vctx, p_resource->p_input)) {
- input_resource_PutVoutLocked(p_resource, dcfg.vout);
+ input_resource_PutVoutLocked(p_resource, dcfg.vout, NULL);
vlc_mutex_unlock(&p_resource->lock);
return NULL;
}
@@ -505,7 +531,12 @@ vout_thread_t *input_resource_RequestVout(input_resource_t *p_resource,
input_ControlPush(p_resource->p_input, INPUT_CONTROL_SET_INITIAL_VIEWPOINT,
¶m);
}
+ vout_rsc->started = true;
vlc_mutex_unlock( &p_resource->lock );
+
+ if (started != NULL)
+ *started = true;
+
return dcfg.vout;
}
diff --git a/src/input/resource.h b/src/input/resource.h
index 7a725aabcf6..219049ee9b8 100644
--- a/src/input/resource.h
+++ b/src/input/resource.h
@@ -39,8 +39,9 @@ sout_instance_t *input_resource_RequestSout( input_resource_t *, sout_instance_t
vout_thread_t *input_resource_RequestVout(input_resource_t *, vlc_video_context *,
const vout_configuration_t *,
- enum vlc_vout_order *order);
-void input_resource_PutVout(input_resource_t *, vout_thread_t *);
+ enum vlc_vout_order *order,
+ bool *started);
+void input_resource_PutVout(input_resource_t *, vout_thread_t *, bool *stopped);
/**
* This function returns one of the current vout if any.
--
2.20.1
More information about the vlc-devel
mailing list