[FFmpeg-devel] [PATCH] avformat/http: handle "content-range: <a>-<b>/*" responses
Aman Gupta
ffmpeg at tmm1.net
Thu Dec 21 04:02:43 EET 2017
On Wed, Dec 13, 2017 at 11:11 AM, Aman Gupta <ffmpeg at tmm1.net> wrote:
> From: Aman Gupta <aman at tmm1.net>
>
> The HTTP spec for the Content-Range response header specifies
> that '*' may be used when the total size of the document is unknown.
>
> Practically speaking, this can be used by a webserver to indicate
> that the underlying video file is still growing, i.e. more video
> data is being appended to the end.
>
> With this commit, the http protocol parses the '*' and instead uses
> the range end when reponding to AVSEEK_SIZE queries.
>
Any thoughts on this patch Anssi?
Thanks,
Aman
> ---
> libavformat/http.c | 28 +++++++++++++++++++++-------
> 1 file changed, 21 insertions(+), 7 deletions(-)
>
> diff --git a/libavformat/http.c b/libavformat/http.c
> index cf86adc617..d4b0d7c929 100644
> --- a/libavformat/http.c
> +++ b/libavformat/http.c
> @@ -67,7 +67,7 @@ typedef struct HTTPContext {
> /* Used if "Transfer-Encoding: chunked" otherwise -1. */
> uint64_t chunksize;
> int chunkend;
> - uint64_t off, end_off, filesize;
> + uint64_t off, end_off, filesize, fileend;
> char *location;
> HTTPAuthState auth_state;
> HTTPAuthState proxy_auth_state;
> @@ -501,6 +501,7 @@ static int http_open(URLContext *h, const char *uri,
> int flags,
> h->is_streamed = 1;
>
> s->filesize = UINT64_MAX;
> + s->fileend = UINT64_MAX;
> s->location = av_strdup(uri);
> if (!s->location)
> return AVERROR(ENOMEM);
> @@ -624,12 +625,21 @@ static void parse_content_range(URLContext *h, const
> char *p)
> {
> HTTPContext *s = h->priv_data;
> const char *slash;
> + const char *dash;
>
> if (!strncmp(p, "bytes ", 6)) {
> + uint64_t range_end = UINT64_MAX;
> p += 6;
> s->off = strtoull(p, NULL, 10);
> - if ((slash = strchr(p, '/')) && strlen(slash) > 0)
> - s->filesize = strtoull(slash + 1, NULL, 10);
> + if ((dash = strchr(p, '-')))
> + range_end = strtoull(dash + 1, NULL, 10);
> + if ((slash = strchr(p, '/')) && strlen(slash) > 0) {
> + if (slash[1] == '*') {
> + s->fileend = range_end;
> + } else {
> + s->filesize = strtoull(slash + 1, NULL, 10);
> + }
> + }
> }
> if (s->seekable == -1 && (!s->is_akamai || s->filesize != 2147483647))
> h->is_streamed = 0; /* we _can_ in fact seek */
> @@ -1253,6 +1263,7 @@ static int http_connect(URLContext *h, const char
> *path, const char *local_path,
> s->off = 0;
> s->icy_data_read = 0;
> s->filesize = UINT64_MAX;
> + s->fileend = UINT64_MAX;
> s->willclose = 0;
> s->end_chunked_post = 0;
> s->end_header = 0;
> @@ -1601,19 +1612,22 @@ static int64_t http_seek_internal(URLContext *h,
> int64_t off, int whence, int fo
> int old_buf_size, ret;
> AVDictionary *options = NULL;
>
> - if (whence == AVSEEK_SIZE)
> + if (whence == AVSEEK_SIZE) {
> + if (s->fileend != UINT64_MAX) {
> + return s->off > s->fileend ? s->off : s->fileend;
> + }
> return s->filesize;
> - else if (!force_reconnect &&
> + } else if (!force_reconnect &&
> ((whence == SEEK_CUR && off == 0) ||
> (whence == SEEK_SET && off == s->off)))
> return s->off;
> - else if ((s->filesize == UINT64_MAX && whence == SEEK_END))
> + else if ((s->filesize == UINT64_MAX && whence == SEEK_END &&
> s->fileend == UINT64_MAX))
> return AVERROR(ENOSYS);
>
> if (whence == SEEK_CUR)
> off += s->off;
> else if (whence == SEEK_END)
> - off += s->filesize;
> + off += s->fileend != UINT64_MAX ? s->fileend : s->filesize;
> else if (whence != SEEK_SET)
> return AVERROR(EINVAL);
> if (off < 0)
> --
> 2.14.3 (Apple Git-98)
>
>
More information about the ffmpeg-devel
mailing list