[vlc-devel] [RFC PATCHv2 05/18] es_out: fix group_id and i_id collision

Rémi Denis-Courmont remi at remlab.net
Tue Feb 18 18:16:17 CET 2020


Hi,

Identification with a tuple of a (reference-counted) pointer and an ID seems like the worse of both worlds. It's not serial, but it's not a single value and its uniqueness depends on the demuxer.

Why can't we identify an ES by its ID pointer, which already exists (though it might be missing a reference count)??

Le 18 février 2020 18:11:18 GMT+02:00, Thomas Guillem <thomas at gllm.fr> a écrit :
>A specified program (group > 0) is identified by its group id and by
>its
>context pointer. The default program (group = 0) can be used by more
>than one
>contexts.
>
>An ES track is now identified by its i_id and by its context pointer.
>In case
>of automatic track ids, the id counter will be handled by each contexts
>(or
>input source). This mean that the id counter starts at 0 for each new
>source.
>
>A slave specifying its group won't be able to be played alongside the
>master
>source by default (except if we play more than one programs at a time).
>---
> src/input/es_out.c | 106 ++++++++++++++++++++++++++++++++-------------
> 1 file changed, 75 insertions(+), 31 deletions(-)
>
>diff --git a/src/input/es_out.c b/src/input/es_out.c
>index 1c98d85add4..4ae27b63734 100644
>--- a/src/input/es_out.c
>+++ b/src/input/es_out.c
>@@ -61,6 +61,9 @@
>*****************************************************************************/
> typedef struct
> {
>+    /* Program context */
>+    es_out_ctx_t *ctx;
>+
>     /* Program ID */
>     int i_id;
> 
>@@ -98,6 +101,10 @@ struct es_out_id_t
>/* weak reference, used by input_decoder_callbacks and vlc_clock_cbs */
>     es_out_t *out;
> 
>+    /* Context used to create this ES. Equals to p_pgrm->ctx when not
>using a
>+     * default program id. */
>+    es_out_ctx_t *ctx;
>+
>     /* ES ID */
>     es_out_pgrm_t *p_pgrm;
> 
>@@ -165,6 +172,9 @@ typedef struct
> {
>     input_thread_t *p_input;
> 
>+    /* Main source context */
>+    es_out_ctx_t *main_ctx;
>+
>     /* */
>     vlc_mutex_t   lock;
> 
>@@ -481,6 +491,13 @@ es_out_t *input_EsOutNew( input_thread_t *p_input,
>float rate )
> 
>     p_sys->out.cbs = &es_out_cbs;
> 
>+    p_sys->main_ctx = es_out_ctx_New(NULL);
>+    if( !p_sys->main_ctx )
>+    {
>+        free( p_sys );
>+        return NULL;
>+    }
>+
>     vlc_mutex_init( &p_sys->lock );
>     p_sys->p_input = p_input;
> 
>@@ -578,6 +595,7 @@ static void EsRelease(es_out_id_t *es)
>         free(es->psz_language);
>         free(es->psz_language_code);
>         es_format_Clean(&es->fmt);
>+        es_out_ctx_Release(es->ctx);
>         free(es);
>     }
> }
>@@ -600,6 +618,8 @@ static void EsOutDelete( es_out_t *out )
> 
>     vlc_mutex_destroy( &p_sys->lock );
> 
>+    es_out_ctx_Release( p_sys->main_ctx );
>+
>     free( p_sys );
> }
> 
>@@ -609,6 +629,7 @@ static void ProgramDelete( es_out_pgrm_t *p_pgrm )
>     vlc_clock_main_Delete( p_pgrm->p_main_clock );
>     if( p_pgrm->p_meta )
>         vlc_meta_Delete( p_pgrm->p_meta );
>+    es_out_ctx_Release( p_pgrm->ctx );
> 
>     free( p_pgrm );
> }
>@@ -1245,10 +1266,11 @@ static void EsOutSendEsEvent(es_out_t *out,
>es_out_id_t *es, int action)
>     });
> }
> 
>-static bool EsOutIsProgramVisible( es_out_t *out, int i_group )
>+static bool EsOutIsProgramVisible( es_out_t *out, es_out_ctx_t *ctx,
>int i_group )
> {
>     es_out_sys_t *p_sys = container_of(out, es_out_sys_t, out);
>-    return p_sys->i_group_id == 0 || p_sys->i_group_id == i_group;
>+    return p_sys->i_group_id == 0
>+        || (p_sys->i_group_id == i_group && p_sys->p_pgrm->ctx ==
>ctx);
> }
> 
> /* EsOutProgramSelect:
>@@ -1333,7 +1355,7 @@ static void EsOutProgramSelect( es_out_t *out,
>es_out_pgrm_t *p_pgrm )
> /* EsOutAddProgram:
>  *  Add a program
>  */
>-static es_out_pgrm_t *EsOutProgramAdd( es_out_t *out, int i_group )
>+static es_out_pgrm_t *EsOutProgramAdd( es_out_t *out, es_out_ctx_t
>*ctx, int i_group )
> {
>     es_out_sys_t *p_sys = container_of(out, es_out_sys_t, out);
>     input_thread_t    *p_input = p_sys->p_input;
>@@ -1343,6 +1365,7 @@ static es_out_pgrm_t *EsOutProgramAdd( es_out_t
>*out, int i_group )
>         return NULL;
> 
>     /* Init */
>+    p_pgrm->ctx = es_out_ctx_Hold( ctx );
>     p_pgrm->i_id = i_group;
>     p_pgrm->i_es = 0;
>     p_pgrm->b_selected = false;
>@@ -1376,7 +1399,7 @@ static es_out_pgrm_t *EsOutProgramAdd( es_out_t
>*out, int i_group )
>     vlc_list_append(&p_pgrm->node, &p_sys->programs);
> 
>     /* Update "program" variable */
>-    if( EsOutIsProgramVisible( out, i_group ) )
>+    if( EsOutIsProgramVisible( out, ctx, i_group ) )
>         input_SendEventProgramAdd( p_input, i_group, NULL );
> 
>if( i_group == p_sys->i_group_id || ( !p_sys->p_pgrm &&
>p_sys->i_group_id == 0 ) )
>@@ -1387,34 +1410,37 @@ static es_out_pgrm_t *EsOutProgramAdd( es_out_t
>*out, int i_group )
> 
> /* EsOutProgramSearch
>  */
>-static es_out_pgrm_t *EsOutProgramSearch( es_out_t *p_out, int i_group
>)
>+static es_out_pgrm_t *EsOutProgramSearch( es_out_t *p_out,
>es_out_ctx_t *ctx,
>+                                          int i_group )
> {
>     es_out_sys_t *p_sys = container_of(p_out, es_out_sys_t, out);
>     es_out_pgrm_t *pgrm;
> 
>     vlc_list_foreach(pgrm, &p_sys->programs, node)
>-        if (pgrm->i_id == i_group)
>+        if (pgrm->i_id == i_group && (pgrm->ctx == ctx || i_group ==
>0))
>             return pgrm;
>+
>     return NULL;
> }
> 
> /* EsOutProgramInsert
>  */
>-static es_out_pgrm_t *EsOutProgramInsert( es_out_t *p_out, int i_group
>)
>+static es_out_pgrm_t *EsOutProgramInsert( es_out_t *p_out,
>es_out_ctx_t *ctx,
>+                                          int i_group )
> {
>-    es_out_pgrm_t *pgrm = EsOutProgramSearch( p_out, i_group );
>-    return pgrm ? pgrm : EsOutProgramAdd( p_out, i_group );
>+    es_out_pgrm_t *pgrm = EsOutProgramSearch( p_out, ctx, i_group );
>+    return pgrm ? pgrm : EsOutProgramAdd( p_out, ctx, i_group );
> }
> 
> /* EsOutDelProgram:
>  *  Delete a program
>  */
>-static int EsOutProgramDel( es_out_t *out, int i_group )
>+static int EsOutProgramDel( es_out_t *out, es_out_ctx_t *ctx, int
>i_group )
> {
>     es_out_sys_t *p_sys = container_of(out, es_out_sys_t, out);
>     input_thread_t    *p_input = p_sys->p_input;
> 
>-    es_out_pgrm_t *p_pgrm = EsOutProgramSearch( out, i_group );
>+    es_out_pgrm_t *p_pgrm = EsOutProgramSearch( out, ctx, i_group );
>     if( p_pgrm == NULL )
>         return VLC_EGENERIC;
> 
>@@ -1483,7 +1509,8 @@ static char *EsInfoCategoryName( es_out_id_t* es
>)
>     return psz_category;
> }
> 
>-static void EsOutProgramMeta( es_out_t *out, int i_group, const
>vlc_meta_t *p_meta )
>+static void EsOutProgramMeta( es_out_t *out, es_out_ctx_t *ctx,
>+                              int i_group, const vlc_meta_t *p_meta )
> {
>     es_out_sys_t *p_sys = container_of(out, es_out_sys_t, out);
>     es_out_pgrm_t     *p_pgrm;
>@@ -1511,9 +1538,9 @@ static void EsOutProgramMeta( es_out_t *out, int
>i_group, const vlc_meta_t *p_me
>     }
> 
>     /* Find program */
>-    if( !EsOutIsProgramVisible( out, i_group ) )
>+    if( !EsOutIsProgramVisible( out, ctx, i_group ) )
>         return;
>-    p_pgrm = EsOutProgramInsert( out, i_group );
>+    p_pgrm = EsOutProgramInsert( out, ctx, i_group );
>     if( !p_pgrm )
>         return;
> 
>@@ -1612,7 +1639,8 @@ static void EsOutProgramMeta( es_out_t *out, int
>i_group, const vlc_meta_t *p_me
>         input_SendEventMetaInfo( p_input );
> }
> 
>-static void EsOutProgramEpgEvent( es_out_t *out, int i_group, const
>vlc_epg_event_t *p_event )
>+static void EsOutProgramEpgEvent( es_out_t *out, es_out_ctx_t *ctx,
>+                                  int i_group, const vlc_epg_event_t
>*p_event )
> {
>     es_out_sys_t *p_sys = container_of(out, es_out_sys_t, out);
>     input_thread_t    *p_input = p_sys->p_input;
>@@ -1620,16 +1648,17 @@ static void EsOutProgramEpgEvent( es_out_t
>*out, int i_group, const vlc_epg_even
>     es_out_pgrm_t     *p_pgrm;
> 
>     /* Find program */
>-    if( !EsOutIsProgramVisible( out, i_group ) )
>+    if( !EsOutIsProgramVisible( out, ctx, i_group ) )
>         return;
>-    p_pgrm = EsOutProgramInsert( out, i_group );
>+    p_pgrm = EsOutProgramInsert( out, ctx, i_group );
>     if( !p_pgrm )
>         return;
> 
>     input_item_SetEpgEvent( p_item, p_event );
> }
> 
>-static void EsOutProgramEpg( es_out_t *out, int i_group, const
>vlc_epg_t *p_epg )
>+static void EsOutProgramEpg( es_out_t *out, es_out_ctx_t *ctx,
>+                             int i_group, const vlc_epg_t *p_epg )
> {
>     es_out_sys_t *p_sys = container_of(out, es_out_sys_t, out);
>     input_thread_t    *p_input = p_sys->p_input;
>@@ -1638,9 +1667,9 @@ static void EsOutProgramEpg( es_out_t *out, int
>i_group, const vlc_epg_t *p_epg
>     char *psz_cat;
> 
>     /* Find program */
>-    if( !EsOutIsProgramVisible( out, i_group ) )
>+    if( !EsOutIsProgramVisible( out, ctx, i_group ) )
>         return;
>-    p_pgrm = EsOutProgramInsert( out, i_group );
>+    p_pgrm = EsOutProgramInsert( out, ctx, i_group );
>     if( !p_pgrm )
>         return;
> 
>@@ -1874,7 +1903,8 @@ static void EsOutFillEsFmt(es_out_t *out,
>es_format_t *fmt)
>     }
> }
> 
>-static es_out_id_t *EsOutAddLocked( es_out_t *out, const es_format_t
>*fmt,
>+static es_out_id_t *EsOutAddLocked( es_out_t *out, es_out_ctx_t *ctx,
>+                                    const es_format_t *fmt,
>                                     es_out_id_t *p_master )
> {
>     es_out_sys_t *p_sys = container_of(out, es_out_sys_t, out);
>@@ -1893,26 +1923,32 @@ static es_out_id_t *EsOutAddLocked( es_out_t
>*out, const es_format_t *fmt,
>         return NULL;
> 
>     es->out = out;
>+    es->ctx = es_out_ctx_Hold( ctx );
> 
>     if( es_format_Copy( &es->fmt, fmt ) != VLC_SUCCESS )
>     {
>         free( es );
>         return NULL;
>     }
>+
>     if( es->fmt.i_id < 0 )
>-        es->fmt.i_id = p_sys->i_id;
>+        es->fmt.i_id = es_out_ctx_GetNewEsID( ctx );
>     if( !es->fmt.i_original_fourcc )
>         es->fmt.i_original_fourcc = es->fmt.i_codec;
> 
>     /* Search the program */
>-    p_pgrm = EsOutProgramInsert( out, fmt->i_group );
>+    p_pgrm = EsOutProgramInsert( out, ctx, fmt->i_group );
>     if( !p_pgrm )
>     {
>         es_format_Clean( &es->fmt );
>+        es_out_ctx_Release( es->ctx );
>         free( es );
>         return NULL;
>     }
> 
>+    /* The group 0 is the default one and can be used by different
>contexts */
>+    assert( fmt->i_group == 0 || p_pgrm->ctx == es->ctx );
>+
>/* Get the number of ES already added in order to get the position of
>the es */
>     es->i_pos = 0;
>     es_out_id_t *it;
>@@ -1989,8 +2025,12 @@ static es_out_id_t *EsOutAdd( es_out_t *out,
>es_out_ctx_t *ctx, const es_format_
> {
>     VLC_UNUSED(ctx);
>     es_out_sys_t *p_sys = container_of(out, es_out_sys_t, out);
>+
>+    if( !ctx )
>+        ctx = p_sys->main_ctx;
>+
>     vlc_mutex_lock( &p_sys->lock );
>-    es_out_id_t *es = EsOutAddLocked( out, fmt, NULL );
>+    es_out_id_t *es = EsOutAddLocked( out, ctx, fmt, NULL );
>     vlc_mutex_unlock( &p_sys->lock );
>     return es;
> }
>@@ -2481,7 +2521,7 @@ static void EsOutCreateCCChannels( es_out_t *out,
>vlc_fourcc_t codec, uint64_t i
>             fmt.psz_description = NULL;
> 
>         es_out_id_t **pp_es = &parent->cc.pp_es[i];
>-        *pp_es = EsOutAddLocked( out, &fmt, parent );
>+        *pp_es = EsOutAddLocked( out, parent->p_pgrm->ctx, &fmt,
>parent );
>         es_format_Clean( &fmt );
> 
>         /* */
>@@ -2750,6 +2790,7 @@ static int EsOutVaControlLocked( es_out_t *out,
>es_out_ctx_t *ctx,
>                                  int i_query, va_list args )
> {
>     es_out_sys_t *p_sys = container_of(out, es_out_sys_t, out);
>+    assert( ctx ); /* == p_sys->main_ctx if the given ctx is NULL */
> 
>     switch( i_query )
>     {
>@@ -3024,12 +3065,12 @@ static int EsOutVaControlLocked( es_out_t *out,
>es_out_ctx_t *ctx,
>         {
>             p_pgrm = p_sys->p_pgrm;
>             if( !p_pgrm )
>-                p_pgrm = EsOutProgramAdd( out, i_group );   /* Create
>it */
>+                p_pgrm = EsOutProgramAdd( out, ctx, i_group );   /*
>Create it */
>         }
>         else
>         {
>             i_group = va_arg( args, int );
>-            p_pgrm = EsOutProgramInsert( out, i_group );
>+            p_pgrm = EsOutProgramInsert( out, ctx, i_group );
>         }
>         if( !p_pgrm )
>             return VLC_EGENERIC;
>@@ -3202,7 +3243,7 @@ static int EsOutVaControlLocked( es_out_t *out,
>es_out_ctx_t *ctx,
>         int i_group = va_arg( args, int );
>         const vlc_meta_t *p_meta = va_arg( args, const vlc_meta_t * );
> 
>-        EsOutProgramMeta( out, i_group, p_meta );
>+        EsOutProgramMeta( out, ctx, i_group, p_meta );
>         return VLC_SUCCESS;
>     }
>     case ES_OUT_SET_GROUP_EPG:
>@@ -3210,7 +3251,7 @@ static int EsOutVaControlLocked( es_out_t *out,
>es_out_ctx_t *ctx,
>         int i_group = va_arg( args, int );
>         const vlc_epg_t *p_epg = va_arg( args, const vlc_epg_t * );
> 
>-        EsOutProgramEpg( out, i_group, p_epg );
>+        EsOutProgramEpg( out, ctx, i_group, p_epg );
>         return VLC_SUCCESS;
>     }
>     case ES_OUT_SET_GROUP_EPG_EVENT:
>@@ -3218,7 +3259,7 @@ static int EsOutVaControlLocked( es_out_t *out,
>es_out_ctx_t *ctx,
>         int i_group = va_arg( args, int );
>const vlc_epg_event_t *p_evt = va_arg( args, const vlc_epg_event_t * );
> 
>-        EsOutProgramEpgEvent( out, i_group, p_evt );
>+        EsOutProgramEpgEvent( out, ctx, i_group, p_evt );
>         return VLC_SUCCESS;
>     }
>     case ES_OUT_SET_EPG_TIME:
>@@ -3233,7 +3274,7 @@ static int EsOutVaControlLocked( es_out_t *out,
>es_out_ctx_t *ctx,
>     {
>         int i_group = va_arg( args, int );
> 
>-        return EsOutProgramDel( out, i_group );
>+        return EsOutProgramDel( out, ctx, i_group );
>     }
> 
>     case ES_OUT_SET_META:
>@@ -3559,6 +3600,9 @@ static int EsOutControl( es_out_t *out,
>es_out_ctx_t *ctx,
>     es_out_sys_t *p_sys = container_of(out, es_out_sys_t, out);
>     int i_ret;
> 
>+    if( !ctx )
>+        ctx = p_sys->main_ctx;
>+
>     vlc_mutex_lock( &p_sys->lock );
>     i_ret = EsOutVaControlLocked( out, ctx, i_query, args );
>     vlc_mutex_unlock( &p_sys->lock );
>-- 
>2.20.1
>
>_______________________________________________
>vlc-devel mailing list
>To unsubscribe or modify your subscription options:
>https://mailman.videolan.org/listinfo/vlc-devel

-- 
Envoyé de mon appareil Android avec Courriel K-9 Mail. Veuillez excuser ma brièveté.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/vlc-devel/attachments/20200218/d76412ff/attachment.html>


More information about the vlc-devel mailing list