diff mbox series

[FFmpeg-devel,3/3] lavf/dashdec: avoid reading the first data segment in read_header

Message ID 20200522054200.74203-3-rcombs@rcombs.me
State New
Headers show
Series [FFmpeg-devel,1/3] lavf/format: handle max probe buffer sizes <2048
Related show

Checks

Context Check Description
andriy/default pending
andriy/make success Make finished
andriy/make_fate success Make fate finished

Commit Message

rcombs May 22, 2020, 5:42 a.m. UTC
This reduces the number of requests that have to be made during startup.
---
 libavformat/dashdec.c | 41 ++++++++++++++++++++++++++---------------
 1 file changed, 26 insertions(+), 15 deletions(-)

Comments

Steven Liu May 22, 2020, 7:19 a.m. UTC | #1
> 2020年5月22日 下午1:42,rcombs <rcombs@rcombs.me> 写道:
> 
> This reduces the number of requests that have to be made during startup.
> ---
> libavformat/dashdec.c | 41 ++++++++++++++++++++++++++---------------
> 1 file changed, 26 insertions(+), 15 deletions(-)
> 
> diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c
> index ec2aadcee3..1bd070c7cb 100644
> --- a/libavformat/dashdec.c
> +++ b/libavformat/dashdec.c
> @@ -1798,6 +1798,19 @@ static int read_data(void *opaque, uint8_t *buf, int buf_size)
>     DASHContext *c = v->parent->priv_data;
> 
> restart:
> +    /* load/update Media Initialization Section, if any */
> +    if ((ret = update_init_section(v)) < 0)
> +        goto end;
> +
> +    if (v->init_sec_buf_read_offset < v->init_sec_data_len) {
> +        /* Push init section out first before first actual fragment */
> +        int copy_size = FFMIN(v->init_sec_data_len - v->init_sec_buf_read_offset, buf_size);
> +        memcpy(buf, v->init_sec_buf, copy_size);
> +        v->init_sec_buf_read_offset += copy_size;
> +        ret = copy_size;
> +        goto end;
> +    }
> +
>     if (!v->input) {
>         free_fragment(&v->cur_seg);
>         v->cur_seg = get_current_fragment(v);
> @@ -1806,11 +1819,6 @@ restart:
>             goto end;
>         }
> 
> -        /* load/update Media Initialization Section, if any */
> -        ret = update_init_section(v);
> -        if (ret)
> -            goto end;
> -
>         ret = open_input(c, v, v->cur_seg);
>         if (ret < 0) {
>             if (ff_check_interrupt(c->interrupt_callback)) {
> @@ -1823,15 +1831,6 @@ restart:
>         }
>     }
> 
> -    if (v->init_sec_buf_read_offset < v->init_sec_data_len) {
> -        /* Push init section out first before first actual fragment */
> -        int copy_size = FFMIN(v->init_sec_data_len - v->init_sec_buf_read_offset, buf_size);
> -        memcpy(buf, v->init_sec_buf, copy_size);
> -        v->init_sec_buf_read_offset += copy_size;
> -        ret = copy_size;
> -        goto end;
> -    }
> -
>     /* check the v->cur_seg, if it is null, get current and double check if the new v->cur_seg*/
>     if (!v->cur_seg) {
>         v->cur_seg = get_current_fragment(v);
> @@ -1940,10 +1939,19 @@ static int reopen_demux_for_component(AVFormatContext *s, struct representation
>     if ((ret = ff_copy_whiteblacklists(pls->ctx, s)) < 0)
>         goto fail;
> 
> +
> +    if (pls->init_sec_data_len <= 0) {
> +        /* load/update Media Initialization Section, if any */
> +        if ((ret = update_init_section(pls)) < 0)
> +            goto fail;
> +    }
> +
>     pls->ctx->flags = AVFMT_FLAG_CUSTOM_IO;
>     pls->ctx->probesize = s->probesize > 0 ? s->probesize : 1024 * 4;
> +    if (pls->init_sec_data_len > 0)
> +        pls->ctx->probesize = FFMIN(pls->ctx->probesize, pls->init_sec_data_len);
>     pls->ctx->max_analyze_duration = s->max_analyze_duration > 0 ? s->max_analyze_duration : 4 * AV_TIME_BASE;
> -    ret = av_probe_input_buffer(&pls->pb, &in_fmt, "", NULL, 0, 0);
> +    ret = av_probe_input_buffer(&pls->pb, &in_fmt, "", NULL, 0, pls->ctx->probesize);
>     if (ret < 0) {
>         av_log(s, AV_LOG_ERROR, "Error when loading first fragment, playlist %d\n", (int)pls->rep_idx);
>         avformat_free_context(pls->ctx);
> @@ -1954,6 +1962,9 @@ static int reopen_demux_for_component(AVFormatContext *s, struct representation
>     pls->ctx->pb = &pls->pb;
>     pls->ctx->io_open  = nested_io_open;
> 
> +    if (pls->init_sec_data_len > 0)
> +        av_dict_set_int(&in_fmt_opts, "header_size", pls->init_sec_data_len, 0);
> +
>     // provide additional information from mpd if available
>     ret = avformat_open_input(&pls->ctx, "", in_fmt, &in_fmt_opts); //pls->init_section->url
>     av_dict_free(&in_fmt_opts);
> -- 
> 2.26.2
> 
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".

Patchset LGTM

Thanks

Steven Liu
Gorilla Maguila May 25, 2020, 1:43 p.m. UTC | #2
These lines:

+    if (pls->init_sec_data_len > 0)
+        pls->ctx->probesize = FFMIN(pls->ctx->probesize,
pls->init_sec_data_len);
     pls->ctx->max_analyze_duration = s->max_analyze_duration > 0 ?
s->max_analyze_duration : 4 * AV_TIME_BASE;
-    ret = av_probe_input_buffer(&pls->pb, &in_fmt, "", NULL, 0, 0);
+    ret = av_probe_input_buffer(&pls->pb, &in_fmt, "", NULL, 0,
pls->ctx->probesize);


cause an Error in av_probe_input_buffer when pls->init_sec_data_len
or pls->ctx->probesize are < 2048 due to the following line in
av_probe_input_buffer:

https://github.com/FFmpeg/FFmpeg/blob/master/libavformat/format.c#L236

El vie., 22 may. 2020 a las 9:22, Steven Liu (<lq@chinaffmpeg.org>)
escribió:

>
>
> > 2020年5月22日 下午1:42,rcombs <rcombs@rcombs.me> 写道:
> >
> > This reduces the number of requests that have to be made during startup.
> > ---
> > libavformat/dashdec.c | 41 ++++++++++++++++++++++++++---------------
> > 1 file changed, 26 insertions(+), 15 deletions(-)
> >
> > diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c
> > index ec2aadcee3..1bd070c7cb 100644
> > --- a/libavformat/dashdec.c
> > +++ b/libavformat/dashdec.c
> > @@ -1798,6 +1798,19 @@ static int read_data(void *opaque, uint8_t *buf,
> int buf_size)
> >     DASHContext *c = v->parent->priv_data;
> >
> > restart:
> > +    /* load/update Media Initialization Section, if any */
> > +    if ((ret = update_init_section(v)) < 0)
> > +        goto end;
> > +
> > +    if (v->init_sec_buf_read_offset < v->init_sec_data_len) {
> > +        /* Push init section out first before first actual fragment */
> > +        int copy_size = FFMIN(v->init_sec_data_len -
> v->init_sec_buf_read_offset, buf_size);
> > +        memcpy(buf, v->init_sec_buf, copy_size);
> > +        v->init_sec_buf_read_offset += copy_size;
> > +        ret = copy_size;
> > +        goto end;
> > +    }
> > +
> >     if (!v->input) {
> >         free_fragment(&v->cur_seg);
> >         v->cur_seg = get_current_fragment(v);
> > @@ -1806,11 +1819,6 @@ restart:
> >             goto end;
> >         }
> >
> > -        /* load/update Media Initialization Section, if any */
> > -        ret = update_init_section(v);
> > -        if (ret)
> > -            goto end;
> > -
> >         ret = open_input(c, v, v->cur_seg);
> >         if (ret < 0) {
> >             if (ff_check_interrupt(c->interrupt_callback)) {
> > @@ -1823,15 +1831,6 @@ restart:
> >         }
> >     }
> >
> > -    if (v->init_sec_buf_read_offset < v->init_sec_data_len) {
> > -        /* Push init section out first before first actual fragment */
> > -        int copy_size = FFMIN(v->init_sec_data_len -
> v->init_sec_buf_read_offset, buf_size);
> > -        memcpy(buf, v->init_sec_buf, copy_size);
> > -        v->init_sec_buf_read_offset += copy_size;
> > -        ret = copy_size;
> > -        goto end;
> > -    }
> > -
> >     /* check the v->cur_seg, if it is null, get current and double check
> if the new v->cur_seg*/
> >     if (!v->cur_seg) {
> >         v->cur_seg = get_current_fragment(v);
> > @@ -1940,10 +1939,19 @@ static int
> reopen_demux_for_component(AVFormatContext *s, struct representation
> >     if ((ret = ff_copy_whiteblacklists(pls->ctx, s)) < 0)
> >         goto fail;
> >
> > +
> > +    if (pls->init_sec_data_len <= 0) {
> > +        /* load/update Media Initialization Section, if any */
> > +        if ((ret = update_init_section(pls)) < 0)
> > +            goto fail;
> > +    }
> > +
> >     pls->ctx->flags = AVFMT_FLAG_CUSTOM_IO;
> >     pls->ctx->probesize = s->probesize > 0 ? s->probesize : 1024 * 4;
> > +    if (pls->init_sec_data_len > 0)
> > +        pls->ctx->probesize = FFMIN(pls->ctx->probesize,
> pls->init_sec_data_len);
> >     pls->ctx->max_analyze_duration = s->max_analyze_duration > 0 ?
> s->max_analyze_duration : 4 * AV_TIME_BASE;
> > -    ret = av_probe_input_buffer(&pls->pb, &in_fmt, "", NULL, 0, 0);
> > +    ret = av_probe_input_buffer(&pls->pb, &in_fmt, "", NULL, 0,
> pls->ctx->probesize);
> >     if (ret < 0) {
> >         av_log(s, AV_LOG_ERROR, "Error when loading first fragment,
> playlist %d\n", (int)pls->rep_idx);
> >         avformat_free_context(pls->ctx);
> > @@ -1954,6 +1962,9 @@ static int
> reopen_demux_for_component(AVFormatContext *s, struct representation
> >     pls->ctx->pb = &pls->pb;
> >     pls->ctx->io_open  = nested_io_open;
> >
> > +    if (pls->init_sec_data_len > 0)
> > +        av_dict_set_int(&in_fmt_opts, "header_size",
> pls->init_sec_data_len, 0);
> > +
> >     // provide additional information from mpd if available
> >     ret = avformat_open_input(&pls->ctx, "", in_fmt, &in_fmt_opts);
> //pls->init_section->url
> >     av_dict_free(&in_fmt_opts);
> > --
> > 2.26.2
> >
> > _______________________________________________
> > ffmpeg-devel mailing list
> > ffmpeg-devel@ffmpeg.org
> > https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> >
> > To unsubscribe, visit link above, or email
> > ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
>
> Patchset LGTM
>
> Thanks
>
> Steven Liu
>
>
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
rcombs May 25, 2020, 4:42 p.m. UTC | #3
> On May 25, 2020, at 08:43, Gorilla Maguila <gorilla.maguila@gmail.com> wrote:
> 
> These lines:
> 
> +    if (pls->init_sec_data_len > 0)
> +        pls->ctx->probesize = FFMIN(pls->ctx->probesize,
> pls->init_sec_data_len);
>     pls->ctx->max_analyze_duration = s->max_analyze_duration > 0 ?
> s->max_analyze_duration : 4 * AV_TIME_BASE;
> -    ret = av_probe_input_buffer(&pls->pb, &in_fmt, "", NULL, 0, 0);
> +    ret = av_probe_input_buffer(&pls->pb, &in_fmt, "", NULL, 0,
> pls->ctx->probesize);
> 
> 
> cause an Error in av_probe_input_buffer when pls->init_sec_data_len
> or pls->ctx->probesize are < 2048 due to the following line in
> av_probe_input_buffer:
> 
> https://github.com/FFmpeg/FFmpeg/blob/master/libavformat/format.c#L236

Apply the patch series in the order it was sent: http://ffmpeg.org/pipermail/ffmpeg-devel/2020-May/263099.html <http://ffmpeg.org/pipermail/ffmpeg-devel/2020-May/263099.html>
> 
> El vie., 22 may. 2020 a las 9:22, Steven Liu (<lq@chinaffmpeg.org>)
> escribió:
> 
>> 
>> 
>>> 2020年5月22日 下午1:42,rcombs <rcombs@rcombs.me> 写道:
>>> 
>>> This reduces the number of requests that have to be made during startup.
>>> ---
>>> libavformat/dashdec.c | 41 ++++++++++++++++++++++++++---------------
>>> 1 file changed, 26 insertions(+), 15 deletions(-)
>>> 
>>> diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c
>>> index ec2aadcee3..1bd070c7cb 100644
>>> --- a/libavformat/dashdec.c
>>> +++ b/libavformat/dashdec.c
>>> @@ -1798,6 +1798,19 @@ static int read_data(void *opaque, uint8_t *buf,
>> int buf_size)
>>>    DASHContext *c = v->parent->priv_data;
>>> 
>>> restart:
>>> +    /* load/update Media Initialization Section, if any */
>>> +    if ((ret = update_init_section(v)) < 0)
>>> +        goto end;
>>> +
>>> +    if (v->init_sec_buf_read_offset < v->init_sec_data_len) {
>>> +        /* Push init section out first before first actual fragment */
>>> +        int copy_size = FFMIN(v->init_sec_data_len -
>> v->init_sec_buf_read_offset, buf_size);
>>> +        memcpy(buf, v->init_sec_buf, copy_size);
>>> +        v->init_sec_buf_read_offset += copy_size;
>>> +        ret = copy_size;
>>> +        goto end;
>>> +    }
>>> +
>>>    if (!v->input) {
>>>        free_fragment(&v->cur_seg);
>>>        v->cur_seg = get_current_fragment(v);
>>> @@ -1806,11 +1819,6 @@ restart:
>>>            goto end;
>>>        }
>>> 
>>> -        /* load/update Media Initialization Section, if any */
>>> -        ret = update_init_section(v);
>>> -        if (ret)
>>> -            goto end;
>>> -
>>>        ret = open_input(c, v, v->cur_seg);
>>>        if (ret < 0) {
>>>            if (ff_check_interrupt(c->interrupt_callback)) {
>>> @@ -1823,15 +1831,6 @@ restart:
>>>        }
>>>    }
>>> 
>>> -    if (v->init_sec_buf_read_offset < v->init_sec_data_len) {
>>> -        /* Push init section out first before first actual fragment */
>>> -        int copy_size = FFMIN(v->init_sec_data_len -
>> v->init_sec_buf_read_offset, buf_size);
>>> -        memcpy(buf, v->init_sec_buf, copy_size);
>>> -        v->init_sec_buf_read_offset += copy_size;
>>> -        ret = copy_size;
>>> -        goto end;
>>> -    }
>>> -
>>>    /* check the v->cur_seg, if it is null, get current and double check
>> if the new v->cur_seg*/
>>>    if (!v->cur_seg) {
>>>        v->cur_seg = get_current_fragment(v);
>>> @@ -1940,10 +1939,19 @@ static int
>> reopen_demux_for_component(AVFormatContext *s, struct representation
>>>    if ((ret = ff_copy_whiteblacklists(pls->ctx, s)) < 0)
>>>        goto fail;
>>> 
>>> +
>>> +    if (pls->init_sec_data_len <= 0) {
>>> +        /* load/update Media Initialization Section, if any */
>>> +        if ((ret = update_init_section(pls)) < 0)
>>> +            goto fail;
>>> +    }
>>> +
>>>    pls->ctx->flags = AVFMT_FLAG_CUSTOM_IO;
>>>    pls->ctx->probesize = s->probesize > 0 ? s->probesize : 1024 * 4;
>>> +    if (pls->init_sec_data_len > 0)
>>> +        pls->ctx->probesize = FFMIN(pls->ctx->probesize,
>> pls->init_sec_data_len);
>>>    pls->ctx->max_analyze_duration = s->max_analyze_duration > 0 ?
>> s->max_analyze_duration : 4 * AV_TIME_BASE;
>>> -    ret = av_probe_input_buffer(&pls->pb, &in_fmt, "", NULL, 0, 0);
>>> +    ret = av_probe_input_buffer(&pls->pb, &in_fmt, "", NULL, 0,
>> pls->ctx->probesize);
>>>    if (ret < 0) {
>>>        av_log(s, AV_LOG_ERROR, "Error when loading first fragment,
>> playlist %d\n", (int)pls->rep_idx);
>>>        avformat_free_context(pls->ctx);
>>> @@ -1954,6 +1962,9 @@ static int
>> reopen_demux_for_component(AVFormatContext *s, struct representation
>>>    pls->ctx->pb = &pls->pb;
>>>    pls->ctx->io_open  = nested_io_open;
>>> 
>>> +    if (pls->init_sec_data_len > 0)
>>> +        av_dict_set_int(&in_fmt_opts, "header_size",
>> pls->init_sec_data_len, 0);
>>> +
>>>    // provide additional information from mpd if available
>>>    ret = avformat_open_input(&pls->ctx, "", in_fmt, &in_fmt_opts);
>> //pls->init_section->url
>>>    av_dict_free(&in_fmt_opts);
>>> --
>>> 2.26.2
>>> 
>>> _______________________________________________
>>> ffmpeg-devel mailing list
>>> ffmpeg-devel@ffmpeg.org
>>> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>>> 
>>> To unsubscribe, visit link above, or email
>>> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
>> 
>> Patchset LGTM
>> 
>> Thanks
>> 
>> Steven Liu
>> 
>> 
>> 
>> _______________________________________________
>> ffmpeg-devel mailing list
>> ffmpeg-devel@ffmpeg.org
>> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>> 
>> To unsubscribe, visit link above, or email
>> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
diff mbox series

Patch

diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c
index ec2aadcee3..1bd070c7cb 100644
--- a/libavformat/dashdec.c
+++ b/libavformat/dashdec.c
@@ -1798,6 +1798,19 @@  static int read_data(void *opaque, uint8_t *buf, int buf_size)
     DASHContext *c = v->parent->priv_data;
 
 restart:
+    /* load/update Media Initialization Section, if any */
+    if ((ret = update_init_section(v)) < 0)
+        goto end;
+
+    if (v->init_sec_buf_read_offset < v->init_sec_data_len) {
+        /* Push init section out first before first actual fragment */
+        int copy_size = FFMIN(v->init_sec_data_len - v->init_sec_buf_read_offset, buf_size);
+        memcpy(buf, v->init_sec_buf, copy_size);
+        v->init_sec_buf_read_offset += copy_size;
+        ret = copy_size;
+        goto end;
+    }
+
     if (!v->input) {
         free_fragment(&v->cur_seg);
         v->cur_seg = get_current_fragment(v);
@@ -1806,11 +1819,6 @@  restart:
             goto end;
         }
 
-        /* load/update Media Initialization Section, if any */
-        ret = update_init_section(v);
-        if (ret)
-            goto end;
-
         ret = open_input(c, v, v->cur_seg);
         if (ret < 0) {
             if (ff_check_interrupt(c->interrupt_callback)) {
@@ -1823,15 +1831,6 @@  restart:
         }
     }
 
-    if (v->init_sec_buf_read_offset < v->init_sec_data_len) {
-        /* Push init section out first before first actual fragment */
-        int copy_size = FFMIN(v->init_sec_data_len - v->init_sec_buf_read_offset, buf_size);
-        memcpy(buf, v->init_sec_buf, copy_size);
-        v->init_sec_buf_read_offset += copy_size;
-        ret = copy_size;
-        goto end;
-    }
-
     /* check the v->cur_seg, if it is null, get current and double check if the new v->cur_seg*/
     if (!v->cur_seg) {
         v->cur_seg = get_current_fragment(v);
@@ -1940,10 +1939,19 @@  static int reopen_demux_for_component(AVFormatContext *s, struct representation
     if ((ret = ff_copy_whiteblacklists(pls->ctx, s)) < 0)
         goto fail;
 
+
+    if (pls->init_sec_data_len <= 0) {
+        /* load/update Media Initialization Section, if any */
+        if ((ret = update_init_section(pls)) < 0)
+            goto fail;
+    }
+
     pls->ctx->flags = AVFMT_FLAG_CUSTOM_IO;
     pls->ctx->probesize = s->probesize > 0 ? s->probesize : 1024 * 4;
+    if (pls->init_sec_data_len > 0)
+        pls->ctx->probesize = FFMIN(pls->ctx->probesize, pls->init_sec_data_len);
     pls->ctx->max_analyze_duration = s->max_analyze_duration > 0 ? s->max_analyze_duration : 4 * AV_TIME_BASE;
-    ret = av_probe_input_buffer(&pls->pb, &in_fmt, "", NULL, 0, 0);
+    ret = av_probe_input_buffer(&pls->pb, &in_fmt, "", NULL, 0, pls->ctx->probesize);
     if (ret < 0) {
         av_log(s, AV_LOG_ERROR, "Error when loading first fragment, playlist %d\n", (int)pls->rep_idx);
         avformat_free_context(pls->ctx);
@@ -1954,6 +1962,9 @@  static int reopen_demux_for_component(AVFormatContext *s, struct representation
     pls->ctx->pb = &pls->pb;
     pls->ctx->io_open  = nested_io_open;
 
+    if (pls->init_sec_data_len > 0)
+        av_dict_set_int(&in_fmt_opts, "header_size", pls->init_sec_data_len, 0);
+
     // provide additional information from mpd if available
     ret = avformat_open_input(&pls->ctx, "", in_fmt, &in_fmt_opts); //pls->init_section->url
     av_dict_free(&in_fmt_opts);