Set discontinuity_indicator to 1 for the first packet

This commit is contained in:
Vanilagy
2026-01-16 16:56:50 +01:00
parent e8b27768a9
commit 282751ec1c
3 changed files with 21 additions and 14 deletions
+2 -2
View File
@@ -14,11 +14,11 @@
source: new Mediabunny.BufferSource(await file.arrayBuffer()), source: new Mediabunny.BufferSource(await file.arrayBuffer()),
}); });
const track = await input.getPrimaryAudioTrack(); const track = await input.getPrimaryVideoTrack();
const sink = new Mediabunny.EncodedPacketSink(track); const sink = new Mediabunny.EncodedPacketSink(track);
for await (const packet of sink.packets()) { for await (const packet of sink.packets()) {
console.log(packet.timestamp, packet.duration, packet.type); //console.log(packet.timestamp, packet.duration, packet.type);
} }
/* /*
+4 -5
View File
@@ -638,10 +638,6 @@ const readPesPacketHeader = (section: Section): PesPacketHeader | null => {
bitstream.skipBits(14); bitstream.skipBits(14);
if (ptsDtsFlags !== 0b10 && ptsDtsFlags !== 0b11) {
return null; // Support only timestamped packets
}
let pts = 0; let pts = 0;
if (ptsDtsFlags === 0b10 || ptsDtsFlags === 0b11) { if (ptsDtsFlags === 0b10 || ptsDtsFlags === 0b11) {
bitstream.skipBits(4); bitstream.skipBits(4);
@@ -651,7 +647,10 @@ const readPesPacketHeader = (section: Section): PesPacketHeader | null => {
bitstream.skipBits(1); bitstream.skipBits(1);
pts += bitstream.readBits(15); pts += bitstream.readBits(15);
} else { } else {
return null; // Support only timestamped packets throw new Error(
'PES packets without PTS are not currently supported. If you think this file should be supported,'
+ ' please report it.',
);
} }
return { return {
+15 -7
View File
@@ -52,6 +52,7 @@ type MpegTsTrackData = {
hevcDecoderConfig: HevcDecoderConfigurationRecord | null; hevcDecoderConfig: HevcDecoderConfigurationRecord | null;
adtsHeader: Uint8Array | null; adtsHeader: Uint8Array | null;
adtsHeaderBitstream: Bitstream | null; adtsHeaderBitstream: Bitstream | null;
firstPacketWritten: boolean;
}; };
type QueuedPacket = { type QueuedPacket = {
@@ -128,6 +129,7 @@ export class MpegTsMuxer extends Muxer {
hevcDecoderConfig: null, hevcDecoderConfig: null,
adtsHeader: null, adtsHeader: null,
adtsHeaderBitstream: null, adtsHeaderBitstream: null,
firstPacketWritten: false,
}; };
this.trackDatas.push(newTrackData); this.trackDatas.push(newTrackData);
@@ -168,6 +170,7 @@ export class MpegTsMuxer extends Muxer {
hevcDecoderConfig: null, hevcDecoderConfig: null,
adtsHeader: null, adtsHeader: null,
adtsHeaderBitstream: null, adtsHeaderBitstream: null,
firstPacketWritten: false,
}; };
this.trackDatas.push(newTrackData); this.trackDatas.push(newTrackData);
@@ -518,18 +521,19 @@ export class MpegTsMuxer extends Muxer {
const totalLength = this.pesHeaderBuffer.length + queuedPacket.data.length; const totalLength = this.pesHeaderBuffer.length + queuedPacket.data.length;
let offset = 0; let offset = 0;
let isFirst = true; let isFirstTsPacket = true;
while (offset < totalLength) { while (offset < totalLength) {
const pusi = isFirst; const pusi = isFirstTsPacket;
const remainingData = totalLength - offset; const remainingData = totalLength - offset;
const needsRandomAccessIndicator = isFirst && queuedPacket.isKeyframe; const randomAccessIndicator = isFirstTsPacket && queuedPacket.isKeyframe;
const discontinuityIndicator = isFirstTsPacket && !trackData.firstPacketWritten;
const basePaddingNeeded = Math.max(0, 184 - remainingData); const basePaddingNeeded = Math.max(0, 184 - remainingData);
let adaptationFieldSize: number; let adaptationFieldSize: number;
if (needsRandomAccessIndicator) { if (randomAccessIndicator || discontinuityIndicator) {
// Random access indicator requires at least 2 bytes // We need at least two bytes
adaptationFieldSize = Math.max(2, basePaddingNeeded); adaptationFieldSize = Math.max(2, basePaddingNeeded);
} else { } else {
adaptationFieldSize = basePaddingNeeded; adaptationFieldSize = basePaddingNeeded;
@@ -543,7 +547,9 @@ export class MpegTsMuxer extends Muxer {
buf[0] = 0; // adaptation_field_length buf[0] = 0; // adaptation_field_length
} else { } else {
buf[0] = adaptationFieldSize - 1; // adaptation_field_length buf[0] = adaptationFieldSize - 1; // adaptation_field_length
buf[1] = Number(needsRandomAccessIndicator) << 6; // flags (random_access_indicator in bit 6) buf[1]
= (Number(discontinuityIndicator) << 7) // discontinuity_indicator
| (Number(randomAccessIndicator) << 6); // random_access_indicator
buf.fill(0xFF, 2, adaptationFieldSize); // stuffing_bytes buf.fill(0xFF, 2, adaptationFieldSize); // stuffing_bytes
} }
@@ -569,8 +575,10 @@ export class MpegTsMuxer extends Muxer {
this.writeTsPacket(trackData.pid, pusi, adaptationField, payload); this.writeTsPacket(trackData.pid, pusi, adaptationField, payload);
offset += payloadSize; offset += payloadSize;
isFirst = false; isFirstTsPacket = false;
} }
trackData.firstPacketWritten = true;
} }
private writeTsPacket( private writeTsPacket(