[vlc-devel] [PATCH 06/11] playlist/directory: attach slaves to input items
Thomas Guillem
thomas at gllm.fr
Fri Apr 1 10:31:05 CEST 2016
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;
+}
+
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;
--
2.8.0.rc3
More information about the vlc-devel
mailing list