[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,
- ¶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
More information about the vlc-devel
mailing list