[vlc-devel] [PATCH 2/2] RFC: input: notify when a control is processed
Thomas Guillem
thomas at gllm.fr
Tue Sep 4 14:42:10 CEST 2018
On Tue, Sep 4, 2018, at 14:35, Thomas Guillem wrote:
> This new event will be used by the future vlc_player. Mainly to be notified
> when a seek command is processed, but this can work with any other input
> controls.
>
> Use-case example with future UI/vlc_player.
>
> The UI can send one or several seek commands to the player
> (INPUT_CONTROL_SET_POSITION, INPUT_CONTROL_SET_TITLE... any commands that
> trigger a seek). The UI saves the control ID of the last seek command (and
> drops old control IDs if more than one seek command are sent in a row). Until
> this last control ID is not notified by input events, the input_thread is
> seeking: the UI can do something accordingly with the seek bar.
>
> There are other way to do it, I could have added a callback (function pointer +
> data) to each vlc_player_t seek commands too.
>
> This solution means that all or some async functions of the future player will
> have a const void **id as last argument.
Humm, this solution doesn't really work if more than one interface are seeking at the same time.
> ---
> include/vlc_input.h | 16 ++++++++++++
> src/input/control.c | 8 +++---
> src/input/event.c | 9 +++++++
> src/input/event.h | 3 +++
> src/input/input.c | 51 ++++++++++++++++++++++++++++++++------
> src/input/input_internal.h | 12 ++++-----
> src/input/var.c | 2 ++
> 7 files changed, 84 insertions(+), 17 deletions(-)
>
> diff --git a/include/vlc_input.h b/include/vlc_input.h
> index 0c1d5a10b7..72c576c0da 100644
> --- a/include/vlc_input.h
> +++ b/include/vlc_input.h
> @@ -344,6 +344,9 @@ typedef enum input_event_type_e
> /* "length" has changed */
> INPUT_EVENT_LENGTH,
>
> + /* "control" has changed: a control had been processed */
> + INPUT_EVENT_CONTROL,
> +
> /* A title has been added or removed or selected.
> * It implies that the chapter has changed (no chapter event is sent) */
> INPUT_EVENT_TITLE,
> @@ -404,6 +407,17 @@ struct vlc_input_event_position
> vlc_tick_t ms;
> };
>
> +struct vlc_input_event_control
> +{
> + enum
> + {
> + VLC_INPUT_CONTROL_SUCCESS,
> + VLC_INPUT_CONTROL_ERROR,
> + VLC_INPUT_CONTROL_CANCELED,
> + } state;
> + const void *id;
> +};
> +
> struct vlc_input_event_chapter
> {
> int title;
> @@ -466,6 +480,8 @@ struct vlc_input_event
> struct vlc_input_event_position position;
> /* INPUT_EVENT_LENGTH */
> vlc_tick_t length;
> + /* INPUT_EVENT_CONTROL_PROCESSED */
> + struct vlc_input_event_control control;
> /* INPUT_EVENT_TITLE */
> int title;
> /* INPUT_EVENT_CHAPTER */
> diff --git a/src/input/control.c b/src/input/control.c
> index bae8a67b7e..d1f13665f2 100644
> --- a/src/input/control.c
> +++ b/src/input/control.c
> @@ -369,11 +369,13 @@ int input_vaControl( input_thread_t *p_input, int
> i_query, va_list args )
> param.viewpoint = *va_arg( args, const vlc_viewpoint_t* );
> if ( i_query == INPUT_SET_INITIAL_VIEWPOINT )
> input_ControlPush( p_input,
> INPUT_CONTROL_SET_INITIAL_VIEWPOINT,
> - ¶m );
> + ¶m, NULL );
> else if ( va_arg( args, int ) )
> - input_ControlPush( p_input,
> INPUT_CONTROL_SET_VIEWPOINT, ¶m);
> + input_ControlPush( p_input,
> INPUT_CONTROL_SET_VIEWPOINT, ¶m,
> + NULL );
> else
> - input_ControlPush( p_input,
> INPUT_CONTROL_UPDATE_VIEWPOINT, ¶m );
> + input_ControlPush( p_input,
> INPUT_CONTROL_UPDATE_VIEWPOINT, ¶m,
> + NULL );
> return VLC_SUCCESS;
> }
>
> diff --git a/src/input/event.c b/src/input/event.c
> index 2095b3e25f..a8944fe93d 100644
> --- a/src/input/event.c
> +++ b/src/input/event.c
> @@ -255,3 +255,12 @@ void input_SendEventParsing( input_thread_t
> *p_input, input_item_node_t *p_root
> .subitems = p_root,
> });
> }
> +
> +void input_SendEventControl( input_thread_t *p_input,
> + const struct vlc_input_event_control
> *event )
> +{
> + input_SendEvent( p_input, &(struct vlc_input_event) {
> + .type = INPUT_EVENT_CONTROL,
> + .control = *event,
> + });
> +}
> diff --git a/src/input/event.h b/src/input/event.h
> index a2fcfe5541..20898d899f 100644
> --- a/src/input/event.h
> +++ b/src/input/event.h
> @@ -51,6 +51,9 @@ void input_SendEventMetaEpg( input_thread_t
> *p_input );
>
> void input_SendEventParsing( input_thread_t *p_input, input_item_node_t
> *p_root );
>
> +void input_SendEventControl( input_thread_t *p_input,
> + const struct vlc_input_event_control
> *event );
> +
> /
> *****************************************************************************
> * Event for es_out.c
>
> *****************************************************************************/
> diff --git a/src/input/input.c b/src/input/input.c
> index eb7199a804..bc5dacd40f 100644
> --- a/src/input/input.c
> +++ b/src/input/input.c
> @@ -69,7 +69,9 @@ static int Init ( input_thread_t
> *p_input );
> static void End ( input_thread_t *p_input );
> static void MainLoop( input_thread_t *p_input, bool
> b_interactive );
>
> -static inline int ControlPop( input_thread_t *, int *,
> input_control_param_t *, vlc_tick_t i_deadline, bool b_postpone_seek );
> +static inline int ControlPop( input_thread_t *, int *,
> input_control_param_t *,
> + void **id, vlc_tick_t i_deadline,
> + bool b_postpone_seek );
> static void ControlRelease( int i_type, const
> input_control_param_t *p_param );
> static bool ControlIsSeekRequest( int i_type );
> static int Control( input_thread_t *, int,
> input_control_param_t, bool *force_update );
> @@ -238,7 +240,7 @@ void input_SetTime( input_thread_t *p_input,
> vlc_tick_t i_time, bool b_fast )
> param.time.i_val = i_time;
> param.time.b_fast_seek = b_fast;
> param.time.b_absolute = true;
> - input_ControlPush( p_input, INPUT_CONTROL_SET_TIME, ¶m );
> + input_ControlPush( p_input, INPUT_CONTROL_SET_TIME, ¶m, NULL );
> }
>
> void input_SetPosition( input_thread_t *p_input, float f_position, bool
> b_fast )
> @@ -248,7 +250,7 @@ void input_SetPosition( input_thread_t *p_input,
> float f_position, bool b_fast )
> param.pos.f_val = f_position;
> param.pos.b_fast_seek = b_fast;
> param.pos.b_absolute = true;
> - input_ControlPush( p_input, INPUT_CONTROL_SET_POSITION, ¶m );
> + input_ControlPush( p_input, INPUT_CONTROL_SET_POSITION, ¶m,
> NULL );
> }
>
> /**
> @@ -811,9 +813,10 @@ static void MainLoop( input_thread_t *p_input, bool
> b_interactive )
> }
>
> int i_type;
> + void *id;
> input_control_param_t param;
>
> - if( ControlPop( p_input, &i_type, ¶m, i_deadline,
> b_postpone ) )
> + if( ControlPop( p_input, &i_type, ¶m, &id, i_deadline,
> b_postpone ) )
> {
> if( b_postpone )
> continue;
> @@ -832,6 +835,16 @@ static void MainLoop( input_thread_t *p_input, bool
> b_interactive )
> i_intf_update = 0;
> }
>
> + if( id )
> + {
> + input_SendEventControl( p_input, &(struct
> vlc_input_event_control) {
> + .state = ret == VLC_SUCCESS ?
> VLC_INPUT_CONTROL_SUCCESS
> + :
> VLC_INPUT_CONTROL_ERROR,
> + .id = id,
> + });
> + free( id );
> + }
> +
> /* Update the wakeup time */
> if( i_wakeup != 0 )
> i_wakeup = es_out_GetWakeup( input_priv(p_input)-
> >p_es_out );
> @@ -1485,13 +1498,17 @@ static void End( input_thread_t * p_input )
> /
> *****************************************************************************
> * Control
>
> *****************************************************************************/
> -void input_ControlPush( input_thread_t *p_input,
> - int i_type, const input_control_param_t
> *p_param )
> +int input_ControlPush( input_thread_t *p_input,
> + int i_type, const input_control_param_t
> *p_param,
> + const void **out_id )
> {
> input_thread_private_t *sys = input_priv(p_input);
>
> + int ret;
> + void *id = out_id ? malloc(1) : NULL;
> vlc_mutex_lock( &sys->lock_control );
> - if( sys->is_stopped || sys->i_control >= INPUT_CONTROL_FIFO_SIZE )
> + if( sys->is_stopped || sys->i_control >= INPUT_CONTROL_FIFO_SIZE
> + || ( out_id && !id ) )
> {
> if( sys->is_stopped )
> msg_Dbg( p_input, "input control stopped, trashing type=%d",
> @@ -1501,11 +1518,14 @@ void input_ControlPush( input_thread_t *p_input,
> i_type );
> if( p_param )
> ControlRelease( i_type, p_param );
> + free(id);
> + ret = VLC_EGENERIC;
> }
> else
> {
> input_control_t c;
> c.i_type = i_type;
> + c.id = id;
> if( p_param )
> c.param = *p_param;
> else
> @@ -1514,8 +1534,12 @@ void input_ControlPush( input_thread_t *p_input,
> sys->control[sys->i_control++] = c;
>
> vlc_cond_signal( &sys->wait_control );
> + if (out_id)
> + *out_id = id;
> + ret = VLC_SUCCESS;
> }
> vlc_mutex_unlock( &sys->lock_control );
> + return ret;
> }
>
> static size_t ControlGetReducedIndexLocked( input_thread_t *p_input )
> @@ -1555,7 +1579,8 @@ static size_t
> ControlGetReducedIndexLocked( input_thread_t *p_input )
>
> static inline int ControlPop( input_thread_t *p_input,
> int *pi_type, input_control_param_t *p_param,
> - vlc_tick_t i_deadline, bool b_postpone_seek )
> + void **id, vlc_tick_t i_deadline,
> + bool b_postpone_seek )
> {
> input_thread_private_t *p_sys = input_priv(p_input);
>
> @@ -1588,12 +1613,22 @@ static inline int ControlPop( input_thread_t
> *p_input,
> for( size_t i = 0; i < i_index; ++i )
> {
> /* Release Reduced controls */
> + if ( p_sys->control[i].id )
> + {
> + input_SendEventControl( p_input, &(struct
> vlc_input_event_control) {
> + .state = VLC_INPUT_CONTROL_CANCELED,
> + .id = p_sys->control[i].id,
> + });
> + free( p_sys->control[i].id );
> + }
> +
> ControlRelease( p_sys->control[i].i_type, &p_sys-
> >control[i].param );
> }
>
> /* */
> *pi_type = p_sys->control[i_index].i_type;
> *p_param = p_sys->control[i_index].param;
> + *id = p_sys->control[i_index].id;
>
> p_sys->i_control -= i_index + 1;
> if( p_sys->i_control > 0 )
> diff --git a/src/input/input_internal.h b/src/input/input_internal.h
> index eb54d19ae3..ae300fcc85 100644
> --- a/src/input/input_internal.h
> +++ b/src/input/input_internal.h
> @@ -97,6 +97,7 @@ typedef union
> typedef struct
> {
> int i_type;
> + void *id;
> input_control_param_t param;
> } input_control_t;
>
> @@ -243,22 +244,21 @@ enum input_control_e
>
> /* Internal helpers */
>
> -void input_ControlPush( input_thread_t *, int, const input_control_param_t * );
> +int input_ControlPush( input_thread_t *, int, const input_control_param_t *,
> + const void ** );
>
> /* XXX for string value you have to allocate it before calling
> * input_ControlPushHelper
> */
> -static inline void input_ControlPushHelper( input_thread_t *p_input,
> int i_type, vlc_value_t *val )
> +static inline int input_ControlPushHelper( input_thread_t *p_input, int
> i_type, vlc_value_t *val )
> {
> if( val != NULL )
> {
> input_control_param_t param = { .val = *val };
> - input_ControlPush( p_input, i_type, ¶m );
> + return input_ControlPush( p_input, i_type, ¶m, NULL );
> }
> else
> - {
> - input_ControlPush( p_input, i_type, NULL );
> - }
> + return input_ControlPush( p_input, i_type, NULL, NULL );
> }
>
> bool input_Stopped( input_thread_t * );
> diff --git a/src/input/var.c b/src/input/var.c
> index ad917e1476..dc0dc30681 100644
> --- a/src/input/var.c
> +++ b/src/input/var.c
> @@ -418,6 +418,8 @@ void input_LegacyEvents( input_thread_t *p_input,
> break;
> case INPUT_EVENT_SUBITEMS:
> break;
> + case INPUT_EVENT_CONTROL:
> + break;
> }
> Trigger( p_input, event->type );
> }
> --
> 2.18.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