[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,
> -                                   &param );
> +                                   &param, NULL );
>              else if ( va_arg( args, int ) )
> -                input_ControlPush( p_input, 
> INPUT_CONTROL_SET_VIEWPOINT, &param);
> +                input_ControlPush( p_input, 
> INPUT_CONTROL_SET_VIEWPOINT, &param,
> +                                   NULL );
>              else
> -                input_ControlPush( p_input, 
> INPUT_CONTROL_UPDATE_VIEWPOINT, &param );
> +                input_ControlPush( p_input, 
> INPUT_CONTROL_UPDATE_VIEWPOINT, &param,
> +                                   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, &param );
> +    input_ControlPush( p_input, INPUT_CONTROL_SET_TIME, &param, 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, &param );
> +    input_ControlPush( p_input, INPUT_CONTROL_SET_POSITION, &param, 
> 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, &param, i_deadline, 
> b_postpone ) )
> +            if( ControlPop( p_input, &i_type, &param, &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, &param );
> +        return input_ControlPush( p_input, i_type, &param, 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