[vlc-commits] [Git][videolan/vlc][master] 8 commits: srt: obsolete SRT_PARAM_CHUNK_SIZE and SRT_PARAM_PAYLOAD_SIZE

Hugo Beauzée-Luyssen (@chouquette) gitlab at videolan.org
Fri Sep 3 07:45:26 UTC 2021



Hugo Beauzée-Luyssen pushed to branch master at VideoLAN / VLC


Commits:
0b0cc7ff by Zhao Zhili at 2021-09-03T07:00:29+00:00
srt: obsolete SRT_PARAM_CHUNK_SIZE and SRT_PARAM_PAYLOAD_SIZE

Firstly, SRTO_PAYLOADSIZE has no effect for receiver. Secondly,
since there is no negotiation of payload size between sender and
receiver, the receiver should use a buffer at least
SRT_LIVE_MAX_PLSIZE bytes, otherwise the data can be truncated.
So the default value of option SRT_PARAM_CHUNK_SIZE is
inappropriate. User may know exactly the sender's payload size
to set the value for SRT_PARAM_CHUNK_SIZE, but there is no much
gain for doing that.

- - - - -
52e3f716 by Zhao Zhili at 2021-09-03T07:00:29+00:00
srt: Fix missing srt_cleanup on error path

- - - - -
e452063d by Zhao Zhili at 2021-09-03T07:00:29+00:00
srt: initialize p_sys->sock to SRT_INVALID_SOCK

Otherwise the zero initialized p_sys->sock will be closed in
srt_schedule_reconnect().

- - - - -
e6b547cc by Zhao Zhili at 2021-09-03T07:00:29+00:00
srt: comment out too verbose log

- - - - -
c90ef66a by Zhao Zhili at 2021-09-03T07:00:29+00:00
access_output/srt: obsolete SRT_PARAM_CHUNK_SIZE

It's the same thing as SRT_PARAM_PAYLOAD_SIZE.

- - - - -
853df267 by Zhao Zhili at 2021-09-03T07:00:29+00:00
access_output/srt: simplify always true condition

- - - - -
53d7fd39 by Zhao Zhili at 2021-09-03T07:00:29+00:00
mux:ts: use block_chain to send data

So access_out can combine multiple ts packets into single chunk.

- - - - -
84bc80de by Zhao Zhili at 2021-09-03T07:00:29+00:00
access_output/srt: send data in payload_size chunks

Fix #26048

To avoid sending a lot of small UDP packets.

- - - - -


3 changed files:

- modules/access/srt.c
- modules/access_output/srt.c
- modules/mux/mpeg/ts.c


Changes:

