Skip to content

Instantly share code, notes, and snippets.

@rcombs
Last active May 12, 2024 16:56
Show Gist options
  • Save rcombs/796f1f79bbaa1b693d3ffbd2a8801276 to your computer and use it in GitHub Desktop.
Save rcombs/796f1f79bbaa1b693d3ffbd2a8801276 to your computer and use it in GitHub Desktop.
diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c
index 8a3436f2be..c904cae374 100644
--- a/libavformat/mpegts.c
+++ b/libavformat/mpegts.c
@@ -2877,10 +2877,16 @@ static int handle_packet(MpegTSContext *ts, const uint8_t *packet, int64_t pos)
} else {
int ret;
- // Note: The position here points actually behind the current packet.
if (tss->type == MPEGTS_PES) {
- if ((ret = tss->u.pes_filter.pes_cb(tss, p, p_end - p, is_start,
- pos - ts->raw_packet_size)) < 0)
+ // Adjust the position back to the start of the packet.
+ // In BD/DVHS packets, this includes a 4-byte timecode at the start
+ // (whereas in broadcast, the 16 bytes of FEC data are at the end).
+ if (ts->raw_packet_size == TS_DVHS_PACKET_SIZE)
+ pos -= TS_DVHS_PACKET_SIZE;
+ else
+ pos -= TS_PACKET_SIZE;
+
+ if ((ret = tss->u.pes_filter.pes_cb(tss, p, p_end - p, is_start, pos)) < 0)
return ret;
}
}
@@ -2937,6 +2943,11 @@ static int read_packet(AVFormatContext *s, uint8_t *buf, int raw_packet_size,
AVIOContext *pb = s->pb;
int len;
+ // DVHS/BDAV extra data is at the start of the packet, so we skip it here.
+ // FEC is at the end, so we'll skip it in finished_reading_packet.
+ if (raw_packet_size == TS_DVHS_PACKET_SIZE)
+ avio_skip(pb, raw_packet_size - TS_PACKET_SIZE);
+
for (;;) {
len = ffio_read_indirect(pb, buf, TS_PACKET_SIZE, data);
if (len != TS_PACKET_SIZE)
@@ -2959,6 +2970,12 @@ static int read_packet(AVFormatContext *s, uint8_t *buf, int raw_packet_size,
static void finished_reading_packet(AVFormatContext *s, int raw_packet_size)
{
AVIOContext *pb = s->pb;
+
+ // DVHS/BDAV's extra data is considered to be at the _start_ of the packet,
+ // so we'll skip it in read_packet(). FEC extra data is at the end, so we skip here.
+ if (raw_packet_size == TS_DVHS_PACKET_SIZE)
+ return;
+
int skip = raw_packet_size - TS_PACKET_SIZE;
if (skip > 0)
avio_skip(pb, skip);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment