]> git.sesse.net Git - vlc/blobdiff - modules/access_output/udp.c
* mp4.c: added support for SVQ1.
[vlc] / modules / access_output / udp.c
index 64dc063d98c8403e2a1c07b272926e2a187d6b92..584358ae4e0366cd85c2f0d029a970d9b12211ee 100644 (file)
@@ -2,7 +2,7 @@
  * udp.c
  *****************************************************************************
  * Copyright (C) 2001, 2002 VideoLAN
- * $Id: udp.c,v 1.20 2004/02/20 17:13:42 massiot Exp $
+ * $Id$
  *
  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
  *          Eric Petit <titer@videolan.org>
@@ -85,7 +85,7 @@ vlc_module_begin();
     set_callbacks( Open, Close );
 vlc_module_end();
 
-typedef struct sout_access_thread_s
+typedef struct sout_access_thread_t
 {
     VLC_COMMON_MEMBERS
 
@@ -96,6 +96,8 @@ typedef struct sout_access_thread_s
     int         i_handle;
 
     int64_t     i_caching;
+    int64_t     i_late;
+    int         i_group;
 
 } sout_access_thread_t;
 
@@ -134,7 +136,7 @@ static int Open( vlc_object_t *p_this )
     if( !( p_sys = p_access->p_sys =
                 malloc( sizeof( sout_access_out_sys_t ) ) ) )
     {
-        msg_Err( p_access, "Not enough memory" );
+        msg_Err( p_access, "not enough memory" );
         return VLC_EGENERIC;
     }
 
@@ -142,8 +144,8 @@ static int Open( vlc_object_t *p_this )
     if( p_access->psz_access != NULL &&
         !strcmp( p_access->psz_access, "rtp" ) )
     {
-        msg_Warn( p_access, "be carefull that rtp ouput work only with ts "
-                  "payload(not an error)" );
+        msg_Warn( p_access, "be careful that rtp output only works with ts "
+                  "payload (not an error)" );
         p_sys->b_rtpts = 1;
     }
     else
@@ -202,7 +204,7 @@ static int Open( vlc_object_t *p_this )
         socket_desc.i_ttl = atoi( psz_val );
     }
     p_sys->p_thread->p_private = (void*)&socket_desc;
-    if( !( p_network = module_Need( p_sys->p_thread, "network", "" ) ) )
+    if( !( p_network = module_Need( p_sys->p_thread, "network", NULL, 0 ) ) )
     {
         msg_Err( p_access, "failed to open a connection (udp)" );
         return VLC_EGENERIC;
@@ -220,10 +222,28 @@ static int Open( vlc_object_t *p_this )
         p_sys->p_thread->i_caching = atoll( psz_val ) * 1000;
     }
 
+    p_sys->p_thread->i_group = 1;
+    if( ( psz_val = sout_cfg_find_value( p_access->p_cfg, "group" ) ) )
+    {
+        p_sys->p_thread->i_group = atoi( psz_val );
+    }
+
+    p_sys->p_thread->i_late = 0;
+    if( ( psz_val = sout_cfg_find_value( p_access->p_cfg, "late" ) ) )
+    {
+        p_sys->p_thread->i_late = atoll( psz_val ) * 1000;
+    }
+
+
     p_sys->i_mtu = socket_desc.i_mtu;
 
+#ifdef WIN32
+    if( vlc_thread_create( p_sys->p_thread, "sout write thread", ThreadWrite,
+                           VLC_THREAD_PRIORITY_HIGHEST, VLC_FALSE ) )
+#else
     if( vlc_thread_create( p_sys->p_thread, "sout write thread", ThreadWrite,
                            VLC_THREAD_PRIORITY_OUTPUT, VLC_FALSE ) )
