]> git.sesse.net Git - vlc/commitdiff
IP Multicast support, courtesy of Mathias Kretschmer <mathias@research.att.com>.
authorChristophe Massiot <massiot@videolan.org>
Mon, 27 Aug 2001 16:13:20 +0000 (16:13 +0000)
committerChristophe Massiot <massiot@videolan.org>
Mon, 27 Aug 2001 16:13:20 +0000 (16:13 +0000)
AUTHORS
plugins/mpeg/input_ts.c
src/input/input.c

diff --git a/AUTHORS b/AUTHORS
index 5e68a03ec2aec27ba5920860e415709b01775bbe..cd33b53f0f6ad1ed53d3cc5420314c8d7da84b9e 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -160,6 +160,10 @@ C: dae
 D: FreeBSD port and tests
 D: KDE interface
 
+N: Mathias Kretschmer
+E: mathias@research.att.com
+D: IP Multicast support
+
 N: Markus Kuespert
 E: ltlBeBoy@beosmail.com
 D: BeOS port of the DVD ioctls
index 8835f795bed775ac939e426a357bd1d617abb185..94879184755b6e155c5ed4cc93752480c06ac5e1 100644 (file)
@@ -2,7 +2,7 @@
  * input_ts.c: TS demux and netlist management
  *****************************************************************************
  * Copyright (C) 1998, 1999, 2000 VideoLAN
- * $Id: input_ts.c,v 1.31 2001/07/30 00:53:05 sam Exp $
+ * $Id: input_ts.c,v 1.32 2001/08/27 16:13:20 massiot Exp $
  *
  * Authors: Henri Fallon <henri@videolan.org>
  *
@@ -331,13 +331,20 @@ static int TSRead( input_thread_t * p_input,
         }
 #else
         i_read = readv( p_input->i_handle, p_iovec, INPUT_READ_ONCE );
+
+        /* Shouldn't happen, but it does - at least under Linux */
+        if( (i_read == -1) && ( (errno == EAGAIN) || (errno = EWOULDBLOCK) ) )
+        {
+            /* just ignore that error */
+            i_read = 0;
+        }
 #endif
         if( i_read == -1 )
         {
             intf_ErrMsg( "input error: TS readv error" );
             return( -1 );
         }
-
+       
         input_NetlistMviovec( p_input->p_method_data,
                 (int)(i_read/TS_PACKET_SIZE) , pp_packets );
 
index 51ba34b323cb133ce1b214c1b2c190d234fd3aec..171700bde6d6ef1f3f10aa684dbdeb9145cb7030 100644 (file)
@@ -4,7 +4,7 @@
  * decoders.
  *****************************************************************************
  * Copyright (C) 1998, 1999, 2000 VideoLAN
- * $Id: input.c,v 1.129 2001/08/09 08:20:26 sam Exp $
+ * $Id: input.c,v 1.130 2001/08/27 16:13:20 massiot Exp $
  *
  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  *
@@ -637,7 +637,10 @@ static void NetworkOpen( input_thread_t * p_input )
     char                *psz_broadcast = NULL;
     int                 i_port = 0;
     int                 i_opt;
+    int                 i_opt_size;
     struct sockaddr_in  sock;
+    unsigned int        i_mc_group;
+
 #ifdef WIN32
     WSADATA Data;
     int i_err;
@@ -766,7 +769,7 @@ static void NetworkOpen( input_thread_t * p_input )
     /* We may want to reuse an already used socket */
     i_opt = 1;
     if( setsockopt( p_input->i_handle, SOL_SOCKET, SO_REUSEADDR,
-                    (void*) &i_opt, sizeof( i_opt ) ) == -1 )
+                    (void *) &i_opt, sizeof( i_opt ) ) == -1 )
     {
         intf_ErrMsg( "input error: can't configure socket (SO_REUSEADDR: %s)",
                      strerror(errno));
@@ -779,7 +782,7 @@ static void NetworkOpen( input_thread_t * p_input )
      * packet loss caused by scheduling problems */
     i_opt = 0x80000;
     if( setsockopt( p_input->i_handle, SOL_SOCKET, SO_RCVBUF,
-                    (void*) &i_opt, sizeof( i_opt ) ) == -1 )
+                    (void *) &i_opt, sizeof( i_opt ) ) == -1 )
     {
         intf_ErrMsg( "input error: can't configure socket (SO_RCVBUF: %s)", 
                      strerror(errno));
@@ -788,6 +791,27 @@ static void NetworkOpen( input_thread_t * p_input )
         return;
     }
 
+    /* Check if we really got what we have asked for, because Linux, etc.
+     * will silently limit the max buffer size to net.core.rmem_max which
+     * is typically only 65535 bytes */
+    i_opt = 0;
+    i_opt_size = sizeof( i_opt );
+    if( getsockopt( p_input->i_handle, SOL_SOCKET, SO_RCVBUF,
+                    (void*) &i_opt, &i_opt_size ) == -1 )
+    {
+        intf_ErrMsg( "input error: can't configure socket (SO_RCVBUF: %s)", 
+                     strerror(errno));
+        close( p_input->i_handle );
+        p_input->b_error = 1;
+        return;
+    }
+    
+    if( i_opt < 0x80000 )
+    {
+        intf_ErrMsg( "input warning: socket receive buffer size just %d instead of %d bytes.\n",
+                     i_opt, 0x80000 );
+    }
+
     /* Build the local socket */
     if ( network_BuildLocalAddr( &sock, i_port, psz_broadcast ) == -1 )
     {
@@ -797,11 +821,15 @@ static void NetworkOpen( input_thread_t * p_input )
         return;
     }
 
+    /* Required for IP_ADD_MEMBERSHIP */
+    i_mc_group = sock.sin_addr.s_addr;
+
 #if defined( WIN32 )
     if ( psz_broadcast != NULL )
     {
         sock.sin_addr.s_addr = INADDR_ANY;
     }
+#define IN_MULTICAST(a)         IN_CLASSD(a)
 #endif
     
     /* Bind it */
@@ -814,6 +842,24 @@ static void NetworkOpen( input_thread_t * p_input )
         return;
     }
 
+    /* Join the m/c group if sock is a multicast address */
+    if( IN_MULTICAST( ntohl(i_mc_group) ) )
+    {
+        struct ip_mreq imr;
+
+        imr.imr_interface.s_addr = htonl(INADDR_ANY);
+        imr.imr_multiaddr.s_addr = i_mc_group;
+        if( setsockopt( p_input->i_handle, IPPROTO_IP,IP_ADD_MEMBERSHIP,
+                        (char*)&imr, sizeof(struct ip_mreq) ) == -1 )
+        {
+            intf_ErrMsg( "input error: failed to join IP multicast group (%s)",
+                         strerror(errno) );
+            close( p_input->i_handle);
+            p_input->b_error = 1;
+            return;
+        }
+    }
+
     /* Build socket for remote connection */
     if ( network_BuildRemoteAddr( &sock, psz_server ) == -1 )
     {
@@ -823,7 +869,7 @@ static void NetworkOpen( input_thread_t * p_input )
         return;
     }
 
-    /* And connect it ... should we really connect ? */
+    /* And connect it */
     if( connect( p_input->i_handle, (struct sockaddr *) &sock,
                  sizeof( sock ) ) == (-1) )
     {
@@ -834,8 +880,6 @@ static void NetworkOpen( input_thread_t * p_input )
         return;
     }
 
-    /* We can't pace control, but FIXME : bug in meuuh's code to sync PCR
-     * with the server. */
     p_input->stream.b_pace_control = 0;
     p_input->stream.b_seekable = 0;