]> git.sesse.net Git - vlc/commitdiff
UDP-Lite access
authorRémi Denis-Courmont <rem@videolan.org>
Mon, 5 Feb 2007 16:32:31 +0000 (16:32 +0000)
committerRémi Denis-Courmont <rem@videolan.org>
Mon, 5 Feb 2007 16:32:31 +0000 (16:32 +0000)
This is completely untested because vlc does not link at the moment :(

NEWS
configure.ac
include/vlc_network.h
modules/access/udp.c
src/network/udp.c

diff --git a/NEWS b/NEWS
index f4d648a3e975aa23fb9146b9dd670808e475aa9a..d38ef9e3fb7c5522d945f42bf4a056d22fd311d6 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -28,6 +28,9 @@ Playlist:
     * Shoutcast TV listings
     * Audioscrobbler/last.fm support
 
+Input/Demuxers:
+  * Support for UDP-Lite (requires OS support) for UDP-Raw and RTP
+
 Decoders:
  * VP60/VP61 codecs support
 
index 49e46dd8a57793dd88eae2aea8776ae3ad8d617e..e9a9866869d1be73af9223376963ff35f95c1a89 100644 (file)
@@ -766,7 +766,7 @@ AC_EGREP_HEADER(strncasecmp,strings.h,[
 dnl Check for headers
 AC_CHECK_HEADERS(signal.h time.h errno.h stdint.h stdbool.h getopt.h strings.h inttypes.h sys/int_types.h wchar.h)
 AC_CHECK_HEADERS(sys/sockio.h fcntl.h sys/types.h sys/time.h sys/times.h sys/ioctl.h sys/stat.h)
-AC_CHECK_HEADERS(arpa/inet.h net/if.h netinet/in.h sys/socket.h)
+AC_CHECK_HEADERS([arpa/inet.h net/if.h netinet/in.h sys/socket.h netinet/udplite.h])
 if test "${SYS}" != "mingw32" -a "${SYS}" != "mingwce"; then
 AC_CHECK_HEADERS(machine/param.h sys/shm.h)
 AC_CHECK_HEADERS(linux/version.h)
index 417fcd51b28cc72574839abf1c38de324a31cc27..ff27b231fd4232ce5fe4853818accee57a4105ad 100644 (file)
@@ -91,8 +91,8 @@ static inline int net_ListenUDP1 (vlc_object_t *obj, const char *host, int port)
        return net_ListenSingle (obj, host, port, AF_UNSPEC, SOCK_DGRAM, IPPROTO_UDP);
 }
 
-#define net_OpenUDP(a, b, c, d, e ) __net_OpenUDP(VLC_OBJECT(a), b, c, d, e)
-VLC_EXPORT( int, __net_OpenUDP, ( vlc_object_t *p_this, const char *psz_bind, int i_bind, const char *psz_server, int i_server ) );
+#define net_OpenDgram( a, b, c, d, e, g, h ) __net_OpenDgram(VLC_OBJECT(a), b, c, d, e, g, h)
+VLC_EXPORT( int, __net_OpenDgram, ( vlc_object_t *p_this, const char *psz_bind, int i_bind, const char *psz_server, int i_server, int family, int proto ) );
 
 VLC_EXPORT( void, net_Close, ( int fd ) );
 VLC_EXPORT( void, net_ListenClose, ( int *fd ) );
index f6c1a3d135ad98252b239a72e0de687fd97d2445..19e4d60c44cfe715d54587914b44a9875658530b 100644 (file)
 #include <vlc_access.h>
 #include <vlc_network.h>
 
+#if defined (HAVE_NETINET_UDPLITE_H)
+# include <netinet/udplite.h>
+#elif defined (__linux__)
+# define UDPLITE_SEND_CSCOV     10
+# define UDPLITE_RECV_CSCOV     11
+#endif
+
+#ifndef IPPROTO_UDPLITE
+# define IPPROTO_UDPLITE 136 /* from IANA */
+#endif
+#ifndef SOL_UDPLITE
+# define SOL_UDPLITE IPPROTO_UDPLITE
+#endif
+
+
 /*****************************************************************************
  * Module descriptor
  *****************************************************************************/
@@ -77,6 +92,9 @@ vlc_module_begin();
     add_shortcut( "rtp" );
     add_shortcut( "rtp4" );
     add_shortcut( "rtp6" );
+    add_shortcut( "udplite" );
+    add_shortcut( "rtplite" );
+
     set_callbacks( Open, Close );
 vlc_module_end();
 
@@ -116,34 +134,25 @@ static int Open( vlc_object_t *p_this )
     char *psz_parser;
     const char *psz_server_addr, *psz_bind_addr = "";
     int  i_bind_port, i_server_port = 0;
+    int fam = AF_UNSPEC, proto = IPPROTO_UDP, cscov = 8;
 
-    /* First set ipv4/ipv6 */
-    var_Create( p_access, "ipv4", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
-    var_Create( p_access, "ipv6", VLC_VAR_BOOL | VLC_VAR_DOINHERIT );
-
-    if( *p_access->psz_access )
-    {
-        vlc_value_t val;
-        /* Find out which shortcut was used */
-        if( !strncmp( p_access->psz_access, "udp4", 6 ) ||
-            !strncmp( p_access->psz_access, "rtp4", 6 ))
+    if (strlen (p_access->psz_access) >= 4)
+        switch (p_access->psz_access[3])
         {
-            val.b_bool = VLC_TRUE;
-            var_Set( p_access, "ipv4", val );
+            case '4':
+                fam = AF_INET;
+                break;
 
-            val.b_bool = VLC_FALSE;
-            var_Set( p_access, "ipv6", val );
+            case '6':
+                fam = AF_INET6;
+                break;
         }
-        else if( !strncmp( p_access->psz_access, "udp6", 6 ) ||
-                 !strncmp( p_access->psz_access, "rtp6", 6 ) )
-        {
-            val.b_bool = VLC_TRUE;
-            var_Set( p_access, "ipv6", val );
-
-            val.b_bool = VLC_FALSE;
-            var_Set( p_access, "ipv4", val );
-        }
-    }
+    if (strcmp (p_access->psz_access + 3, "lite") == 0)
+        proto = IPPROTO_UDPLITE;
+    if (strncmp (p_access->psz_access, "rtp", 3) == 0)
+        /* Checksum coverage: RTP header is AT LEAST 12 bytes
+         * in addition to UDP header (8 bytes) */
+        cscov += 12;
 
     i_bind_port = var_CreateGetInteger( p_access, "server-port" );
 
@@ -195,19 +204,23 @@ static int Open( vlc_object_t *p_this )
     p_access->info.b_prebuffered = VLC_FALSE;
     MALLOC_ERR( p_access->p_sys, access_sys_t ); p_sys = p_access->p_sys;
 
-    p_sys->fd = net_OpenUDP( p_access, psz_bind_addr, i_bind_port,
-                                      psz_server_addr, i_server_port );
-    if( p_sys->fd < 0 )
+    p_sys->fd = net_Open( p_access, psz_bind_addr, i_bind_port,
+                          psz_server_addr, i_server_port, fam, SOCK_DGRAM, proto );
+    free (psz_name);
+    if( p_sys->fd == -1 )
     {
         msg_Err( p_access, "cannot open socket" );
-        free( psz_name );
         free( p_sys );
         return VLC_EGENERIC;
     }
-    free( psz_name );
 
     net_StopSend( p_sys->fd );
 
+#ifdef UDPLITE_RECV_CSCOV
+    if (proto == IPPROTO_UDPLITE)
+        setsockopt (p_sys->fd, SOL_UDPLITE, UDPLITE_RECV_CSCOV, &cscov, sizeof (cscov));
+#endif
+
     /* FIXME */
     p_sys->i_mtu = var_CreateGetInteger( p_access, "mtu" );
     if( p_sys->i_mtu <= 1 )
index b86948b16fb75d28e2e3dd859acf66c30f83b4e7..70d18566ba3e651fcd858fd08e711c03465bf8f7 100644 (file)
@@ -618,25 +618,27 @@ int __net_ConnectUDP( vlc_object_t *p_this, const char *psz_host, int i_port,
 
 
 /*****************************************************************************
- * __net_OpenUDP:
+ * __net_OpenDgram:
  *****************************************************************************
- * Open a UDP connection and return a handle
+ * OpenDgram a datagram socket and return a handle
  *****************************************************************************/
-int __net_OpenUDP( vlc_object_t *obj, const char *psz_bind, int i_bind,
-                   const char *psz_server, int i_server )
+int __net_OpenDgram( vlc_object_t *obj, const char *psz_bind, int i_bind,
+                     const char *psz_server, int i_server,
+                     int family, int protocol )
 {
     struct addrinfo hints, *loc, *rem;
     int val;
 
     if( !*psz_server )
-        return net_ListenUDP1 (obj, psz_bind, i_bind);
+        return net_ListenSingle (obj, psz_bind, i_bind,
+                                 family, SOCK_DGRAM, protocol);
 
     msg_Dbg( obj, "net: connecting to [%s]:%d from [%s]:%d",
              psz_server, i_server, psz_bind, i_bind );
 
     memset (&hints, 0, sizeof (hints));
+    hints.ai_family = family;
     hints.ai_socktype = SOCK_DGRAM;
-    hints.ai_protocol = IPPROTO_UDP;
     hints.ai_flags = AI_PASSIVE;
 
     val = vlc_getaddrinfo (obj, psz_server, i_server, &hints, &rem);
@@ -659,7 +661,7 @@ int __net_OpenUDP( vlc_object_t *obj, const char *psz_bind, int i_bind,
     for (struct addrinfo *ptr = loc; ptr != NULL; ptr = ptr->ai_next)
     {
         int fd = net_Socket (obj, ptr->ai_family, ptr->ai_socktype,
-                             ptr->ai_protocol);
+                             protocol ?: ptr->ai_protocol);
         if (fd == -1)
             continue; // usually, address family not supported