From 5574f54de8a088481ff209b7b87bccad4122f190 Mon Sep 17 00:00:00 2001 From: =?utf8?q?R=C3=A9mi=20Denis-Courmont?= Date: Thu, 11 Sep 2008 20:36:52 +0300 Subject: [PATCH] SAP announce: rewrite, use one thread per SAP group (fixes #1839) --- include/vlc_common.h | 2 - src/libvlc-module.c | 3 +- src/stream_output/announce.c | 12 +- src/stream_output/sap.c | 506 +++++++++++------------------- src/stream_output/stream_output.h | 37 +-- 5 files changed, 190 insertions(+), 370 deletions(-) diff --git a/include/vlc_common.h b/include/vlc_common.h index f240599067..ab422c8e09 100644 --- a/include/vlc_common.h +++ b/include/vlc_common.h @@ -263,8 +263,6 @@ typedef struct sout_stream_t sout_stream_t; typedef struct sout_stream_sys_t sout_stream_sys_t; typedef struct config_chain_t config_chain_t; -typedef struct sap_session_t sap_session_t; -typedef struct sap_address_t sap_address_t; typedef struct session_descriptor_t session_descriptor_t; typedef struct announce_method_t announce_method_t; typedef struct announce_handler_t announce_handler_t; diff --git a/src/libvlc-module.c b/src/libvlc-module.c index e39df12ca8..0edd0f7c7c 100644 --- a/src/libvlc-module.c +++ b/src/libvlc-module.c @@ -1832,8 +1832,7 @@ vlc_module_begin(); PACKETIZER_TEXT, PACKETIZER_LONGTEXT, true ); set_subcategory( SUBCAT_SOUT_SAP ); - add_bool( "sap-flow-control", false, NULL, ANN_SAPCTRL_TEXT, - ANN_SAPCTRL_LONGTEXT, true ); + add_obsolete_bool( "sap-flow-control" ); add_integer( "sap-interval", 5, NULL, ANN_SAPINTV_TEXT, ANN_SAPINTV_LONGTEXT, true ); diff --git a/src/stream_output/announce.c b/src/stream_output/announce.c index 7dedc1e050..25a62ca2f6 100644 --- a/src/stream_output/announce.c +++ b/src/stream_output/announce.c @@ -176,10 +176,7 @@ static announce_handler_t *announce_HandlerCreate( vlc_object_t *p_this ) int announce_HandlerDestroy( announce_handler_t *p_announce ) { if( p_announce->p_sap ) - { - /* Exit the SAP */ - vlc_object_release( p_announce->p_sap ); - } + SAP_Destroy( p_announce->p_sap ); /* Free the structure */ vlc_object_release( p_announce ); @@ -201,7 +198,7 @@ static int announce_Register( announce_handler_t *p_announce, /* Do we already have a SAP announce handler ? */ if( !p_announce->p_sap ) { - sap_handler_t *p_sap = announce_SAPHandlerCreate( p_announce ); + sap_handler_t *p_sap = SAP_Create (VLC_OBJECT(p_announce)); msg_Dbg( p_announce, "creating SAP announce handler"); if( !p_sap ) { @@ -212,7 +209,7 @@ static int announce_Register( announce_handler_t *p_announce, } /* this will set p_session->p_sap for later deletion */ msg_Dbg( p_announce, "adding SAP session"); - p_announce->p_sap->pf_add( p_announce->p_sap, p_session ); + SAP_Add( p_announce->p_sap, p_session ); } else { @@ -228,7 +225,6 @@ static int announce_UnRegister( announce_handler_t *p_announce, session_descriptor_t *p_session ) { msg_Dbg( p_announce, "unregistering announce" ); - if( p_announce->p_sap ) - p_announce->p_sap->pf_del( p_announce->p_sap, p_session ); + SAP_Del( p_announce->p_sap, p_session ); return VLC_SUCCESS; } diff --git a/src/stream_output/sap.c b/src/stream_output/sap.c index 88fdf578cf..e3c9d19f0c 100644 --- a/src/stream_output/sap.c +++ b/src/stream_output/sap.c @@ -40,144 +40,131 @@ #include #include -#include #include "stream_output.h" #include "libvlc.h" /* SAP is always on that port */ -#define SAP_PORT 9875 +#define IPPORT_SAP 9875 -#define DEFAULT_PORT "1234" - -#undef EXTRA_DEBUG - -/* SAP Specific structures */ - -/* 100ms */ -#define SAP_IDLE ((mtime_t)(0.100*CLOCK_FREQ)) -#define SAP_MAX_BUFFER 65534 -#define MIN_INTERVAL 2 -#define MAX_INTERVAL 300 +/* A SAP session descriptor, enqueued in the SAP handler queue */ +typedef struct sap_session_t +{ + struct sap_session_t *next; + const session_descriptor_t *p_sd; + size_t length; + uint8_t data[0]; +} sap_session_t; /* A SAP announce address. For each of these, we run the * control flow algorithm */ -struct sap_address_t +typedef struct sap_address_t { - char *psz_address; - struct sockaddr_storage orig; - socklen_t origlen; - int i_rfd; /* Read socket */ - int i_wfd; /* Write socket */ - - /* Used for flow control */ - mtime_t t1; - bool b_enabled; - bool b_ready; - int i_interval; - int i_buff; - int i_limit; -}; + struct sap_address_t *next; -/* A SAP session descriptor, enqueued in the SAP handler queue */ -struct sap_session_t { - uint8_t *psz_data; - size_t i_length; - sap_address_t *p_address; - session_descriptor_t *p_sd; - - /* Last and next send */ - mtime_t i_next; -}; - -/***************************************************************************** - * Local prototypes - *****************************************************************************/ -static void * RunThread( vlc_object_t *p_this); -static int ComputeRate( sap_address_t *p_address ); + vlc_thread_t thread; + vlc_mutex_t lock; + vlc_cond_t wait; -static void announce_SendSAPAnnounce( sap_handler_t *p_sap, - sap_session_t *p_session ); + char group[NI_MAXNUMERICHOST]; + struct sockaddr_storage orig; + socklen_t origlen; + int fd; + unsigned interval; + unsigned session_count; + sap_session_t *first; +} sap_address_t; -static int announce_SAPAnnounceAdd( sap_handler_t *p_sap, - session_descriptor_t *p_session ); +/* The SAP handler, running in a separate thread */ +struct sap_handler_t +{ + VLC_COMMON_MEMBERS -static int announce_SAPAnnounceDel( sap_handler_t *p_sap, - session_descriptor_t *p_session ); + vlc_mutex_t lock; + sap_address_t *first; +}; -static void announce_SAPHandlerDestructor( vlc_object_t *p_this ); +#define SAP_MAX_BUFFER 65534 +#define MIN_INTERVAL 2 +#define MAX_INTERVAL 300 +/***************************************************************************** + * Local prototypes + *****************************************************************************/ +static void *RunThread (void *); /** * Create the SAP handler * - * \param p_announce the parent announce_handler + * \param p_announce a VLC object * \return the newly created SAP handler or NULL on error */ -sap_handler_t *announce_SAPHandlerCreate( announce_handler_t *p_announce ) +sap_handler_t *SAP_Create (vlc_object_t *p_announce) { sap_handler_t *p_sap; - p_sap = vlc_custom_create( VLC_OBJECT(p_announce), sizeof( sap_handler_t ), - VLC_OBJECT_ANNOUNCE, "sap announcer" ); - if( !p_sap ) + p_sap = vlc_custom_create (p_announce, sizeof (*p_sap), + VLC_OBJECT_GENERIC, "sap sender"); + if (p_sap == NULL) return NULL; - p_sap->pf_add = announce_SAPAnnounceAdd; - p_sap->pf_del = announce_SAPAnnounceDel; + vlc_mutex_init (&p_sap->lock); + p_sap->first = NULL; + return p_sap; +} - p_sap->i_sessions = 0; - p_sap->i_addresses = 0; - p_sap->i_current_session = 0; +void SAP_Destroy (sap_handler_t *p_sap) +{ + assert (p_sap->first == NULL); + vlc_mutex_destroy (&p_sap->lock); + vlc_object_release (p_sap); +} - p_sap->b_control = config_GetInt( p_sap, "sap-flow-control"); +static sap_address_t *AddressCreate (vlc_object_t *obj, const char *group) +{ + int fd = net_ConnectUDP (obj, group, IPPORT_SAP, 255); + if (fd == -1) + return NULL; - if( vlc_thread_create( p_sap, "sap handler", RunThread, - VLC_THREAD_PRIORITY_LOW, false ) ) + sap_address_t *addr = malloc (sizeof (*addr)); + if (addr == NULL) { - msg_Dbg( p_announce, "unable to spawn SAP handler thread"); - vlc_object_release( p_sap ); + net_Close (fd); return NULL; } - vlc_object_set_destructor( p_sap, announce_SAPHandlerDestructor ); - - msg_Dbg( p_announce, "thread created, %i sessions", p_sap->i_sessions); - - return p_sap; -} + strlcpy (addr->group, group, sizeof (addr->group)); + addr->fd = fd; + addr->origlen = sizeof (addr->orig); + getsockname (fd, (struct sockaddr *)&addr->orig, &addr->origlen); -static void announce_SAPHandlerDestructor( vlc_object_t * p_this ) -{ - sap_handler_t *p_sap = (sap_handler_t *)p_this; - int i; + addr->interval = var_CreateGetInteger (obj, "sap-interval"); + vlc_mutex_init (&addr->lock); + vlc_cond_init (&addr->wait); + addr->session_count = 0; + addr->first = NULL; - /* Free the remaining sessions */ - for( i = 0 ; i< p_sap->i_sessions ; i++) + if (vlc_clone (&addr->thread, RunThread, addr, VLC_THREAD_PRIORITY_LOW)) { - sap_session_t *p_session = p_sap->pp_sessions[i]; - FREENULL( p_session->psz_data ); - REMOVE_ELEM( p_sap->pp_sessions, p_sap->i_sessions , i ); - FREENULL( p_session ); + msg_Err (obj, "unable to spawn SAP announce thread"); + net_Close (fd); + free (addr); + return NULL; } + return addr; +} - /* Free the remaining addresses */ - for( i = 0 ; i< p_sap->i_addresses ; i++) - { - sap_address_t *p_address = p_sap->pp_addresses[i]; - FREENULL( p_address->psz_address ); - if( p_address->i_rfd > -1 ) - { - net_Close( p_address->i_rfd ); - } - if( p_address->i_wfd > -1 && p_sap->b_control ) - { - net_Close( p_address->i_wfd ); - } - REMOVE_ELEM( p_sap->pp_addresses, p_sap->i_addresses, i ); - FREENULL( p_address ); - } +static void AddressDestroy (sap_address_t *addr) +{ + assert (addr->first == NULL); + + vlc_cancel (addr->thread); + vlc_join (addr->thread, NULL); + vlc_cond_destroy (&addr->wait); + vlc_mutex_destroy (&addr->lock); + net_Close (addr->fd); + free (addr); } /** @@ -185,63 +172,42 @@ static void announce_SAPHandlerDestructor( vlc_object_t * p_this ) * \param p_this the SAP Handler object * \return nothing */ -static void * RunThread( vlc_object_t *p_this) +static void *RunThread (void *self) { - sap_handler_t *p_sap = (sap_handler_t*)p_this; - sap_session_t *p_session; - /* TODO: Use poll() instead of msleep()). */ + sap_address_t *addr = self; + + vlc_mutex_lock (&addr->lock); + mutex_cleanup_push (&addr->lock); for (;;) { - int i; + sap_session_t *p_session; + mtime_t deadline; - msleep( SAP_IDLE ); + while (addr->first == NULL) + vlc_cond_wait (&addr->wait, &addr->lock); - /* If needed, get the rate info */ - if( p_sap->b_control == true ) - { - for( i = 0 ; i< p_sap->i_addresses ; i++) - { - if( p_sap->pp_addresses[i]->b_enabled == true ) - { - ComputeRate( p_sap->pp_addresses[i] ); - } - } - } + assert (addr->session_count > 0); - /* Find the session to announce */ - vlc_object_lock( p_sap ); - if( p_sap->i_sessions > p_sap->i_current_session + 1) - { - p_sap->i_current_session++; - } - else if( p_sap->i_sessions > 0) + deadline = mdate (); + for (p_session = addr->first; p_session; p_session = p_session->next) { - p_sap->i_current_session = 0; - } - else - { - vlc_object_unlock( p_sap ); - continue; - } - p_session = p_sap->pp_sessions[p_sap->i_current_session]; + send (addr->fd, p_session->data, p_session->length, 0); + deadline += addr->interval * CLOCK_FREQ / addr->session_count; - /* And announce it */ - if( p_session->p_address->b_enabled == true && - p_session->p_address->b_ready == true ) - { - int canc = vlc_savecancel (); - announce_SendSAPAnnounce( p_sap, p_session ); - vlc_restorecancel (canc); + if (vlc_cond_timedwait (&addr->wait, &addr->lock, deadline) == 0) + break; /* list may have changed! */ } - vlc_object_unlock( p_sap ); } - return NULL; + + vlc_cleanup_pop (); + assert (0); } -/* Add a SAP announce */ -static int announce_SAPAnnounceAdd( sap_handler_t *p_sap, - session_descriptor_t *p_session ) +/** + * Add a SAP announce + */ +int SAP_Add (sap_handler_t *p_sap, session_descriptor_t *p_session) { int i; char psz_addr[NI_MAXNUMERICHOST]; @@ -251,11 +217,9 @@ static int announce_SAPAnnounceAdd( sap_handler_t *p_sap, struct sockaddr_storage addr; socklen_t addrlen; - vlc_object_lock( p_sap ); addrlen = p_session->addrlen; if ((addrlen == 0) || (addrlen > sizeof (addr))) { - vlc_object_unlock( p_sap ); msg_Err( p_sap, "No/invalid address specified for SAP announce" ); return VLC_EGENERIC; } @@ -322,7 +286,6 @@ static int announce_SAPAnnounceAdd( sap_handler_t *p_sap, { msg_Err( p_sap, "Out-of-scope multicast address " "not supported by SAP" ); - vlc_object_unlock( p_sap ); return VLC_EGENERIC; } @@ -331,7 +294,6 @@ static int announce_SAPAnnounceAdd( sap_handler_t *p_sap, } default: - vlc_object_unlock( p_sap ); msg_Err( p_sap, "Address family %d not supported by SAP", addr.ss_family ); return VLC_EGENERIC; @@ -342,84 +304,39 @@ static int announce_SAPAnnounceAdd( sap_handler_t *p_sap, if( i ) { - vlc_object_unlock( p_sap ); msg_Err( p_sap, "%s", vlc_gai_strerror( i ) ); return VLC_EGENERIC; } + /* Find/create SAP address thread */ msg_Dbg( p_sap, "using SAP address: %s", psz_addr); - /* XXX: Check for dupes */ - p_sap_session = (sap_session_t*)malloc(sizeof(sap_session_t)); - p_sap_session->p_sd = p_session; - p_sap_session->p_address = NULL; - - /* Add the address to the buffer */ - for( i = 0; i < p_sap->i_addresses; i++) - { - if( !strcmp( psz_addr, p_sap->pp_addresses[i]->psz_address ) ) - { - p_sap_session->p_address = p_sap->pp_addresses[i]; + vlc_mutex_lock (&p_sap->lock); + sap_address_t *sap_addr; + for (sap_addr = p_sap->first; sap_addr; sap_addr = sap_addr->next) + if (!strcmp (psz_addr, sap_addr->group)) break; - } - } - if( p_sap_session->p_address == NULL ) + if (sap_addr == NULL) { - sap_address_t *p_address = (sap_address_t *) - malloc( sizeof(sap_address_t) ); - if( !p_address ) - { - vlc_object_unlock( p_sap ); - return VLC_ENOMEM; - } - p_address->psz_address = strdup( psz_addr ); - p_address->i_wfd = net_ConnectUDP( VLC_OBJECT(p_sap), psz_addr, SAP_PORT, 255 ); - if( p_address->i_wfd != -1 ) - { - shutdown( p_address->i_wfd, SHUT_RD ); - p_address->origlen = sizeof (p_address->orig); - getsockname (p_address->i_wfd, (struct sockaddr *)&p_address->orig, - &p_address->origlen); - } - - if( p_sap->b_control == true ) - { - p_address->i_rfd = net_ListenUDP1( (vlc_object_t*)p_sap, psz_addr, SAP_PORT ); - if( p_address->i_rfd != -1 ) - shutdown( p_address->i_rfd, SHUT_WR ); - p_address->i_buff = 0; - p_address->b_enabled = true; - p_address->b_ready = false; - p_address->i_limit = 10000; /* 10000 bps */ - p_address->t1 = 0; - } - else - { - p_address->b_enabled = true; - p_address->b_ready = true; - p_address->i_interval = config_GetInt( p_sap,"sap-interval"); - p_address->i_rfd = -1; - } - - if( p_address->i_wfd == -1 || (p_address->i_rfd == -1 - && p_sap->b_control ) ) + sap_addr = AddressCreate (VLC_OBJECT(p_sap), psz_addr); + if (sap_addr == NULL) { - msg_Warn( p_sap, "disabling address" ); - p_address->b_enabled = false; + vlc_mutex_unlock (&p_sap->lock); + return VLC_EGENERIC; } - - INSERT_ELEM( p_sap->pp_addresses, - p_sap->i_addresses, - p_sap->i_addresses, - p_address ); - p_sap_session->p_address = p_address; + sap_addr->next = p_sap->first; + p_sap->first = sap_addr; } + /* Switch locks. + * NEVER take the global SAP lock when holding a SAP thread lock! */ + vlc_mutex_lock (&sap_addr->lock); + vlc_mutex_unlock (&p_sap->lock); - memcpy (&p_session->orig, &p_sap_session->p_address->orig, - p_session->origlen = p_sap_session->p_address->origlen); + memcpy (&p_session->orig, &sap_addr->orig, sap_addr->origlen); + p_session->origlen = sap_addr->origlen; - size_t headsize = 20; + size_t headsize = 20, length; switch (p_session->orig.ss_family) { #ifdef AF_INET6 @@ -431,27 +348,24 @@ static int announce_SAPAnnounceAdd( sap_handler_t *p_sap, headsize += 4; break; default: - msg_Err( p_sap, "Address family %d not supported by SAP", - addr.ss_family ); - vlc_object_unlock( p_sap ); - return VLC_EGENERIC; + assert (0); } - /* If needed, build the SDP */ - assert( p_session->psz_sdp != NULL ); - - p_sap_session->i_next = 0; - p_sap_session->i_length = headsize + strlen (p_session->psz_sdp); - p_sap_session->psz_data = malloc (p_sap_session->i_length + 1); - if (p_sap_session->psz_data == NULL) + /* XXX: Check for dupes */ + length = headsize + strlen (p_session->psz_sdp); + p_sap_session = malloc (sizeof (*p_sap_session) + length + 1); + if (p_sap_session == NULL) { - free (p_session->psz_sdp); - vlc_object_unlock( p_sap ); - return VLC_ENOMEM; + vlc_mutex_unlock (&sap_addr->lock); + return VLC_EGENERIC; /* NOTE: we should destroy the thread if left unused */ } + p_sap_session->next = sap_addr->first; + sap_addr->first = p_sap_session; + p_sap_session->p_sd = p_session; + p_sap_session->length = length; /* Build the SAP Headers */ - uint8_t *psz_head = p_sap_session->psz_data; + uint8_t *psz_head = p_sap_session->data; /* SAPv1, not encrypted, not compressed */ psz_head[0] = 0x20; @@ -492,127 +406,59 @@ static int announce_SAPAnnounceAdd( sap_handler_t *p_sap, /* Build the final message */ strcpy( (char *)psz_head + headsize, p_session->psz_sdp); - /* Enqueue the announce */ - INSERT_ELEM( p_sap->pp_sessions, - p_sap->i_sessions, - p_sap->i_sessions, - p_sap_session ); - msg_Dbg( p_sap,"%i addresses, %i sessions", - p_sap->i_addresses,p_sap->i_sessions); - - vlc_object_unlock( p_sap ); - + sap_addr->session_count++; + vlc_cond_signal (&sap_addr->wait); + vlc_mutex_unlock (&sap_addr->lock); return VLC_SUCCESS; } -/* Remove a SAP Announce */ -static int announce_SAPAnnounceDel( sap_handler_t *p_sap, - session_descriptor_t *p_session ) +/** + * Remove a SAP Announce + */ +void SAP_Del (sap_handler_t *p_sap, const session_descriptor_t *p_session) { - int i; - vlc_object_lock( p_sap ); + vlc_mutex_lock (&p_sap->lock); - msg_Dbg( p_sap, "removing session %p from SAP", p_session); + /* TODO: give a handle back in SAP_Add, and use that... */ + sap_address_t *addr, **paddr; + sap_session_t *session, **psession; - /* Dequeue the announce */ - for( i = 0; i< p_sap->i_sessions; i++) + paddr = &p_sap->first; + for (addr = p_sap->first; addr; addr = addr->next) { - if( p_session == p_sap->pp_sessions[i]->p_sd ) + psession = &addr->first; + vlc_mutex_lock (&addr->lock); + for (session = addr->first; session; session = session->next) { - free( p_session->psz_sdp ); - sap_session_t *p_mysession = p_sap->pp_sessions[i]; - REMOVE_ELEM( p_sap->pp_sessions, - p_sap->i_sessions, - i ); - - free( p_mysession->psz_data ); - free( p_mysession ); - break; + if (session->p_sd == p_session) + goto found; + psession = &session->next; } + vlc_mutex_unlock (&addr->lock); + paddr = &addr->next; } + assert (0); - /* XXX: Dequeue the address too if it is not used anymore - * TODO: - address refcount - - send a SAP deletion packet */ - - msg_Dbg( p_sap,"%i announcements remaining", p_sap->i_sessions ); - - vlc_object_unlock( p_sap ); - - return VLC_SUCCESS; -} - -static void announce_SendSAPAnnounce( sap_handler_t *p_sap, - sap_session_t *p_session ) -{ - mtime_t now = mdate(); - - if( p_session->i_next >= now ) - return; - - ssize_t i_ret = send( p_session->p_address->i_wfd, p_session->psz_data, - p_session->i_length, 0 ); - if( i_ret != (ssize_t)p_session->i_length ) - { - msg_Warn( p_sap, "SAP send failed on address %s (%zd/%zu)", - p_session->p_address->psz_address, - i_ret, p_session->i_length ); - } - p_session->i_next = now + p_session->p_address->i_interval*CLOCK_FREQ; -} - -static int ComputeRate( sap_address_t *p_address ) -{ - uint8_t buffer[SAP_MAX_BUFFER]; - ssize_t i_tot = 0; - mtime_t i_temp; - int i_rate; - - if( p_address->t1 == 0 ) - { - p_address->t1 = mdate(); - return VLC_SUCCESS; - } - for (;;) - { - /* Might be too slow if we have huge data */ - ssize_t i_read = recv( p_address->i_rfd, buffer, SAP_MAX_BUFFER, 0 ); - if (i_read == -1) - break; - i_tot += i_read; - } +found: + *psession = session->next; - i_temp = mdate(); + if (addr->first == NULL) + /* Last session for this address -> unlink the address */ + *paddr = addr->next; + vlc_mutex_unlock (&p_sap->lock); - /* We calculate the rate every 5 seconds */ - if( i_temp - p_address->t1 < 5000000 ) + if (addr->first == NULL) { - p_address->i_buff += i_tot; - return VLC_SUCCESS; + /* Last session for this address -> unlink the address */ + vlc_mutex_unlock (&addr->lock); + AddressDestroy (addr); } - - /* Bits/second */ - i_rate = (int)(8*1000000*((mtime_t)p_address->i_buff + (mtime_t)i_tot ) / - (i_temp - p_address->t1 )); - - p_address->i_limit = 10000; - - p_address->i_interval = ((1000*i_rate / p_address->i_limit) * - (MAX_INTERVAL - MIN_INTERVAL))/1000 + MIN_INTERVAL; - - if( p_address->i_interval > MAX_INTERVAL || p_address->i_interval < 0 ) + else { - p_address->i_interval = MAX_INTERVAL; + addr->session_count--; + vlc_cond_signal (&addr->wait); + vlc_mutex_unlock (&addr->lock); } -#ifdef EXTRA_DEBUG - msg_Dbg( p_sap,"%s:%i: rate=%i, interval = %i s", - p_address->psz_address,SAP_PORT, i_rate, p_address->i_interval ); -#endif - p_address->b_ready = true; - - p_address->t1 = i_temp; - p_address->i_buff = 0; - - return VLC_SUCCESS; + free (session); } diff --git a/src/stream_output/stream_output.h b/src/stream_output/stream_output.h index b4f748357b..49b3efa0da 100644 --- a/src/stream_output/stream_output.h +++ b/src/stream_output/stream_output.h @@ -47,36 +47,15 @@ struct sout_packetizer_input_t }; #define sout_NewInstance(a,b) __sout_NewInstance(VLC_OBJECT(a),b) -VLC_EXPORT( sout_instance_t *, __sout_NewInstance, ( vlc_object_t *, const char * ) ); -VLC_EXPORT( void, sout_DeleteInstance, ( sout_instance_t * ) ); +sout_instance_t * __sout_NewInstance( vlc_object_t *, const char * ); +void sout_DeleteInstance( sout_instance_t * ); -VLC_EXPORT( sout_packetizer_input_t *, sout_InputNew,( sout_instance_t *, es_format_t * ) ); -VLC_EXPORT( int, sout_InputDelete, ( sout_packetizer_input_t * ) ); -VLC_EXPORT( int, sout_InputSendBuffer, ( sout_packetizer_input_t *, block_t* ) ); +sout_packetizer_input_t *sout_InputNew( sout_instance_t *, es_format_t * ); +int sout_InputDelete( sout_packetizer_input_t * ); +int sout_InputSendBuffer( sout_packetizer_input_t *, block_t* ); /* Announce system */ -/* The SAP handler, running in a separate thread */ -struct sap_handler_t -{ - VLC_COMMON_MEMBERS /* needed to create a thread */ - - sap_session_t **pp_sessions; - sap_address_t **pp_addresses; - - bool b_control; - - int i_sessions; - int i_addresses; - - int i_current_session; - - int (*pf_add) ( sap_handler_t*, session_descriptor_t *); - int (*pf_del) ( sap_handler_t*, session_descriptor_t *); - - /* private data, not in p_sys as there is one kind of sap_handler_t */ -}; - struct session_descriptor_t { struct sockaddr_storage orig; @@ -98,7 +77,9 @@ struct announce_handler_t int announce_HandlerDestroy( announce_handler_t * ); -/* Release it with vlc_object_release() */ -sap_handler_t *announce_SAPHandlerCreate( announce_handler_t *p_announce ); +sap_handler_t *SAP_Create (vlc_object_t *); +void SAP_Destroy (sap_handler_t *); +int SAP_Add (sap_handler_t *, session_descriptor_t *); +void SAP_Del (sap_handler_t *, const session_descriptor_t *); #endif -- 2.39.2