All: Support for SAP advertising in stream output
authorClément Stenac <zorglub@videolan.org>
Tue, 20 May 2003 16:20:33 +0000 (16:20 +0000)
committerClément Stenac <zorglub@videolan.org>
Tue, 20 May 2003 16:20:33 +0000 (16:20 +0000)
add sap, or sap="Name" in the stream output options

Makefile.am
NEWS
include/announce.h [new file with mode: 0644]
include/vlc/sout.h
include/vlc_common.h
modules/stream_out/standard.c
src/misc/modules.c
src/stream_output/announce.c [new file with mode: 0644]

index 8246ac6..a62a877 100644 (file)
@@ -194,6 +194,7 @@ HEADERS_include = \
        include/os_specific.h \
        include/stream_control.h \
        include/stream_output.h \
+       include/announce.h \
        include/variables.h \
        include/video.h \
        include/video_output.h \
@@ -426,6 +427,7 @@ SOURCES_libvlc_common = \
        src/audio_output/output.c \
        src/audio_output/intf.c \
        src/stream_output/stream_output.c \
+       src/stream_output/announce.c \
        src/misc/mtime.c \
        src/misc/modules.c \
        src/misc/threads.c \
diff --git a/NEWS b/NEWS
index 90b52a0..5d42ff6 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,4 @@
-$Id: NEWS,v 1.42 2003/05/18 18:56:57 hartman Exp $
+$Id: NEWS,v 1.43 2003/05/20 16:20:33 zorglub Exp $
 
 Changes between 0.5.3 and 0.6.0:
 ---------------------------------
@@ -31,6 +31,7 @@ Interfaces:
 Stream output:
  * New stream output scheme. It is now possible to build a chain of stream outputs allowing for instance to stream and display some content at the same time.
  * The stream output now allows to transcode content on the fly.
+ * SAP (Session Announcement Protocol) support.
 
 Miscellaneous:
  * New reset option for the preferences
diff --git a/include/announce.h b/include/announce.h
new file mode 100644 (file)
index 0000000..6b9d2f2
--- /dev/null
@@ -0,0 +1,67 @@
+/*****************************************************************************
+ * announce.h : Session announcement
+ *****************************************************************************
+ * Copyright (C) 2002 VideoLAN
+ * $Id: announce.h,v 1.1 2003/05/20 16:20:33 zorglub Exp $
+ *
+ * Authors: Christophe Massiot <massiot@via.ecp.fr>
+ *          Laurent Aimar <fenrir@via.ecp.fr>
+ *          Eric Petit <titer@videolan.org>
+ *
+ * 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.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * sap_session_t: SAP Session descriptor
+ *****************************************************************************/
+
+#if defined( UNDER_CE )
+#   include <winsock.h>
+#elif defined( WIN32 )
+#   include <winsock2.h>
+#   include <ws2tcpip.h>
+#   define close closesocket
+#else
+#   include <netdb.h>                                         /* hostent ... */
+#   include <sys/socket.h>
+#   include <netinet/in.h>
+#   ifdef HAVE_ARPA_INET_H
+#       include <arpa/inet.h>                    /* inet_ntoa(), inet_aton() */
+#   endif
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+#   include <sys/types.h>
+#endif
+
+
+struct sap_session_t
+{
+        char psz_url[256];
+        char psz_name[1024];
+        module_t p_network;
+        unsigned int socket;
+        unsigned int sendnow;
+        struct sockaddr_in addr;
+};
+
+
+
+/*****************************************************************************
+ * Prototypes
+ *****************************************************************************/
+VLC_EXPORT( sap_session_t *,            sout_SAPNew,         ( sout_instance_t *,char * , char * ) );
+VLC_EXPORT( void,            sout_SAPSend,        ( sout_instance_t *,sap_session_t * ) );
+VLC_EXPORT( void,            sout_SAPDelete,      ( sap_session_t * ) );
index c067fe4..a01adb1 100644 (file)
@@ -2,7 +2,7 @@
  * sout.h: video output header for vlc
  *****************************************************************************
  * Copyright (C) 2002 VideoLAN
- * $Id: sout.h,v 1.1 2002/08/12 22:12:50 massiot Exp $
+ * $Id: sout.h,v 1.2 2003/05/20 16:20:33 zorglub Exp $
  *
  * 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
@@ -35,7 +35,7 @@ extern "C" {
  * Required internal headers
  *****************************************************************************/
 #include "stream_output.h"
-
+        
 # ifdef __cplusplus
 }
 # endif
index 54999a2..26359ed 100644 (file)
@@ -3,7 +3,7 @@
  * Collection of useful common types and macros definitions
  *****************************************************************************
  * Copyright (C) 1998, 1999, 2000 VideoLAN
- * $Id: vlc_common.h,v 1.63 2003/05/12 19:11:53 gbazin Exp $
+ * $Id: vlc_common.h,v 1.64 2003/05/20 16:20:33 zorglub Exp $
  *
  * Authors: Samuel Hocevar <sam@via.ecp.fr>
  *          Vincent Seguin <seguin@via.ecp.fr>
