Skip to content

Commit 9f30782

Browse files
AkarinVSAsd-g
authored andcommitted
common/lwlibav_video.c: be more careful when to compensate for the TC field in mpegts
Updates #6. Signed-off-by: akarin <i@akarin.info>
1 parent 668faea commit 9f30782

File tree

1 file changed

+21
-1
lines changed

1 file changed

+21
-1
lines changed

common/lwlibav_video.c

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -614,7 +614,27 @@ static int lavf_seek_frame
614614
// incorrect synchronization point.
615615
// https://github.com/FFmpeg/FFmpeg/blob/n4.4/libavformat/mpegts.c#L2898
616616
if ((flags & AVSEEK_FLAG_BYTE) && strcmp(s->iformat->name, "mpegts") == 0) {
617-
timestamp += 4; // skip the TC header
617+
// However, not all mpegts files are BD, e.g. TV ts does not have such a 4B
618+
// TP_extra_header.
619+
//
620+
// There is no easy way to differentiate between the two (using file extension
621+
// will be too fragile.) Fortunately, the top 2-bit of TP_extra_header is
622+
// the copy permission indication, which all sources seem to set to 0, so
623+
// the first byte of TP_extra_header should not be 0x47, and we can use
624+
// this to detect these two cases.
625+
//
626+
// We do the offset compensation only when the 1st byte is not 0x47 and the
627+
// 5th byte is 0x47.
628+
// This test should not affect the performance much as av_seek_frame is going
629+
// to read at least 188 bytes from position timestamp anyway.
630+
unsigned char buf[5];
631+
const char sync_byte = 0x47;
632+
avio_seek(s->pb, timestamp, SEEK_SET);
633+
avio_read(s->pb, buf, sizeof buf);
634+
if (buf[0] != sync_byte && buf[4] == sync_byte)
635+
timestamp += 4; // skip the TC header
636+
// There is no need to restore file pointer as we have set AVSEEK_FLAG_BYTE and
637+
// so we are going to seek to timestamp anyway.
618638
}
619639
return av_seek_frame(s, stream_index, timestamp, flags);
620640
}

0 commit comments

Comments
 (0)