[vlc-devel] [PATCH 06/11] playlist/directory: attach slaves to input items

Thomas Guillem thomas at gllm.fr
Mon Apr 4 19:15:39 CEST 2016



On Sat, Apr 2, 2016, at 11:32, Rémi Denis-Courmont wrote:
> On Friday 01 April 2016 10:31:05 Thomas Guillem wrote:
> > From: Benjamin Adolphi <b.adolphi at gmail.com>
> > 
> > ---
> >  modules/demux/playlist/directory.c | 176
> > ++++++++++++++++++++++++++++++++++++- 1 file changed, 175 insertions(+), 1
> > deletion(-)
> > 
> > diff --git a/modules/demux/playlist/directory.c
> > b/modules/demux/playlist/directory.c index b57f9db..d2c8706 100644
> > --- a/modules/demux/playlist/directory.c
> > +++ b/modules/demux/playlist/directory.c
> > @@ -28,6 +28,8 @@
> >  # include "config.h"
> >  #endif
> > 
> > +#include <ctype.h>
> > +
> >  #include <vlc_common.h>
> >  #include <vlc_demux.h>
> > 
> > @@ -44,6 +46,17 @@ struct demux_sys_t
> >  
> > ***************************************************************************
> > **/ static int Demux( demux_t *p_demux );
> > 
> > +static const char *const ppsz_sub_exts[] = { SLAVE_SPU_EXTENSIONS, NULL };
> > +static const char *const ppsz_audio_exts[] = { SLAVE_AUDIO_EXTENSIONS, NULL
> > }; +
> > +static struct {
> > +    int i_type;
> > +    const char *const *ppsz_exts;
> > +} p_slave_list[] = {
> > +    { SLAVE_TYPE_SPU, ppsz_sub_exts },
> > +    { SLAVE_TYPE_AUDIO, ppsz_audio_exts },
> > +};
> > +#define SLAVE_TYPE_COUNT (sizeof(p_slave_list) / sizeof(*p_slave_list))
> > 
> >  int Import_Dir ( vlc_object_t *p_this)
> >  {
> > @@ -105,6 +118,31 @@ static bool has_ext( const char *psz_exts, const char
> > *psz_uri ) return false;
> >  }
> > 
> > +static bool is_slave( const char *psz_name, int *p_slave_type )
> > +{
> > +    const char *psz_ext = strrchr( psz_name, '.' );
> > +    if( psz_ext == NULL )
> > +        return false;
> > +
> > +    size_t i_extlen = strlen( ++psz_ext );
> > +    if( i_extlen == 0 )
> > +        return false;
> > +
> > +    for( unsigned int i = 0; i < SLAVE_TYPE_COUNT; ++i )
> > +    {
> > +        for( const char *const *ppsz_slave_ext = p_slave_list[i].ppsz_exts;
> > +             *ppsz_slave_ext != NULL; ppsz_slave_ext++ )
> > +        {
> > +            if( !strncasecmp( psz_ext, *ppsz_slave_ext, i_extlen ) )
> > +            {
> > +                *p_slave_type = p_slave_list[i].i_type;
> > +                return true;
> > +            }
> > +        }
> > +    }
> > +    return false;
> > +}
> 
> Direct comparison works for file paths, not for URIs. Ditto in the
> existing 
> code above.

I see 2 solutions:
 - Convert psz_uri to a vlc_url_t and do our cmp operations on
 url->psz_path

 - Add a psz_filepath in input_item_t. Directory demuxers will be able
 to set a path and an uri.

Additionally, The second solution will be a proper way to handle uri
decoding when a remote access wants to open a decoded path. Indeed, This
new path could be passed to input_thread/demux/accesses. The
psz_filepath variable on accesses/demuxers should be valid for every
kind of accesses and not only the local one. 

