diff options
author | Michael Niedermayer <michael@niedermayer.cc> | 2015-09-06 19:58:10 +0200 |
---|---|---|
committer | Michael Niedermayer <michael@niedermayer.cc> | 2015-09-07 19:26:43 +0200 |
commit | 9bd68dea2b7f4a79aa6c35b6193e3122c8ef2db7 (patch) | |
tree | 0fce6e2bdece2867d2cc86b27be74efaec24343c | |
parent | 83c6a880a6682ca909681ff429133e01f347f93d (diff) | |
download | ffmpeg-9bd68dea2b7f4a79aa6c35b6193e3122c8ef2db7.tar.gz |
avformat/http: Add reconnect_at_eof and reconnect_streamed options
They allow reconnecting endless live streams which fail with eof
Reviewed-by: Zhang Rui <bbcallen@gmail.com>
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
-rw-r--r-- | doc/protocols.texi | 7 | ||||
-rw-r--r-- | libavformat/http.c | 14 |
2 files changed, 17 insertions, 4 deletions
diff --git a/doc/protocols.texi b/doc/protocols.texi index 905bc0979f..ea5c5319a2 100644 --- a/doc/protocols.texi +++ b/doc/protocols.texi @@ -260,6 +260,13 @@ Set timeout in microseconds of socket I/O operations used by the underlying low operation. By default it is set to -1, which means that the timeout is not specified. +@item reconnect_at_eof +If set then eof is treated like an error and causes reconnection, this is usefull +for live / endless streams. + +@item reconnect_streamed +If set then even streamed/non seekable streams will be reconnected on errors. + @item mime_type Export the MIME type. diff --git a/libavformat/http.c b/libavformat/http.c index dfe04ad63a..aa60aefed9 100644 --- a/libavformat/http.c +++ b/libavformat/http.c @@ -105,6 +105,8 @@ typedef struct HTTPContext { int send_expect_100; char *method; int reconnect; + int reconnect_at_eof; + int reconnect_streamed; int listen; char *resource; int reply_code; @@ -142,6 +144,8 @@ static const AVOption options[] = { { "end_offset", "try to limit the request to bytes preceding this offset", OFFSET(end_off), AV_OPT_TYPE_INT64, { .i64 = 0 }, 0, INT64_MAX, D }, { "method", "Override the HTTP method or set the expected HTTP method from a client", OFFSET(method), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, D | E }, { "reconnect", "auto reconnect after disconnect before EOF", OFFSET(reconnect), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, D }, + { "reconnect_at_eof", "auto reconnect at EOF", OFFSET(reconnect_at_eof), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, D }, + { "reconnect_streamed", "auto reconnect streamed / non seekable streams", OFFSET(reconnect_streamed), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, D }, { "listen", "listen on HTTP", OFFSET(listen), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 2, D | E }, { "resource", "The resource requested by a client", OFFSET(resource), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, E }, { "reply_code", "The http status code to return to a client", OFFSET(reply_code), AV_OPT_TYPE_INT, { .i64 = 200}, INT_MIN, 599, E}, @@ -1241,11 +1245,13 @@ static int http_read_stream(URLContext *h, uint8_t *buf, int size) return http_buf_read_compressed(h, buf, size); #endif /* CONFIG_ZLIB */ read_ret = http_buf_read(h, buf, size); - if (read_ret < 0 && s->reconnect && !h->is_streamed && s->filesize > 0 && s->off < s->filesize) { + if ( (read_ret < 0 && s->reconnect && (!h->is_streamed || s->reconnect_streamed) && s->filesize > 0 && s->off < s->filesize) + || (read_ret == 0 && s->reconnect_at_eof && (!h->is_streamed || s->reconnect_streamed))) { + int64_t target = h->is_streamed ? 0 : s->off; av_log(h, AV_LOG_INFO, "Will reconnect at %"PRId64" error=%s.\n", s->off, av_err2str(read_ret)); - seek_ret = http_seek_internal(h, s->off, SEEK_SET, 1); - if (seek_ret != s->off) { - av_log(h, AV_LOG_ERROR, "Failed to reconnect at %"PRId64".\n", s->off); + seek_ret = http_seek_internal(h, target, SEEK_SET, 1); + if (seek_ret != target) { + av_log(h, AV_LOG_ERROR, "Failed to reconnect at %"PRId64".\n", target); return read_ret; } |