/*
\TODO: Debug messages: "__FILE__, __LINE__" ok ???, Wrn/Err ???
\TODO: Change names to VLC standard ???
+ \TODO: Rewrite this using the new service discovery API (see sap.c, shout.c).
*/
-#include <stdlib.h>
#include <vector>
#include <string>
#include <upnp/upnptools.h>
#undef PACKAGE_NAME
-#include <vlc/vlc.h>
-#include <vlc/intf.h>
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
-#include "vlc_strings.h"
+#include <vlc_common.h>
+#include <vlc_plugin.h>
+#include <vlc_playlist.h>
// VLC handle
struct services_discovery_sys_t
{
- playlist_item_t *p_node_cat;
- playlist_item_t *p_node;
playlist_t *p_playlist;
+ playlist_item_t *p_node_cat;
+ playlist_item_t *p_node_one;
};
Lockable( Cookie* c )
{
- vlc_mutex_init( c->serviceDiscovery, &_mutex );
+ vlc_mutex_init( &_mutex );
}
~Lockable()
static int Open( vlc_object_t* );
static void Close( vlc_object_t* );
static void Run( services_discovery_t *p_sd );
+static playlist_t *pl_Get( services_discovery_t *p_sd )
+{
+ return p_sd->p_sys->p_playlist;
+}
// Module descriptor
vlc_module_begin();
set_shortname( "UPnP" );
-set_description( _( "Universal Plug'n'Play discovery ( Intel SDK )" ) );
+set_description( N_( "Universal Plug'n'Play discovery ( Intel SDK )" ) );
set_category( CAT_PLAYLIST );
set_subcategory( SUBCAT_PLAYLIST_SD );
set_capability( "services_discovery", 0 );
p_sd->pf_run = Run;
p_sd->p_sys = p_sys;
+ p_sys->p_playlist = pl_Yield( p_sd );
/* Create our playlist node */
- p_sys->p_playlist = ( playlist_t * )vlc_object_find( p_sd,
- VLC_OBJECT_PLAYLIST,
- FIND_ANYWHERE );
- if( !p_sys->p_playlist )
- {
- msg_Warn( p_sd, "unable to find playlist, cancelling UPnP listening" );
- return VLC_EGENERIC;
- }
-
- playlist_NodesPairCreate( p_sys->p_playlist, _("Devices"),
- &p_sys->p_node_cat, &p_sys->p_node,
- VLC_TRUE );
+ vlc_object_lock( p_sys->p_playlist );
+ playlist_NodesPairCreate( pl_Get( p_sd ), _("Devices"),
+ &p_sys->p_node_cat, &p_sys->p_node_one,
+ true );
+ vlc_object_unlock( p_sys->p_playlist );
return VLC_SUCCESS;
}
services_discovery_t *p_sd = ( services_discovery_t* )p_this;
services_discovery_sys_t *p_sys = p_sd->p_sys;
- if( p_sys->p_playlist )
- {
- playlist_NodeDelete( p_sys->p_playlist, p_sys->p_node, VLC_TRUE,
- VLC_TRUE );
- playlist_NodeDelete( p_sys->p_playlist, p_sys->p_node_cat, VLC_TRUE,
- VLC_TRUE );
- vlc_object_release( p_sys->p_playlist );
- }
-
+ playlist_NodeDelete( pl_Get( p_sd ), p_sys->p_node_one, true,
+ true );
+ playlist_NodeDelete( pl_Get( p_sd ), p_sys->p_node_cat, true,
+ true );
+ pl_Release( p_sd );
free( p_sys );
}
res = UpnpInit( 0, 0 );
if( res != UPNP_E_SUCCESS )
{
- msg_Err( p_sd, "%s", UpnpGetErrorMessage( res ) );
- return;
+ msg_Err( p_sd, "%s", UpnpGetErrorMessage( res ) );
+ return;
}
Cookie cookie;
res = UpnpRegisterClient( Callback, &cookie, &cookie.clientHandle );
if( res != UPNP_E_SUCCESS )
{
- msg_Err( p_sd, "%s", UpnpGetErrorMessage( res ) );
- goto shutDown;
+ msg_Err( p_sd, "%s", UpnpGetErrorMessage( res ) );
+ goto shutDown;
}
res = UpnpSearchAsync( cookie.clientHandle, 5, MEDIA_SERVER_DEVICE_TYPE, &cookie );
if( res != UPNP_E_SUCCESS )
{
- msg_Err( p_sd, "%s", UpnpGetErrorMessage( res ) );
- goto shutDown;
+ msg_Err( p_sd, "%s", UpnpGetErrorMessage( res ) );
+ goto shutDown;
}
msg_Dbg( p_sd, "UPnP discovery started" );
- while( !p_sd->b_die )
+ while( vlc_object_alive (p_sd) )
{
- msleep( 500 );
+ msleep( 500 );
}
msg_Dbg( p_sd, "UPnP discovery stopped" );
const char* resultString = ixmlNode_getNodeValue( textNode );
char* resultXML = strdup( resultString );
-
- resolve_xml_special_chars( resultXML );
IXML_Document* browseDoc = ixmlParseBuffer( resultXML );
case UPNP_EVENT_SUBSCRIBE_COMPLETE:
msg_Warn( cookie->serviceDiscovery, "subscription complete" );
break;
-
+
case UPNP_DISCOVERY_SEARCH_TIMEOUT:
msg_Warn( cookie->serviceDiscovery, "search timeout" );
break;
-
+
default:
msg_Dbg( cookie->serviceDiscovery, "%s:%d: DEBUG: UNHANDLED EVENT ( TYPE=%d )", __FILE__, __LINE__, eventType );
break;
{
if ( _contents )
{
- playlist_NodeDelete( _cookie->serviceDiscovery->p_sys->p_playlist,
- _playlistNode,
- true,
- true );
+ playlist_NodeDelete( pl_Get( _cookie->serviceDiscovery ) ,
+ _playlistNode, true, true );
}
delete _contents;
void MediaServer::fetchContents()
{
Container* root = new Container( 0, "0", getFriendlyName() );
+ playlist_t * p_playlist = pl_Get( _cookie->serviceDiscovery );
_fetchContents( root );
if ( _contents )
{
- vlc_mutex_lock( &_cookie->serviceDiscovery->p_sys->p_playlist->object_lock );
-
- playlist_NodeEmpty( _cookie->serviceDiscovery->p_sys->p_playlist,
- _playlistNode,
- true );
-
- vlc_mutex_unlock( &_cookie->serviceDiscovery->p_sys->p_playlist->object_lock );
-
- delete _contents;
+ PL_LOCK;
+ playlist_NodeEmpty( p_playlist, _playlistNode, true );
+ PL_UNLOCK;
+ delete _contents;
}
_contents = root;
void MediaServer::_buildPlaylist( Container* parent )
{
+ playlist_t *p_playlist = pl_Get( _cookie->serviceDiscovery );
for ( unsigned int i = 0; i < parent->getNumContainers(); i++ )
{
- Container* container = parent->getContainer( i );
- playlist_item_t* parentNode = parent->getPlaylistNode();
+ Container* container = parent->getContainer( i );
+ playlist_item_t* parentNode = parent->getPlaylistNode();
- char* title = strdup( container->getTitle() );
- playlist_item_t* node = playlist_NodeCreate( _cookie->serviceDiscovery->p_sys->p_playlist,
- title,
- parentNode );
- free( title );
+ char* title = strdup( container->getTitle() );
+ playlist_item_t* node = playlist_NodeCreate( p_playlist, title, parentNode, 0, NULL );
+ free( title );
- container->setPlaylistNode( node );
- _buildPlaylist( container );
+ container->setPlaylistNode( node );
+ _buildPlaylist( container );
}
for ( unsigned int i = 0; i < parent->getNumItems(); i++ )
{
- Item* item = parent->getItem( i );
- playlist_item_t* parentNode = parent->getPlaylistNode();
-
- playlist_item_t* node = playlist_ItemNew( _cookie->serviceDiscovery,
- item->getResource(),
- item->getTitle() );
-
- playlist_NodeAddItem( _cookie->serviceDiscovery->p_sys->p_playlist,
- node,
- parentNode, PLAYLIST_APPEND, PLAYLIST_END );
-
- item->setPlaylistNode( node );
+ Item* item = parent->getItem( i );
+ playlist_item_t* parentNode = parent->getPlaylistNode();
+
+ input_item_t* p_input = input_ItemNew( _cookie->serviceDiscovery,
+ item->getResource(),
+ item->getTitle() );
+ int i_cat;
+ /* FIXME: playlist_AddInput() can fail */
+ playlist_BothAddInput( p_playlist, p_input, parentNode,
+ PLAYLIST_APPEND, PLAYLIST_END, &i_cat, NULL,
+ pl_Unlocked );
+ vlc_gc_decref( p_input );
+ /* TODO: do this better by storing ids */
+ playlist_item_t *p_node = playlist_ItemGetById( p_playlist, i_cat, false );
+ assert( p_node );
+ item->setPlaylistNode( p_node );
}
}
_list.push_back( s );
char* name = strdup( s->getFriendlyName() );
- playlist_item_t* node = playlist_NodeCreate( _cookie->serviceDiscovery->p_sys->p_playlist,
- name,
- _cookie->serviceDiscovery->p_sys->p_node );
+ playlist_item_t* node = playlist_NodeCreate( pl_Get( _cookie->serviceDiscovery ),
+ name,
+ _cookie->serviceDiscovery->p_sys->p_node_cat, 0, NULL );
free( name );
s->setPlaylistNode( node );