[vlc-devel] [PATCH 01/16] Add vlc_player_SelectTrackList
Roland Bewick
roland.bewick at gmail.com
Mon May 27 17:35:39 CEST 2019
On 27/05/2019 2:39 PM, Thomas Guillem wrote:
> Hi,
>
> On Tue, May 21, 2019, at 20:09, Roland Bewick wrote:
>> ---
>> include/vlc_es_out.h | 1 +
>> include/vlc_player.h | 26 ++++++++
>> 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 | 22 +++++++
>> src/input/input_internal.h | 5 ++
>> src/input/player.c | 85 +++++++++++++++++++++++++++
>> src/libvlccore.sym | 1 +
>> 10 files changed, 187 insertions(+)
> We could split this commit in three: es_out/input/player. I can do it myself when I actually merge it if you agree (preserving your authorship)
I can split the commit this time since I have to make some changes in
the following commits anyway. Thanks for your offer.
>
>> diff --git a/include/vlc_es_out.h b/include/vlc_es_out.h
>> index b690d570e9..47e2012ab9 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** */
>> ES_OUT_UNSET_ES, /* arg1= es_out_id_t* res=can fail */
>> ES_OUT_RESTART_ES, /* arg1= es_out_id_t* */
>>
>> diff --git a/include/vlc_player.h b/include/vlc_player.h
>> index 1aa5f8e687..f2df800797 100644
>> --- a/include/vlc_player.h
>> +++ b/include/vlc_player.h
>> @@ -1675,6 +1675,32 @@ vlc_player_GetSelectedTrack(vlc_player_t
>> *player, enum es_format_category_e cat)
>> VLC_API void
>> vlc_player_SelectTrack(vlc_player_t *player, vlc_es_id_t *es_id);
>>
>> +
>> +/**
>> + * Select multiple tracks from a list of ES identifiers. Any currently
>> + * selected track not referenced in the list will be unselected.
>> + *
>> + * @warning there is no guarantee all requested tracks will be
>> selected.
>> + * Only one audio track can be selected at a time. Two subtitle tracks
>> + * can be selected simultaneously if dual subtitles are enabled.
>> + *
>> + * @warning behaviour is undefined if the list is not null-terminated.
>> + *
>> + * @note A successful call will trigger the
>> + * vlc_player_cbs.on_track_selection_changed event for each track that
>> has
>> + * its selection state changed.
>> + *
>> + * @param player locked player instance
>> + * @param cat VIDEO_ES, AUDIO_ES or SPU_ES
>> + * @param es_id_list a null-terminated list of ES identifiers.
>> + * (ES IDs can be retrieved from vlc_player_cbs.on_track_list_changed
>> or
>> + * vlc_player_GetTrackAt())
>> + */
>> +VLC_API void
>> +vlc_player_SelectTrackList(vlc_player_t *player,
>> + enum es_format_category_e cat,
>> + vlc_es_id_t *const es_id_list[]);
>> +
>> /**
>> * Select the next track
>> *
>> diff --git a/modules/access/bluray.c b/modules/access/bluray.c
>> index c452327aeb..cd88dcc4cf 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 2026fb8c22..933249c39b 100644
>> --- a/src/input/es_out.c
>> +++ b/src/input/es_out.c
>> @@ -217,6 +217,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 **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 );
>>
>> @@ -2182,6 +2184,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 **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 )
>> {
>> @@ -2601,6 +2638,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 **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 406c6f2237..21a041a1f8 100644
>> --- a/src/input/es_out_timeshift.c
>> +++ b/src/input/es_out_timeshift.c
>> @@ -738,6 +738,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_GET_ES_OBJECTS_BY_ID:
>> diff --git a/src/input/input.c b/src/input/input.c
>> index 381b85a9fd..eea40b59c1 100644
>> --- a/src/input/input.c
>> +++ b/src/input/input.c
>> @@ -1712,6 +1712,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;
>> @@ -2130,6 +2142,16 @@ 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 )
>> + {
>> + /* TODO: demux_Control(..., DEMUX_SET_ES_LIST, ... ) */
>> + }
>> + break;
>> + }
>> case INPUT_CONTROL_UNSET_ES:
>> es_out_Control( input_priv(p_input)->p_es_out_display,
>> ES_OUT_UNSET_ES, param.id );
>> diff --git a/src/input/input_internal.h b/src/input/input_internal.h
>> index 18495881c2..3bcb5a9f83 100644
>> --- a/src/input/input_internal.h
>> +++ b/src/input/input_internal.h
>> @@ -85,6 +85,10 @@ typedef union
>> 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;
>> } time;
>> @@ -247,6 +251,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,
>>
>> diff --git a/src/input/player.c b/src/input/player.c
>> index da02375a66..551b9928f1 100644
>> --- a/src/input/player.c
>> +++ b/src/input/player.c
>> @@ -1312,6 +1312,91 @@ vlc_player_SelectTrack(vlc_player_t *player,
>> vlc_es_id_t *id)
>> vlc_player_vout_OSDTrack(player, id, true);
>> }
>>
>> +void
>> +vlc_player_SelectTrackList(vlc_player_t *player,
>> + enum es_format_category_e cat,
>> + vlc_es_id_t *const es_id_list[])
>> +{
>> + struct vlc_player_input *input =
>> vlc_player_get_input_locked(player);
>> + if (!input)
>> + return;
>> +
>> + /* First, count and hold all the ES Ids.
>> + Ids will be released in input.c:ControlRelease */
>> + size_t id_count;
>> + for (id_count = 0; ; id_count++)
>> + {
>> + vlc_es_id_t *es_id = es_id_list[id_count];
>> + if (es_id == NULL)
>> + break;
>> +
>> + vlc_es_id_Hold( es_id );
>> + }
>> +
>> + /* Copy es_id_list into an allocated list so that it remains in
>> memory until
>> + selection completes. The list will be freed in
>> input.c:ControlRelease */
>> + struct vlc_es_id_t **allocated_ids =
>> + malloc(sizeof(vlc_es_id_t *) * (id_count + 1));
> You forgot to check the malloc return.
I'll fix this, thanks.
>
>> +
>> + for (size_t i = 0; i <= id_count; i++)
>> + {
>> + allocated_ids[i] = es_id_list[i];
>> + }
>> +
>> + /* Attempt to select all the requested tracks */
>> + input_ControlPush( input->thread, INPUT_CONTROL_SET_ES_LIST,
>> + &(input_control_param_t) {
>> + .list.cat = cat,
>> + .list.ids = allocated_ids,
>> + } );
>> +
>> + /* Display track selection message */
>> + bool selected_new_track = false;
>> + for (size_t i = 0; i < id_count; i++)
>> + {
>> + vlc_es_id_t *es_id = es_id_list[i];
>> +
>> + const struct vlc_player_track *track =
>> vlc_player_GetTrack(player, es_id);
>> + assert(track);
>> +
>> + if (!track->selected)
>> + {
>> + vlc_player_vout_OSDTrack(player, es_id, true);
>> + selected_new_track = true;
>> + }
>> + }
>> +
>> + if (!selected_new_track)
>> + {
>> + /* Display track deselection message */
>> + size_t count = vlc_player_GetTrackCount(player, cat);
>> + if (!count)
>> + return;
>> +
>> + for (size_t i = 0; i < count; ++i)
>> + {
>> + const struct vlc_player_track *track =
>> + vlc_player_GetTrackAt(player, cat, i);
>> + assert(track);
>> + if (track->selected)
>> + {
>> + bool selected = false;
>> + for (size_t j = 0; j < id_count; j++)
>> + {
>> + if (es_id_list[j] == track->es_id)
>> + {
>> + selected = true;
>> + break;
>> + }
>> + }
>> +
>> + if (!selected)
>> + vlc_player_vout_OSDTrack(player, track->es_id,
>> false);
>> + }
>> + }
>> + }
>> +}
>> +
>> static void
>> vlc_player_CycleTrack(vlc_player_t *player, enum es_format_category_e
>> cat,
>> bool next)
>> diff --git a/src/libvlccore.sym b/src/libvlccore.sym
>> index efc07fbb25..03a503e1ea 100644
>> --- a/src/libvlccore.sym
>> +++ b/src/libvlccore.sym
>> @@ -856,6 +856,7 @@ vlc_player_SelectTeletextPage
>> vlc_player_SelectTitle
>> vlc_player_SelectTitleIdx
>> vlc_player_SelectTrack
>> +vlc_player_SelectTrackList
>> vlc_player_SetAssociatedSubsFPS
>> vlc_player_SetAtoBLoop
>> vlc_player_SetAudioDelay
>> --
>> 2.11.0
>>
>> _______________________________________________
>> vlc-devel mailing list
>> To unsubscribe or modify your subscription options:
>> https://mailman.videolan.org/listinfo/vlc-devel
> _______________________________________________
> 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