[FFmpeg-devel] [PATCH] avformat/http: support auto reconnect
wm4
nfxjfg at googlemail.com
Fri Mar 6 15:33:24 CET 2015
On Fri, 6 Mar 2015 18:19:14 +0800
Zhang Rui <bbcallen at gmail.com> wrote:
> ---
> libavformat/http.c | 32 +++++++++++++++++++++++++++-----
> 1 file changed, 27 insertions(+), 5 deletions(-)
>
> diff --git a/libavformat/http.c b/libavformat/http.c
> index 55dcb6e..9d44f3b 100644
> --- a/libavformat/http.c
> +++ b/libavformat/http.c
> @@ -93,6 +93,7 @@ typedef struct HTTPContext {
> AVDictionary *chained_options;
> int send_expect_100;
> char *method;
> + int reconnect;
> } HTTPContext;
>
> #define OFFSET(x) offsetof(HTTPContext, x)
> @@ -123,6 +124,7 @@ static const AVOption options[] = {
> { "offset", "initial byte offset", OFFSET(off), AV_OPT_TYPE_INT64, { .i64 = 0 }, 0, INT64_MAX, D },
> { "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", OFFSET(method), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, E },
> + { "reconnect", "auto reconnect after disconnect before EOF", OFFSET(reconnect), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, D },
The default of this setting is probably worth a discussion.
> { NULL }
> };
>
> @@ -908,10 +910,12 @@ static int http_buf_read_compressed(URLContext *h, uint8_t *buf, int size)
> }
> #endif /* CONFIG_ZLIB */
>
> +static int64_t http_seek_internal(URLContext *h, int64_t off, int whence, int force_reconnect);
> +
> static int http_read_stream(URLContext *h, uint8_t *buf, int size)
> {
> HTTPContext *s = h->priv_data;
> - int err, new_location;
> + int err, new_location, read_ret, seek_ret;
>
> if (!s->hd)
> return AVERROR_EOF;
> @@ -945,7 +949,19 @@ static int http_read_stream(URLContext *h, uint8_t *buf, int size)
> if (s->compressed)
> return http_buf_read_compressed(h, buf, size);
> #endif /* CONFIG_ZLIB */
> - return http_buf_read(h, buf, size);
> + read_ret = http_buf_read(h, buf, size);
> + if (s->reconnect && s->filesize > 0 && s->off < s->filesize && read_ret < 0) {
Maybe it should check is_streamed (seekability) too?
> + av_log(h, AV_LOG_WARNING, "Will reconnect at %"PRId64".\n", s->off);
> + seek_ret = http_seek_internal(h, s->off, SEEK_SET, 1);
> + if (seek_ret != s->off) {
> + av_log(h, AV_LOG_WARNING, "Failed to reconnect at %"PRId64".\n", s->off);
> + return read_ret;
Not sure if it should return read_ret or seek_ret...
> + }
> +
> + read_ret = http_buf_read(h, buf, size);
> + }
> +
> + return read_ret;
> }
>
> // Like http_read_stream(), but no short reads.
> @@ -1104,7 +1120,7 @@ static int http_close(URLContext *h)
> return ret;
> }
>
> -static int64_t http_seek(URLContext *h, int64_t off, int whence)
> +static int64_t http_seek_internal(URLContext *h, int64_t off, int whence, int force_reconnect)
> {
> HTTPContext *s = h->priv_data;
> URLContext *old_hd = s->hd;
> @@ -1115,8 +1131,9 @@ static int64_t http_seek(URLContext *h, int64_t off, int whence)
>
> if (whence == AVSEEK_SIZE)
> return s->filesize;
> - else if ((whence == SEEK_CUR && off == 0) ||
> - (whence == SEEK_SET && off == s->off))
> + else if (!force_reconnect &&
> + ((whence == SEEK_CUR && off == 0) ||
> + (whence == SEEK_SET && off == s->off)))
> return s->off;
> else if ((s->filesize == -1 && whence == SEEK_END) || h->is_streamed)
> return AVERROR(ENOSYS);
> @@ -1151,6 +1168,11 @@ static int64_t http_seek(URLContext *h, int64_t off, int whence)
> return off;
> }
>
> +static int64_t http_seek(URLContext *h, int64_t off, int whence)
> +{
> + return http_seek_internal(h, off, whence, 0);
> +}
> +
> static int http_get_file_handle(URLContext *h)
> {
> HTTPContext *s = h->priv_data;
In generals looks sane to me.
More information about the ffmpeg-devel
mailing list