diff --git a/NEWS b/NEWS index 868abcdc61..fe0f7e24ba 100644 --- a/NEWS +++ b/NEWS @@ -42,6 +42,7 @@ Access: * New HTTP/TLS access module for HTTP 2.0 support * Named pipes and device nodes are no longer included in directory listings by default. Use --list-special-files to include them back. + * Support for timeout in udp input --udp-input= Decoder: * OMX GPU-zerocopy support for decoding and display on Android using OpenMax IL diff --git a/modules/access/udp.c b/modules/access/udp.c index 9e08b55ef0..d860fb4095 100644 --- a/modules/access/udp.c +++ b/modules/access/udp.c @@ -43,6 +43,9 @@ #include #include #include +#ifdef HAVE_POLL +# include +#endif #include #define MTU 65535 @@ -55,6 +58,7 @@ static void Close( vlc_object_t * ); #define BUFFER_TEXT N_("Receive buffer") #define BUFFER_LONGTEXT N_("UDP receive buffer size (bytes)" ) +#define TIMEOUT_TEXT N_("UDP Source timeout (sec)") vlc_module_begin () set_shortname( N_("UDP" ) ) @@ -64,6 +68,7 @@ vlc_module_begin () add_obsolete_integer( "server-port" ) /* since 2.0.0 */ add_integer( "udp-buffer", 0x400000, BUFFER_TEXT, BUFFER_LONGTEXT, true ) + add_integer( "udp-timeout", -1, TIMEOUT_TEXT, NULL, true ) set_capability( "access", 0 ) add_shortcut( "udp", "udpstream", "udp4", "udp6" ) @@ -74,10 +79,12 @@ vlc_module_end () struct access_sys_t { int fd; + int timeout; size_t fifo_size; block_fifo_t *fifo; vlc_sem_t semaphore; vlc_thread_t thread; + bool timeout_reached; }; /***************************************************************************** @@ -181,6 +188,11 @@ static int Open( vlc_object_t *p_this ) sys->fifo_size = var_InheritInteger( p_access, "udp-buffer"); vlc_sem_init( &sys->semaphore, 0 ); + sys->timeout = var_InheritInteger( p_access, "udp-timeout"); + sys->timeout_reached = false; + if( sys->timeout > 0) + sys->timeout *= 1000; + if( vlc_clone( &sys->thread, ThreadRead, p_access, VLC_THREAD_PRIORITY_INPUT ) ) { @@ -254,7 +266,12 @@ static block_t *BlockUDP( access_t *p_access ) vlc_sem_wait_i11e(&sys->semaphore); vlc_fifo_Lock(sys->fifo); - block = vlc_fifo_DequeueUnlocked(sys->fifo); + + block = vlc_fifo_DequeueAllUnlocked(sys->fifo); + + if (unlikely(sys->timeout_reached == true)) + p_access->info.b_eof=true; + vlc_fifo_Unlock(sys->fifo); return block; @@ -283,10 +300,22 @@ static void* ThreadRead( void *data ) block_cleanup_push(pkt); do { -#ifndef LIBVLC_USE_PTHREAD - struct pollfd ufd = { .fd = sys->fd, .events = POLLIN }; - while (poll(&ufd, 1, -1) <= 0); /* cancellation point */ -#endif + int poll_return=0; + struct pollfd ufd[1]; + ufd[0].fd = sys->fd; + ufd[0].events = POLLIN; + + while ((poll_return = poll(ufd, 1, sys->timeout)) < 0); /* cancellation point */ + if (unlikely( poll_return == 0)) + { + msg_Err( access, "Timeout on receiving, timeout %d seconds", sys->timeout/1000 ); + vlc_fifo_Lock(sys->fifo); + sys->timeout_reached=true; + vlc_fifo_Unlock(sys->fifo); + vlc_sem_post(&sys->semaphore); + len=0; + break; + } len = recv(sys->fd, pkt->p_buffer, MTU, 0); } while (len == -1);