[FFmpeg-trac] #9071(avformat:new): HLS (EXT-X-BYTERANGE) and persistent connection how Range header is replaced ?

FFmpeg trac at avcodec.org
Sat Jan 23 11:31:46 EET 2021


#9071: HLS (EXT-X-BYTERANGE)  and persistent connection how Range header is
replaced ?
------------------------------------+------------------------------------
             Reporter:  e2iplayer   |                    Owner:
                 Type:  defect      |                   Status:  new
             Priority:  important   |                Component:  avformat
              Version:  git-master  |               Resolution:
             Keywords:              |               Blocked By:
             Blocking:              |  Reproduced by developer:  0
Analyzed by developer:  1           |
------------------------------------+------------------------------------

Comment (by e2iplayer):

 Unfortunately not. I tried to made some investigation but I don't
 understand how options are propagated between contexts.

 Please take a look:

 {{{
 diff -x '*.[^ch]' -uNr ffmpeg2/libavformat/hls.c ffmpeg/libavformat/hls.c
 --- ffmpeg-4.2.2_http/ffmpeg-4.2.2/libavformat/hls.c    2021-01-19
 10:18:44.494479917 +0100
 +++ ffmpeg-4.2.2/libavformat/hls.c      2021-01-20 13:01:54.113543376
 +0100
 @@ -598,8 +598,10 @@
      return 0;
  }

 +int ff_http_do_new_request2(URLContext *h, const char *uri, AVDictionary
 *opts);
 +
  static int open_url_keepalive(AVFormatContext *s, AVIOContext **pb,
 -                              const char *url)
 +                              const char *url, AVDictionary *opts)
  {
  #if !CONFIG_HTTP_PROTOCOL
      return AVERROR_PROTOCOL_NOT_FOUND;
 @@ -608,7 +610,7 @@
      URLContext *uc = ffio_geturlcontext(*pb);
      av_assert0(uc);
      (*pb)->eof_reached = 0;
 -    ret = ff_http_do_new_request(uc, url);
 +    ret = ff_http_do_new_request2(uc, url, opts);
      if (ret < 0) {
          ff_format_io_close(s, pb);
      }
 @@ -661,7 +663,7 @@
          return AVERROR_INVALIDDATA;

      if (is_http && c->http_persistent && *pb) {
 -        ret = open_url_keepalive(c->ctx, pb, url);
 +        ret = open_url_keepalive(c->ctx, pb, url, tmp);
          if (ret == AVERROR_EXIT) {
              return ret;
          } else if (ret < 0) {
 @@ -718,7 +720,10 @@

      if (is_http && !in && c->http_persistent && c->playlist_pb) {
          in = c->playlist_pb;
 -        ret = open_url_keepalive(c->ctx, &c->playlist_pb, url);
 +        AVDictionary *opts = NULL;
 +        av_dict_copy(&opts, c->avio_opts, 0);
 +        ret = open_url_keepalive(c->ctx, &c->playlist_pb, url, opts);
 +        av_dict_free(&opts);
          if (ret == AVERROR_EXIT) {
              return ret;
          } else if (ret < 0) {
 diff -x '*.[^ch]' -uNr ffmpeg2/libavformat/http.c
 ffmpeg/libavformat/http.c
 --- ffmpeg-4.2.2_http/ffmpeg-4.2.2/libavformat/http.c   2021-01-19
 10:20:05.614484136 +0100
 +++ ffmpeg-4.2.2/libavformat/http.c     2021-01-20 14:07:25.875704582
 +0100
 @@ -242,6 +242,7 @@

      err = http_connect(h, path, local_path, hoststr,
                         auth, proxyauth, &location_changed);
 +
      if (err < 0)
          return err;

 @@ -304,8 +305,9 @@
          return location_changed;
      return ff_http_averror(s->http_code, AVERROR(EIO));
  }
 +int ff_http_do_new_request2(URLContext *h, const char *uri, AVDictionary
 *opts);

 -int ff_http_do_new_request(URLContext *h, const char *uri)
 +int ff_http_do_new_request2(URLContext *h, const char *uri, AVDictionary
 *opts)
  {
      HTTPContext *s = h->priv_data;
      AVDictionary *options = NULL;
 @@ -350,12 +352,32 @@
      if (!s->location)
          return AVERROR(ENOMEM);


      av_log(s, AV_LOG_INFO, "Opening \'%s\' for %s\n", uri, h->flags &
 AVIO_FLAG_WRITE ? "writing" : "reading");
 +    if (opts) {
 +        AVDictionaryEntry *t = NULL;
 +        while ((t = av_dict_get(opts, "", t, AV_DICT_IGNORE_SUFFIX))) {
 +            if (!strcmp(t->key, "offset")) {
 +                s->off = strtoull(t->value, NULL, 10);
 +            }
 +            if (!strcmp(t->key, "end_offset")) {
 +                s->end_off = strtoull(t->value, NULL, 10);
 +            }
 +        }
 +        av_dict_copy(&options, opts, 0);
 +    }
      ret = http_open_cnx(h, &options);
      av_dict_free(&options);
      return ret;
  }

 +int ff_http_do_new_request(URLContext *h, const char *uri)
 +{
 +    return ff_http_do_new_request2(h, uri, NULL);
 +}
 +


 }}}

 I do not undestand why this:

 {{{
 +        AVDictionaryEntry *t = NULL;
 +        while ((t = av_dict_get(opts, "", t, AV_DICT_IGNORE_SUFFIX))) {
 +            if (!strcmp(t->key, "offset")) {
 +                s->off = strtoull(t->value, NULL, 10);
 +            }
 +            if (!strcmp(t->key, "end_offset")) {
 +                s->end_off = strtoull(t->value, NULL, 10);
 +            }
 +        }

 }}}

 is needed? Why this is not automaticly applied to URLContext in the
 function
 ret = http_open_cnx(h, &options);

 do you have any idea?

--
Ticket URL: <https://trac.ffmpeg.org/ticket/9071#comment:2>
FFmpeg <https://ffmpeg.org>
FFmpeg issue tracker


More information about the FFmpeg-trac mailing list