[vlc-devel] [PATCH 1/9] input: change input_Read() behavior

Thomas Guillem thomas at gllm.fr
Wed Jun 1 16:48:41 CEST 2016



On Wed, Jun 1, 2016, at 16:19, Rémi Denis-Courmont wrote:
> Le 2016-06-01 13:24, Thomas Guillem a écrit :
> > Users will have more control when they need to read an input 
> > synchronously.
> > They'll be able to interrupt it from an other thread for example. 
> > This
> > function can now be used to preparse an item if the input_thread_t
> > was created with input_CreatePreparser().
> 
> > ---
> >  include/vlc_input.h                    |  3 +-
> >  lib/media_list.c                       |  9 ++++-
> >  modules/services_discovery/mediadirs.c |  7 +++-
> >  src/input/input.c                      | 72
> > ++++++++++++++++++++--------------
> >  src/playlist/loadsave.c                | 15 ++++++-
> >  5 files changed, 70 insertions(+), 36 deletions(-)
> >
> > diff --git a/include/vlc_input.h b/include/vlc_input.h
> > index 7633e9d..f72f8d2 100644
> > --- a/include/vlc_input.h
> > +++ b/include/vlc_input.h
> > @@ -509,8 +509,7 @@ VLC_API int input_Start( input_thread_t * );
> >
> >  VLC_API void input_Stop( input_thread_t * );
> >
> > -VLC_API int input_Read( vlc_object_t *, input_item_t * );
> > -#define input_Read(a,b) input_Read(VLC_OBJECT(a),b)
> > +VLC_API int input_Read( input_thread_t *, bool );
> 
> I don't get why the flag is needed.

For the case where input_Read is called from a thread that handle its
own interrupt context.
I'm not sure about this flag either. There is 3 solutions:
 - Don't care about the current thread interrupt ctx
 - Restore the old thread interrupt ctx when input_Read() is done. Is if
 safe ?
 - Don't handle interrupt ctx in input_Read() and let the caller play
 with it.

