[vlc-devel] [PATCH 05/20] input: add INPUT_CONTROL_SET_ES_LIST

Roland Bewick roland.bewick at gmail.com
Fri Jun 21 06:56:55 CEST 2019


On 20/06/2019 10:23 PM, Thomas Guillem wrote:
> From: Roland Bewick <roland.bewick at gmail.com>
>
> Signed-off-by: Thomas Guillem <thomas at gllm.fr>
> ---
>   include/vlc_es_out.h                          |  1 +
>   modules/access/bluray.c                       |  1 +
>   modules/demux/adaptive/plumbing/FakeESOut.cpp |  1 +
>   src/input/es_out.c                            | 44 +++++++++++++++++++
>   src/input/es_out_timeshift.c                  |  1 +
>   src/input/input.c                             | 41 +++++++++++++++++
>   src/input/input_internal.h                    |  5 +++
>   7 files changed, 94 insertions(+)
>
> diff --git a/include/vlc_es_out.h b/include/vlc_es_out.h
> index 06b6a8f338..8ee4ef0be1 100644
> --- a/include/vlc_es_out.h
> +++ b/include/vlc_es_out.h
> @@ -36,6 +36,7 @@ enum es_out_query_e
>   {
>       /* set or change the selected ES in its category (audio/video/spu) */
>       ES_OUT_SET_ES,      /* arg1= es_out_id_t*                   */
> +    ES_OUT_SET_ES_LIST, /* arg1= es_out_id_t *const* (null terminated array) */
>       ES_OUT_UNSET_ES,    /* arg1= es_out_id_t* res=can fail      */
>       ES_OUT_RESTART_ES,  /* arg1= es_out_id_t*                   */
>   
> diff --git a/modules/access/bluray.c b/modules/access/bluray.c
> index 95f1afe389..b12a416e36 100644
> --- a/modules/access/bluray.c
> +++ b/modules/access/bluray.c
> @@ -1546,6 +1546,7 @@ static int bluray_esOutControl(es_out_t *p_out, int i_query, va_list args)
>   
>           case ES_OUT_SET_ES_DEFAULT:
>           case ES_OUT_SET_ES:
> +        case ES_OUT_SET_ES_LIST:
>           case ES_OUT_UNSET_ES:
>           case ES_OUT_SET_ES_STATE:
>               i_ret = VLC_EGENERIC;
> diff --git a/modules/demux/adaptive/plumbing/FakeESOut.cpp b/modules/demux/adaptive/plumbing/FakeESOut.cpp
> index 69d00f7e7f..f1f274e0cf 100644
> --- a/modules/demux/adaptive/plumbing/FakeESOut.cpp
> +++ b/modules/demux/adaptive/plumbing/FakeESOut.cpp
> @@ -470,6 +470,7 @@ int FakeESOut::esOutControl_Callback(es_out_t *fakees, int i_query, va_list args
>           }
>   
>           case ES_OUT_SET_ES:
> +        case ES_OUT_SET_ES_LIST:
>           case ES_OUT_SET_ES_DEFAULT:
>           case ES_OUT_SET_ES_STATE:
>               return VLC_SUCCESS;
> diff --git a/src/input/es_out.c b/src/input/es_out.c
> index 1da90c76fa..366c9e65c7 100644
> --- a/src/input/es_out.c
> +++ b/src/input/es_out.c
> @@ -220,6 +220,8 @@ static void         EsOutDel    ( es_out_t *, es_out_id_t * );
>   
>   static void         EsOutTerminate( es_out_t * );
>   static void         EsOutSelect( es_out_t *, es_out_id_t *es, bool b_force );
> +static void         EsOutSelectList( es_out_t *, enum es_format_category_e cat,
> +                                     vlc_es_id_t *const* es_id_list );
>   static void         EsOutUpdateInfo( es_out_t *, es_out_id_t *es, const vlc_meta_t * );
>   static int          EsOutSetRecord(  es_out_t *, bool b_record );
>   
> @@ -2219,6 +2221,41 @@ static void EsOutSelect( es_out_t *out, es_out_id_t *es, bool b_force )
>           p_esprops->p_main_es = es;
>   }
>   
> +static void EsOutSelectList( es_out_t *out, enum es_format_category_e cat,
> +                             vlc_es_id_t * const*es_id_list )
> +{
> +
> +    es_out_sys_t *p_sys = container_of(out, es_out_sys_t, out);
> +    es_out_id_t *other;
> +
> +    foreach_es_then_es_slaves(other)
> +    {
> +        if( other->fmt.i_cat == cat )
> +        {
> +            bool select = false;
> +            for( size_t i = 0; ; i++ )
> +            {
> +                vlc_es_id_t *es_id = es_id_list[i];
> +                if( es_id == NULL )
> +                    break;
> +                else if( es_id->i_id == other->id.i_id )
> +                {
> +                    select = true;
> +                    break;
> +                }
> +            }
> +            if( !select && EsIsSelected( other ) )
> +            {
> +                EsOutUnselectEs( out, other, other->p_pgrm == p_sys->p_pgrm );
> +            }
> +            else if( select && !EsIsSelected( other ) )
> +            {
> +                EsOutSelectEs( out, other );
> +            }
> +        }
> +    }
> +}
> +
>   static void EsOutCreateCCChannels( es_out_t *out, vlc_fourcc_t codec, uint64_t i_bitmap,
>                                      const char *psz_descfmt, es_out_id_t *parent )
>   {
> @@ -2668,6 +2705,13 @@ static int EsOutVaControlLocked( es_out_t *out, int i_query, va_list args )
>           EsOutStopFreeVout( out );
>           return VLC_SUCCESS;
>       }
> +    case ES_OUT_SET_ES_LIST:
> +    {
> +        enum es_format_category_e cat = va_arg( args, enum es_format_category_e );
> +        vlc_es_id_t *const*es_id_list = va_arg( args, vlc_es_id_t ** );
> +        EsOutSelectList( out, cat, es_id_list );
> +        return VLC_SUCCESS;
> +    }
>       case ES_OUT_UNSET_ES:
>       {
>           es_out_id_t *es = va_arg( args, es_out_id_t * ), *other;
> diff --git a/src/input/es_out_timeshift.c b/src/input/es_out_timeshift.c
> index cff9691d71..2fd8855251 100644
> --- a/src/input/es_out_timeshift.c
> +++ b/src/input/es_out_timeshift.c
> @@ -737,6 +737,7 @@ static int ControlLocked( es_out_t *p_out, int i_query, va_list args )
>   
>       /* Invalid queries for this es_out level */
>       case ES_OUT_SET_ES_BY_ID:
> +    case ES_OUT_SET_ES_LIST:
>       case ES_OUT_RESTART_ES_BY_ID:
>       case ES_OUT_SET_ES_DEFAULT_BY_ID:
>       case ES_OUT_STOP_ALL_ES:
> diff --git a/src/input/input.c b/src/input/input.c
> index efc338f33c..ab96f29afa 100644
> --- a/src/input/input.c
> +++ b/src/input/input.c
> @@ -1594,6 +1594,18 @@ static void ControlRelease( int i_type, const input_control_param_t *p_param )
>       case INPUT_CONTROL_RESTART_ES:
>           vlc_es_id_Release( p_param->id );
>           break;
> +    case INPUT_CONTROL_SET_ES_LIST:
> +    {
> +        for (size_t i = 0; ; i++)
> +        {
> +            vlc_es_id_t *es_id = p_param->list.ids[i];
> +            if (es_id == NULL)
> +                break;
> +            vlc_es_id_Release(es_id);
> +        }
> +        free(p_param->list.ids);
> +        break;
> +    }
>   
>       default:
>           break;
> @@ -2013,6 +2025,35 @@ static bool Control( input_thread_t *p_input,
>                   demux_Control( input_priv(p_input)->master->p_demux, DEMUX_SET_ES,
>                                  vlc_es_id_GetInputId( param.id ) );
>               break;
> +        case INPUT_CONTROL_SET_ES_LIST:
> +        {
> +            if( es_out_Control( input_priv(p_input)->p_es_out_display,
> +                                ES_OUT_SET_ES_LIST, param.list.cat,
> +                                param.list.ids ) == VLC_SUCCESS )
> +            {
> +                if( param.list.ids[0] != NULL && param.list.ids[1] == NULL )
> +                    demux_Control( input_priv(p_input)->master->p_demux, DEMUX_SET_ES,
> +                                   vlc_es_id_GetInputId( param.list.ids[0] ) );

If two tracks were selected previously and now we want to select a 
single track, is it OK to use DEMUX_SET_ES instead of DEMUX_SET_ES_LIST?

DEMUX_SET_ES would then have to disable all ids except the given id. It 
looks like it won't cause any issues with the current demuxers because 
they seem to only support single selection, but it's inconsistent with 
how the ES selection works.

> +                else
> +                {
> +                    /* Send an array of int id from the array of es_id to the
> +                     * demux */
> +                    size_t count;
> +                    for (count = 0; param.list.ids[count] != NULL; count++);
> +
> +                    int *ids = count ? vlc_alloc(count, sizeof(int)) : NULL;
> +                    if (count == 0 || ids)
> +                    {
> +                        for (size_t i = 0; i < count; ++i)
> +                            ids[i] = vlc_es_id_GetInputId(param.list.ids[i]);
> +                        demux_Control(input_priv(p_input)->master->p_demux,
> +                                      DEMUX_SET_ES_LIST, count, ids);
> +                    }
> +                    free(ids);
> +                }
> +            }
> +            break;
> +        }
>           case INPUT_CONTROL_UNSET_ES:
>               es_out_Control( input_priv(p_input)->p_es_out_display,
>                               ES_OUT_UNSET_ES, vlc_es_id_get_out(param.id) );
> diff --git a/src/input/input_internal.h b/src/input/input_internal.h
> index 3b2f5533e9..b159033b1c 100644
> --- a/src/input/input_internal.h
> +++ b/src/input/input_internal.h
> @@ -434,6 +434,10 @@ typedef union
>       vlc_value_t val;
>       vlc_viewpoint_t viewpoint;
>       vlc_es_id_t *id;
> +    struct {
> +        enum es_format_category_e cat;
> +        vlc_es_id_t **ids;
> +    } list;
>       struct {
>           bool b_fast_seek;
>           vlc_tick_t i_val;
> @@ -580,6 +584,7 @@ enum input_control_e
>       INPUT_CONTROL_RESTART_ES_BY_ID,
>   
>       INPUT_CONTROL_SET_ES,
> +    INPUT_CONTROL_SET_ES_LIST,  // select a list of ES atomically
>       INPUT_CONTROL_UNSET_ES,
>       INPUT_CONTROL_RESTART_ES,
>   


More information about the vlc-devel mailing list