=====================================
modules/access/srt.c
=====================================
@@ -93,7 +93,6 @@ static bool srt_schedule_reconnect(stream_t *p_stream)
 {
     vlc_object_t *strm_obj = (vlc_object_t *) p_stream;
     int i_latency=var_InheritInteger( p_stream, SRT_PARAM_LATENCY );
-    int i_payload_size = var_InheritInteger( p_stream, SRT_PARAM_PAYLOAD_SIZE );
     int stat;
     char *psz_passphrase = var_InheritString( p_stream, SRT_PARAM_PASSPHRASE );
     bool passphrase_needs_free = true;
@@ -140,8 +139,6 @@ static bool srt_schedule_reconnect(stream_t *p_stream)
         if (srt_parse_url( url, &params )) {
             if (params.latency != -1)
                 i_latency = params.latency;
-            if (params.payload_size != -1)
-                i_payload_size = params.payload_size;
             if (params.passphrase != NULL) {
                 free( psz_passphrase );
                 passphrase_needs_free = false;
@@ -190,11 +187,6 @@ static bool srt_schedule_reconnect(stream_t *p_stream)
                 SRTO_STREAMID, psz_streamid, strlen(psz_streamid) );
     }
 
-    /* set maximum payload size */
-    srt_set_socket_option( strm_obj, SRT_PARAM_PAYLOAD_SIZE, p_sys->sock,
-            SRTO_PAYLOADSIZE, &i_payload_size, sizeof(i_payload_size) );
-
-
     srt_epoll_add_usock( p_sys->i_poll_id, p_sys->sock,
         &(int) { SRT_EPOLL_ERR | SRT_EPOLL_IN });
 
@@ -235,7 +227,6 @@ out:
 static block_t *BlockSRT(stream_t *p_stream, bool *restrict eof)
 {
     stream_sys_t *p_sys = p_stream->p_sys;
-    int i_chunk_size = var_InheritInteger( p_stream, SRT_PARAM_CHUNK_SIZE );
     int i_poll_timeout = var_InheritInteger( p_stream, SRT_PARAM_POLL_TIMEOUT );
     /* SRT doesn't have a concept of EOF for live streams. */
     VLC_UNUSED(eof);
@@ -249,9 +240,8 @@ static block_t *BlockSRT(stream_t *p_stream, bool *restrict eof)
     if ( p_sys->i_chunks == 0 )
         p_sys->i_chunks = SRT_MIN_CHUNKS_TRYREAD;
 
-    size_t i_chunk_size_actual = ( i_chunk_size > 0 )
-        ? i_chunk_size : SRT_DEFAULT_CHUNK_SIZE;
-    size_t bufsize = i_chunk_size_actual * p_sys->i_chunks;
+    const size_t i_chunk_size = SRT_LIVE_MAX_PLSIZE;
+    const size_t bufsize = i_chunk_size * p_sys->i_chunks;
     block_t *pkt = block_Alloc( bufsize );
     if ( unlikely( pkt == NULL ) )
     {
@@ -297,7 +287,7 @@ static block_t *BlockSRT(stream_t *p_stream, bool *restrict eof)
          * each iteration.
          */
         pkt->i_buffer = 0;
-        while ( ( bufsize - pkt->i_buffer ) >= i_chunk_size_actual )
+        while ( ( bufsize - pkt->i_buffer ) >= i_chunk_size )
         {
             int stat = srt_recvmsg( p_sys->sock,
                 (char *)( pkt->p_buffer + pkt->i_buffer ),
@@ -309,18 +299,19 @@ static block_t *BlockSRT(stream_t *p_stream, bool *restrict eof)
             pkt->i_buffer += (size_t)stat;
         }
 
+#if 0
         msg_Dbg ( p_stream, "Read %zu bytes out of a max of %zu"
             " (%d chunks of %zu bytes)", pkt->i_buffer,
-            p_sys->i_chunks * i_chunk_size_actual, p_sys->i_chunks,
-                 i_chunk_size_actual );
-
+            p_sys->i_chunks * i_chunk_size, p_sys->i_chunks,
+                i_chunk_size );
+#endif
 
         /* Gradually adjust number of chunks we read at a time
         * up to a predefined maximum. The actual number we might
         * settle on depends on stream's bit rate.
         */
         size_t rem = bufsize - pkt->i_buffer;
-        if ( rem < i_chunk_size_actual )
+        if ( rem < i_chunk_size )
         {
             if ( p_sys->i_chunks < SRT_MAX_CHUNKS_TRYREAD )
             {
@@ -391,6 +382,7 @@ static int Open(vlc_object_t *p_this)
         msg_Err( p_stream, "Failed to create poll id for SRT socket." );
         goto failed;
     }
+    p_sys->sock = SRT_INVALID_SOCK;
 
     if ( !srt_schedule_reconnect( p_stream ) )
     {
@@ -405,8 +397,9 @@ static int Open(vlc_object_t *p_this)
     return VLC_SUCCESS;
 
 failed:
-    if ( p_sys->sock != -1 ) srt_close( p_sys->sock );
+    if ( p_sys->sock != SRT_INVALID_SOCK ) srt_close( p_sys->sock );
     if ( p_sys->i_poll_id != -1 ) srt_epoll_release( p_sys->i_poll_id );
+    srt_cleanup();
 
     return VLC_EGENERIC;
 }
@@ -430,8 +423,7 @@ vlc_module_begin ()
     set_category( CAT_INPUT )
     set_subcategory( SUBCAT_INPUT_ACCESS )
 
-    add_integer( SRT_PARAM_CHUNK_SIZE, SRT_DEFAULT_CHUNK_SIZE,
-            N_( "SRT chunk size (bytes)" ), NULL )
+    add_obsolete_integer( SRT_PARAM_CHUNK_SIZE )
     add_integer( SRT_PARAM_POLL_TIMEOUT, SRT_DEFAULT_POLL_TIMEOUT,
             N_( "Return poll wait after timeout milliseconds (-1 = infinite)" ),
             NULL )
@@ -439,8 +431,7 @@ vlc_module_begin ()
             N_( "SRT latency (ms)" ), NULL )
     add_password( SRT_PARAM_PASSPHRASE, "",
             N_( "Password for stream encryption" ), NULL )
-    add_integer( SRT_PARAM_PAYLOAD_SIZE, SRT_DEFAULT_PAYLOAD_SIZE,
-            N_( "SRT maximum payload size (bytes)" ), NULL )
+    add_obsolete_integer( SRT_PARAM_PAYLOAD_SIZE )
     add_integer( SRT_PARAM_KEY_LENGTH, SRT_DEFAULT_KEY_LENGTH,
             SRT_KEY_LENGTH_TEXT, NULL )
     change_integer_list( srt_key_lengths, srt_key_length_names )


=====================================
modules/access_output/srt.c
=====================================
@@ -29,6 +29,7 @@
 #include <vlc_plugin.h>
 #include <vlc_sout.h>
 #include <vlc_block.h>
+#include <vlc_block_helper.h>
 #include <vlc_network.h>
 
 typedef struct
@@ -37,6 +38,8 @@ typedef struct
     int           i_poll_id;
     bool          b_interrupted;
     vlc_mutex_t   lock;
+    int           i_payload_size;
+    block_bytestream_t block_stream;
 } sout_access_out_sys_t;
 
 static void srt_wait_interrupted(void *p_data)
@@ -182,8 +185,16 @@ static bool srt_schedule_reconnect(sout_access_out_t *p_access)
     }
 
     /* set maximumu payload size */
-    srt_set_socket_option( access_obj, SRT_PARAM_PAYLOAD_SIZE, p_sys->sock,
+    stat = srt_set_socket_option( access_obj, SRT_PARAM_PAYLOAD_SIZE, p_sys->sock,
             SRTO_PAYLOADSIZE, &i_payload_size, sizeof(i_payload_size) );
+    if ( stat == SRT_ERROR )
+    {
+        msg_Err( p_access, "Failed to config payload size, %s",
+                 srt_getlasterror_str() );
+        failed = true;
+        goto out;
+    }
+    p_sys->i_payload_size = i_payload_size;
 
     /* set maximum bandwidth limit*/
     srt_set_socket_option( access_obj, SRT_PARAM_BANDWIDTH_OVERHEAD_LIMIT,
@@ -229,20 +240,58 @@ out:
 static ssize_t Write( sout_access_out_t *p_access, block_t *p_buffer )
 {
     sout_access_out_sys_t *p_sys = p_access->p_sys;
-    int i_len = 0;
-    size_t i_chunk_size = var_InheritInteger( p_access, SRT_PARAM_CHUNK_SIZE);
     int i_poll_timeout = var_InheritInteger( p_access, SRT_PARAM_POLL_TIMEOUT );
     bool b_interrupted = false;
+    ssize_t i_len = 0;
+    int chunk_size;
+    uint8_t chunk[SRT_LIVE_MAX_PLSIZE];
+
+    if ( p_buffer == NULL )
+        return 0;
+    block_BytestreamPush( &p_sys->block_stream, p_buffer );
 
     vlc_interrupt_register( srt_wait_interrupted, p_access);
 
-    while( p_buffer )
+    while( true )
     {
-        block_t *p_next;
+        /* We can leave the remaining bytes less than i_payload_size for next
+         * Write() round, but it will add delay.
+         */
+        chunk_size = __MIN( block_BytestreamRemaining( &p_sys->block_stream ),
+                            p_sys->i_payload_size );
+        if ( chunk_size == 0 )
+            break;
 
-        i_len += p_buffer->i_buffer;
+        if ( vlc_killed() )
+        {
+            /* We are told to stop. Stop. */
+            i_len = VLC_EGENERIC;
+            goto out;
+        }
 
-        while( p_buffer->i_buffer )
+        switch( srt_getsockstate( p_sys->sock ) )
+        {
+            case SRTS_CONNECTED:
+                /* Good to go */
+                break;
+            case SRTS_BROKEN:
+            case SRTS_NONEXIST:
+            case SRTS_CLOSED:
+                /* Failed. Schedule recovery. */
+                if ( !srt_schedule_reconnect( p_access ) )
+                    msg_Err( p_access, "Failed to schedule connect");
+                /* Fall-through */
+            default:
+                /* Not ready */
+                i_len = VLC_EGENERIC;
+                goto out;
+        }
+
+        SRTSOCKET ready[1];
+        int readycnt = 1;
+        if ( srt_epoll_wait( p_sys->i_poll_id,
+            0, 0, &ready[0], &readycnt,
+            i_poll_timeout, NULL, 0, NULL, 0 ) < 0)
         {
             if ( vlc_killed() )
             {
@@ -251,90 +300,53 @@ static ssize_t Write( sout_access_out_t *p_access, block_t *p_buffer )
                 goto out;
             }
 
-            switch( srt_getsockstate( p_sys->sock ) )
+            /* if 'srt_epoll_wait' is interrupted, we still need to
+            *  finish sending current block or it may be sent only
+            *  partially. TODO: this delay can be prevented,
+            *  possibly with a FIFO and an additional thread.
+            */
+            vlc_mutex_lock( &p_sys->lock );
+            if ( p_sys->b_interrupted )
             {
-                case SRTS_CONNECTED:
-                    /* Good to go */
-                    break;
-                case SRTS_BROKEN:
-                case SRTS_NONEXIST:
-                case SRTS_CLOSED:
-                    /* Failed. Schedule recovery. */
-                    if ( !srt_schedule_reconnect( p_access ) )
-                        msg_Err( p_access, "Failed to schedule connect");
-                    /* Fall-through */
-                default:
-                    /* Not ready */
-                    i_len = VLC_EGENERIC;
-                    goto out;
+                srt_epoll_add_usock( p_sys->i_poll_id, p_sys->sock,
+                    &(int) { SRT_EPOLL_ERR | SRT_EPOLL_OUT });
+                p_sys->b_interrupted = false;
+                b_interrupted = true;
             }
+            vlc_mutex_unlock( &p_sys->lock );
 
-            SRTSOCKET ready[1];
-            int readycnt = 1;
-            if ( srt_epoll_wait( p_sys->i_poll_id,
-                0, 0, &ready[0], &readycnt,
-                i_poll_timeout, NULL, 0, NULL, 0 ) < 0)
+            if ( !b_interrupted )
             {
-                if ( vlc_killed() )
-                {
-                    /* We are told to stop. Stop. */
-                    i_len = VLC_EGENERIC;
-                    goto out;
-                }
-
-                /* if 'srt_epoll_wait' is interrupted, we still need to
-                *  finish sending current block or it may be sent only
-                *  partially. TODO: this delay can be prevented,
-                *  possibly with a FIFO and an additional thread.
-                */
-                vlc_mutex_lock( &p_sys->lock );
-                if ( p_sys->b_interrupted )
-                {
-                    srt_epoll_add_usock( p_sys->i_poll_id, p_sys->sock,
-                        &(int) { SRT_EPOLL_ERR | SRT_EPOLL_OUT });
-                    p_sys->b_interrupted = false;
-                    b_interrupted = true;
-                }
-                vlc_mutex_unlock( &p_sys->lock );
-
-                if ( !b_interrupted )
-                {
-                    continue;
-                }
-                else if ( (true) )
-                {
-                    msg_Dbg( p_access, "srt_epoll_wait was interrupted");
-                }
+                continue;
             }
-
-            if ( readycnt > 0  && ready[0] == p_sys->sock
-                && srt_getsockstate( p_sys->sock ) == SRTS_CONNECTED)
+            else
             {
-                size_t i_write = __MIN( p_buffer->i_buffer, i_chunk_size );
-                if (srt_sendmsg2( p_sys->sock,
-                    (char *)p_buffer->p_buffer, i_write, 0 ) == SRT_ERROR )
-                {
-                    msg_Warn( p_access, "send error: %s", srt_getlasterror_str() );
-                    i_len = VLC_EGENERIC;
-                    goto out;
-                }
-
-                p_buffer->p_buffer += i_write;
-                p_buffer->i_buffer -= i_write;
+                msg_Dbg( p_access, "srt_epoll_wait was interrupted");
             }
         }
 
-        p_next = p_buffer->p_next;
-        block_Release( p_buffer );
-        p_buffer = p_next;
-
-        if ( b_interrupted )
+        if ( readycnt > 0  && ready[0] == p_sys->sock
+            && srt_getsockstate( p_sys->sock ) == SRTS_CONNECTED)
         {
-            goto out;
+            if ( block_GetBytes( &p_sys->block_stream, chunk,
+                                 chunk_size ) != VLC_SUCCESS )
+                break;
+            if (srt_sendmsg2( p_sys->sock,
+                (char *)chunk, chunk_size, 0 ) == SRT_ERROR )
+            {
+                msg_Warn( p_access, "send error: %s", srt_getlasterror_str() );
+                i_len = VLC_EGENERIC;
+                goto out;
+            }
+            else
+            {
+                i_len += chunk_size;
+            }
         }
     }
 
 out:
+    block_BytestreamEmpty( &p_sys->block_stream );
     vlc_interrupt_unregister();
 
     /* Re-add the socket to the poll if we were interrupted */
@@ -347,7 +359,6 @@ out:
     }
     vlc_mutex_unlock( &p_sys->lock );
 
-    if ( i_len <= 0 ) block_ChainRelease( p_buffer );
     return i_len;
 }
 
@@ -392,6 +403,7 @@ static int Open( vlc_object_t *p_this )
     srt_startup();
 
     vlc_mutex_init( &p_sys->lock );
+    block_BytestreamInit( &p_sys->block_stream );
 
     p_access->p_sys = p_sys;
 
@@ -431,6 +443,7 @@ static void Close( vlc_object_t * p_this )
     srt_epoll_remove_usock( p_sys->i_poll_id, p_sys->sock );
     srt_close( p_sys->sock );
     srt_epoll_release( p_sys->i_poll_id );
+    block_BytestreamRelease( &p_sys->block_stream );
 
     srt_cleanup();
 }
@@ -442,8 +455,7 @@ vlc_module_begin()
     set_category( CAT_SOUT )
     set_subcategory( SUBCAT_SOUT_ACO )
 
-    add_integer( SRT_PARAM_CHUNK_SIZE, SRT_DEFAULT_CHUNK_SIZE,
-            N_( "SRT chunk size (bytes)" ), NULL )
+    add_obsolete_integer( SRT_PARAM_CHUNK_SIZE )
     add_integer( SRT_PARAM_POLL_TIMEOUT, SRT_DEFAULT_POLL_TIMEOUT,
             N_( "Return poll wait after timeout milliseconds (-1 = infinite)" ),
             NULL )
@@ -453,6 +465,7 @@ vlc_module_begin()
             NULL )
     add_integer( SRT_PARAM_PAYLOAD_SIZE, SRT_DEFAULT_PAYLOAD_SIZE,
             N_( "SRT maximum payload size (bytes)" ), NULL )
