[vlc-devel] [PATCH] decoder: pass es_out_id_t to decoder callbacks
Thomas Guillem
thomas at gllm.fr
Mon Jul 1 15:03:10 CEST 2019
LGTM
On Sun, Jun 30, 2019, at 21:58, Romain Vimont wrote:
> We need both es_out_t (or es_out_sys_t) and vlc_es_id_t (or es_out_id_t)
> from decoder callbacks.
>
> Commit a2bc9e15516093162da31c09546880b7aaaa6f0b only passed
> es_out_sys_t, and retrieved the matching ES by comparing its decoder
> instance. However, this was racy, because the list of ES may change from
> any thread. Locking the es_out_sys_t mutex would cause other problems
> (deadlock).
>
> Instead, reference the es_out_t from es_out_id_t, and use the
> es_out_id_t instance as userdata passed to decoder callbacks.
> ---
> src/input/es_out.c | 93 +++++++++++++++++++++++++---------------------
> 1 file changed, 51 insertions(+), 42 deletions(-)
>
> diff --git a/src/input/es_out.c b/src/input/es_out.c
> index ffcac69623..2eda8a158c 100644
> --- a/src/input/es_out.c
> +++ b/src/input/es_out.c
> @@ -95,6 +95,8 @@ struct es_out_id_t
> {
> vlc_es_id_t id;
>
> + es_out_t *out;
> +
> /* ES ID */
> es_out_pgrm_t *p_pgrm;
>
> @@ -263,73 +265,69 @@ static inline int EsOutGetClosedCaptionsChannel(
> const es_format_t *p_fmt )
> for( int fetes_i=0; fetes_i<2; fetes_i++ ) \
> vlc_list_foreach( pos, (!fetes_i ? &p_sys->es :
> &p_sys->es_slaves), node )
>
> -static vlc_es_id_t *
> -FindEsIdFromDecoder(es_out_sys_t *p_sys, decoder_t *decoder)
> -{
> - es_out_id_t *es;
> - foreach_es_then_es_slaves(es)
> - if (es->p_dec == decoder)
> - return &es->id;
> - return NULL;
> -}
> -
> static void
> decoder_on_vout_added(decoder_t *decoder, vout_thread_t *vout,
> enum vlc_vout_order order, void *userdata)
> {
> - es_out_sys_t *priv = userdata;
> - if (!priv->p_input)
> - return;
> + (void) decoder;
> +
> + es_out_id_t *id = userdata;
> + es_out_t *out = id->out;
> + es_out_sys_t *p_sys = container_of(out, es_out_sys_t, out);
>
> - vlc_es_id_t *id = FindEsIdFromDecoder(priv, decoder);
> - assert(id);
> + if (!p_sys->p_input)
> + return;
>
> struct vlc_input_event_vout event = {
> .action = VLC_INPUT_EVENT_VOUT_ADDED,
> .vout = vout,
> .order = order,
> - .id = id,
> + .id = &id->id,
> };
>
> - input_SendEventVout(priv->p_input, &event);
> + input_SendEventVout(p_sys->p_input, &event);
> }
>
> static void
> decoder_on_vout_deleted(decoder_t *decoder, vout_thread_t *vout, void
> *userdata)
> {
> - es_out_sys_t *priv = userdata;
> - if (!priv->p_input)
> - return;
> + (void) decoder;
>
> - vlc_es_id_t *id = FindEsIdFromDecoder(priv, decoder);
> - assert(id);
> + es_out_id_t *id = userdata;
> + es_out_t *out = id->out;
> + es_out_sys_t *p_sys = container_of(out, es_out_sys_t, out);
> +
> + if (!p_sys->p_input)
> + return;
>
> struct vlc_input_event_vout event = {
> .action = VLC_INPUT_EVENT_VOUT_DELETED,
> .vout = vout,
> .order = VLC_VOUT_ORDER_NONE,
> - .id = id,
> + .id = &id->id,
> };
>
> - input_SendEventVout(priv->p_input, &event);
> + input_SendEventVout(p_sys->p_input, &event);
> }
>
> static void
> decoder_on_thumbnail_ready(decoder_t *decoder, picture_t *pic, void *userdata)
> {
> - es_out_sys_t *priv = userdata;
> - if (!priv->p_input)
> - return;
> + (void) decoder;
>
> - vlc_es_id_t *id = FindEsIdFromDecoder(priv, decoder);
> - assert(id);
> + es_out_id_t *id = userdata;
> + es_out_t *out = id->out;
> + es_out_sys_t *p_sys = container_of(out, es_out_sys_t, out);
> +
> + if (!p_sys->p_input)
> + return;
>
> struct vlc_input_event event = {
> .type = INPUT_EVENT_THUMBNAIL_READY,
> .thumbnail = pic,
> };
>
> - input_SendEvent(priv->p_input, &event);
> + input_SendEvent(p_sys->p_input, &event);
> }
>
> static void
> @@ -338,11 +336,14 @@ decoder_on_new_video_stats(decoder_t *decoder,
> unsigned decoded, unsigned lost,
> {
> (void) decoder;
>
> - es_out_sys_t *priv = userdata;
> - if (!priv->p_input)
> + es_out_id_t *id = userdata;
> + es_out_t *out = id->out;
> + es_out_sys_t *p_sys = container_of(out, es_out_sys_t, out);
> +
> + if (!p_sys->p_input)
> return;
>
> - struct input_stats *stats = input_priv(priv->p_input)->stats;
> + struct input_stats *stats = input_priv(p_sys->p_input)->stats;
> if (!stats)
> return;
>
> @@ -360,11 +361,14 @@ decoder_on_new_audio_stats(decoder_t *decoder,
> unsigned decoded, unsigned lost,
> {
> (void) decoder;
>
> - es_out_sys_t *priv = userdata;
> - if (!priv->p_input)
> + es_out_id_t *id = userdata;
> + es_out_t *out = id->out;
> + es_out_sys_t *p_sys = container_of(out, es_out_sys_t, out);
> +
> + if (!p_sys->p_input)
> return;
>
> - struct input_stats *stats = input_priv(priv->p_input)->stats;
> + struct input_stats *stats = input_priv(p_sys->p_input)->stats;
> if (!stats)
> return;
>
> @@ -383,11 +387,14 @@ decoder_get_attachments(decoder_t *decoder,
> {
> (void) decoder;
>
> - es_out_sys_t *priv = userdata;
> - if (!priv->p_input)
> + es_out_id_t *id = userdata;
> + es_out_t *out = id->out;
> + es_out_sys_t *p_sys = container_of(out, es_out_sys_t, out);
> +
> + if (!p_sys->p_input)
> return -1;
>
> - return input_GetAttachments(priv->p_input, ppp_attachment);
> + return input_GetAttachments(p_sys->p_input, ppp_attachment);
> }
>
> static const struct input_decoder_callbacks decoder_cbs = {
> @@ -798,7 +805,7 @@ static int EsOutSetRecord( es_out_t *out, bool b_record )
> input_DecoderNew( VLC_OBJECT(p_input), &p_es->fmt, NULL,
> input_priv(p_input)->p_resource,
> p_sys->p_sout_record, false,
> - &decoder_cbs, p_sys );
> + &decoder_cbs, p_es );
>
> if( p_es->p_dec_record && p_sys->b_buffering )
> input_DecoderStartWait( p_es->p_dec_record );
> @@ -1869,6 +1876,8 @@ static es_out_id_t *EsOutAddSlaveLocked( es_out_t
> *out, const es_format_t *fmt,
> if( !es )
> return NULL;
>
> + es->out = out;
> +
> if( es_format_Copy( &es->fmt, fmt ) != VLC_SUCCESS )
> {
> free( es );
> @@ -2008,7 +2017,7 @@ static void EsOutCreateDecoder( es_out_t *out,
> es_out_id_t *p_es )
> input_thread_private_t *priv = input_priv(p_input);
> dec = input_DecoderNew( VLC_OBJECT(p_input), &p_es->fmt,
> p_es->p_clock,
> priv->p_resource, priv->p_sout,
> - priv->b_thumbnailing, &decoder_cbs, p_sys
> );
> + priv->b_thumbnailing, &decoder_cbs, p_es );
> if( dec != NULL )
> {
> input_DecoderChangeRate( dec, p_sys->rate );
> @@ -2021,7 +2030,7 @@ static void EsOutCreateDecoder( es_out_t *out,
> es_out_id_t *p_es )
> p_es->p_dec_record =
> input_DecoderNew( VLC_OBJECT(p_input), &p_es->fmt,
> NULL,
> priv->p_resource,
> p_sys->p_sout_record, false,
> - &decoder_cbs, p_sys );
> + &decoder_cbs, p_es );
> if( p_es->p_dec_record && p_sys->b_buffering )
> input_DecoderStartWait( p_es->p_dec_record );
> }
> --
> 2.20.1
>
> _______________________________________________
> vlc-devel mailing list
> To unsubscribe or modify your subscription options:
> https://mailman.videolan.org/listinfo/vlc-devel
More information about the vlc-devel
mailing list