+#endif
     {
         msg_Err( p_access->p_sout, "cannot spawn sout access thread" );
         vlc_object_destroy( p_sys->p_thread );
@@ -249,6 +269,10 @@ static int Open( vlc_object_t *p_this )
     msg_Info( p_access, "Open: addr:`%s' port:`%d'", psz_dst_addr, i_dst_port);
 
     free( psz_dst_addr );
+
+    /* update p_sout->i_out_pace_nocontrol */
+    p_access->p_sout->i_out_pace_nocontrol++;
+
     return VLC_SUCCESS;
 }
 
@@ -281,13 +305,10 @@ static void Close( vlc_object_t * p_this )
         sout_BufferDelete( p_access->p_sout, p_sys->p_buffer );
     }
 
-#if defined( UNDER_CE )
-    CloseHandle( (HANDLE)p_sys->p_thread->i_handle );
-#elif defined( WIN32 )
-    closesocket( p_sys->p_thread->i_handle );
-#else
-    close( p_sys->p_thread->i_handle );
-#endif
+    net_Close( p_sys->p_thread->i_handle );
+
+    /* update p_sout->i_out_pace_nocontrol */
+    p_access->p_sout->i_out_pace_nocontrol--;
 
     free( p_sys );
     msg_Info( p_access, "Close" );
@@ -410,8 +431,10 @@ static void ThreadWrite( vlc_object_t *p_this )
     sout_access_thread_t *p_thread = (sout_access_thread_t*)p_this;
     sout_instance_t      *p_sout = p_thread->p_sout;
     mtime_t              i_date_last = -1;
+    mtime_t              i_to_send = p_thread->i_group;
+    int                  i_dropped_packets = 0;
 
-    while( ! p_thread->b_die )
+    while( !p_thread->b_die )
     {
         sout_buffer_t *p_pk;
         mtime_t       i_date, i_sent;
@@ -423,41 +446,63 @@ static void ThreadWrite( vlc_object_t *p_this )
         {
             if( i_date - i_date_last > 2000000 )
             {
-                msg_Dbg( p_thread, "mmh, hole > 2s -> drop" );
+                if( !i_dropped_packets )
+                    msg_Dbg( p_thread, "mmh, hole > 2s -> drop" );
 
                 sout_BufferDelete( p_sout, p_pk );
                 i_date_last = i_date;
+                i_dropped_packets++;
                 continue;
             }
             else if( i_date - i_date_last < 0 )
             {
-                msg_Dbg( p_thread, "mmh, paquets in the past -> drop" );
+                if( !i_dropped_packets )
+                    msg_Dbg( p_thread, "mmh, paquets in the past -> drop" );
 
                 sout_BufferDelete( p_sout, p_pk );
                 i_date_last = i_date;
+                i_dropped_packets++;
                 continue;
             }
         }
 
         i_sent = mdate();
-        if ( i_sent > i_date + 100000 )
+        if( p_thread->i_late > 0 && i_sent > i_date + p_thread->i_late )
         {
-            msg_Dbg( p_thread, "late packet to send (" I64Fd ") -> drop",
-                     i_sent - i_date );
+            if( !i_dropped_packets )
+            {
+                msg_Dbg( p_thread, "late packet to send (" I64Fd ") -> drop",
+                         i_sent - i_date );
+            }
             sout_BufferDelete( p_sout, p_pk );
             i_date_last = i_date;
+            i_dropped_packets++;
             continue;
         }
 
-        mwait( i_date );
+        i_to_send--;
+        if ( !i_to_send )
+        {
+            mwait( i_date );
+            i_to_send = p_thread->i_group;
+        }
         send( p_thread->i_handle, p_pk->p_buffer, p_pk->i_size, 0 );
 
+        if( i_dropped_packets )
+        {
+            msg_Dbg( p_thread, "dropped %i packets", i_dropped_packets );
+            i_dropped_packets = 0;
+        }
+
+#if 0
         i_sent = mdate();
         if ( i_sent > i_date + 20000 )
         {
             msg_Dbg( p_thread, "packet has been sent too late (" I64Fd ")",
                      i_sent - i_date );
         }
+#endif
+
         sout_BufferDelete( p_sout, p_pk );
         i_date_last = i_date;
     }