#define INPUT_UPDATE_META 0x0040
#define INPUT_UPDATE_SIGNAL 0x0080
-/** Get the input item for an input thread
- * FIXME see src/input/item.c but is is unsafe unless
- * you hold p_input
+/**
+ * This defines private core storage for an input.
*/
-VLC_EXPORT(input_item_t*, input_GetItem, (input_thread_t*));
-
typedef struct input_thread_private_t input_thread_private_t;
+/**
+ * This defines an opaque input resource handler.
+ */
+typedef struct input_resource_t input_resource_t;
+
/**
* Main structure representing an input thread. This structure is mostly
* private. The only public fields are READ-ONLY. You must use the helpers
} input_event_type_e;
-/** @}*/
-
-/*****************************************************************************
- * Prototypes
- *****************************************************************************/
-
/**
- * It will create a new input thread.
- *
- * You must call input_StopThread() on it and then vlc_object_release().
+ * Input queries
*/
-#define input_CreateThread(a,b) __input_CreateThread(VLC_OBJECT(a),b)
-VLC_EXPORT( input_thread_t *, __input_CreateThread, ( vlc_object_t *, input_item_t * ) );
-
-/**
- * It will ask a input_thread_t to stop.
- *
- * b_abort must be true when a user stop is requested and not because you have
- * detected an error or an eof. It will be used to properly send the
- * INPUT_EVENT_ABORT event.
- */
-VLC_EXPORT( void, input_StopThread, ( input_thread_t *, bool b_abort ) );
-
-#define input_Read(a,b,c) __input_Read(VLC_OBJECT(a),b, c)
-VLC_EXPORT( int, __input_Read, ( vlc_object_t *, input_item_t *, bool ) );
-
enum input_query_e
{
/* input variable "position" */
INPUT_GET_VOUTS, /* arg1=vout_thread_t ***, int * res=can fail */
};
+/** @}*/
+
+/*****************************************************************************
+ * Prototypes
+ *****************************************************************************/
+
+#define input_Create(a,b,c,d) __input_Create(VLC_OBJECT(a),b,c,d)
+VLC_EXPORT( input_thread_t *, __input_Create, ( vlc_object_t *p_parent, input_item_t *, const char *psz_log, input_resource_t * ) );
+
+#define input_CreateAndStart(a,b,c) __input_CreateAndStart(VLC_OBJECT(a),b,c)
+VLC_EXPORT( input_thread_t *, __input_CreateAndStart, ( vlc_object_t *p_parent, input_item_t *, const char *psz_log ) );
+
+VLC_EXPORT( int, input_Start, ( input_thread_t * ) );
+
+VLC_EXPORT( void, input_Stop, ( input_thread_t *, bool b_abort ) );
+
+#define input_Read(a,b,c) __input_Read(VLC_OBJECT(a),b, c)
+VLC_EXPORT( int, __input_Read, ( vlc_object_t *, input_item_t *, bool ) );
+
VLC_EXPORT( int, input_vaControl,( input_thread_t *, int i_query, va_list ) );
+
VLC_EXPORT( int, input_Control, ( input_thread_t *, int i_query, ... ) );
+/**
+ * Get the input item for an input thread
+ *
+ * You have to keep a reference to the input or to the input_item_t until
+ * you do not need it anymore.
+ */
+VLC_EXPORT( input_item_t*, input_GetItem, ( input_thread_t * ) );
+
/**
* It will return the current state of the input.
* Provided for convenience.
vlc_object_release( (vlc_object_t *)(pp_vout[i]) );
p_vout = (i_vout >= 1) ? pp_vout[0] : NULL;
- free (pp_vout);
+ free( pp_vout );
return p_vout;
}
/* Do not let a pts_delay from access/demux go beyong 60s */
#define INPUT_PTS_DELAY_MAX INT64_C(60000000)
+/**
+ * Create a new input_thread_t.
+ *
+ * You need to call input_Start on it when you are done
+ * adding callback on the variables/events you want to monitor.
+ *
+ * \param p_parent a vlc_object
+ * \param p_item an input item
+ * \param psz_log an optional prefix for this input logs
+ * \param p_resource an optional input ressource
+ * \return a pointer to the spawned input thread
+ */
+
+input_thread_t *__input_Create( vlc_object_t *p_parent,
+ input_item_t *p_item,
+ const char *psz_log, input_resource_t *p_resource )
+{
+
+ return Create( p_parent, p_item, psz_log, false, p_resource );
+}
+
+/**
+ * Create a new input_thread_t and start it.
+ *
+ * Provided for convenience.
+ *
+ * \see input_Create
+ */
+input_thread_t *__input_CreateAndStart( vlc_object_t *p_parent,
+ input_item_t *p_item, const char *psz_log )
+{
+ input_thread_t *p_input = __input_Create( p_parent, p_item, psz_log, NULL );
+
+ if( input_Start( p_input ) )
+ {
+ vlc_object_release( p_input );
+ return NULL;
+ }
+ return p_input;
+}
+
+/**
+ * Initialize an input thread and run it. This thread will clean after itself,
+ * you can forget about it. It can work either in blocking or non-blocking mode
+ *
+ * \param p_parent a vlc_object
+ * \param p_item an input item
+ * \param b_block should we block until read is finished ?
+ * \return an error code, VLC_SUCCESS on success
+ */
+int __input_Read( vlc_object_t *p_parent, input_item_t *p_item,
+ bool b_block )
+{
+ input_thread_t *p_input;
+
+ p_input = Create( p_parent, p_item, NULL, false, NULL );
+ if( !p_input )
+ return VLC_EGENERIC;
+
+ if( b_block )
+ {
+ RunAndDestroy( VLC_OBJECT(p_input) );
+ return VLC_SUCCESS;
+ }
+ else
+ {
+ if( vlc_thread_create( p_input, "input", RunAndDestroy,
+ VLC_THREAD_PRIORITY_INPUT ) )
+ {
+ input_ChangeState( p_input, ERROR_S );
+ msg_Err( p_input, "cannot create input thread" );
+ vlc_object_release( p_input );
+ return VLC_EGENERIC;
+ }
+ }
+ return VLC_SUCCESS;
+}
+
+/**
+ * Initialize an input and initialize it to preparse the item
+ * This function is blocking. It will only accept parsing regular files.
+ *
+ * \param p_parent a vlc_object_t
+ * \param p_item an input item
+ * \return VLC_SUCCESS or an error
+ */
+int input_Preparse( vlc_object_t *p_parent, input_item_t *p_item )
+{
+ input_thread_t *p_input;
+
+ /* Allocate descriptor */
+ p_input = Create( p_parent, p_item, NULL, true, NULL );
+ if( !p_input )
+ return VLC_EGENERIC;
+
+ if( !Init( p_input ) )
+ End( p_input );
+
+ vlc_object_release( p_input );
+
+ return VLC_SUCCESS;
+}
+
+/**
+ * Start a input_thread_t created by input_Create.
+ *
+ * You must not start an already running input_thread_t.
+ *
+ * \param the input thread to start
+ */
+int input_Start( input_thread_t *p_input )
+{
+ /* Create thread and wait for its readiness. */
+ if( vlc_thread_create( p_input, "input", Run,
+ VLC_THREAD_PRIORITY_INPUT ) )
+ {
+ input_ChangeState( p_input, ERROR_S );
+ msg_Err( p_input, "cannot create input thread" );
+ return VLC_EGENERIC;
+ }
+ return VLC_SUCCESS;
+}
+
+/**
+ * Request a running input thread to stop and die
+ *
+ * b_abort must be true when a user stop is requested and not because you have
+ * detected an error or an eof. It will be used to properly send the
+ * INPUT_EVENT_ABORT event.
+ *
+ * \param p_input the input thread to stop
+ * \param b_abort true if the input has been aborted by a user request
+ */
+void input_Stop( input_thread_t *p_input, bool b_abort )
+{
+ /* Set die for input and ALL of this childrens (even (grand-)grand-childrens)
+ * It is needed here even if it is done in INPUT_CONTROL_SET_DIE handler to
+ * unlock the control loop */
+ ObjectKillChildrens( p_input, VLC_OBJECT(p_input) );
+
+ vlc_mutex_lock( &p_input->p->lock_control );
+ p_input->p->b_abort |= b_abort;
+ vlc_mutex_unlock( &p_input->p->lock_control );
+
+ input_ControlPush( p_input, INPUT_CONTROL_SET_DIE, NULL );
+}
+
+input_resource_t *input_DetachResource( input_thread_t *p_input )
+{
+ assert( p_input->b_dead );
+
+ input_resource_SetInput( p_input->p->p_resource, NULL );
+
+ input_resource_t *p_resource = input_resource_Detach( p_input->p->p_resource );
+ p_input->p->p_sout = NULL;
+
+ return p_resource;
+}
+
+/**
+ * Get the item from an input thread
+ * FIXME it does not increase ref count of the item.
+ * if it is used after p_input is destroyed nothing prevent it from
+ * being freed.
+ */
+input_item_t *input_GetItem( input_thread_t *p_input )
+{
+ assert( p_input && p_input->p );
+ return p_input->p->p_item;
+}
+
+/*****************************************************************************
+ * ObjectKillChildrens
+ *****************************************************************************/
+static void ObjectKillChildrens( input_thread_t *p_input, vlc_object_t *p_obj )
+{
+ vlc_list_t *p_list;
+ int i;
+
+ /* FIXME ObjectKillChildrens seems a very bad idea in fact */
+ i = vlc_internals( p_obj )->i_object_type;
+ if( i == VLC_OBJECT_VOUT ||i == VLC_OBJECT_AOUT ||
+ p_obj == VLC_OBJECT(p_input->p->p_sout) ||
+ i == VLC_OBJECT_DECODER || i == VLC_OBJECT_PACKETIZER )
+ return;
+
+ vlc_object_kill( p_obj );
+
+ p_list = vlc_list_children( p_obj );
+ for( i = 0; i < p_list->i_count; i++ )
+ ObjectKillChildrens( p_input, p_list->p_values[i].p_object );
+ vlc_list_release( p_list );
+}
+
/*****************************************************************************
* This function creates a new input, and returns a pointer
* to its description. On error, it returns NULL.
free( p_input->p );
}
-/**
- * Initialize an input thread and run it. You will need to monitor the
- * thread to clean up after it is done
- *
- * \param p_parent a vlc_object
- * \param p_item an input item
- * \return a pointer to the spawned input thread
- */
-input_thread_t *__input_CreateThread( vlc_object_t *p_parent,
- input_item_t *p_item )
-{
- return __input_CreateThreadExtended( p_parent, p_item, NULL, NULL );
-}
-
-/* */
-input_thread_t *__input_CreateThreadExtended( vlc_object_t *p_parent,
- input_item_t *p_item,
- const char *psz_log, input_resource_t *p_resource )
-{
- input_thread_t *p_input;
-
- p_input = Create( p_parent, p_item, psz_log, false, p_resource );
- if( !p_input )
- return NULL;
-
- /* Create thread and wait for its readiness. */
- if( vlc_thread_create( p_input, "input", Run,
- VLC_THREAD_PRIORITY_INPUT ) )
- {
- input_ChangeState( p_input, ERROR_S );
- msg_Err( p_input, "cannot create input thread" );
- vlc_object_detach( p_input );
- vlc_object_release( p_input );
- return NULL;
- }
-
- return p_input;
-}
-
-/**
- * Initialize an input thread and run it. This thread will clean after itself,
- * you can forget about it. It can work either in blocking or non-blocking mode
- *
- * \param p_parent a vlc_object
- * \param p_item an input item
- * \param b_block should we block until read is finished ?
- * \return an error code, VLC_SUCCESS on success
- */
-int __input_Read( vlc_object_t *p_parent, input_item_t *p_item,
- bool b_block )
-{
- input_thread_t *p_input;
-
- p_input = Create( p_parent, p_item, NULL, false, NULL );
- if( !p_input )
- return VLC_EGENERIC;
-
- if( b_block )
- {
- RunAndDestroy( VLC_OBJECT(p_input) );
- return VLC_SUCCESS;
- }
- else
- {
- if( vlc_thread_create( p_input, "input", RunAndDestroy,
- VLC_THREAD_PRIORITY_INPUT ) )
- {
- input_ChangeState( p_input, ERROR_S );
- msg_Err( p_input, "cannot create input thread" );
- vlc_object_release( p_input );
- return VLC_EGENERIC;
- }
- }
- return VLC_SUCCESS;
-}
-
-/**
- * Initialize an input and initialize it to preparse the item
- * This function is blocking. It will only accept parsing regular files.
- *
- * \param p_parent a vlc_object_t
- * \param p_item an input item
- * \return VLC_SUCCESS or an error
- */
-int input_Preparse( vlc_object_t *p_parent, input_item_t *p_item )
-{
- input_thread_t *p_input;
-
- /* Allocate descriptor */
- p_input = Create( p_parent, p_item, NULL, true, NULL );
- if( !p_input )
- return VLC_EGENERIC;
-
- if( !Init( p_input ) )
- End( p_input );
-
- vlc_object_detach( p_input );
- vlc_object_release( p_input );
-
- return VLC_SUCCESS;
-}
-
-/**
- * Request a running input thread to stop and die
- *
- * \param the input thread to stop
- */
-void input_StopThread( input_thread_t *p_input, bool b_abort )
-{
- /* Set die for input and ALL of this childrens (even (grand-)grand-childrens)
- * It is needed here even if it is done in INPUT_CONTROL_SET_DIE handler to
- * unlock the control loop */
- ObjectKillChildrens( p_input, VLC_OBJECT(p_input) );
-
- vlc_mutex_lock( &p_input->p->lock_control );
- p_input->p->b_abort |= b_abort;
- vlc_mutex_unlock( &p_input->p->lock_control );
-
- input_ControlPush( p_input, INPUT_CONTROL_SET_DIE, NULL );
-}
-
-input_resource_t *input_DetachResource( input_thread_t *p_input )
-{
- assert( p_input->b_dead );
-
- input_resource_SetInput( p_input->p->p_resource, NULL );
-
- input_resource_t *p_resource = input_resource_Detach( p_input->p->p_resource );
- p_input->p->p_sout = NULL;
-
- return p_resource;
-}
-
-/**
- * Get the item from an input thread
- * FIXME it does not increase ref count of the item.
- * if it is used after p_input is destroyed nothing prevent it from
- * being freed.
- */
-input_item_t *input_GetItem( input_thread_t *p_input )
-{
- assert( p_input && p_input->p );
- return p_input->p->p_item;
-}
-
-/*****************************************************************************
- * ObjectKillChildrens
- *****************************************************************************/
-static void ObjectKillChildrens( input_thread_t *p_input, vlc_object_t *p_obj )
-{
- vlc_list_t *p_list;
- int i;
-
- /* FIXME ObjectKillChildrens seems a very bad idea in fact */
- i = vlc_internals( p_obj )->i_object_type;
- if( i == VLC_OBJECT_VOUT ||i == VLC_OBJECT_AOUT ||
- p_obj == VLC_OBJECT(p_input->p->p_sout) ||
- i == VLC_OBJECT_DECODER || i == VLC_OBJECT_PACKETIZER )
- return;
-
- vlc_object_kill( p_obj );
-
- p_list = vlc_list_children( p_obj );
- for( i = 0; i < p_list->i_count; i++ )
- ObjectKillChildrens( p_input, p_list->p_values[i].p_object );
- vlc_list_release( p_list );
-}
-
/*****************************************************************************
* Run: main thread loop
* This is the "normal" thread that spawns the input processing chain,