Optimize I-Frame parsing

#5392
This commit is contained in:
Rob Walch
2026-04-09 19:05:07 -07:00
parent 84d322496d
commit b52527a68e
3 changed files with 55 additions and 58 deletions
+11 -9
View File
@@ -867,15 +867,17 @@ export default class MP4Remuxer extends Logger implements Remuxer {
this.videoSampleDuration = mp4SampleDuration;
this.isVideoContiguous = true;
if (__USE_IFRAMES__) {
if (chunkMeta.iframe && outputSamples.length === 1) {
outputSamples[0].duration = mp4SampleDuration =
chunkMeta.duration * timeScale;
this.nextVideoTs = nextVideoTs =
firstDTS + mp4SampleDuration - initTime;
} else {
this.warn(
`Not adjusting IFrame duration (sample count ${outputSamples.length})`,
);
if (chunkMeta.iframe) {
if (outputSamples.length === 1) {
outputSamples[0].duration = mp4SampleDuration =
chunkMeta.duration * timeScale;
this.nextVideoTs = nextVideoTs =
firstDTS + mp4SampleDuration - initTime;
} else {
this.warn(
`Not adjusting IFrame duration (sample count ${outputSamples.length})`,
);
}
}
}
const moof = MP4.moof(
+22 -28
View File
@@ -274,34 +274,28 @@ class PassThroughRemuxer extends Logger implements Remuxer {
if (trun.length === 1 && trun[0].samples.length) {
const sampleOffset = trun[0].sampleOffset;
let totalSize = 0;
const samples = trun[0].samples
.map((sample): TrackFragmentSample | null => {
const {
cts,
size,
flags: { dependsOn, isNonSync },
} = sample;
if (sampleOffset + totalSize + size > data.length) {
return null;
}
totalSize += size;
return {
cts: cts || 0,
duration: sampleDuration,
size,
flags: {
isLeading: 0,
isDependedOn: 0,
hasRedundancy: 0,
degradPrio: 0,
dependsOn,
isNonSync,
paddingValue: 0,
},
};
})
.filter((sampleOrNull) => !!sampleOrNull);
const samples = trun[0].samples.map((sample): TrackFragmentSample => {
const { cts, size, flags } = sample;
const { dependsOn, isNonSync } = Object.assign(
{ dependsOn: 2, isNonSync: 0 },
flags,
);
totalSize += size;
return {
cts: cts || 0,
duration: sampleDuration,
size,
flags: {
isLeading: 0,
isDependedOn: 0,
hasRedundancy: 0,
degradPrio: 0,
dependsOn,
isNonSync,
paddingValue: 0,
},
};
});
if (samples.length) {
const lastSample = samples[samples.length - 1];
let lastSampleDuration = duration * initData.video.timescale;
+22 -21
View File
@@ -702,7 +702,7 @@ export function parseSinf(sinf: Uint8Array): BoxDataOrUndefined {
type TrackFragmentRunSample = {
cts?: number;
size: number;
flags: {
flags?: {
dependsOn: 1 | 2;
isNonSync: 0 | 1;
};
@@ -855,7 +855,6 @@ export function getSampleData(
for (let ix = 0; ix < sampleCount; ix++) {
const sample: TrackFragmentRunSample = {
size: 0,
flags: { isNonSync: 0, dependsOn: 2 },
};
if (sampleDurationPresent) {
sampleDuration = readUint32(trun, offset);
@@ -869,30 +868,32 @@ export function getSampleData(
} else {
sample.size = defaultSampleSize;
}
sampleOffset += sample.size;
if (sampleOffset <= eof) {
samples[ix] = sample;
}
sampleOffset += sample.size;
if (sampleFlagsPresent) {
const isNonSyncSample = trun[offset + 1] & 0x01;
sample.flags.dependsOn = (trun[offset] & 0x03) === 1 ? 1 : 2;
sample.flags.isNonSync = isNonSyncSample ? 1 : 0;
if (!isNonSyncSample) {
if (trackTimes.keyFrameIndex === undefined) {
trackTimes.keyFrameIndex = ix;
trackTimes.keyFrameStart = sampleDTS;
if (sampleFlagsPresent) {
const isNonSyncSample = trun[offset + 1] & 0x01;
sample.flags = {
isNonSync: isNonSyncSample ? 1 : 0,
dependsOn: (trun[offset] & 0x03) === 1 ? 1 : 2,
};
if (!isNonSyncSample) {
if (trackTimes.keyFrameIndex === undefined) {
trackTimes.keyFrameIndex = ix;
trackTimes.keyFrameStart = sampleDTS;
}
}
offset += 4;
}
offset += 4;
}
if (sampleCompositionTimeOffsetPresent) {
const version = trun[0];
if (version === 0) {
sample.cts = readUint32(trun, offset);
} else {
sample.cts = readSint32(trun, offset);
if (sampleCompositionTimeOffsetPresent) {
const version = trun[0];
if (version === 0) {
sample.cts = readUint32(trun, offset);
} else {
sample.cts = readSint32(trun, offset);
}
offset += 4;
}
offset += 4;
}
sampleDTS += sampleDuration;
rawDuration += sampleDuration;