[FFmpeg-devel] [PATCH] lavf/mov: fix hang while seek on a kind of fragmented mp4.

C.H.Liu liuchh83 at gmail.com
Sun Feb 3 17:08:57 EET 2019


Hi Marton,


Thanks for your replay.


The case I met is shown in attached pictures. Each 'moof' only contain one
track's data. So the reference id of the first 'sidx' box is 1. The the
reference id of the second 'sidx' box is 2.

Then we read below segment info in mp4 demuxer:

|MOVFragmentIndex

|----MOVFragmentIndexItem[0]

|--------MOVFragmentStreamInfo[0] {sidx_pts=20000}

|--------MOVFragmentStreamInfo[1] {sidx_pts=AV_NOPTS_VALUE}

|----MOVFragmentIndexItem[1]

|--------MOVFragmentStreamInfo[0] {sidx_pts=AV_NOPTS_VALUE}

|--------MOVFragmentStreamInfo[1] {sidx_pts=0}

|...

If you seek a point to this file, you can NOT exit the while statement in
search_frag_timestamp().

You can easily create the test clip: ffmpeg -i INPUT_VIDEO -c copy
-movflags dash+frag_keyframe+skip_trailer+separate_moof out.mp4

[image: sidx0.png]
[image: sidx1.png]

On the other hand, you are right. I should only fall back to linear
searching if needed. It is more efficient.
I'll send the patch again.

Thanks and Regards,
Charles Liu

Marton Balint <cus at passwd.hu> 于2019年2月3日周日 上午12:03写道:

>
>
> On Sat, 2 Feb 2019, Charles Liu wrote:
>
> > Binary searching would hang if the fragment items do NOT have timestamp
> for the specified stream.
> >
> > For example, a fmp4 consists of separated 'moof' boxes for each track,
> and separated 'sidx' for each segment, but no 'mfra' box.
> > Then every fragment item only have the timestamp for one of its tracks.
>
> I don't see why you are changing the search to be linear. Is it possible
> the some of the stream fragmens have NOPTS_VALUE but other don't? In this
> case you should keep the binary search and only fall back to linear search
> if binary search finds an AV_NOPTS_VALUE. See similar code in function
> mxf_absolute_bodysid_offset of libavformat/mxfdec.c.
>
> On the other hand, if either all stream segments have AV_NOPTS_VALUE, or
> none of them do, then why don't you simply break out of the loop with
> error?
>
> Thanks,
> Marton
>
>
> >
> > Signed-off-by: Charles Liu <liuchh83 at gmail.com>
> > ---
> > libavformat/mov.c | 21 +++++++++------------
> > 1 file changed, 9 insertions(+), 12 deletions(-)
> >
> > diff --git a/libavformat/mov.c b/libavformat/mov.c
> > index 9b9739f788..ce1130ad07 100644
> > --- a/libavformat/mov.c
> > +++ b/libavformat/mov.c
> > @@ -1266,9 +1266,8 @@ static int64_t get_frag_time(MOVFragmentIndex
> *frag_index,
> > static int search_frag_timestamp(MOVFragmentIndex *frag_index,
> >                                  AVStream *st, int64_t timestamp)
> > {
> > -    int a, b, m;
> >     int64_t frag_time;
> > -    int id = -1;
> > +    int i, frag = 0, id = -1;
> >
> >     if (st) {
> >         // If the stream is referenced by any sidx, limit the search
> > @@ -1278,20 +1277,18 @@ static int
> search_frag_timestamp(MOVFragmentIndex *frag_index,
> >             id = st->id;
> >     }
> >
> > -    a = -1;
> > -    b = frag_index->nb_items;
> > -
> > -    while (b - a > 1) {
> > -        m = (a + b) >> 1;
> > -        frag_time = get_frag_time(frag_index, m, id);
> > +    for (i = 0; i < frag_index->nb_items; i++) {
> > +        frag_time = get_frag_time(frag_index, i, id);
> >         if (frag_time != AV_NOPTS_VALUE) {
> > -            if (frag_time >= timestamp)
> > -                b = m;
> >             if (frag_time <= timestamp)
> > -                a = m;
> > +                frag = i;
> > +            else {
> > +                break;
> > +            }
> >         }
> >     }
> > -    return a;
> > +
> > +    return frag;
> > }
> >
> > static int update_frag_index(MOVContext *c, int64_t offset)
> > --
> > 2.20.1
> >
> > _______________________________________________
> > ffmpeg-devel mailing list
> > ffmpeg-devel at ffmpeg.org
> > http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: sidx0.png
Type: image/png
Size: 287964 bytes
Desc: not available
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20190203/a09879e7/attachment.png>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: sidx1.png
Type: image/png
Size: 294710 bytes
Desc: not available
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20190203/a09879e7/attachment-0001.png>


More information about the ffmpeg-devel mailing list