From 8b61d4ef6120a68ea9e4dd3865d6a35d11965e2c Mon Sep 17 00:00:00 2001 From: =?utf8?q?Cl=C3=A9ment=20Stenac?= Date: Mon, 8 Nov 2004 18:19:51 +0000 Subject: [PATCH] Initial Services discovery support --- Makefile.am | 1 + configure.ac | 6 +- include/vlc_common.h | 2 + include/vlc_objects.h | 1 + include/vlc_playlist.h | 22 +++ modules/misc/Modules.am | 1 - modules/{misc => services_discovery}/hal.c | 79 +++++----- modules/{misc => services_discovery}/sap.c | 170 ++++++++++----------- src/interface/interface.c | 2 - src/libvlc.c | 4 + src/libvlc.h | 7 + src/misc/objects.c | 4 + src/playlist/playlist.c | 7 +- src/playlist/services_discovery.c | 158 +++++++++++++++++++ 14 files changed, 332 insertions(+), 132 deletions(-) rename modules/{misc => services_discovery}/hal.c (77%) rename modules/{misc => services_discovery}/sap.c (84%) create mode 100644 src/playlist/services_discovery.c diff --git a/Makefile.am b/Makefile.am index 13f1af4591..fbba9cf222 100644 --- a/Makefile.am +++ b/Makefile.am @@ -330,6 +330,7 @@ SOURCES_libvlc_common = \ src/playlist/item.c \ src/playlist/item-ext.c \ src/playlist/info.c \ + src/playlist/services_discovery.c \ src/input/access.c \ src/input/clock.c \ src/input/control.c \ diff --git a/configure.ac b/configure.ac index a917cb4a0b..39b9ca34b3 100644 --- a/configure.ac +++ b/configure.ac @@ -678,8 +678,9 @@ fi dnl Check for hal PKG_CHECK_MODULES(HAL, hal >= 0.2.97, [AC_DEFINE(HAVE_HAL, [], [Define if you have the HAL library]) - VLC_ADD_LDFLAGS([vlc],[$HAL_LIBS]) - VLC_ADD_CFLAGS([vlc],[$HAL_CFLAGS])], + VLC_ADD_PLUGINS([hal]) + VLC_ADD_LDFLAGS([vlc hal],[$HAL_LIBS]) + VLC_ADD_CFLAGS([vlc hal],[$HAL_CFLAGS])], [AC_MSG_WARN(HAL library not found)]) dnl Build the gtk_main plugins? @@ -4216,6 +4217,7 @@ AC_CONFIG_FILES([ modules/mux/Makefile modules/mux/mpeg/Makefile modules/packetizer/Makefile + modules/services_discovery/Makefile modules/stream_out/Makefile modules/stream_out/transrate/Makefile modules/video_chroma/Makefile diff --git a/include/vlc_common.h b/include/vlc_common.h index e863930c2a..c83454b12e 100644 --- a/include/vlc_common.h +++ b/include/vlc_common.h @@ -221,6 +221,8 @@ typedef struct playlist_t playlist_t; typedef struct playlist_item_t playlist_item_t; typedef struct playlist_view_t playlist_view_t; typedef struct playlist_export_t playlist_export_t; +typedef struct services_discovery_t services_discovery_t; +typedef struct services_discovery_sys_t services_discovery_sys_t; /* Modules */ typedef struct module_bank_t module_bank_t; diff --git a/include/vlc_objects.h b/include/vlc_objects.h index 6c040393c2..b3965902ff 100644 --- a/include/vlc_objects.h +++ b/include/vlc_objects.h @@ -57,6 +57,7 @@ #define VLC_OBJECT_VOD (-23) #define VLC_OBJECT_SPU (-24) #define VLC_OBJECT_TLS (-25) +#define VLC_OBJECT_SD (-26) #define VLC_OBJECT_GENERIC (-666) diff --git a/include/vlc_playlist.h b/include/vlc_playlist.h index 8c04ce72e5..ca28271657 100644 --- a/include/vlc_playlist.h +++ b/include/vlc_playlist.h @@ -112,6 +112,19 @@ struct playlist_view_t */ typedef enum { PLAYLIST_STOPPED,PLAYLIST_RUNNING,PLAYLIST_PAUSED } playlist_status_t; + +struct services_discovery_t +{ + VLC_COMMON_MEMBERS + const char *psz_module; + + module_t *p_module; + + services_discovery_sys_t *p_sys; + void (*pf_run) ( services_discovery_t *); +}; + + /** * Structure containing information about the playlist */ @@ -146,6 +159,9 @@ struct playlist_t playlist_item_t * p_general; /**< Keep a pointer on the "general" category */ + services_discovery_t **pp_sds; + int i_sds; + vlc_bool_t b_go_next; /*< Go further than the parent node ? */ struct { @@ -210,6 +226,12 @@ VLC_EXPORT( int, playlist_Control, ( playlist_t *, int, ... ) ); VLC_EXPORT( int, playlist_Clear, ( playlist_t * ) ); +/* Services discovery */ + +VLC_EXPORT( int, playlist_ServicesDiscoveryAdd, (playlist_t *, const char *)); +VLC_EXPORT( void, playlist_ServicesDiscoveryRemove, (playlist_t *, const char *)); +VLC_EXPORT( int, playlist_AddSDModules, (playlist_t *, char *)); + /* Item management functions (act on items) */ #define playlist_AddItem(p,pi,i1,i2) playlist_ItemAdd(p,pi,i1,i2) #define playlist_ItemNew( a , b, c ) __playlist_ItemNew(VLC_OBJECT(a) , b , c ) diff --git a/modules/misc/Modules.am b/modules/misc/Modules.am index 5f449e7963..f61139b7b8 100644 --- a/modules/misc/Modules.am +++ b/modules/misc/Modules.am @@ -2,7 +2,6 @@ SOURCES_gtk_main = gtk_main.c SOURCES_gnome_main = gtk_main.c SOURCES_gtk2_main = gtk_main.c SOURCES_gnome2_main = gtk_main.c -SOURCES_sap = sap.c SOURCES_screensaver = screensaver.c SOURCES_qte_main = qte_main.cpp SOURCES_freetype = freetype.c diff --git a/modules/misc/hal.c b/modules/services_discovery/hal.c similarity index 77% rename from modules/misc/hal.c rename to modules/services_discovery/hal.c index 3744d55042..9ee9e9aa65 100644 --- a/modules/misc/hal.c +++ b/modules/services_discovery/hal.c @@ -62,7 +62,7 @@ vlc_module_begin(); set_description( _("HAL device detection") ); - set_capability( "interface", 0 ); + set_capability( "services_discovery", 0 ); set_callbacks( Open, Close ); vlc_module_end(); @@ -72,10 +72,10 @@ vlc_module_end(); * Local structures *****************************************************************************/ -struct intf_sys_t +struct services_discovery_sys_t { LibHalContext *p_ctx; - + /* playlist node */ playlist_item_t *p_node; @@ -86,42 +86,42 @@ struct intf_sys_t *****************************************************************************/ /* Main functions */ - static void Run ( intf_thread_t *p_intf ); + static void Run ( services_discovery_t *p_intf ); /***************************************************************************** * Open: initialize and create stuff *****************************************************************************/ static int Open( vlc_object_t *p_this ) { - intf_thread_t *p_intf = ( intf_thread_t* )p_this; - intf_sys_t *p_sys = malloc( sizeof( intf_sys_t ) ); + services_discovery_t *p_sd = ( services_discovery_t* )p_this; + services_discovery_sys_t *p_sys = malloc( + sizeof( services_discovery_sys_t ) ); playlist_t *p_playlist; playlist_view_t *p_view; - p_intf->pf_run = Run; - p_intf->p_sys = p_sys; + p_sd->pf_run = Run; + p_sd->p_sys = p_sys; if( !( p_sys->p_ctx = hal_initialize( NULL, FALSE ) ) ) { free( p_sys ); - msg_Err( p_intf, "hal not available" ); + msg_Err( p_sd, "hal not available" ); return VLC_EGENERIC; } /* Create our playlist node */ - p_playlist = (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, + p_playlist = (playlist_t *)vlc_object_find( p_sd, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE ); if( !p_playlist ) { - msg_Warn( p_intf, "unable to find playlist, cancelling HAL listening"); + msg_Warn( p_sd, "unable to find playlist, cancelling HAL listening"); return VLC_EGENERIC; } p_view = playlist_ViewFind( p_playlist, VIEW_CATEGORY ); p_sys->p_node = playlist_NodeCreate( p_playlist, VIEW_CATEGORY, _("Devices"), p_view->p_root ); - vlc_object_release( p_playlist ); return VLC_SUCCESS; @@ -132,27 +132,27 @@ static int Open( vlc_object_t *p_this ) *****************************************************************************/ static void Close( vlc_object_t *p_this ) { - intf_thread_t *p_intf = ( intf_thread_t* )p_this; - intf_sys_t *p_sys = p_intf->p_sys; - + services_discovery_t *p_sd = ( services_discovery_t* )p_sd; + services_discovery_sys_t *p_sys = malloc( + sizeof( services_discovery_sys_t ) ); free( p_sys ); } -static void AddDvd( intf_thread_t *p_intf, char *psz_device ) +static void AddDvd( services_discovery_t *p_sd, char *psz_device ) { char *psz_name; char *psz_uri; char *psz_blockdevice; - intf_sys_t *p_sys = p_intf->p_sys; + services_discovery_sys_t *p_sys = p_sd->p_sys; playlist_t *p_playlist; playlist_item_t *p_item; - psz_name = hal_device_get_property_string( p_intf->p_sys->p_ctx, + psz_name = hal_device_get_property_string( p_sd->p_sys->p_ctx, psz_device, "volume.label" ); - psz_blockdevice = hal_device_get_property_string( p_intf->p_sys->p_ctx, + psz_blockdevice = hal_device_get_property_string( p_sd->p_sys->p_ctx, psz_device, "block.device" ); asprintf( &psz_uri, "dvd://%s", psz_blockdevice ); /* Create the playlist item here */ - p_item = playlist_ItemNew( p_intf, psz_uri, + p_item = playlist_ItemNew( p_sd, psz_uri, psz_name ); free( psz_uri ); hal_free_string( psz_device ); @@ -161,11 +161,11 @@ static void AddDvd( intf_thread_t *p_intf, char *psz_device ) return; } p_item->i_flags &= ~PLAYLIST_SKIP_FLAG; - p_playlist = (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, + p_playlist = (playlist_t *)vlc_object_find( p_sd, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE ); if( !p_playlist ) { - msg_Err( p_intf, "playlist not found" ); + msg_Err( p_sd, "playlist not found" ); return; } @@ -173,22 +173,21 @@ static void AddDvd( intf_thread_t *p_intf, char *psz_device ) PLAYLIST_APPEND, PLAYLIST_END ); vlc_object_release( p_playlist ); - - } -static void AddCdda( intf_thread_t *p_intf, char *psz_device ) + +static void AddCdda( services_discovery_t *p_sd, char *psz_device ) { char *psz_name = "Audio CD"; char *psz_uri; char *psz_blockdevice; - intf_sys_t *p_sys = p_intf->p_sys; + services_discovery_sys_t *p_sys = p_sd->p_sys; playlist_t *p_playlist; playlist_item_t *p_item; - psz_blockdevice = hal_device_get_property_string( p_intf->p_sys->p_ctx, + psz_blockdevice = hal_device_get_property_string( p_sd->p_sys->p_ctx, psz_device, "block.device" ); asprintf( &psz_uri, "cdda://%s", psz_blockdevice ); /* Create the playlist item here */ - p_item = playlist_ItemNew( p_intf, psz_uri, + p_item = playlist_ItemNew( p_sd, psz_uri, psz_name ); free( psz_uri ); hal_free_string( psz_device ); @@ -197,11 +196,11 @@ static void AddCdda( intf_thread_t *p_intf, char *psz_device ) return; } p_item->i_flags &= ~PLAYLIST_SKIP_FLAG; - p_playlist = (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, + p_playlist = (playlist_t *)vlc_object_find( p_sd, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE ); if( !p_playlist ) { - msg_Err( p_intf, "playlist not found" ); + msg_Err( p_sd, "playlist not found" ); return; } @@ -210,13 +209,12 @@ static void AddCdda( intf_thread_t *p_intf, char *psz_device ) vlc_object_release( p_playlist ); - } -static void ParseDevice( intf_thread_t *p_intf, char *psz_device ) +static void ParseDevice( services_discovery_t *p_sd, char *psz_device ) { char *psz_disc_type; - intf_sys_t *p_sys = p_intf->p_sys; + services_discovery_sys_t *p_sys = p_sd->p_sys; if( hal_device_property_exists( p_sys->p_ctx, psz_device, "volume.disc.type" ) ) { @@ -225,40 +223,39 @@ static void ParseDevice( intf_thread_t *p_intf, char *psz_device ) "volume.disc.type" ); if( !strcmp( psz_disc_type, "dvd_rom" ) ) { - AddDvd( p_intf, psz_device ); + AddDvd( p_sd, psz_device ); } else if( !strcmp( psz_disc_type, "cd_rom" ) ) { if( hal_device_get_property_bool( p_sys->p_ctx, psz_device, "volume.disc.has_audio" ) ) { - AddCdda( p_intf, psz_device ); + AddCdda( p_sd, psz_device ); } } hal_free_string( psz_disc_type ); } - } /***************************************************************************** * Run: main HAL thread *****************************************************************************/ -static void Run( intf_thread_t *p_intf ) +static void Run( services_discovery_t *p_sd ) { int i, i_devices; char **devices; - intf_sys_t *p_sys = p_intf->p_sys; + services_discovery_sys_t *p_sys = p_sd->p_sys; /* parse existing devices first */ if( ( devices = hal_get_all_devices( p_sys->p_ctx, &i_devices ) ) ) { for( i = 0; i < i_devices; i++ ) { - ParseDevice( p_intf, devices[ i ] ); + ParseDevice( p_sd, devices[ i ] ); } } - while( !p_intf->b_die ) + while( !p_sd->b_die ) { - msleep( 1000 ); + msleep( 100000 ); } } diff --git a/modules/misc/sap.c b/modules/services_discovery/sap.c similarity index 84% rename from modules/misc/sap.c rename to modules/services_discovery/sap.c index 76f8f46c7b..efe33fcab4 100644 --- a/modules/misc/sap.c +++ b/modules/services_discovery/sap.c @@ -106,7 +106,7 @@ vlc_module_begin(); add_bool( "sap-parse", 1 , NULL, SAP_PARSE_TEXT,SAP_PARSE_LONGTEXT, VLC_TRUE ); - set_capability( "interface", 0 ); + set_capability( "services_discovery", 0 ); set_callbacks( Open, Close ); add_submodule(); @@ -167,7 +167,7 @@ struct sap_announce_t playlist_item_t *p_item; }; -struct intf_sys_t +struct services_discovery_sys_t { /* Socket descriptors */ int i_fd; @@ -195,21 +195,21 @@ struct intf_sys_t /* Main functions */ static int Demux( demux_t *p_demux ); static int Control( demux_t *, int, va_list ); - static void Run ( intf_thread_t *p_intf ); + static void Run ( services_discovery_t *p_sd ); /* Main parsing functions */ static int ParseConnection( vlc_object_t *p_obj, sdp_t *p_sdp ); - static int ParseSAP( intf_thread_t *p_intf, uint8_t *p_buffer, int i_read ); - static sdp_t * ParseSDP( vlc_object_t *p_intf, char* psz_sdp ); - static sap_announce_t *CreateAnnounce( intf_thread_t *, uint16_t, sdp_t * ); - static int RemoveAnnounce( intf_thread_t *p_intf, sap_announce_t *p_announce ); + static int ParseSAP( services_discovery_t *p_sd, uint8_t *p_buffer, int i_read ); + static sdp_t * ParseSDP( vlc_object_t *p_sd, char* psz_sdp ); + static sap_announce_t *CreateAnnounce( services_discovery_t *, uint16_t, sdp_t * ); + static int RemoveAnnounce( services_discovery_t *p_sd, sap_announce_t *p_announce ); /* Cache */ - static void CacheLoad( intf_thread_t *p_intf ); - static void CacheSave( intf_thread_t *p_intf ); + static void CacheLoad( services_discovery_t *p_sd ); + static void CacheSave( services_discovery_t *p_sd ); /* Helper functions */ static char *GetAttribute( sdp_t *p_sdp, const char *psz_search ); - static int InitSocket( intf_thread_t *p_intf, char *psz_address, int i_port ); + static int InitSocket( services_discovery_t *p_sd, char *psz_address, int i_port ); #ifdef HAVE_ZLIB_H static int Decompress( unsigned char *psz_src, unsigned char **_dst, int i_len ); static void FreeSDP( sdp_t *p_sdp ); @@ -225,17 +225,17 @@ static int ismult( char * ); *****************************************************************************/ static int Open( vlc_object_t *p_this ) { - intf_thread_t *p_intf = ( intf_thread_t* )p_this; - intf_sys_t *p_sys = malloc( sizeof( intf_sys_t ) ); + services_discovery_t *p_sd = ( services_discovery_t* )p_this; + services_discovery_sys_t *p_sys = malloc( sizeof( services_discovery_sys_t ) ); playlist_t *p_playlist; playlist_view_t *p_view; - p_sys->i_timeout = config_GetInt( p_intf,"sap-timeout" ); + p_sys->i_timeout = config_GetInt( p_sd,"sap-timeout" ); - p_intf->pf_run = Run; - p_intf->p_sys = p_sys; + p_sd->pf_run = Run; + p_sd->p_sys = p_sys; p_sys->pi_fd = NULL; p_sys->i_fd = 0; @@ -243,16 +243,16 @@ static int Open( vlc_object_t *p_this ) /* FIXME */ p_sys->b_strict = VLC_FALSE; - if( config_GetInt( p_intf, "sap-use-cache" ) ) + if( config_GetInt( p_sd, "sap-use-cache" ) ) { - CacheLoad( p_intf ); + CacheLoad( p_sd ); } - if( config_GetInt( p_intf, "sap-ipv4" ) ) + if( config_GetInt( p_sd, "sap-ipv4" ) ) { - InitSocket( p_intf, SAP_V4_ADDRESS, SAP_PORT ); + InitSocket( p_sd, SAP_V4_ADDRESS, SAP_PORT ); } - if( config_GetInt( p_intf, "sap-ipv6" ) ) + if( config_GetInt( p_sd, "sap-ipv6" ) ) { /* TODO */ } @@ -261,16 +261,16 @@ static int Open( vlc_object_t *p_this ) if( p_sys->i_fd == 0 ) { - msg_Err( p_intf, "unable to read on any address"); + msg_Err( p_sd, "unable to read on any address"); return VLC_EGENERIC; } /* Create our playlist node */ - p_playlist = (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, + p_playlist = (playlist_t *)vlc_object_find( p_sd, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE ); if( !p_playlist ) { - msg_Warn( p_intf, "unable to find playlist, cancelling SAP listening"); + msg_Warn( p_sd, "unable to find playlist, cancelling SAP listening"); return VLC_EGENERIC; } @@ -322,8 +322,8 @@ static int OpenDemux( vlc_object_t *p_this ) *****************************************************************************/ static void Close( vlc_object_t *p_this ) { - intf_thread_t *p_intf = ( intf_thread_t* )p_this; - intf_sys_t *p_sys = p_intf->p_sys; + services_discovery_t *p_sd = ( services_discovery_t* )p_this; + services_discovery_sys_t *p_sys = p_sd->p_sys; int i; for( i = p_sys->i_fd-1 ; i >= 0 ; i-- ) @@ -331,14 +331,14 @@ static void Close( vlc_object_t *p_this ) net_Close( p_sys->pi_fd[i] ); } - if( config_GetInt( p_intf, "sap-use-cache" ) ) + if( config_GetInt( p_sd, "sap-use-cache" ) ) { - CacheSave( p_intf ); + CacheSave( p_sd ); } for( i = p_sys->i_announces - 1; i>= 0; i-- ) { - RemoveAnnounce( p_intf, p_sys->pp_announces[i] ); + RemoveAnnounce( p_sd, p_sys->pp_announces[i] ); } free( p_sys ); @@ -359,7 +359,7 @@ static void CloseDemux( vlc_object_t *p_this ) *****************************************************************************/ #define MAX_SAP_BUFFER 5000 -static void Run( intf_thread_t *p_intf ) +static void Run( services_discovery_t *p_sd ) { uint8_t *p_buffer; /* Dirty hack to slow down the startup of the sap interface */ @@ -367,53 +367,53 @@ static void Run( intf_thread_t *p_intf ) // msleep( 500000 ); /* read SAP packets */ - while( !p_intf->b_die ) + while( !p_sd->b_die ) { p_buffer = (uint8_t *)malloc( MAX_SAP_BUFFER ); if( !p_buffer ) { - msg_Err( p_intf, "out of memory"); - p_intf->b_die = VLC_TRUE; + msg_Err( p_sd, "out of memory"); + p_sd->b_die = VLC_TRUE; continue; } - int i_read = net_Select( p_intf, p_intf->p_sys->pi_fd, NULL, - p_intf->p_sys->i_fd, p_buffer, + int i_read = net_Select( p_sd, p_sd->p_sys->pi_fd, NULL, + p_sd->p_sys->i_fd, p_buffer, MAX_SAP_BUFFER, 500000 ); #if 0 /* Check for items that need deletion */ - for( i = 0 ; i< p_intf->p_sys->i_announces ; i++ ) + for( i = 0 ; i< p_sd->p_sys->i_announces ; i++ ) { struct sap_announce_t *p_announce; mtime_t i_timeout = ( mtime_t ) 1000000*p_sys->i_timeout; - if( mdate() - p_intf->p_sys->pp_announces[i]->i_last > i_timeout ) + if( mdate() - p_sd->p_sys->pp_announces[i]->i_last > i_timeout ) { - msg_Dbg( p_intf,"Time out for %s, deleting (%i/%i)", - p_intf->p_sys->pp_announces[i]->psz_name, - i , p_intf->p_sys->i_announces ); + msg_Dbg( p_sd,"Time out for %s, deleting (%i/%i)", + p_sd->p_sys->pp_announces[i]->psz_name, + i , p_sd->p_sys->i_announces ); /* Remove the playlist item */ - p_playlist = vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, + p_playlist = vlc_object_find( p_sd, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE ); if( p_playlist ) { int i_pos = playlist_GetPositionById( p_playlist, - p_intf->p_sys->pp_announces[i]->i_id ); + p_sd->p_sys->pp_announces[i]->i_id ); playlist_Delete( p_playlist, i_pos ); vlc_object_release( p_playlist ); } /* Free the p_announce */ - p_announce = p_intf->p_sys->pp_announces[i]; + p_announce = p_sd->p_sys->pp_announces[i]; if( p_announce->psz_name ) free( p_announce->psz_name ); if( p_announce->psz_uri ) free( p_announce->psz_uri ); /* Remove the sap_announce from the array */ - REMOVE_ELEM( p_intf->p_sys->pp_announces, - p_intf->p_sys->i_announces, + REMOVE_ELEM( p_sd->p_sys->pp_announces, + p_sd->p_sys->i_announces, i ); free( p_announce ); @@ -427,7 +427,7 @@ static void Run( intf_thread_t *p_intf ) { if( i_read < 0 ) { - msg_Warn( p_intf, "socket read error" ); + msg_Warn( p_sd, "socket read error" ); } continue; } @@ -435,7 +435,7 @@ static void Run( intf_thread_t *p_intf ) p_buffer[i_read] = '\0'; /* Parse the packet */ - ParseSAP( p_intf, p_buffer, i_read ); + ParseSAP( p_sd, p_buffer, i_read ); free( p_buffer ); } @@ -521,7 +521,7 @@ static int Control( demux_t *p_demux, int i_query, va_list args ) * Local functions **************************************************************/ -static int ParseSAP( intf_thread_t *p_intf, uint8_t *p_buffer, int i_read ) +static int ParseSAP( services_discovery_t *p_sd, uint8_t *p_buffer, int i_read ) { int i_version, i_address_type, i_hash, i; uint8_t *psz_sdp; @@ -538,26 +538,26 @@ static int ParseSAP( intf_thread_t *p_intf, uint8_t *p_buffer, int i_read ) if( i_version != 1 ) { - msg_Dbg( p_intf, "strange sap version %d found", i_version ); + msg_Dbg( p_sd, "strange sap version %d found", i_version ); } i_address_type = p_buffer[0] & 0x10; if( (p_buffer[0] & 0x08) != 0 ) { - msg_Dbg( p_intf, "reserved bit incorrectly set" ); + msg_Dbg( p_sd, "reserved bit incorrectly set" ); return VLC_EGENERIC; } if( (p_buffer[0] & 0x04) != 0 ) { - msg_Dbg( p_intf, "session deletion packet" ); + msg_Dbg( p_sd, "session deletion packet" ); b_need_delete = VLC_TRUE; } if( p_buffer[0] & 0x02 ) { - msg_Dbg( p_intf, "encrypted packet, unsupported" ); + msg_Dbg( p_sd, "encrypted packet, unsupported" ); return VLC_EGENERIC; } @@ -565,9 +565,9 @@ static int ParseSAP( intf_thread_t *p_intf, uint8_t *p_buffer, int i_read ) i_hash = ( p_buffer[2] << 8 ) + p_buffer[3]; - if( p_intf->p_sys->b_strict && i_hash == 0 ) + if( p_sd->p_sys->b_strict && i_hash == 0 ) { - msg_Dbg( p_intf, "strict mode, discarding announce with null id hash"); + msg_Dbg( p_sd, "strict mode, discarding announce with null id hash"); return VLC_EGENERIC; } @@ -594,7 +594,7 @@ static int ParseSAP( intf_thread_t *p_intf, uint8_t *p_buffer, int i_read ) free( p_decompressed_buffer ); } #else - msg_Warn( p_intf, "Ignoring compressed sap packet" ); + msg_Warn( p_sd, "Ignoring compressed sap packet" ); return VLC_EGENERIC; #endif } @@ -615,7 +615,7 @@ static int ParseSAP( intf_thread_t *p_intf, uint8_t *p_buffer, int i_read ) } /* Parse SDP info */ - p_sdp = ParseSDP( VLC_OBJECT(p_intf), psz_sdp ); + p_sdp = ParseSDP( VLC_OBJECT(p_sd), psz_sdp ); if( p_sdp == NULL ) { @@ -625,14 +625,14 @@ static int ParseSAP( intf_thread_t *p_intf, uint8_t *p_buffer, int i_read ) /* Decide whether we should add a playlist item for this SDP */ /* Multi-media or no-parse -> pass to LIVE.COM */ - if( p_sdp->i_media > 1 || p_intf->p_sys->b_parse == VLC_FALSE ) + if( p_sdp->i_media > 1 || p_sd->p_sys->b_parse == VLC_FALSE ) { asprintf( &p_sdp->psz_uri, "sdp://%s", p_sdp->psz_sdp ); } else { /* Parse connection information (c= & m= ) */ - if( ParseConnection( VLC_OBJECT(p_intf), p_sdp ) ) + if( ParseConnection( VLC_OBJECT(p_sd), p_sdp ) ) { p_sdp->psz_uri = NULL; } @@ -640,21 +640,21 @@ static int ParseSAP( intf_thread_t *p_intf, uint8_t *p_buffer, int i_read ) if( p_sdp->psz_uri == NULL ) return VLC_EGENERIC; - for( i = 0 ; i< p_intf->p_sys->i_announces ; i++ ) + for( i = 0 ; i< p_sd->p_sys->i_announces ; i++ ) { /* FIXME: slow */ /* FIXME: we create a new announce each time the sdp changes */ - if( !strcmp( p_intf->p_sys->pp_announces[i]->p_sdp->psz_sdp, + if( !strcmp( p_sd->p_sys->pp_announces[i]->p_sdp->psz_sdp, p_sdp->psz_sdp ) ) { if( b_need_delete ) { - RemoveAnnounce( p_intf, p_intf->p_sys->pp_announces[i]); + RemoveAnnounce( p_sd, p_sd->p_sys->pp_announces[i]); return VLC_SUCCESS; } else { - p_intf->p_sys->pp_announces[i]->i_last = mdate(); + p_sd->p_sys->pp_announces[i]->i_last = mdate(); FreeSDP( p_sdp ); return VLC_SUCCESS; } @@ -663,15 +663,15 @@ static int ParseSAP( intf_thread_t *p_intf, uint8_t *p_buffer, int i_read ) /* Add item */ if( p_sdp->i_media > 1 ) { - msg_Dbg( p_intf, "passing to LIVE.COM" ); + msg_Dbg( p_sd, "passing to LIVE.COM" ); } - CreateAnnounce( p_intf, i_hash, p_sdp ); + CreateAnnounce( p_sd, i_hash, p_sdp ); return VLC_SUCCESS; } -sap_announce_t *CreateAnnounce( intf_thread_t *p_intf, uint16_t i_hash, +sap_announce_t *CreateAnnounce( services_discovery_t *p_sd, uint16_t i_hash, sdp_t *p_sdp ) { playlist_t *p_playlist; @@ -681,8 +681,8 @@ sap_announce_t *CreateAnnounce( intf_thread_t *p_intf, uint16_t i_hash, sizeof(sap_announce_t ) ); if( !p_sap ) { - msg_Err( p_intf, "out of memory"); - p_intf->b_die = VLC_TRUE; + msg_Err( p_sd, "out of memory"); + p_sd->b_die = VLC_TRUE; return NULL; } p_sap->i_last = mdate(); @@ -691,7 +691,7 @@ sap_announce_t *CreateAnnounce( intf_thread_t *p_intf, uint16_t i_hash, p_sap->p_item = NULL; /* Create the playlist item here */ - p_item = playlist_ItemNew( p_intf, p_sap->p_sdp->psz_uri, + p_item = playlist_ItemNew( p_sd, p_sap->p_sdp->psz_uri, p_sap->p_sdp->psz_sessionname ); if( !p_item ) @@ -706,11 +706,11 @@ sap_announce_t *CreateAnnounce( intf_thread_t *p_intf, uint16_t i_hash, psz_value = GetAttribute( p_sap->p_sdp, "plgroup" ); } - p_playlist = (playlist_t *)vlc_object_find( p_intf, VLC_OBJECT_PLAYLIST, + p_playlist = (playlist_t *)vlc_object_find( p_sd, VLC_OBJECT_PLAYLIST, FIND_ANYWHERE ); if( !p_playlist ) { - msg_Err( p_intf, "playlist not found" ); + msg_Err( p_sd, "playlist not found" ); FREE( psz_value ); free( p_sap ); return NULL; @@ -718,17 +718,17 @@ sap_announce_t *CreateAnnounce( intf_thread_t *p_intf, uint16_t i_hash, if( psz_value != NULL ) { - p_child = playlist_ChildSearchName( p_intf->p_sys->p_node, psz_value ); + p_child = playlist_ChildSearchName( p_sd->p_sys->p_node, psz_value ); if( p_child == NULL ) { p_child = playlist_NodeCreate( p_playlist, VIEW_CATEGORY, - psz_value, p_intf->p_sys->p_node ); + psz_value, p_sd->p_sys->p_node ); } } else { - p_child = p_intf->p_sys->p_node; + p_child = p_sd->p_sys->p_node; } p_item->i_flags &= ~PLAYLIST_SKIP_FLAG; @@ -740,8 +740,8 @@ sap_announce_t *CreateAnnounce( intf_thread_t *p_intf, uint16_t i_hash, p_sap->p_item = p_item; - TAB_APPEND( p_intf->p_sys->i_announces, - p_intf->p_sys->pp_announces, + TAB_APPEND( p_sd->p_sys->i_announces, + p_sd->p_sys->pp_announces, p_sap ); return p_sap; @@ -1071,15 +1071,15 @@ static int ismult( char *psz_uri ) return( i_value < 224 ? VLC_FALSE : VLC_TRUE ); } -static int InitSocket( intf_thread_t *p_intf, char *psz_address, int i_port ) +static int InitSocket( services_discovery_t *p_sd, char *psz_address, int i_port ) { - int i_fd = net_OpenUDP( p_intf, psz_address, i_port, "", 0 ); + int i_fd = net_OpenUDP( p_sd, psz_address, i_port, "", 0 ); if( i_fd != -1 ) { - INSERT_ELEM( p_intf->p_sys->pi_fd, - p_intf->p_sys->i_fd, - p_intf->p_sys->i_fd, + INSERT_ELEM( p_sd->p_sys->pi_fd, + p_sd->p_sys->i_fd, + p_sd->p_sys->i_fd, i_fd ); return VLC_SUCCESS; } @@ -1161,18 +1161,18 @@ static void FreeSDP( sdp_t *p_sdp ) free( p_sdp ); } -static int RemoveAnnounce( intf_thread_t *p_intf, sap_announce_t *p_announce ) +static int RemoveAnnounce( services_discovery_t *p_sd, sap_announce_t *p_announce ) { - msg_Err( p_intf, "remove not implemented"); + msg_Err( p_sd, "remove not implemented"); return VLC_SUCCESS; } -static void CacheLoad( intf_thread_t *p_intf ) +static void CacheLoad( services_discovery_t *p_sd ) { - msg_Warn( p_intf, "Cache not implemented") ; + msg_Warn( p_sd, "Cache not implemented") ; } -static void CacheSave( intf_thread_t *p_intf ) +static void CacheSave( services_discovery_t *p_sd ) { - msg_Warn( p_intf, "Cache not implemented") ; + msg_Warn( p_sd, "Cache not implemented") ; } diff --git a/src/interface/interface.c b/src/interface/interface.c index 1a8ee0f8a2..9383abc2c7 100644 --- a/src/interface/interface.c +++ b/src/interface/interface.c @@ -359,8 +359,6 @@ static void RunInterface( intf_thread_t *p_intf ) var_Change( p_intf, "intf-add", VLC_VAR_ADDCHOICE, &val, &text ); val.psz_string = "logger"; text.psz_string = "Debug logging"; var_Change( p_intf, "intf-add", VLC_VAR_ADDCHOICE, &val, &text ); - val.psz_string = "sap"; text.psz_string = "SAP Playlist"; - var_Change( p_intf, "intf-add", VLC_VAR_ADDCHOICE, &val, &text ); val.psz_string = "gestures"; text.psz_string = "Mouse Gestures"; var_Change( p_intf, "intf-add", VLC_VAR_ADDCHOICE, &val, &text ); diff --git a/src/libvlc.c b/src/libvlc.c index 9b378c5e95..551f40a220 100644 --- a/src/libvlc.c +++ b/src/libvlc.c @@ -649,6 +649,10 @@ int VLC_Init( int i_object, int i_argc, char *ppsz_argv[] ) return VLC_EGENERIC; } + /* Add service discovery modules */ + playlist_AddSDModules( p_playlist, + config_GetPsz( p_playlist, "services-discovery" ) ); + /* * Load background interfaces */ diff --git a/src/libvlc.h b/src/libvlc.h index 3198751eb4..8efcd08db1 100644 --- a/src/libvlc.h +++ b/src/libvlc.h @@ -545,6 +545,11 @@ static char *ppsz_align_descriptions[] = "These options define the behavior of the playlist. Some " \ "of them can be overridden in the playlist dialog box." ) +#define SD_TEXT N_( "Services discovery modules") +#define SD_LONGTEXT N_( \ + "Specifies the services discovery modules to load, separated by commas." \ + "Typical values are sap, hal, ..." ) + #define RANDOM_TEXT N_("Play files randomly forever") #define RANDOM_LONGTEXT N_( \ "When selected, VLC will randomly play files in the playlist until " \ @@ -994,6 +999,8 @@ vlc_module_begin(); /* Playlist options */ add_category_hint( N_("Playlist"), PLAYLIST_CAT_LONGTEXT , VLC_FALSE ); + add_string( "services-discovery", 0, NULL, + SD_TEXT, SD_LONGTEXT, VLC_FALSE ); add_bool( "random", 0, NULL, RANDOM_TEXT, RANDOM_LONGTEXT, VLC_FALSE ); change_short('Z'); add_bool( "loop", 0, NULL, LOOP_TEXT, LOOP_LONGTEXT, VLC_FALSE ); diff --git a/src/misc/objects.c b/src/misc/objects.c index a8bc6cde2e..92edd69993 100644 --- a/src/misc/objects.c +++ b/src/misc/objects.c @@ -126,6 +126,10 @@ void * __vlc_object_create( vlc_object_t *p_this, int i_type ) i_size = sizeof(playlist_t); psz_type = "playlist"; break; + case VLC_OBJECT_SD: + i_size = sizeof(services_discovery_t); + psz_type = "services discovery"; + break; case VLC_OBJECT_INPUT: i_size = sizeof(input_thread_t); psz_type = "input"; diff --git a/src/playlist/playlist.c b/src/playlist/playlist.c index e69cf0f6ef..1d65e8783a 100644 --- a/src/playlist/playlist.c +++ b/src/playlist/playlist.c @@ -134,7 +134,6 @@ playlist_t * __playlist_Create ( vlc_object_t *p_parent ) p_playlist->i_sort = SORT_ID; p_playlist->i_order = ORDER_NORMAL; - /* Finally, launch the thread ! */ if( vlc_thread_create( p_playlist, "playlist", RunThread, VLC_THREAD_PRIORITY_LOW, VLC_TRUE ) ) @@ -161,6 +160,12 @@ void playlist_Destroy( playlist_t * p_playlist ) int i; p_playlist->b_die = 1; + for( i = 0 ; i< p_playlist->i_sds ; i++ ) + { + playlist_ServicesDiscoveryRemove( p_playlist, + p_playlist->pp_sds[i]->psz_module ); + } + vlc_thread_join( p_playlist ); var_Destroy( p_playlist, "intf-change" ); diff --git a/src/playlist/services_discovery.c b/src/playlist/services_discovery.c new file mode 100644 index 0000000000..a77ed3496b --- /dev/null +++ b/src/playlist/services_discovery.c @@ -0,0 +1,158 @@ +/***************************************************************************** + * services_discovery.c : Manage playlist services_discovery modules + ***************************************************************************** + * Copyright (C) 1999-2004 VideoLAN + * $Id: playlist.c 9216 2004-11-07 10:43:52Z zorglub $ + * + * Authors: Clément Stenac + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. + *****************************************************************************/ +#include /* free(), strtol() */ +#include /* sprintf() */ +#include /* strerror() */ + +#include +#include +#include +#include + +#include "vlc_playlist.h" + +/***************************************************************************** + * Local prototypes + *****************************************************************************/ + +static void RunSD( services_discovery_t *p_sd ); + + +/*************************************************************************** +***************************************************************************/ + +int playlist_ServicesDiscoveryAdd( playlist_t *p_playlist, + const char *psz_module ) +{ + services_discovery_t *p_sd; + + p_sd = vlc_object_create( p_playlist, VLC_OBJECT_SD ); + p_sd->pf_run = NULL; + + p_sd->p_module = module_Need( p_sd, "services_discovery", psz_module, 0 ); + + if( p_sd->p_module == NULL ) + { + msg_Err( p_playlist, "no suitable services discovery module" ); + vlc_object_destroy( p_sd ); + return VLC_EGENERIC; + } + + p_sd->psz_module = strdup( psz_module ); + p_sd->b_die = VLC_FALSE; + + vlc_mutex_lock( &p_playlist->object_lock ); + + INSERT_ELEM( p_playlist->pp_sds, p_playlist->i_sds, p_playlist->i_sds, + p_sd ); + + vlc_mutex_unlock( &p_playlist->object_lock ); + + if( vlc_thread_create( p_sd, "services_discovery", RunSD, + VLC_THREAD_PRIORITY_LOW, VLC_FALSE ) ) + { + msg_Err( p_sd, "cannot create services discovery thread" ); + vlc_object_destroy( p_sd ); + return VLC_EGENERIC; + } + + + return VLC_SUCCESS; +} + +void playlist_ServicesDiscoveryRemove( playlist_t * p_playlist, + const char *psz_module ) +{ + int i; + services_discovery_t *p_sd = NULL; + vlc_mutex_lock( &p_playlist->object_lock ); + + for( i = 0 ; i< p_playlist->i_sds ; i ++ ) + { + if( !strcmp( psz_module, p_playlist->pp_sds[i]->psz_module ) ) + { + p_sd = p_playlist->pp_sds[i]; + REMOVE_ELEM( p_playlist->pp_sds, p_playlist->i_sds, i ); + break; + } + } + + if( p_sd ) + { + p_sd->b_die = VLC_TRUE; + vlc_thread_join( p_sd ); + module_Unneed( p_sd, p_sd->p_module ); + vlc_object_destroy( p_sd ); + } + else + { + msg_Warn( p_playlist, "module %s is not loaded", psz_module ); + } + + vlc_mutex_unlock( &p_playlist->object_lock ); + return; +} + +/** + * Load all service discovery modules in a string + * + * \param p_playlist the playlist + * \param psz_modules a list of modules separated by commads + * return VLC_SUCCESS or an error + */ +int playlist_AddSDModules( playlist_t *p_playlist, char *psz_modules ) +{ + if( psz_modules && *psz_modules ) + { + char *psz_parser = psz_modules; + char *psz_next; + + while( psz_parser && *psz_parser ) + { + while( *psz_parser == ' ' || *psz_parser == ',' ) + { + psz_parser++; + } + + if( (psz_next = strchr( psz_parser, ',' ) ) ) + { + *psz_next++ = '\0'; + } + if( *psz_parser == '\0' ) + { + break; + } + + playlist_ServicesDiscoveryAdd( p_playlist, psz_parser ); + + psz_parser = psz_next; + } + } + return VLC_SUCCESS; +} + +static void RunSD( services_discovery_t *p_sd ) +{ + p_sd->pf_run( p_sd ); + return; +} -- 2.39.2