X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Frtpproto.c;h=7dd60421581e6d21a97dadc9c5ab13574a5dbb5e;hb=626535f6a169e2d821b969e0ea77125ba7482113;hp=1f0a82ac7e545db06b0f6ce517db851781be9fd7;hpb=5ab44ff20cdc0e05adecbd0cd352d25fcb930094;p=ffmpeg diff --git a/libavformat/rtpproto.c b/libavformat/rtpproto.c index 1f0a82ac7e5..7dd60421581 100644 --- a/libavformat/rtpproto.c +++ b/libavformat/rtpproto.c @@ -60,6 +60,7 @@ typedef struct RTPContext { char *sources; char *block; char *fec_options_str; + int64_t rw_timeout; } RTPContext; #define OFFSET(x) offsetof(RTPContext, x) @@ -75,6 +76,7 @@ static const AVOption options[] = { { "write_to_source", "Send packets to the source address of the latest received packet", OFFSET(write_to_source), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, .flags = D|E }, { "pkt_size", "Maximum packet size", OFFSET(pkt_size), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags = D|E }, { "dscp", "DSCP class", OFFSET(dscp), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags = D|E }, + { "timeout", "set timeout (in microseconds) of socket I/O operations", OFFSET(rw_timeout), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, .flags = D|E }, { "sources", "Source list", OFFSET(sources), AV_OPT_TYPE_STRING, { .str = NULL }, .flags = D|E }, { "block", "Block list", OFFSET(block), AV_OPT_TYPE_STRING, { .str = NULL }, .flags = D|E }, { "fec", "FEC", OFFSET(fec_options_str), AV_OPT_TYPE_STRING, { .str = NULL }, .flags = E }, @@ -265,6 +267,9 @@ static int rtp_open(URLContext *h, const char *uri, int flags) if (av_find_info_tag(buf, sizeof(buf), "dscp", p)) { s->dscp = strtol(buf, NULL, 10); } + if (av_find_info_tag(buf, sizeof(buf), "timeout", p)) { + s->rw_timeout = strtol(buf, NULL, 10); + } if (av_find_info_tag(buf, sizeof(buf), "sources", p)) { av_strlcpy(include_sources, buf, sizeof(include_sources)); ff_ip_parse_sources(h, buf, &s->filters); @@ -280,6 +285,8 @@ static int rtp_open(URLContext *h, const char *uri, int flags) block = s->block; } } + if (s->rw_timeout >= 0) + h->rw_timeout = s->rw_timeout; if (s->fec_options_str) { p = s->fec_options_str; @@ -301,8 +308,7 @@ static int rtp_open(URLContext *h, const char *uri, int flags) goto fail; } if (s->ttl > 0) { - snprintf(buf, sizeof (buf), "%d", s->ttl); - av_dict_set(&fec_opts, "ttl", buf, 0); + av_dict_set_int(&fec_opts, "ttl", s->ttl, 0); } } @@ -363,10 +369,8 @@ static int rtp_open(URLContext *h, const char *uri, int flags) return 0; fail: - if (s->rtp_hd) - ffurl_close(s->rtp_hd); - if (s->rtcp_hd) - ffurl_close(s->rtcp_hd); + ffurl_closep(&s->rtp_hd); + ffurl_closep(&s->rtcp_hd); ffurl_closep(&s->fec_hd); av_free(fec_protocol); av_dict_free(&fec_opts); @@ -378,9 +382,10 @@ static int rtp_read(URLContext *h, uint8_t *buf, int size) RTPContext *s = h->priv_data; int len, n, i; struct pollfd p[2] = {{s->rtp_fd, POLLIN, 0}, {s->rtcp_fd, POLLIN, 0}}; - int poll_delay = h->flags & AVIO_FLAG_NONBLOCK ? 0 : 100; + int poll_delay = h->flags & AVIO_FLAG_NONBLOCK ? 0 : POLLING_TIME; struct sockaddr_storage *addrs[2] = { &s->last_rtp_source, &s->last_rtcp_source }; socklen_t *addr_lens[2] = { &s->last_rtp_source_len, &s->last_rtcp_source_len }; + int runs = h->rw_timeout / 1000 / POLLING_TIME; for(;;) { if (ff_check_interrupt(&h->interrupt_callback)) @@ -404,6 +409,8 @@ static int rtp_read(URLContext *h, uint8_t *buf, int size) continue; return len; } + } else if (n == 0 && h->rw_timeout > 0 && --runs <= 0) { + return AVERROR(ETIMEDOUT); } else if (n < 0) { if (ff_neterrno() == AVERROR(EINTR)) continue; @@ -506,8 +513,8 @@ static int rtp_close(URLContext *h) ff_ip_reset_filters(&s->filters); - ffurl_close(s->rtp_hd); - ffurl_close(s->rtcp_hd); + ffurl_closep(&s->rtp_hd); + ffurl_closep(&s->rtcp_hd); ffurl_closep(&s->fec_hd); return 0; }