> 
> > +
> >  static int compar_type( input_item_t *p1, input_item_t *p2 )
> >  {
> >      if( p1->i_type != p2->i_type )
> > @@ -142,12 +180,118 @@ static int compar_version( input_item_t *p1,
> > input_item_t *p2 ) return strverscmp( p1->psz_name, p2->psz_name );
> >  }
> > 
> > +static char *name_from_uri(const char *psz_uri)
> > +{
> > +    char *psz_filename = strdup( psz_uri );
> > +    if( !psz_filename )
> > +        return NULL;
> > +
> > +    char *psz_ptr = psz_filename;
> > +
> > +    /* remove folders */
> > +    char *psz_slash = strrchr( psz_ptr, '/' );
> > +    if( psz_slash )
> > +        psz_ptr = psz_slash + 1;
> > +
> > +    /* remove extension */
> > +    char *psz_dot = strrchr( psz_ptr, '.' );
> > +    if( psz_dot )
> > +        *psz_dot = '\0';
> > +
> > +    /* remove leading white spaces */
> > +    while( *psz_ptr != '\0' && *psz_ptr == ' ' )
> > +        psz_ptr++;
> > +
> > +    /* remove trailing white spaces */
> > +    int i = strlen( psz_ptr ) - 1;
> > +    while( psz_ptr[i] == ' ' && i >= 0 )
> > +        psz_ptr[i--] = '\0';
> > +
> > +    /* convert to lower case */
> > +    char *psz_p = psz_ptr;
> > +    while( *psz_p != '\0' )
> > +    {
> > +        *psz_p = tolower( *psz_p );
> > +        psz_p++;
> > +    }
> > +
> > +    psz_ptr = strdup( psz_ptr );
> > +    free( psz_filename );
> > +    return psz_ptr;
> > +}
> > +
> > +static uint8_t calculate_slave_priority(input_item_t *p_item,
> > input_item_slave *p_slave) +{
> > +    char *psz_item_name = name_from_uri( p_item->psz_uri );
> > +    char *psz_slave_name = name_from_uri( p_slave->psz_uri );
> > +
> > +    if( !psz_item_name || !psz_slave_name)
> > +    {
> > +        p_slave->i_priority = SLAVE_PRIORITY_NONE;
> > +        goto done;
> > +    }
> > +
> > +    /* check if the names match exactly */
> > +    if( !strcmp( psz_item_name, psz_slave_name ) )
> > +    {
> > +        p_slave->i_priority = SLAVE_PRIORITY_MATCH_ALL;
> > +        goto done;
> > +    }
> > +
> > +    /* check if the item name is a substring of the slave name */
> > +    const char *psz_sub = strstr( psz_slave_name, psz_item_name );
> > +
> > +    if( psz_sub )
> > +    {
> > +        /* check if the item name was found at the end of the slave name */
> > +        if( strlen( psz_sub + strlen( psz_item_name ) ) == 0 )
> > +        {
> > +            p_slave->i_priority = SLAVE_PRIORITY_MATCH_RIGHT;
> > +            goto done;
> > +        }
> > +        else
> > +        {
> > +            p_slave->i_priority = SLAVE_PRIORITY_MATCH_LEFT;
> > +            goto done;
> > +        }
> > +    }
> > +    p_slave->i_priority = SLAVE_PRIORITY_MATCH_NONE;
> > +done:
> > +    free( psz_item_name );
> > +    free( psz_slave_name );
> > +    return p_slave->i_priority;
> > +}
> > +
> > +static void attach_slaves( demux_t *p_demux, input_item_node_t *p_node,
> > +                           input_item_slave **pp_slaves, int i_slaves )
> > +{
> > +    int i_fuzzy = var_InheritInteger( p_demux, "sub-autodetect-fuzzy" );
> > +    if ( i_fuzzy == 0 )
> > +        return;
> > +    for( int i = 0; i < p_node->i_children; i++ )
> > +    {
> > +        input_item_t *p_item = p_node->pp_children[i]->p_item;
> > +        for( int j = 0; j < i_slaves; j++ )
> > +        {
> > +            input_item_slave *p_slave = pp_slaves[j];
> > +            if( p_slave != NULL
> > +             && calculate_slave_priority( p_item, p_slave ) >= i_fuzzy )
> > +            {
> > +                input_item_AddSlave( p_item, p_slave );
> > +                pp_slaves[j] = NULL;
> > +            }
> > +        }
> > +    }
> > +}
> > +
> >  static int Demux( demux_t *p_demux )
> >  {
> >      int i_ret = VLC_SUCCESS;
> >      input_item_t *p_input;
> >      input_item_node_t *p_node;
> >      input_item_t *p_item;
> > +    input_item_slave **pp_slaves;
> > +    int i_slaves;
> >      char *psz_ignored_exts;
> >      bool b_show_hiddenfiles;
> > 
> > @@ -156,11 +300,12 @@ static int Demux( demux_t *p_demux )
> >      if( p_node == NULL )
> >          return VLC_ENOMEM;
> >      p_node->b_can_loop = p_demux->p_sys->b_dir_can_loop;
> > -    input_item_Release(p_input);
> > 
> >      b_show_hiddenfiles = var_InheritBool( p_demux, "show-hiddenfiles" );
> >      psz_ignored_exts = var_InheritString( p_demux, "ignore-filetypes" );
> > 
> > +    TAB_INIT( i_slaves, pp_slaves );
> > +
> >      while( !i_ret && ( p_item = stream_ReadDir( p_demux->s ) ) )
> >      {
> >          int i_name_len = p_item->psz_name ? strlen( p_item->psz_name ) : 0;
> > @@ -170,6 +315,21 @@ static int Demux( demux_t *p_demux )
> > 
> >           || strcmp( p_item->psz_name, ".." ) == 0
> >           || ( !b_show_hiddenfiles && p_item->psz_name[0] == '.' ) )
> > 
> >              goto skip_item;
> > +
> > +        /* Find slaves */
> > +        int i_slave_type;
> > +        if( is_slave( p_item->psz_name, &i_slave_type ) )
> > +        {
> > +            input_item_slave *p_slave = input_item_slave_New(
> > p_item->psz_uri, +                                                         
> >     i_slave_type, +                                                        
> >      SLAVE_PRIORITY_NONE ); +            if( !p_slave )
> > +                i_ret = VLC_ENOMEM;
> > +            else
> > +                INSERT_ELEM( pp_slaves, i_slaves, i_slaves, p_slave );
> > +            goto skip_item;
> > +        }
> > +
> >          /* skip ignored files */
> >          if( has_ext( psz_ignored_exts, p_item->psz_name ) )
> >              goto skip_item;
> > @@ -182,13 +342,27 @@ skip_item:
> >      }
> >      free( psz_ignored_exts );
> > 
> > +    input_item_Release( p_input );
> > +
> >      if( i_ret )
> >      {
> >          msg_Warn( p_demux, "unable to read directory" );
> >          input_item_node_Delete( p_node );
> > +
> > +        for( int i = 0; i < i_slaves; i++ )
> > +            input_item_slave_Delete( pp_slaves[i] );
> > +        TAB_CLEAN( i_slaves, pp_slaves );
> >          return i_ret;
> >      }
> > 
> > +    attach_slaves( p_demux, p_node, pp_slaves, i_slaves );
> > +    for( int i = 0; i < i_slaves; i++ )
> > +    {
> > +        if( pp_slaves[i] != NULL )
> > +            input_item_slave_Delete( pp_slaves[i] );
> > +    }
> > +    TAB_CLEAN( i_slaves, pp_slaves );
> > +
> >      if( !p_demux->p_sys->b_dir_sorted )
> >      {
> >          input_item_compar_cb compar_cb = NULL;
> 
> -- 
> 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