[vlc-devel] [PATCH 3/4] sout: lock sout_stream_t individually
Steve Lhomme
robux4 at ycbcr.xyz
Mon Oct 12 08:57:20 CEST 2020
This lock looks like in belongs in the duplicate module rather that do a
lock for all sout_stream_t users.
On 2020-10-11 16:30, RĂ©mi Denis-Courmont wrote:
> The stream output is called from multiple threads without
> synchronisation, notably at least one thread per ES decoder. Normally,
> the stream output instance (sout_instance_t) lock will serialise all
> calls to the first stream output module instance (sout_stream_t) in the
> stream output chain.
>
> This is not practical if there is also concurrency within the chain.
> One notable case is when the select/duplicate module is used in filter
> mode and one of the select/duplicate target is threaded, e.g.:
>
> #duplicate{dst=transcode{...},dst=transcode{...}}:std{...}
>
> In that example, the standard output can be called from both transcode
> filters.
>
> To solve this, add a lock for each element in the stream output chain.
> Alternatively, we could drop filter mode from select/duplicate, leaving
> only the (more common) output mode where duplicate is the last element
> in the chain.
> ---
> src/stream_output/stream_output.c | 44 +++++++++++++++++++++++++++----
> 1 file changed, 39 insertions(+), 5 deletions(-)
>
> diff --git a/src/stream_output/stream_output.c b/src/stream_output/stream_output.c
> index e0769dc749..069fe57346 100644
> --- a/src/stream_output/stream_output.c
> +++ b/src/stream_output/stream_output.c
> @@ -736,38 +736,71 @@ static void mrl_Clean( mrl_t *p_mrl )
>
> struct sout_stream_private {
> sout_stream_t stream;
> + vlc_mutex_t lock;
> module_t *module;
> };
>
> #define sout_stream_priv(s) \
> container_of(s, struct sout_stream_private, stream)
>
> +static void sout_StreamLock(sout_stream_t *s)
> +{
> + vlc_mutex_lock(&sout_stream_priv(s)->lock);
> +}
> +
> +static void sout_StreamUnlock(sout_stream_t *s)
> +{
> + vlc_mutex_unlock(&sout_stream_priv(s)->lock);
> +}
> +
> void *sout_StreamIdAdd(sout_stream_t *s, const es_format_t *fmt)
> {
> - return s->ops->add(s, fmt);
> + void *id;
> +
> + sout_StreamLock(s);
> + id = s->ops->add(s, fmt);
> + sout_StreamUnlock(s);
> + return id;
> }
>
> void sout_StreamIdDel(sout_stream_t *s, void *id)
> {
> + sout_StreamLock(s);
> s->ops->del(s, id);
> + sout_StreamUnlock(s);
> }
>
> int sout_StreamIdSend(sout_stream_t *s, void *id, block_t *b)
> {
> - return s->ops->send(s, id, b);
> + int val;
> +
> + sout_StreamLock(s);
> + val = s->ops->send(s, id, b);
> + sout_StreamUnlock(s);
> + return val;
> }
>
> void sout_StreamFlush(sout_stream_t *s, void *id)
> {
> if (s->ops->flush != NULL)
> + {
> + sout_StreamLock(s);
> s->ops->flush(s, id);
> + sout_StreamUnlock(s);
> + }
> }
>
> int sout_StreamControlVa(sout_stream_t *s, int i_query, va_list args)
> {
> - if (s->ops->control == NULL)
> - return VLC_EGENERIC;
> - return s->ops->control(s, i_query, args);
> + int val = VLC_EGENERIC;
> +
> + if (s->ops->control != NULL)
> + {
> + sout_StreamLock(s);
> + val = s->ops->control(s, i_query, args);
> + sout_StreamUnlock(s);
> + }
> + return val;
> }
>
> /* Destroy a "stream_out" module */
> @@ -823,6 +856,7 @@ static sout_stream_t *sout_StreamNew( vlc_object_t *parent, char *psz_name,
> if (unlikely(priv == NULL))
> return NULL;
>
> + vlc_mutex_init(&priv->lock);
> p_stream = &priv->stream;
> p_stream->psz_name = psz_name;
> p_stream->p_cfg = p_cfg;
> --
> 2.28.0
>
> _______________________________________________
> 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