]> git.sesse.net Git - vlc/blobdiff - modules/access_output/udp.c
* modules/access_output/udp.c: When using --udp-group, do not send two PCRs
[vlc] / modules / access_output / udp.c
index d998b604d2d7a75217f7aa92edcf25e6b52da208..9c4d5270bdf6b2a1d0858c87ae4649ae81b64e76 100644 (file)
@@ -87,6 +87,9 @@ static void Close( vlc_object_t * );
 
 vlc_module_begin();
     set_description( _("UDP stream output") );
+    set_shortname( N_( "UDP" ) );
+    set_category( CAT_SOUT );
+    set_subcategory( SUBCAT_SOUT_ACO );
     add_integer( SOUT_CFG_PREFIX "caching", DEFAULT_PTS_DELAY / 1000, NULL, CACHING_TEXT, CACHING_LONGTEXT, VLC_TRUE );
     add_integer( SOUT_CFG_PREFIX "ttl", 0, NULL,TTL_TEXT, TTL_LONGTEXT,
                                  VLC_TRUE );
@@ -121,10 +124,8 @@ static int  WriteRaw( sout_access_out_t *, block_t * );
 static int  Seek    ( sout_access_out_t *, off_t  );
 
 static void ThreadWrite( vlc_object_t * );
-
 static block_t *NewUDPPacket( sout_access_out_t *, mtime_t );
 
-
 typedef struct sout_access_thread_t
 {
     VLC_COMMON_MEMBERS
@@ -147,12 +148,13 @@ struct sout_access_out_sys_t
     uint16_t            i_sequence_number;
     uint32_t            i_ssrc;
 
-    unsigned int        i_mtu;
+    int                 i_mtu;
 
     block_t             *p_buffer;
 
     sout_access_thread_t *p_thread;
 
+    vlc_bool_t          b_mtu_warning;
 };
 
 #define DEFAULT_PORT 1234
@@ -174,15 +176,16 @@ static int Open( vlc_object_t *p_this )
 
     vlc_value_t         val;
 
-    sout_CfgParse( p_access, SOUT_CFG_PREFIX, ppsz_sout_options, p_access->p_cfg );
+    sout_CfgParse( p_access, SOUT_CFG_PREFIX,
+                   ppsz_sout_options, p_access->p_cfg );
 
-    if( !( p_sys = p_access->p_sys =
-                malloc( sizeof( sout_access_out_sys_t ) ) ) )
+    if( !( p_sys = malloc( sizeof( sout_access_out_sys_t ) ) ) )
     {
         msg_Err( p_access, "not enough memory" );
         return VLC_EGENERIC;
     }
-
+    memset( p_sys, 0, sizeof(sout_access_out_sys_t) );
+    p_access->p_sys = p_sys;
 
     if( p_access->psz_access != NULL &&
         !strcmp( p_access->psz_access, "rtp" ) )
@@ -285,18 +288,13 @@ static int Open( vlc_object_t *p_this )
     p_sys->i_ssrc            = rand()&0xffffffff;
 
     var_Get( p_access, SOUT_CFG_PREFIX "raw", &val );
-    if( val.b_bool )
-    {
-        p_access->pf_write = WriteRaw;
-    }
-    else
-    {
-        p_access->pf_write = Write;
-    }
+    if( val.b_bool )  p_access->pf_write = WriteRaw;
+    else p_access->pf_write = Write;
 
     p_access->pf_seek = Seek;
 
-    msg_Dbg( p_access, "udp access output opened(%s:%d)", psz_dst_addr, i_dst_port );
+    msg_Dbg( p_access, "udp access output opened(%s:%d)",
+             psz_dst_addr, i_dst_port );
 
     free( psz_dst_addr );
 
@@ -328,10 +326,7 @@ static void Close( vlc_object_t * p_this )
 
     block_FifoRelease( p_sys->p_thread->p_fifo );
 
-    if( p_sys->p_buffer )
-    {
-        block_Release( p_sys->p_buffer );
-    }
+    if( p_sys->p_buffer ) block_Release( p_sys->p_buffer );
 
     net_Close( p_sys->p_thread->i_handle );
 
