[vlc-devel] [PATCH 2/2] srt: Read several chunks per blocking read call
Romain Vimont
rom1v at videolabs.io
Fri Oct 12 15:15:35 CEST 2018
On Mon, Aug 20, 2018 at 10:20:10AM +0300, Olivier Crête wrote:
> Hi,
>
> Re-ping about this patch?
>
> Olivier
>
> On Thu, 2018-07-26 at 17:47 -0400, Olivier Crête wrote:
> > From: Roman Diouskine <rdiouskine at haivision.com>
> >
> > libsrt input is asynchonously buffered internally and it makes sense
> > to empty those receive buffers as much as possible on every signaled
> > receive event from epoll. Doing so reduces context
> > switching/re-scheduling and improves performance.
> > ---
> > modules/access/srt.c | 62 +++++++++++++++++++++++++++++++++++++-----
> > --
> > 1 file changed, 53 insertions(+), 9 deletions(-)
> >
> > diff --git a/modules/access/srt.c b/modules/access/srt.c
> > index 5b7734310b..c95123c738 100644
> > --- a/modules/access/srt.c
> > +++ b/modules/access/srt.c
> > @@ -40,6 +40,9 @@
> > /* libsrt defines default packet size as 1316 internally
> > * so srt module takes same value. */
> > #define SRT_DEFAULT_CHUNK_SIZE 1316
> > +/* Minimum/Maximum chunks to allow reading at a time from libsrt */
> > +#define SRT_MIN_CHUNKS_TRYREAD 10
> > +#define SRT_MAX_CHUNKS_TRYREAD 100
> > /* The default timeout is -1 (infinite) */
> > #define SRT_DEFAULT_POLL_TIMEOUT -1
> > /* The default latency is 125
> > @@ -64,6 +67,7 @@ typedef struct
> > bool b_interrupted;
> > char *psz_host;
> > int i_port;
> > + int i_chunks; /* Number of chunks to allocate in the
> > next read */
> > } stream_sys_t;
> >
> > static void srt_wait_interrupted(void *p_data)
> > @@ -193,6 +197,11 @@ static bool srt_schedule_reconnect(stream_t
> > *p_stream)
> > failed = true;
> > }
> >
> > + /* Reset the number of chunks to allocate as the bitrate of
> > + * the stream may have changed.
> > + */
> > + p_sys->i_chunks = SRT_MIN_CHUNKS_TRYREAD;
> > +
> > out:
> > if (failed && p_sys->sock != SRT_INVALID_SOCK)
> > {
> > @@ -221,7 +230,13 @@ static block_t *BlockSRT(stream_t *p_stream,
> > bool *restrict eof)
> > return NULL;
> > }
> >
> > - block_t *pkt = block_Alloc( i_chunk_size );
> > + 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;
> > + block_t *pkt = block_Alloc( bufsize );
> > if ( unlikely( pkt == NULL ) )
> > {
> > return NULL;
> > @@ -259,20 +274,49 @@ static block_t *BlockSRT(stream_t *p_stream,
> > bool *restrict eof)
> > continue;
> > }
> >
> > - int stat = srt_recvmsg( p_sys->sock,
> > - (char *)pkt->p_buffer, i_chunk_size );
> > - if ( stat > 0 )
> > + /* Try to get as much data as possible out of the lib, if
> > there
> > + * is still some left, increase the number of chunks to read
> > so that
> > + * it will read faster on the next iteration. This way the
> > buffer will
> > + * grow until it reads fast enough to keep the library empty
> > after
> > + * each iteration.
> > + */
> > + pkt->i_buffer = 0;
> > + while ( ( bufsize - pkt->i_buffer ) >= i_chunk_size_actual )
> > + {
> > + int stat = srt_recvmsg( p_sys->sock,
> > + (char *)( pkt->p_buffer + pkt->i_buffer ),
> > + bufsize - pkt->i_buffer );
> > + if ( stat <= 0 )
> > + {
> > + break;
If the first srt_recvmsg() returns <= 0, then BlockSRT() now returns an
empty block_t, while it returned NULL before the patch.
I don't know if this is important.
Otherwise, the logic looks good to me.
> > + }
> > + pkt->i_buffer += (size_t)stat;
> > + }
> > +
> > + 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 );
> > +
> > +
> > + /* 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 )
> > {
> > - pkt->i_buffer = stat;
> > - goto out;
> > + if ( p_sys->i_chunks < SRT_MAX_CHUNKS_TRYREAD )
> > + {
> > + p_sys->i_chunks++;
> > + }
> > }
> >
> > goto out;
> > }
> >
> > - /* if the poll reports errors for any reason at all
> > - * including a timeout, or there is a read error,
> > - * we skip the turn.
> > + /* if the poll reports errors for any reason at all,
> > + * including a timeout, we skip the turn.
> > */
> >
> > block_Release(pkt);
> --
> Olivier Crête
> olivier.crete at collabora.com
>
> _______________________________________________
> vlc-devel mailing list
> To unsubscribe or modify your subscription options:
> https://mailman.videolan.org/listinfo/vlc-devel
More information about the vlc-devel
mailing list