> 
> >
> >  VLC_API int input_vaControl( input_thread_t *, int i_query, va_list  
> > );
> >
> > diff --git a/lib/media_list.c b/lib/media_list.c
> > index 82fee60..7d8737c 100644
> > --- a/lib/media_list.c
> > +++ b/lib/media_list.c
> > @@ -267,7 +267,14 @@ libvlc_media_list_add_file_content(
> > libvlc_media_list_t * p_mlist,
> >          return -1;
> >      }
> >
> > -    input_Read( p_mlist->p_libvlc_instance->p_libvlc_int, 
> > p_input_item );
> > +    input_thread_t *p_input =
> > +        input_Create( p_mlist->p_libvlc_instance->p_libvlc_int,
> > p_input_item,
> > +                      NULL, NULL );
> > +    if( p_input != NULL )
> > +    {
> > +        input_Read( p_input, false );
> > +        input_Close( p_input );
> > +    }
> >      return 0;
> >  }
> >
> > diff --git a/modules/services_discovery/mediadirs.c
> > b/modules/services_discovery/mediadirs.c
> > index 0d1c262..957daa5 100644
> > --- a/modules/services_discovery/mediadirs.c
> > +++ b/modules/services_discovery/mediadirs.c
> > @@ -205,7 +205,12 @@ static void *Run( void *data )
> >          vlc_event_attach( p_em, vlc_InputItemSubItemAdded,
> >                            input_item_subitem_added, p_sd );
> >
> > -        input_Read( p_sd, p_root );
> > +        input_thread_t *p_input = input_Create( p_sd, p_root, NULL, 
> > NULL );
> > +        if( p_input != NULL )
> > +        {
> > +            input_Read( p_input, false );
> > +            input_Close( p_input );
> > +        }
> >
> >          vlc_event_detach( p_em, vlc_InputItemSubItemAdded,
> >                            input_item_subitem_added, p_sd );
> > diff --git a/src/input/input.c b/src/input/input.c
> > index 5307203..effca97 100644
> > --- a/src/input/input.c
> > +++ b/src/input/input.c
> > @@ -55,8 +55,8 @@
> >
> > 
> > /*****************************************************************************
> >   * Local prototypes
> >
> > 
> > *****************************************************************************/
> > -static  void *Run( void * );
> > -static  void *Preparse( void * );
> > +static  void Run( input_thread_t * );
> > +static  void Preparse( input_thread_t * );
> >
> >  static input_thread_t * Create  ( vlc_object_t *, input_item_t *,
> >                                    const char *, bool, 
> > input_resource_t * );
> > @@ -126,27 +126,29 @@ input_thread_t *input_Create( vlc_object_t 
> > *p_parent,
> >      return Create( p_parent, p_item, psz_log, false, p_resource );
> >  }
> >
> > -#undef input_Read
> >  /**
> > - * Initialize an input thread and run it until it stops by itself.
> > + * Read a input_thread_t created by input_Create() or
> > input_CreatePreparser().
> >   *
> > - * \param p_parent a vlc_object
> > - * \param p_item an input item
> > + * The read is executed in the current thread and is blockling. This
> > function
> > + * can be interrupted with input_Stop()
> > + *
> > + * \param the input thread to read
> > + * \param true if the interrupt context is handled by the 
> > input_thead_t
> >   * \return an error code, VLC_SUCCESS on success
> >   */
> > -int input_Read( vlc_object_t *p_parent, input_item_t *p_item )
> > +int input_Read( input_thread_t *p_input, bool b_interrupt )
> >  {
> > -    input_thread_t *p_input = Create( p_parent, p_item, NULL, false, 
> > NULL );
> > -    if( !p_input )
> > -        return VLC_EGENERIC;
> > +    if( b_interrupt )
> > +        vlc_interrupt_set(&p_input->p->interrupt);
> >
> > -    if( !Init( p_input ) )
> > -    {
> > -        MainLoop( p_input, false );
> > -        End( p_input );
> > -    }
> > +    if( p_input->b_preparsing )
> > +        Preparse( p_input );
> > +    else
> > +        Run( p_input );
> > +
> > +    if( b_interrupt )
> > +        vlc_interrupt_set( NULL );
> >
> > -    vlc_object_release( p_input );
> >      return VLC_SUCCESS;
> >  }
> >
> > @@ -156,6 +158,26 @@ input_thread_t *input_CreatePreparser(
> > vlc_object_t *parent,
> >      return Create( parent, item, NULL, true, NULL );
> >  }
> >
> > +static void *ThreadRun( void *obj )
> > +{
> > +    input_thread_t *p_input = (input_thread_t *)obj;
> > +
> > +    vlc_interrupt_set(&p_input->p->interrupt);
> > +
> > +    Run( p_input );
> > +    return NULL;
> > +}
> > +
> > +static void *ThreadPreparse( void *obj )
> > +{
> > +    input_thread_t *p_input = (input_thread_t *)obj;
> > +
> > +    vlc_interrupt_set(&p_input->p->interrupt);
> > +
> > +    Preparse( p_input );
> > +    return NULL;
> > +}
> > +
> >  /**
> >   * Start a input_thread_t created by input_Create.
> >   *
> > @@ -165,10 +187,10 @@ input_thread_t *input_CreatePreparser(
> > vlc_object_t *parent,
> >   */
> >  int input_Start( input_thread_t *p_input )
> >  {
> > -    void *(*func)(void *) = Run;
> > +    void *(*func)(void *) = ThreadRun;
> >
> >      if( p_input->b_preparsing )
> > -        func = Preparse;
> > +        func = ThreadPreparse;
> >
> >      assert( !p_input->p->is_running );
> >      /* Create thread and wait for its readiness. */
> > @@ -471,12 +493,8 @@ static input_thread_t *Create( vlc_object_t
> > *p_parent, input_item_t *p_item,
> >   * This is the "normal" thread that spawns the input processing 
> > chain,
> >   * reads the stream, cleans up and waits
> >
> > 
> > *****************************************************************************/
> > -static void *Run( void *obj )
> > +static void Run( input_thread_t *p_input )
> >  {
> > -    input_thread_t *p_input = (input_thread_t *)obj;
> > -
> > -    vlc_interrupt_set(&p_input->p->interrupt);
> > -
> >      if( !Init( p_input ) )
> >      {
> >          if( p_input->p->b_can_pace_control &&
> > p_input->p->b_out_pace_control )
> > @@ -493,15 +511,10 @@ static void *Run( void *obj )
> >      }
> >
> >      input_SendEventDead( p_input );
> > -    return NULL;
> >  }
> >
> > -static void *Preparse( void *obj )
> > +static void Preparse( input_thread_t *p_input )
> >  {
> > -    input_thread_t *p_input = (input_thread_t *)obj;
> > -
> > -    vlc_interrupt_set(&p_input->p->interrupt);
> > -
> >      if( !Init( p_input ) )
> >      {   /* if the demux is a playlist, call Mainloop that will call
> >           * demux_Demux in order to fetch sub items */
> > @@ -518,7 +531,6 @@ static void *Preparse( void *obj )
> >      }
> >
> >      input_SendEventDead( p_input );
> > -    return NULL;
> >  }
> >
> >  bool input_Stopped( input_thread_t *input )
> > diff --git a/src/playlist/loadsave.c b/src/playlist/loadsave.c
> > index adbc92d..e5754a3 100644
> > --- a/src/playlist/loadsave.c
> > +++ b/src/playlist/loadsave.c
> > @@ -88,6 +88,17 @@ out:
> >     return ret;
> >  }
> >
> > +static int item_Read( vlc_object_t *p_parent, input_item_t *p_item )
> > +{
> > +    input_thread_t *p_input = input_Create( p_parent, p_item, NULL, 
> > NULL );
> > +    if( p_input == NULL )
> > +        return VLC_EGENERIC;
> > +
> > +    input_Read( p_input, false );
> > +    input_Close( p_input );
> > +    return VLC_SUCCESS;
> > +}
> > +
> >  int playlist_Import( playlist_t *p_playlist, const char *psz_file )
> >  {
> >      input_item_t *p_input;
> > @@ -105,7 +116,7 @@ int playlist_Import( playlist_t *p_playlist,
> > const char *psz_file )
> >      vlc_object_t *dummy = vlc_object_create( p_playlist, sizeof 
> > (*dummy) );
> >      var_Create( dummy, "meta-file", VLC_VAR_VOID );
> >
> > -    int ret = input_Read( dummy, p_input );
> > +    int ret = item_Read( dummy, p_input );
> >
> >      vlc_object_release( dummy );
> >      return ret;
> > @@ -175,7 +186,7 @@ int playlist_MLLoad( playlist_t *p_playlist )
> >
> >      vlc_object_t *dummy = vlc_object_create( p_playlist, sizeof 
> > (*dummy) );
> >      var_Create( dummy, "meta-file", VLC_VAR_VOID );
> > -    input_Read( dummy, p_input );
> > +    item_Read( dummy, p_input );
> >      vlc_object_release( dummy );
> >
> >      vlc_event_detach( &p_input->event_manager,
> > vlc_InputItemSubItemTreeAdded,
> 
> -- 
> Rémi Denis-Courmont
> http://www.remlab.net/
> _______________________________________________
> 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