[FFmpeg-devel,2/3] flvdec: Mark the demuxer as allowing discontinuous timestamps

Submitted by Michael Niedermayer on Jan. 15, 2019, 9:24 p.m.

Details

Message ID 20190115212425.GF3501@michaelspb
State New
Headers show

Commit Message

Michael Niedermayer Jan. 15, 2019, 9:24 p.m.
On Thu, Jan 03, 2019 at 04:21:37PM +0000, Derek Buitenhuis wrote:
> On 03/01/2019 01:33, Michael Niedermayer wrote:
> > The file looks like 2 files concatenated, even with FLV main header between 
> > them. 
> 
> Yes, they all seem to be. I was under the impression FLV didn't have a header to
> check against like this. Seems I was wrong.
> 
> > the patch below should make this work with sequential demuxing assuming the
> > 2 files dont change streams somehow with the normal demuxer.
> > 
> > not sure this is the best way to do it ...
> 
> [...]
> 
> > also trying a random other flv related tool, FLVTool2 1.0.6 does not seem to
> > demux the 2nd file of the 2 correctly. Which makes me suspect more that the
> > file is invalid. Not that this would fundamentally change anything
> 
> Some do, some don't. Classic multimedia.
> 
> I would also be OK with a patch that simply stops demuxing like many programs
> seem to do, instead of outputting the packets. Up to you which you prefer; I have
> no strong opinion between the two.
> 
> > diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c
> > index 4b9f46902b..c9423da31c 100644
> > --- a/libavformat/flvdec.c
> > +++ b/libavformat/flvdec.c
> 
> [...]
> 
> >  static int probe(AVProbeData *p, int live)
> > @@ -917,6 +919,17 @@ static int resync(AVFormatContext *s)
> >          flv->resync_buffer[j ] =
> >          flv->resync_buffer[j1] = avio_r8(s->pb);
> >  
> > +        if (i >= 8) {
> > +            uint8_t *d = flv->resync_buffer + j1 - 8;
> > +            if (d[0] == 'F' &&
> > +                d[1] == 'L' &&
> > +                d[2] == 'V' &&
> > +                d[3] < 5 && d[5] == 0) {
> > +                av_log(s, AV_LOG_WARNING, "Concatenated FLV detected, might fail to demux, decode and seek %Ld\n", flv->last_ts);
> > +                flv->time_offset = flv->last_ts + 1;
> > +            }
> > +        }
> 
> How does this affect seeking? That is, is it safe? If it beaks seeking,
> it may be better to not output the concatenated packets at all.

Heres a better patch which may work with seeking as long as there are only
2 files concatenated

i think completely discarding the parts after the concatenation would cause
user complaints and they would have a point, if the data is in there we
should be able to recover it for muxing it in a better file at least

commit 41db08743da8a624c35d138130379aa1a46d3a53 (HEAD -> master)
Author: Michael Niedermayer <michael@niedermayer.cc>
Date:   Thu Jan 3 01:08:31 2019 +0100

    avformat/flvdec: Try to support some concatenated flv files
    
    Fixes: discont.flv
    
    Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>





[...]

Comments

Derek Buitenhuis Jan. 17, 2019, 9:45 p.m.
On 15/01/2019 21:24, Michael Niedermayer wrote:
> Heres a better patch which may work with seeking as long as there are only
> 2 files concatenated
> 
> i think completely discarding the parts after the concatenation would cause
> user complaints and they would have a point, if the data is in there we
> should be able to recover it for muxing it in a better file at least

No strong opinion. You can push.

- Derek
Michael Niedermayer Jan. 30, 2019, 11:18 p.m.
On Thu, Jan 17, 2019 at 09:45:04PM +0000, Derek Buitenhuis wrote:
> On 15/01/2019 21:24, Michael Niedermayer wrote:
> > Heres a better patch which may work with seeking as long as there are only
> > 2 files concatenated
> > 
> > i think completely discarding the parts after the concatenation would cause
> > user complaints and they would have a point, if the data is in there we
> > should be able to recover it for muxing it in a better file at least
> 
> No strong opinion. You can push.

will apply

thanks

[...]

Patch hide | download patch | download mbox

diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c
index 4b9f46902b..80bbc5cfeb 100644
--- a/libavformat/flvdec.c
+++ b/libavformat/flvdec.c
@@ -72,6 +72,9 @@  typedef struct FLVContext {
     int64_t *keyframe_filepositions;
     int missing_streams;
     AVRational framerate;
+    int64_t last_ts;
+    int64_t time_offset;
+    int64_t time_pos;
 } FLVContext;
 
 static int probe(AVProbeData *p, int live)
@@ -917,6 +920,18 @@  static int resync(AVFormatContext *s)
         flv->resync_buffer[j ] =
         flv->resync_buffer[j1] = avio_r8(s->pb);
 
+        if (i >= 8 && pos) {
+            uint8_t *d = flv->resync_buffer + j1 - 8;
+            if (d[0] == 'F' &&
+                d[1] == 'L' &&
+                d[2] == 'V' &&
+                d[3] < 5 && d[5] == 0) {
+                av_log(s, AV_LOG_WARNING, "Concatenated FLV detected, might fail to demux, decode and seek %Ld\n", flv->last_ts);
+                flv->time_offset = flv->last_ts + 1;
+                flv->time_pos    = avio_tell(s->pb);
+            }
+        }
+
         if (i > 22) {
             unsigned lsize2 = AV_RB32(flv->resync_buffer + j1 - 4);
             if (lsize2 >= 11 && lsize2 + 8LL < FFMIN(i, RESYNC_BUFFER_SIZE)) {
@@ -1072,6 +1087,10 @@  skip:
         }
         av_log(s, AV_LOG_TRACE, "%d %X %d \n", stream_type, flags, st->discard);
 
+        if (flv->time_pos <= pos) {
+            dts += flv->time_offset;
+        }
+
         if ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) &&
             ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY ||
               stream_type == FLV_STREAM_TYPE_AUDIO))
@@ -1282,6 +1301,10 @@  leave:
             }
         }
     }
+
+    if (ret >= 0)
+        flv->last_ts = pkt->dts;
+
     return ret;
 }