[FFmpeg-devel] [PATCH] Maintain HTTP options across multiple requests in HLS demuxer

Micah Galizia micahgalizia at gmail.com
Sun Dec 23 19:50:12 CET 2012

On Sun, Dec 23, 2012 at 8:50 AM, Clément Bœsch <ubitux at gmail.com> wrote:

> On Thu, Dec 20, 2012 at 10:17:16PM -0500, Micah Galizia wrote:
> > Hello,
> >
> > I emailed yesterday about the HLS demuxer not setting HTTP options, such
> as
> > "user-agent" or "headers", after the first playlist request. Nobody
> > responded, so here is a patch.
> >
> > I think the most intrusive aspect of this change is the addition of an
> > AVDictionary pointer to the AVFormatContext to store the initial options.
> > The rest of the changes are confined to hls.c.
> >
> > I've run this against `make fate` and there were no errors and all that
> > came from patcheck were innocuous messages.
> >
> > Thanks in advance for the review.
> >
> Sorry for the long delay…
> > diff --git a/libavformat/avformat.h b/libavformat/avformat.h
> > index c907d4e..f0d6b95 100644
> > --- a/libavformat/avformat.h
> > +++ b/libavformat/avformat.h
> > @@ -1087,6 +1087,11 @@ typedef struct AVFormatContext {
> >      AVDictionary *metadata;
> >
> >      /**
> > +     * Copy of initial options.
> > +     */
> > +    AVDictionary *options;
> > +
> > +    /**
> You can't insert this here; it's breaking ABI. It would be allowed at the
> end, but I wonder if you can't do this differently…
> Why don't you just add a AVDictionary to the local HLSContext, and use it
> all the time instead?

I wanted to do something like that originally but there were a few serious
problems I ran up against. I was even prepared to look at the AVIOContext
within the AVFormatContext (s->pb) and pull the options from the AVClass,
but that got ugly _really_ quick.

It seems that by design the original options are never actually passed into
the hls demuxer. In init_input (utils.c) the av_probe_input_buffer call
does not receive any options, so the AVInputFormat (hls in this case) is
never aware of the original AVDictionary. Even if we did change all of
those methods to pass the dictionary around, there is still a problem due
to the call to avio_open2 in init_input before calling

If we follow the trail of the options from avformat_open_input, we pass
through init_input, avio_open2, and ffurl_open. In ffurl_open
av_opt_set_dict is called on those original AVDictionary options.
av_opt_set_dict removes any option it matches against our URLProtocol
(http) so nobody else can use them.  I assume that this is for performance
reasons, not wanting to revisit options that were already used. Because of
this, even if we did pass the AVDictionary to av_probe_input_buffer, there
wouldn't be any http options left in them...

Which is why I ended up going with the easiest solution of storing a copy
of them in the AVFormatContext, which is always available to every class.

So, thoughts? I'm not opposed to doing it another way, but the ideas I had
were not good. Also, I've attached a second revision because I was leaking
memory in the first, and I've moved the Dictionary to the bottom of the
AVFormatContext as you suggested was necessary.


"The mark of an immature man is that he wants to die nobly for a cause,
while the mark of the mature man is that he wants to live humbly for
one."   --W. Stekel
-------------- next part --------------
A non-text attachment was scrubbed...
Name: hls_http_options2.patch
Type: application/octet-stream
Size: 4639 bytes
Desc: not available
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20121223/c63616bb/attachment.obj>

More information about the ffmpeg-devel mailing list