diff options
author | Michael Niedermayer <michael@niedermayer.cc> | 2019-01-03 01:08:31 +0100 |
---|---|---|
committer | Michael Niedermayer <michael@niedermayer.cc> | 2019-01-31 00:24:38 +0100 |
commit | b559c58a03f88dcbf1e61875bb494743d4c6d081 (patch) | |
tree | a3568535b7ddf04f49c3ab268a881c405adb076b | |
parent | 8a23a2b7de386a98d8da5e0d5b6d8880413c5f46 (diff) | |
download | ffmpeg-b559c58a03f88dcbf1e61875bb494743d4c6d081.tar.gz |
avformat/flvdec: Try to support some concatenated flv files
Fixes: discont.flv
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
-rw-r--r-- | libavformat/flvdec.c | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c index 4b9f46902b..972e333313 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 %"PRId64"\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; } |