[vlc-devel] [PATCH 2/2] RFC: input: notify when a control is processed

Thomas Guillem thomas at gllm.fr
Tue Sep 4 14:35:45 CEST 2018


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.
---
 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



More information about the vlc-devel mailing list