]> git.sesse.net Git - vlc/blobdiff - modules/access_output/udp.c
* modules/codec/dvbsub.c: oops, small fix.
[vlc] / modules / access_output / udp.c
index 710d4d5dc6f3911a51acb043e7d13909fd1c7113..cc32019f359336f929b17236e8e49ad93df9a4cf 100644 (file)
@@ -62,16 +62,40 @@ static void Close( vlc_object_t * );
 
 #define CACHING_TEXT N_("Caching value (ms)")
 #define CACHING_LONGTEXT N_( \
-    "Allows you to modify the default caching value for udp streams. This " \
+    "Allows you to modify the default caching value for UDP streams. This " \
     "value should be set in millisecond units." )
 
+#define TTL_TEXT N_("Time To Live")
+#define TTL_LONGTEXT N_("Allows you to define the time to live of the " \
+                        "outgoing stream.")
+
+#define GROUP_TEXT N_("Group packets")
+#define GROUP_LONGTEXT N_("Packets can be sent one by one at the right time " \
+                          "or by groups. This allows you to give the number " \
+                          "of packets that will be sent at a time. It " \
+                          "helps reducing the scheduling load on " \
+                          "heavily-loaded systems." )
+#define LATE_TEXT N_("Late delay (ms)" )
+#define LATE_LONGTEXT N_("Late packets are dropped. This allows you to give " \
+                       "the time (in milliseconds) a packet is allowed to be" \
+                       " late.")
+#define RAW_TEXT N_("Raw write")
+#define RAW_LONGTEXT N_("If you enable this option, packets will be sent " \
+                       "directly, without trying to fill the MTU (ie, " \
+                       "without trying to make the biggest possible packets " \
+                       "in order to improve streaming)." )
+
 vlc_module_begin();
-    set_description( _("UDP stream ouput") );
+    set_description( _("UDP stream output") );
     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", "", VLC_TRUE );
-    add_integer( SOUT_CFG_PREFIX "group", 1, NULL, "group", "", VLC_TRUE );
-    add_integer( SOUT_CFG_PREFIX "late", 0, NULL, "late (ms)", "", VLC_TRUE );
-    add_bool( SOUT_CFG_PREFIX "raw",  0, NULL, "raw", "", VLC_TRUE );
+    add_integer( SOUT_CFG_PREFIX "ttl", 0, NULL,TTL_TEXT, TTL_LONGTEXT,
+                                 VLC_TRUE );
+    add_integer( SOUT_CFG_PREFIX "group", 1, NULL, GROUP_TEXT, GROUP_LONGTEXT,
+                                 VLC_TRUE );
+    add_integer( SOUT_CFG_PREFIX "late", 0, NULL, LATE_TEXT, LATE_LONGTEXT,
+                                 VLC_TRUE );
+    add_bool( SOUT_CFG_PREFIX "raw",  0, NULL, RAW_TEXT, RAW_LONGTEXT,
+                                 VLC_TRUE );
 
     set_capability( "sout access", 100 );
     add_shortcut( "udp" );
@@ -97,10 +121,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
@@ -123,12 +145,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
@@ -150,15 +173,16 @@ static int Open( vlc_object_t *p_this )
 
     vlc_value_t         val;
 
-    sout_ParseCfg( 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" ) )
@@ -261,18 +285,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 );
 
@@ -304,10 +323,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 );
 
@@ -324,40 +340,54 @@ 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_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;
@@ -450,7 +480,8 @@ 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;
@@ -460,7 +491,8 @@ static void ThreadWrite( vlc_object_t *p_this )
             else if( i_date - i_date_last < 0 )
             {
                 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;