Re: [FFmpeg-devel] [PATCH] avformat/http: support auto reconnect
On Thu, Mar 12, 2015 at 11:39:55AM +0800, Zhang Rui wrote: --- libavformat/http.c | 32 +++- 1 file changed, 27 insertions(+), 5 deletions(-) applied thanks [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB Complexity theory is the science of finding the exact solution to an approximation. Benchmarking OTOH is finding an approximation of the exact signature.asc Description: Digital signature ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH] avformat/http: support auto reconnect
--- libavformat/http.c | 32 +++- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/libavformat/http.c b/libavformat/http.c index 55dcb6e..86380b2 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 }, { 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 (read_ret 0 s-reconnect !h-is_streamed s-filesize 0 s-off s-filesize) { +av_log(h, AV_LOG_INFO, 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_ERROR, Failed to reconnect at %PRId64.\n, s-off); +return read_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; -- 2.0.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH] avformat/http: support auto reconnect
+{ 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. The default value is not my concern, So I make the default behavior remain unchanged. May I have your suggestion? +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? I'll fix it. +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() returns the bytes received, while seek() returns the offset it seeked to, which could be different from the request offset. (at least, no document guarantee) And I doubt if seek() could returns AVERROR_EOF. Whatever, it is read() which causes http_read() failure, but not seek(). In generals looks sane to me. Thanks for your review. ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH] avformat/http: support auto reconnect
On Fri, 6 Mar 2015 18:19:14 +0800 Zhang Rui bbcal...@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. ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
Re: [FFmpeg-devel] [PATCH] avformat/http: support auto reconnect
On 6 March 2015 at 11:19, Zhang Rui bbcal...@gmail.com wrote: 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) { minor: you can chek read_ret 0 first, this condition usually will net be meet. +av_log(h, AV_LOG_WARNING, Will reconnect at %PRId64.\n, s-off); Not sure this should be a warning. maybe info, debug or verbose? +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); This should be an error I think. ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
[FFmpeg-devel] [PATCH] avformat/http: support auto reconnect
--- 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 }, { 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) { +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; +} + +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; -- 2.0.0 ___ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org http://ffmpeg.org/mailman/listinfo/ffmpeg-devel