+        change_integer_range( 1, SRT_LIVE_MAX_PLSIZE )
     add_integer( SRT_PARAM_BANDWIDTH_OVERHEAD_LIMIT,
             SRT_DEFAULT_BANDWIDTH_OVERHEAD_LIMIT,
             N_( "SRT maximum bandwidth ceiling (bytes)" ), NULL )


=====================================
modules/mux/mpeg/ts.c
=====================================
@@ -1728,6 +1728,8 @@ static void TSDate( sout_mux_t *p_mux, sout_buffer_chain_t *p_chain_ts,
     }
 
     /* msg_Dbg( p_mux, "real pck=%d", i_packet_count ); */
+    block_t *p_list = NULL;
+    block_t **pp_last = &p_list;
     for (int i = 0; i < i_packet_count; i++ )
     {
         block_t *p_ts = BufferChainGet( p_chain_ts );
@@ -1751,8 +1753,10 @@ static void TSDate( sout_mux_t *p_mux, sout_buffer_chain_t *p_chain_ts,
         /* latency */
         p_ts->i_dts += p_sys->i_shaping_delay * 3 / 2;
 
-        sout_AccessOutWrite( p_mux->p_access, p_ts );
+        block_ChainLastAppend( &pp_last, p_ts );
     }
+    if ( p_list != NULL )
+        sout_AccessOutWrite( p_mux->p_access, p_list );
 }
 
 static block_t *TSNew( sout_mux_t *p_mux, sout_input_sys_t *p_stream,



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/6a81d00090386b6a337f8c46814aa3f6d9eb503d...84bc80de2334747c29e319bb3695bae1f2d2ade9

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/6a81d00090386b6a337f8c46814aa3f6d9eb503d...84bc80de2334747c29e319bb3695bae1f2d2ade9
You're receiving this email because of your account on code.videolan.org.




More information about the vlc-commits mailing list