[FFmpeg-devel] [PATCH] udp: add option "timeout" for read

Andrey Utkin andrey.krieger.utkin at gmail.com
Fri Aug 17 18:52:05 CEST 2012


2012/8/17 Nicolas George <nicolas.george at normalesup.org>:
> Le nonidi 29 thermidor, an CCXX, Andrey Utkin a écrit :
>> Let UDP reading return error if cannot get data in timeout.
>> Parameter takes value in same units as av_gettime(), microseconds.
>
> Do you have a reason for implementing that for UDP and not for all protocols
> at once?

UDP is just what hurts me now... Your idea is better, i'll redo it a
level higher.

>
>> ---
>>  doc/protocols.texi |    3 +++
>>  libavformat/udp.c  |   23 +++++++++++++++++++++--
>>  2 files changed, 24 insertions(+), 2 deletions(-)
>>
>> diff --git a/doc/protocols.texi b/doc/protocols.texi
>> index be19239..265fe13 100644
>> --- a/doc/protocols.texi
>> +++ b/doc/protocols.texi
>> @@ -686,6 +686,9 @@ packets with size of 188 bytes. If not specified defaults to 7*4096.
>>  @item overrun_nonfatal=@var{1|0}
>>  Survive in case of UDP receiving circular buffer overrun. Default
>>  value is 0.
>> +
>> + at item timeout=@var{microseconds}
>> +In read mode: if no data arrived in more than this time interval, raise error.
>>  @end table
>>
>>  Some usage examples of the UDP protocol with @command{ffmpeg} follow.
>> diff --git a/libavformat/udp.c b/libavformat/udp.c
>> index f93c607..5ed47e8 100644
>> --- a/libavformat/udp.c
>> +++ b/libavformat/udp.c
>> @@ -64,6 +64,7 @@ typedef struct {
>>      struct sockaddr_storage dest_addr;
>>      int dest_addr_len;
>>      int is_connected;
>> +    int64_t read_timeout;
>>
>>      /* Circular Buffer variables for use in UDP receive code */
>>      int circular_buffer_size;
>> @@ -77,6 +78,7 @@ typedef struct {
>>  #endif
>>      uint8_t tmp[UDP_MAX_PKT_SIZE+4];
>>      int remaining_in_dg;
>> +    int64_t waiting_data_since_time;  /* used for 'timeout' option */
>>  } UDPContext;
>>
>>  static void log_net_error(void *ctx, int level, const char* prefix)
>> @@ -549,6 +551,8 @@ static int udp_open(URLContext *h, const char *uri, int flags)
>>                      break;
>>              }
>>          }
>> +        if (!is_output && av_find_info_tag(buf, sizeof(buf), "timeout", p))
>> +            s->read_timeout = strtol(buf, NULL, 10);
>>      }
>>
>>      /* fill the dest addr */
>> @@ -700,6 +704,8 @@ static int udp_read(URLContext *h, uint8_t *buf, int size)
>>      int ret;
>>      int avail, nonblock = h->flags & AVIO_FLAG_NONBLOCK;
>>
>> +    if (s->waiting_data_since_time && (av_gettime() - s->waiting_data_since_time > s->read_timeout))
>> +        return AVERROR(EIO);
>
> The error value seems wrong: ETIMEDOUT seems more appropriate.

OK.

>>  #if HAVE_PTHREAD_CANCEL
>>      if (s->fifo) {
>>          pthread_mutex_lock(&s->mutex);
>> @@ -718,6 +724,7 @@ static int udp_read(URLContext *h, uint8_t *buf, int size)
>>                  av_fifo_generic_read(s->fifo, buf, avail, NULL);
>>                  av_fifo_drain(s->fifo, AV_RL32(tmp) - avail);
>>                  pthread_mutex_unlock(&s->mutex);
>> +                s->waiting_data_since_time = 0;
>
> Why this?

As you can see, this value is used as indicator that we are actually
involved in wait since certain moment. When we've got a data portion,
this is no longer true.

-- 
Andrey Utkin


More information about the ffmpeg-devel mailing list