@@ -255,6 +255,7 @@ typedef struct sout_mux_t sout_mux_t;
 typedef struct sout_stream_t    sout_stream_t;
 typedef struct sout_cfg_t       sout_cfg_t;
 typedef struct sout_format_t    sout_format_t;
+typedef struct sap_session_t    sap_session_t;
 /* Decoders */
 typedef struct decoder_fifo_t decoder_fifo_t;
 
index 9cb5664..b249389 100644 (file)
@@ -2,7 +2,7 @@
  * standard.c
  *****************************************************************************
  * Copyright (C) 2001, 2002 VideoLAN
- * $Id: standard.c,v 1.1 2003/04/13 20:00:21 fenrir Exp $
+ * $Id: standard.c,v 1.2 2003/05/20 16:20:33 zorglub Exp $
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *
  *****************************************************************************/
 #include <stdlib.h>
 #include <string.h>
+#include <unistd.h>
 
 #include <vlc/vlc.h>
 #include <vlc/sout.h>
+#include <announce.h>
 
 /*****************************************************************************
  * Exported prototypes
@@ -53,7 +55,9 @@ vlc_module_end();
 
 struct sout_stream_sys_t
 {
-    sout_mux_t *p_mux;
+    sout_mux_t           *p_mux;
+    sap_session_t        *p_sap;
+    unsigned int          b_sap;
 };
 
 /*****************************************************************************
@@ -63,18 +67,39 @@ static int Open( vlc_object_t *p_this )
 {
     sout_stream_t       *p_stream = (sout_stream_t*)p_this;
     sout_instance_t     *p_sout = p_stream->p_sout;
-    sout_stream_sys_t   *p_sys;
+    sout_stream_sys_t   *p_sys = malloc( sizeof( sout_stream_sys_t) );
 
     char                *psz_mux    = sout_cfg_find_value( p_stream->p_cfg, "mux" );
     char                *psz_access = sout_cfg_find_value( p_stream->p_cfg, "access" );
     char                *psz_url    = sout_cfg_find_value( p_stream->p_cfg, "url" );
 
-    sout_access_out_t *p_access;
-    sout_mux_t        *p_mux;
+    sout_cfg_t          *p_sap_cfg  = sout_cfg_find( p_stream->p_cfg, "sap" );
 
-    msg_Dbg( p_this, "creating `%s/%s://%s'",
-             psz_access, psz_mux, psz_url );
+    char                *psz_sap = NULL;
 
+    sap_session_t       *p_sap = NULL;
+    
+    sout_access_out_t *p_access;
+    sout_mux_t        *p_mux;    
+   
+   p_sys->b_sap=0;
+   /* SAP is only valid for UDP or RTP streaming */
+   if(p_sap_cfg && (strstr(psz_access,"udp") || strstr( psz_access ,  "rtp" )))
+   {
+        msg_Info( p_this, "SAP Enabled");
+        p_sys->b_sap=1;
+        if(p_sap_cfg->psz_value)
+        {
+                psz_sap = strdup( p_sap_cfg->psz_value );
+        }
+        else
+        {
+                psz_sap = strdup ( psz_url );
+        }        
+   }
+   msg_Dbg( p_this, "creating `%s/%s://%s'",
+             psz_access, psz_mux, psz_url );
+       
     /* *** find and open appropriate access module *** */
     p_access = sout_AccessOutNew( p_sout, psz_access, psz_url );
     if( p_access == NULL )
@@ -97,18 +122,25 @@ static int Open( vlc_object_t *p_this )
     }
     msg_Dbg( p_stream, "mux opened" );
 
+    /*  *** Create the SAP Session structure *** */
+    if(p_sys->b_sap)
+    {        
+        msg_Dbg( p_sout , "Creating SAP" );
+        p_sap = sout_SAPNew( p_sout , psz_url , psz_sap );
+    }   
+    
     /* XXX beurk */
     p_sout->i_preheader = __MAX( p_sout->i_preheader, p_mux->i_preheader );
 
-    p_sys        = malloc( sizeof( sout_stream_sys_t ) );
-    p_sys->p_mux = p_mux;
 
+    p_sys->p_mux = p_mux;
+    p_sys->p_sap = p_sap;
+    
     p_stream->pf_add    = Add;
     p_stream->pf_del    = Del;
     p_stream->pf_send   = Send;
 
     p_stream->p_sys     = p_sys;
-
     return VLC_SUCCESS;
 }
 
@@ -123,6 +155,8 @@ static void Close( vlc_object_t * p_this )
 
     sout_access_out_t *p_access = p_sys->p_mux->p_access;
 
+    if(p_sys -> b_sap)
+            sout_SAPDelete( p_sys->p_sap ); 
 
     sout_MuxDelete( p_sys->p_mux );
     sout_AccessOutDelete( p_access );