@@ -348,40 +343,56 @@ static void Close( vlc_object_t * p_this )
 static int Write( sout_access_out_t *p_access, block_t *p_buffer )
 {
     sout_access_out_sys_t *p_sys = p_access->p_sys;
-    unsigned int i_write;
 
     while( p_buffer )
     {
         block_t *p_next;
-        if( p_buffer->i_buffer > p_sys->i_mtu )
-        {
-            msg_Warn( p_access, "arggggggggggggg packet size > mtu" );
-            i_write = p_sys->i_mtu;
-        }
-        else
+        int i_packets = 0;
+
+        if( !p_sys->b_mtu_warning && p_buffer->i_buffer > p_sys->i_mtu )
         {
-            i_write = p_buffer->i_buffer;
+            msg_Warn( p_access, "packet size > MTU, you should probably "
+                      "increase the MTU" );
+            p_sys->b_mtu_warning = VLC_TRUE;
         }
 
-        /* if we have enough data, enque the buffer */
+        /* Check if there is enough space in the buffer */
         if( p_sys->p_buffer &&
-            p_sys->p_buffer->i_buffer + i_write > p_sys->i_mtu )
+            p_sys->p_buffer->i_buffer + p_buffer->i_buffer > p_sys->i_mtu )
         {
             block_FifoPut( p_sys->p_thread->p_fifo, p_sys->p_buffer );
             p_sys->p_buffer = NULL;
         }
 
-        if( !p_sys->p_buffer )
+        while( p_buffer->i_buffer )
         {
-            p_sys->p_buffer = NewUDPPacket( p_access, p_buffer->i_dts );
-        }
+            int i_write = __MIN( p_buffer->i_buffer, p_sys->i_mtu );
+
+            i_packets++;
+
+            if( !p_sys->p_buffer )
+            {
+                p_sys->p_buffer = NewUDPPacket( p_access, p_buffer->i_dts );
+                if( !p_sys->p_buffer ) break;
+            }
 
-        if( p_buffer->i_buffer > 0 )
-        {
             memcpy( p_sys->p_buffer->p_buffer + p_sys->p_buffer->i_buffer,
                     p_buffer->p_buffer, i_write );
+
             p_sys->p_buffer->i_buffer += i_write;
+            p_buffer->p_buffer += i_write;
+            p_buffer->i_buffer -= i_write;
+            if ( p_buffer->i_flags & BLOCK_FLAG_CLOCK )
+                p_sys->p_buffer->i_flags |= BLOCK_FLAG_CLOCK;
+
+            if( p_sys->p_buffer->i_buffer == p_sys->i_mtu || i_packets > 1 )
+            {
+                /* Flush */
+                block_FifoPut( p_sys->p_thread->p_fifo, p_sys->p_buffer );
+                p_sys->p_buffer = NULL;
+            }
         }
+
         p_next = p_buffer->p_next;
         block_Release( p_buffer );
         p_buffer = p_next;
@@ -474,17 +485,19 @@ static void ThreadWrite( vlc_object_t *p_this )
             if( i_date - i_date_last > 2000000 )
             {
                 if( !i_dropped_packets )
-                    msg_Dbg( p_thread, "mmh, hole > 2s -> drop" );
+                    msg_Dbg( p_thread, "mmh, hole ("I64Fd" > 2s) -> drop",
+                             i_date - i_date_last );
 
                 block_Release( p_pk  );
                 i_date_last = i_date;
                 i_dropped_packets++;
                 continue;
             }
-            else if( i_date - i_date_last < 0 )
+            else if( i_date - i_date_last < -15000 )
             {
                 if( !i_dropped_packets )
-                    msg_Dbg( p_thread, "mmh, paquets in the past -> drop" );
+                    msg_Dbg( p_thread, "mmh, packets in the past ("I64Fd")"
+                             " -> drop", i_date - i_date_last );
 
                 block_Release( p_pk  );
                 i_date_last = i_date;
@@ -508,7 +521,7 @@ static void ThreadWrite( vlc_object_t *p_this )
         }
 
         i_to_send--;
-        if ( !i_to_send )
+        if ( !i_to_send || (p_pk->i_flags & BLOCK_FLAG_CLOCK) )
         {
             mwait( i_date );
             i_to_send = p_thread->i_group;
@@ -521,7 +534,7 @@ static void ThreadWrite( vlc_object_t *p_this )
             i_dropped_packets = 0;
         }
 
-#if 0
+#if 1
         i_sent = mdate();
         if ( i_sent > i_date + 20000 )
         {