X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fstream_output%2Fannounce.c;h=37e3300b7ca981086681fff8cd9870200019de2b;hb=12ade3e3bc975d5426ba4af155b7372c31093b31;hp=79739c858f6a85e791dbd509c72df079fe00a402;hpb=08b246eacb1858c1b7d50aadeebd61ea7e6fc231;p=vlc diff --git a/src/stream_output/announce.c b/src/stream_output/announce.c index 79739c858f..37e3300b7c 100644 --- a/src/stream_output/announce.c +++ b/src/stream_output/announce.c @@ -1,10 +1,10 @@ /***************************************************************************** - * announce.c : Session announcement + * announce.c : announce handler ***************************************************************************** - * Copyright (C) 2002 VideoLAN + * Copyright (C) 2002-2007 the VideoLAN team + * $Id$ * - * Authors: Clément Stenac - * Damien Lucas + * 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 @@ -18,172 +18,132 @@ * * 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. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/ /***************************************************************************** * Preamble *****************************************************************************/ -#include /* free() */ -#include /* sprintf() */ -#include /* strerror() */ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif -#include +#include +#include +#include "stream_output.h" +#include "libvlc.h" -#include -#undef DEBUG_BUFFER +#include -#include -#include +struct announce_method_t +{ +} sap_method; -#define SAP_ADDR "224.2.127.254" /* Standard port and address for SAP */ -#define SAP_PORT 9875 +/**************************************************************************** + * Sout-side functions + ****************************************************************************/ -/***************************************************************************** - * sout_SAPNew: Creates a SAP Session - *****************************************************************************/ -sap_session_t * sout_SAPNew ( sout_instance_t *p_sout , char * psz_url_arg , char *psz_port_arg , char * psz_name_arg ) +static void sap_destroy (vlc_object_t *p_this) { - sap_session_t *p_new; - module_t *p_network; - network_socket_t socket_desc; - char psz_network[12]; - struct sockaddr_in addr; - - p_new = (sap_session_t *)malloc( sizeof ( sap_session_t ) ) ; - - if ( !p_new ) - return NULL; - - sprintf ( p_new->psz_url , "%s" , psz_url_arg ); - sprintf ( p_new->psz_name , "%s" , psz_name_arg ); - sprintf ( p_new->psz_port, "%s" , psz_port_arg ); /* Not implemented in SO */ - - msg_Dbg (p_sout , "Creating SAP Socket" ); - - socket_desc.i_type = NETWORK_UDP; - socket_desc.psz_bind_addr = ""; - socket_desc.i_bind_port = 0; - socket_desc.psz_server_addr = SAP_ADDR; - socket_desc.i_server_port = SAP_PORT; - socket_desc.i_handle = 0; - - sprintf ( psz_network, "ipv4" ); - - p_sout->p_private=(void*) &socket_desc; - - if( !( p_network = module_Need( p_sout, "network", psz_network ) ) ) - { - msg_Warn( p_sout, "failed to open a connection (udp)" ); - } - - module_Unneed( p_sout, p_network ); - - p_new->socket = socket_desc.i_handle; - - memset( &addr , 0 , sizeof(addr) ); - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = inet_addr(SAP_ADDR); - addr.sin_port = htons( SAP_PORT ); - - p_new->addr = addr; - - return(p_new); + libvlc_priv (p_this->p_libvlc)->p_sap = NULL; } -/***************************************************************************** - * sout_SAPDelete: Deletes a SAP Session - *****************************************************************************/ -void sout_SAPDelete( sout_instance_t *p_sout , sap_session_t * p_this ) +#undef sout_AnnounceRegisterSDP + +static vlc_mutex_t sap_mutex = VLC_STATIC_MUTEX; + +/** + * Registers a new session with the announce handler, using a pregenerated SDP + * + * \param obj a VLC object + * \param psz_sdp the SDP to register + * \param psz_dst session address (needed for SAP address auto detection) + * \param p_method an announce method descriptor + * \return the new session descriptor structure + */ +session_descriptor_t * +sout_AnnounceRegisterSDP( vlc_object_t *obj, const char *psz_sdp, + const char *psz_dst, announce_method_t *p_method ) { - if( close(p_this->socket) ) - msg_Err ( p_sout, "Unable to close SAP socket"); - if( p_this ) free(p_this); -} + assert (p_method == &sap_method); + (void) p_method; -/***************************************************************************** - * sout_SAPSend: Sends a SAP packet - *****************************************************************************/ -void sout_SAPSend( sout_instance_t *p_sout, sap_session_t * p_this ) -{ - char *sap_head; - char sap_msg[1000]; - char *sap_send; - char *payload_type="application/sdp"; - int i_send_result; - int i; - int i_header_size; - int i_msg_size; - int i_size; - - if( p_this->sendnow == 24 ) + session_descriptor_t *p_session = calloc( 1, sizeof (*p_session) ); + if( !p_session ) + return NULL; + + p_session->psz_sdp = strdup( psz_sdp ); + + /* GRUIK. We should not convert back-and-forth from string to numbers */ + struct addrinfo *res; + if (vlc_getaddrinfo (obj, psz_dst, 0, NULL, &res) == 0) { - i_header_size = 9 + strlen( payload_type ); - sap_head = ( char * )malloc( i_header_size * sizeof( char ) ); - - if( ! sap_head ) - { - msg_Err( p_sout , "No memory left"); - return; - } - - sap_head[0]=0x20; /* Means IPv4, not encrypted, not compressed */ - sap_head[1]=0x00; /* No authentification */ - sap_head[2]=0x42; /* Version */ - sap_head[3]=0x12; /* Version */ - - sap_head[4]=0x01; /* Source IP FIXME: we should get the real address */ - sap_head[5]=0x02; /* idem */ - sap_head[6]=0x03; /* idem */ - sap_head[7]=0x04; /* idem */ - - strncpy( sap_head+8 , payload_type , 15 ); - sap_head[ i_header_size-1 ] = '\0'; - - /* Do not add spaces at beginning of the lines ! */ - sprintf(sap_msg,"v=0\n\ -o=VideoLAN 3247692199 3247895918 IN IP4 VideoLAN\n\ -s=%s\n\ -u=VideoLAN\n\ -t=0 0\n\ -m=audio %s udp 14\n\ -c=IN IP4 %s/15\n\ -a=type:test\n", p_this->psz_name , p_this->psz_port , p_this->psz_url ); - - i_msg_size = strlen( sap_msg ); - i_size = i_msg_size + i_header_size; - - sap_send = ( char* )malloc( i_size*sizeof(char) ); - - if(! sap_send) - { - msg_Err( p_sout , "No memory left") ; - return; - } - - for(i=0 ; isocket , sap_send , i_size , 0 , (struct sockaddr *)&p_this->addr , sizeof(p_this->addr) ); - - if(i_send_result == -1) - { - msg_Warn(p_sout , "SAP Send failed on socket %i. " , p_this->socket ); - perror("sendto"); - } - p_this->sendnow = 0; - if(sap_send) free(sap_send); - if(sap_head) free(sap_head); - } - p_this->sendnow++; + if (res->ai_addrlen <= sizeof (p_session->addr)) + memcpy (&p_session->addr, res->ai_addr, + p_session->addrlen = res->ai_addrlen); + freeaddrinfo (res); + } + + vlc_mutex_lock (&sap_mutex); + sap_handler_t *p_sap = libvlc_priv (obj->p_libvlc)->p_sap; + if (p_sap == NULL) + { + p_sap = SAP_Create (VLC_OBJECT (obj->p_libvlc)); + libvlc_priv (obj->p_libvlc)->p_sap = p_sap; + vlc_object_set_destructor ((vlc_object_t *)p_sap, sap_destroy); + } + else + vlc_object_hold ((vlc_object_t *)p_sap); + vlc_mutex_unlock (&sap_mutex); + + if (p_sap == NULL) + goto error; + + msg_Dbg (obj, "adding SAP session"); + SAP_Add (p_sap, p_session ); + return p_session; + +error: + free (p_session->psz_sdp); + free (p_session); + return NULL; +} + +#undef sout_AnnounceUnRegister +/** + * Unregisters an existing session + * + * \param obj a VLC object + * \param p_session the session descriptor + * \return VLC_SUCCESS or an error + */ +int sout_AnnounceUnRegister( vlc_object_t *obj, + session_descriptor_t *p_session ) +{ + sap_handler_t *p_sap = libvlc_priv (obj->p_libvlc)->p_sap; + + msg_Dbg (obj, "removing SAP session"); + SAP_Del (p_sap, p_session); + + vlc_mutex_lock (&sap_mutex); + vlc_object_release ((vlc_object_t *)p_sap); + vlc_mutex_unlock (&sap_mutex); + + free (p_session->psz_sdp); + free (p_session); + + return 0; +} + +/** + * \return the SAP announce method + */ +announce_method_t * sout_SAPMethod (void) +{ + return &sap_method; +} + +void sout_MethodRelease (announce_method_t *m) +{ + assert (m == &sap_method); }