Fix fragment reading bug

This commit is contained in:
Vanilagy
2025-01-02 18:16:06 +01:00
parent d476c42424
commit af26b4aab4
4 changed files with 45 additions and 23 deletions
+10 -2
View File
@@ -37,15 +37,23 @@
});
const audioTrack = await input.getPrimaryAudioTrack();
const drain = new Metamuxer.EncodedAudioChunkDrain(audioTrack);
for await (const chunk of drain.chunks()) {
console.log(chunk);
}
console.log("Done??")
/*
const drain = new Metamuxer.AudioBufferDrain(audioTrack);
const chunks = drain.buffers()
const a = chunks.next();
*/
//chunks.return();
console.log(await a)
//console.log("Done")
/*
+23 -15
View File
@@ -41,7 +41,8 @@ type InternalTrack = {
demuxer: IsobmffDemuxer;
inputTrack: InputTrack | null;
timescale: number;
durationInTimescale: number;
durationInMovieTimescale: number;
durationInMediaTimescale: number;
rotation: Rotation;
sampleTableOffset: number;
sampleTable: SampleTable | null;
@@ -458,6 +459,7 @@ export class IsobmffDemuxer extends Demuxer {
} else {
// We already know this fragment
const fragment = this.fragments[index]!;
// Even if we already know the fragment, we might not yet know its predecessor
if (currentFragment) currentFragment.nextFragment = fragment;
currentFragment = fragment;
}
@@ -527,7 +529,8 @@ export class IsobmffDemuxer extends Demuxer {
inputTrack: null,
info: null,
timescale: -1,
durationInTimescale: -1,
durationInMovieTimescale: -1,
durationInMediaTimescale: -1,
rotation: 0,
sampleTableOffset: -1,
sampleTable: null,
@@ -582,11 +585,13 @@ export class IsobmffDemuxer extends Demuxer {
if (version === 0) {
this.isobmffReader.pos += 8;
track.id = this.isobmffReader.readU32();
this.isobmffReader.pos += 8;
this.isobmffReader.pos += 4;
track.durationInMovieTimescale = this.isobmffReader.readU32();
} else if (version === 1) {
this.isobmffReader.pos += 16;
track.id = this.isobmffReader.readU32();
this.isobmffReader.pos += 12;
this.isobmffReader.pos += 4;
track.durationInMovieTimescale = this.isobmffReader.readU64();
} else {
throw new Error(`Incorrect track header version ${version}.`);
}
@@ -601,7 +606,7 @@ export class IsobmffDemuxer extends Demuxer {
return x[0] === values[0] && x[1] === values[1] && x[3] === values[2] && x[4] === values[3];
});
if (matrixIndex === -1) {
// console.warn(`Wacky rotation matrix ${rotationMatrix}; sticking with no rotation.`);
console.warn(`Wacky rotation matrix ${values.join(',')}; sticking with no rotation.`);
track.rotation = 0;
} else {
track.rotation = (90 * matrixIndex) as Rotation;
@@ -618,11 +623,11 @@ export class IsobmffDemuxer extends Demuxer {
if (version === 0) {
this.isobmffReader.pos += 8;
track.timescale = this.isobmffReader.readU32();
track.durationInTimescale = this.isobmffReader.readU32();
track.durationInMediaTimescale = this.isobmffReader.readU32();
} else if (version === 1) {
this.isobmffReader.pos += 16;
track.timescale = this.isobmffReader.readU32();
track.durationInTimescale = this.isobmffReader.readU64();
track.durationInMediaTimescale = this.isobmffReader.readU64();
}
}; break;
@@ -2046,10 +2051,11 @@ abstract class IsobmffTrackBacking<Chunk extends EncodedVideoChunk | EncodedAudi
} else {
const fragment = this.internalTrack.fragments[fragmentIndex]!;
if (!lookupEntry || fragment.moofOffset >= fragment.moofOffset) {
if (!lookupEntry || fragment.moofOffset >= lookupEntry.moofOffset) {
isobmffReader.pos = fragment.moofOffset + fragment.moofSize;
prevFragment = fragment;
} else {
// Use the lookup entry
isobmffReader.pos = lookupEntry.moofOffset;
}
}
@@ -2078,13 +2084,21 @@ abstract class IsobmffTrackBacking<Chunk extends EncodedVideoChunk | EncodedAudi
if (boxInfo.name === 'moof') {
const index = binarySearchExact(demuxer.fragments, startPos, x => x.moofOffset);
let fragment: Fragment;
if (index === -1) {
// This is the first time we've seen this fragment
isobmffReader.pos = startPos;
const fragment = await demuxer.readFragment();
fragment = await demuxer.readFragment();
if (prevFragment) prevFragment.nextFragment = fragment;
prevFragment = fragment;
} else {
// We already know this fragment
fragment = demuxer.fragments[index]!;
// Even if we already know the fragment, we might not yet know its predecessor
if (prevFragment) prevFragment.nextFragment = fragment;
prevFragment = fragment;
}
const { fragmentIndex, sampleIndex, correctSampleFound } = getBestMatch();
if (correctSampleFound) {
@@ -2095,12 +2109,6 @@ abstract class IsobmffTrackBacking<Chunk extends EncodedVideoChunk | EncodedAudi
bestFragmentIndex = fragmentIndex;
bestSampleIndex = sampleIndex;
}
} else {
// We already know this fragment
const fragment = demuxer.fragments[index]!;
if (prevFragment) prevFragment.nextFragment = fragment;
prevFragment = fragment;
}
}
isobmffReader.pos = startPos + boxInfo.totalSize;
+6
View File
@@ -62,6 +62,12 @@ export class IsobmffReader {
return high * 0x100000000 + low;
}
readI64() {
const high = this.readI32();
const low = this.readU32();
return high * 0x100000000 + low;
}
readF64() {
const { view, offset } = this.reader.getViewAndOffset(this.pos, this.pos + 8);
this.pos += 8;
+1 -1
View File
@@ -431,7 +431,7 @@ export abstract class BaseMediaFrameDrain<
}
const chunks = chunkDrain.chunks(keyChunk, chunksEndTimestamp);
await chunks.next();
await chunks.next(); // Skip the start chunk as we already have it
while (currentChunk && !ended) {
if (frameQueue.length + decoder.getDecodeQueueSize() > MAX_QUEUE_SIZE) {