@@ -167,8 +201,14 @@ static int     Send     ( sout_stream_t *p_stream, sout_stream_id_t *id, sout_bu
 {
     sout_stream_sys_t *p_sys = p_stream->p_sys;
 
+        sout_instance_t         *p_sout = p_stream->p_sout;
+
+    
     sout_MuxSendBuffer( p_sys->p_mux, id->p_input, p_buffer );
 
+    if(p_sys -> b_sap)
+       sout_SAPSend( p_sout , p_sys->p_sap );
+   
     return VLC_SUCCESS;
 }
 
index 1696603..c5c9ca1 100644 (file)
@@ -2,7 +2,7 @@
  * modules.c : Builtin and plugin modules management functions
  *****************************************************************************
  * Copyright (C) 2001 VideoLAN
- * $Id: modules.c,v 1.119 2003/05/05 16:09:36 gbazin Exp $
+ * $Id: modules.c,v 1.120 2003/05/20 16:20:33 zorglub Exp $
  *
  * Authors: Samuel Hocevar <sam@zoy.org>
  *          Ethan C. Baldridge <BaldridgeE@cadmus.com>
@@ -86,6 +86,7 @@
 #include "aout_internal.h"
 
 #include "stream_output.h"
+#include "announce.h"
 
 #include "iso_lang.h"
 
diff --git a/src/stream_output/announce.c b/src/stream_output/announce.c
new file mode 100644 (file)
index 0000000..4534a1d
--- /dev/null
@@ -0,0 +1,136 @@
+/*****************************************************************************
+ * announce.c : Session announcement
+ *****************************************************************************
+ * Copyright (C) 2002 VideoLAN
+ *
+ * Authors: Christophe Massiot <massiot@via.ecp.fr>
+ *          Laurent Aimar <fenrir@via.ecp.fr>
+ *          Eric Petit <titer@videolan.org>
+ *
+ * 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.
+ *****************************************************************************/
+
+/*****************************************************************************
+ * Preamble
+ *****************************************************************************/
+#include <stdlib.h>                                                /* free() */
+#include <stdio.h>                                              /* sprintf() */
+#include <string.h>                                            /* strerror() */
+
+#include <vlc/vlc.h>
+
+#include <vlc/sout.h>
+#undef DEBUG_BUFFER
+
+#include <announce.h>
+#include <network.h>
+
+#define SAP_ADDR "224.2.127.254"
+#define SAP_PORT 9875
+
+/*****************************************************************************
+ * sout_SAPNew: Creates a SAP Session
+ *****************************************************************************/
+sap_session_t * sout_SAPNew ( sout_instance_t *p_sout , char * psz_url_arg , char * psz_name_arg )
+{
+        sap_session_t           *p_new;
+        module_t                *p_network;
+        network_socket_t        socket_desc;
+        char                    psz_network[12];       
+        struct                  sockaddr_in addr;
+        int                     ttl=15;
+              
+        p_new = (sap_session_t *)malloc( sizeof ( sap_session_t ) ) ;
+        
+        sprintf ( p_new->psz_url , "%s" , psz_url_arg );
+        sprintf ( p_new->psz_name , "%s" , psz_name_arg );
+        
+        msg_Dbg (p_sout , "Creating SAP Socket" );
+        
+        socket_desc.i_type        = NETWORK_UDP;
+        socket_desc.psz_bind_addr = SAP_ADDR;
+        socket_desc.i_bind_port   = SAP_PORT;
+        socket_desc.psz_server_addr   = "";
+        socket_desc.i_server_port     = 0;
+        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 );
+    
+        setsockopt( p_new->socket, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl) );
+     
+        p_new->addr=(struct sockaddr_in)addr;
+    
+        return(p_new);
+}
+
+/*****************************************************************************
+ * sout_SAPDelete: Deletes a SAP Session 
+ *****************************************************************************/
+void sout_SAPDelete( sap_session_t * p_this )
+{
+        shutdown(p_this->socket,0);
+        free(p_this);        
+}       
+
+/*****************************************************************************
+ * sout_SAPSend: Sends a SAP packet 
+ *****************************************************************************/
+void sout_SAPSend( sout_instance_t *p_sout, sap_session_t * p_this )
+{ 
+      char sap_msg[2048];
+      char *user="VideoLAN";
+      char *machine="VideoLAN";
+      char *site="VideoLAN";
+      int i_send_result;
+     
+    if(p_this->sendnow == 24)
+    {      
+      sprintf(sap_msg,"         ***øv=0 \n\
+      o=%s 3247692199 3247895918 IN IP4 %s \n\
+      s=%s\n\
+      u=%s \n\
+      t=3247691400 3250117800 \n\
+      a=type:test   \n\
+      m=audio 1234 udp 14 \n\
+      c=IN IP4 %s/15  \n\
+      xxxxxxxxxxxxxxxxxxxxx \n ",user,machine,p_this->psz_name,site,p_this->psz_url);
+        
+     i_send_result =  sendto( p_this->socket , sap_msg , strlen(sap_msg) , 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("send"); 
+     }
+     p_this->sendnow=0;
+    }
+     p_this->sendnow++;  
+}