#include "vlc_playlist.h"
#include "vlc_events.h"
#include <vlc_services_discovery.h>
+#include <vlc_probe.h>
#include "playlist_internal.h"
#include "../libvlc.h"
+typedef struct
+{
+ char *name;
+ char *longname;
+} vlc_sd_probe_t;
-/*
- * Services discovery
- * Basically you just listen to Service discovery event through the
- * sd's event manager.
- * That's how the playlist get's Service Discovery information
- */
+int vlc_sd_probe_Add (vlc_probe_t *probe, const char *name,
+ const char *longname)
+{
+ vlc_sd_probe_t names = { strdup(name), strdup(longname) };
+
+ if (unlikely (names.name == NULL || names.longname == NULL
+ || vlc_probe_add (probe, &names, sizeof (names))))
+ {
+ free (names.name);
+ free (names.longname);
+ return VLC_ENOMEM;
+ }
+ return VLC_PROBE_CONTINUE;
+}
+
+#undef vlc_sd_GetNames
/**
* Gets the list of available services discovery plugins.
*/
-char **vlc_sd_GetNames( char ***pppsz_longnames )
+char **vlc_sd_GetNames (vlc_object_t *obj, char ***pppsz_longnames)
{
- return module_GetModulesNamesForCapability( "services_discovery",
- pppsz_longnames );
+ size_t count;
+ vlc_sd_probe_t *tab = vlc_probe (obj, "services probe", &count);
+
+ if (count == 0)
+ {
+ free (tab);
+ return NULL;
+ }
+
+ char **names = malloc (sizeof(char *) * (count + 1));
+ char **longnames = malloc (sizeof(char *) * (count + 1));
+
+ if (unlikely (names == NULL || longnames == NULL))
+ abort();
+ for( size_t i = 0; i < count; i++ )
+ {
+ names[i] = tab[i].name;
+ longnames[i] = tab[i].longname;
+ }
+ free (tab);
+ names[count] = longnames[count] = NULL;
+ *pppsz_longnames = longnames;
+ return names;
}
+
+struct vlc_sd_internal_t
+{
+ /* the playlist items for category and onelevel */
+ playlist_item_t *p_cat;
+ playlist_item_t *p_one;
+ services_discovery_t *p_sd; /**< Loaded service discovery modules */
+ char *psz_name;
+};
+
+static void services_discovery_Destructor ( vlc_object_t *p_obj );
+
+/*
+ * Services discovery
+ * Basically you just listen to Service discovery event through the
+ * sd's event manager.
+ * That's how the playlist get's Service Discovery information
+ */
+
/***********************************************************************
* Create
***********************************************************************/
vlc_event_manager_register_event_type( &p_sd->event_manager,
vlc_ServicesDiscoveryEnded );
+ vlc_object_set_destructor( p_sd, services_discovery_Destructor );
vlc_object_attach( p_sd, p_super );
return p_sd;
p_sd->p_module = NULL;
}
+/***********************************************************************
+ * Destructor
+ ***********************************************************************/
+static void services_discovery_Destructor ( vlc_object_t *p_obj )
+{
+ services_discovery_t * p_sd = (services_discovery_t *)p_obj;
+ assert(!p_sd->p_module); /* Forgot to call Stop */
+ vlc_event_manager_fini( &p_sd->event_manager );
+}
+
/***********************************************************************
* GetLocalizedName
***********************************************************************/
* XXX: Why don't we have a function to ensure that in the playlist code ? */
playlist_Lock( p_parent->p_playlist );
p_pl_item = playlist_ItemFindFromInputAndRoot( p_parent->p_playlist,
- p_input->i_id, p_parent, false );
+ p_input, p_parent, false );
if( p_pl_item && p_pl_item->i_children > -1 )
playlist_NodeDelete( p_parent->p_playlist, p_pl_item, true, false );
}
/* Free in playlist_ServicesDiscoveryRemove */
- struct playlist_services_discovery_support_t * p_sds;
- p_sds = malloc( sizeof(struct playlist_services_discovery_support_t) );
+ vlc_sd_internal_t * p_sds = malloc( sizeof(*p_sds) );
if( !p_sds )
{
vlc_sd_Destroy( p_sd );
p_sds->p_sd = p_sd;
p_sds->p_one = p_one;
p_sds->p_cat = p_cat;
+ p_sds->psz_name = strdup( psz_module );
PL_LOCK;
TAB_APPEND( pl_priv(p_playlist)->i_sds, pl_priv(p_playlist)->pp_sds, p_sds );
}
int playlist_ServicesDiscoveryRemove( playlist_t * p_playlist,
- const char *psz_module )
+ const char *psz_name )
{
- struct playlist_services_discovery_support_t * p_sds = NULL;
- int i;
+ playlist_private_t *priv = pl_priv( p_playlist );
+ vlc_sd_internal_t * p_sds = NULL;
PL_LOCK;
- for( i = 0 ; i< pl_priv(p_playlist)->i_sds ; i ++ )
+ for( int i = 0; i < priv->i_sds; i++ )
{
- if( !strcmp( psz_module, module_get_object( pl_priv(p_playlist)->pp_sds[i]->p_sd->p_module ) ) )
+ if( !strcmp( psz_name, priv->pp_sds[i]->psz_name ) )
{
- p_sds = pl_priv(p_playlist)->pp_sds[i];
- REMOVE_ELEM( pl_priv(p_playlist)->pp_sds, pl_priv(p_playlist)->i_sds, i );
+ p_sds = priv->pp_sds[i];
+ REMOVE_ELEM( priv->pp_sds, priv->i_sds, i );
break;
}
}
if( !p_sds )
{
- msg_Warn( p_playlist, "module %s is not loaded", psz_module );
+ msg_Warn( p_playlist, "discovery %s is not loaded", psz_name );
return VLC_EGENERIC;
}
PL_UNLOCK;
vlc_sd_Destroy( p_sd );
+ free( p_sds->psz_name );
free( p_sds );
return VLC_SUCCESS;
}
bool playlist_IsServicesDiscoveryLoaded( playlist_t * p_playlist,
- const char *psz_module )
+ const char *psz_name )
{
- int i;
+ playlist_private_t *priv = pl_priv( p_playlist );
+ bool found = false;
PL_LOCK;
- for( i = 0 ; i< pl_priv(p_playlist)->i_sds ; i ++ )
+ for( int i = 0; i < priv->i_sds; i++ )
{
- if( !strcmp( psz_module, module_get_object( pl_priv(p_playlist)->pp_sds[i]->p_sd->p_module ) ) )
+ vlc_sd_internal_t *sd = priv->pp_sds[i];
+
+ if( sd->psz_name && !strcmp( psz_name, sd->psz_name ) )
{
- PL_UNLOCK;
- return true;
+ found = true;
+ break;
}
}
PL_UNLOCK;
- return false;
+ return found;
}
void playlist_ServicesDiscoveryKillAll( playlist_t *p_playlist )
{
- while( pl_priv(p_playlist)->i_sds > 0 )
+ playlist_private_t *priv = pl_priv( p_playlist );
+
+ while( priv->i_sds > 0 )
playlist_ServicesDiscoveryRemove( p_playlist,
- module_get_object( pl_priv(p_playlist)->pp_sds[0]->p_sd->p_module ) );
+ priv->pp_sds[0]->psz_name );
}