Skip to content

Commit

Permalink
Fix PTS calculation on rollover.
Browse files Browse the repository at this point in the history
When a rollover was occuring the timeoffset value was incorrectly
calculated due to taking the minimum PTS from the new set of rollovers,
this lead to a very large delta on the PTS for the audio and led to
incorrect PTS values.

This happened to be fixed by the silent gap code just below, which set
the sample pts and dts to be the expected next value, but this now makes
it so on well-formed media, the else branch is essentially a no-op
because the delta is zero.
  • Loading branch information
itsjamie authored and Rob Walch committed Jul 31, 2020
1 parent 0210d76 commit 7fcdeac
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 11 deletions.
12 changes: 2 additions & 10 deletions src/demux/tsdemuxer.js
Original file line number Diff line number Diff line change
Expand Up @@ -487,22 +487,14 @@ class TSDemuxer {
(frag[11] & 0xFE) * 16384 +// 1 << 14
(frag[12] & 0xFF) * 128 +// 1 << 7
(frag[13] & 0xFE) / 2;
// check if greater than 2^32 -1
if (pesPts > 4294967295) {
// decrement 2^33
pesPts -= 8589934592;
}

if (pesFlags & 0x40) {
pesDts = (frag[14] & 0x0E) * 536870912 +// 1 << 29
(frag[15] & 0xFF) * 4194304 +// 1 << 22
(frag[16] & 0xFE) * 16384 +// 1 << 14
(frag[17] & 0xFF) * 128 +// 1 << 7
(frag[18] & 0xFE) / 2;
// check if greater than 2^32 -1
if (pesDts > 4294967295) {
// decrement 2^33
pesDts -= 8589934592;
}

if (pesPts - pesDts > 60 * 90000) {
logger.warn(`${Math.round((pesPts - pesDts) / 90000)}s delta between PTS and DTS, align them`);
pesPts = pesDts;
Expand Down
16 changes: 15 additions & 1 deletion src/remux/mp4-remuxer.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,21 @@ class MP4Remuxer {
// if first audio DTS is not aligned with first video DTS then we need to take that into account
// when providing timeOffset to remuxAudio / remuxVideo. if we don't do that, there might be a permanent / small
// drift between audio and video streams
const startPTS = videoTrack.samples.reduce((minPTS, sample) => Math.min(minPTS, sample.pts), videoTrack.samples[0].pts);
let rolloverDetected = false;
const startPTS = videoTrack.samples.reduce((minPTS, sample) => {
const delta = sample.pts - minPTS;
if (delta < -4294967296) { // 2^32, see PTSNormalize for reasoning, but we're hitting a rollover here, and we don't want that to impact the timeOffset calculation
rolloverDetected = true;
return minPTS;
} else if (delta > 0) {
return minPTS;
} else {
return sample.pts;
}
}, videoTrack.samples[0].pts);
if (rolloverDetected) {
logger.debug('PTS rollover detected');
}
const tsDelta = audioTrack.samples[0].pts - startPTS;
const audiovideoTimestampDelta = tsDelta / videoTrack.inputTimeScale;
audioTimeOffset += Math.max(0, audiovideoTimestampDelta);
Expand Down

0 comments on commit 7fcdeac

Please sign in to comment.