diff mbox

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

Message ID 20190103013308.GB3501@michaelspb
State Superseded
Headers show

Commit Message

Michael Niedermayer Jan. 3, 2019, 1:33 a.m. UTC
On Mon, Nov 26, 2018 at 01:51:25PM +0000, Derek Buitenhuis wrote:
> On 23/11/2018 02:16, Michael Niedermayer wrote:
> > do we have some sample flv files that require this patchset / that have
> > discontinuites.
> 
> I have many. I've mailed you one privately, while I work on getting a public one.
> 
> > another thing i just realize now, why is this discontinuity issues coming up
> > now? flv support is very old. This should be a long standing issue
> 
> Probably not many codebases check the DISCONT flag. I only just added proper
> discontinuity handling to some codebases this year, and that's why *I* noticed.
> Chances are most people use the ffmpeg cli which seems to handle stuff differently,
> and doesn't necessarily care about the flag. In my case, I only try to 'fix'
> discontinuities if they appear to be in a format that allows them, during indexing.
> 
> I could add a workaround specific to FLV, or some threshold stuff, but I'd prefer
> that demuxers which may output discontinuous timestamps say they do.

The file looks like 2 files concatenated, even with FLV main header between 
them. 

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

thx




[...]

Comments

Derek Buitenhuis Jan. 3, 2019, 4:21 p.m. UTC | #1
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.

Cheers,
- Derek
diff mbox

Patch

diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c
index 4b9f46902b..c9423da31c 100644
--- a/libavformat/flvdec.c
+++ b/libavformat/flvdec.c
@@ -72,6 +72,8 @@  typedef struct FLVContext {
     int64_t *keyframe_filepositions;
     int missing_streams;
     AVRational framerate;
+    int64_t last_ts;
+    int64_t time_offset;
 } FLVContext;
 
 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;
+            }
+        }
+
         if (i > 22) {
             unsigned lsize2 = AV_RB32(flv->resync_buffer + j1 - 4);
             if (lsize2 >= 11 && lsize2 + 8LL < FFMIN(i, RESYNC_BUFFER_SIZE)) {
@@ -1238,8 +1251,8 @@  retry_duration:
     ret = av_get_packet(s->pb, pkt, size);
     if (ret < 0)
         return ret;
-    pkt->dts          = dts;
-    pkt->pts          = pts == AV_NOPTS_VALUE ? dts : pts;
+    pkt->dts          = dts + flv->time_offset;
+    pkt->pts          = (pts == AV_NOPTS_VALUE ? dts : pts) +flv->time_offset ;
     pkt->stream_index = st->index;
     pkt->pos          = pos;
     if (flv->new_extradata[stream_type]) {
@@ -1282,6 +1295,10 @@  leave:
             }
         }
     }
+
+    if (ret >= 0)
+        flv->last_ts = pkt->dts;
+
     return ret;
 }