[vlc-devel] [PATCH 01/16] Add vlc_player_SelectTrackList
Roland Bewick
roland.bewick at gmail.com
Wed May 22 09:18:05 CEST 2019
On 22/05/2019 1:59 PM, Thomas Guillem wrote:
> Hi,
>
> I'm AFK, I'll do my review and (hopefully) merge on friday or monday. This set looks promising.
Great, thanks for letting me know.
Roland
>
> On Tue, May 21, 2019, at 20:13, Roland Bewick wrote:
>> On 22/05/2019 1:08 AM, 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(+)
>>>
>>> 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));
>>> +
>>> + 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
>> Hi again,
>>
>> This patch set uses the more general-purpose vlc_player_SelectTrackList
>> to control dual subtitle selection.
>>
>> The majority of the changes can be seen in the following commits:
>>
>> - Patch 01 (Implementation of vlc_player_SelectTrackList and
>> EsOutSelectList)
>> - Patch 02 (Demux control for new INPUT_CONTROL_SET_ES_LIST event)
>> - Patch 05 (Using vlc_player_SelectTrackList from the QT subtitle menu)
>> - Patch 13 (Using vlc_player_SelectTrackList for secondary subtitle
>> track cycling)
>>
>> Please let me know if you have any comments.
>>
>> Thanks,
>> Roland
>>
>> _______________________________________________
>> 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