UNPKG

@isomp4/box-moof

Version:

Implements encoding and decoding of the moof box type

140 lines (139 loc) 5.13 kB
import { FullBoxEncoding } from "@isomp4/core"; export var TrackRunSample; (function (TrackRunSample) { function parseFlags(flags) { // Flags is in big-endian format, so first bit fields are high bits return { // 4 bits reserved isLeading: (flags >>> 26 & 0b11), dependsOn: (flags >>> 24 & 0b11), isDependedOn: (flags >>> 22 & 0b11), hasRedundancy: (flags >>> 20 & 0b11), paddingValue: flags >>> 17 & 0b111, isSync: (flags >>> 16 & 0b1) === 0, degradationPriority: flags & 0xFFFF, }; } TrackRunSample.parseFlags = parseFlags; })(TrackRunSample || (TrackRunSample = {})); export var TrackRunBox; (function (TrackRunBox) { function parseFlags(flags) { return { dataOffsetPresent: (flags & 0x000001) !== 0, firstSampleFlagsPresent: (flags & 0x000004) !== 0, sampleDurationPresent: (flags & 0x000100) !== 0, sampleSizePresent: (flags & 0x000200) !== 0, sampleFlagsPresent: (flags & 0x000400) !== 0, sampleCompositionTimeOffsetsPresent: (flags & 0x000800) !== 0, }; } TrackRunBox.parseFlags = parseFlags; })(TrackRunBox || (TrackRunBox = {})); class TrackRunBoxEncoding extends FullBoxEncoding { constructor() { super("trun"); } encodingLength(obj) { return super.encodingLength(obj); // TODO implement } encodeTo(obj, buffer) { const requiredBytes = super.encodeTo(obj, buffer); if (requiredBytes > 0) { return requiredBytes; } // let offset = this.encodedBytes; // // TODO implementing encoding // this.encodedBytes = offset; return 0; } decode(buffer, header) { const superBox = super.decode(buffer, header); if (typeof superBox === "number") { return superBox; } let offset = this.decodedBytes; if (buffer.length < offset + 4) { return offset + 4; } const sampleCount = buffer.readUInt32BE(offset); offset += 4; const bflags = TrackRunBox.parseFlags(superBox.flags); let dataOffset; if (bflags.dataOffsetPresent) { if (buffer.length < offset + 4) { return offset + 4; } dataOffset = buffer.readInt32BE(offset); // signed offset += 4; } let firstSampleFlags; if (bflags.firstSampleFlagsPresent) { if (bflags.sampleFlagsPresent) { throw new Error("Malformed input: Sample flags shall not be present!"); } if (buffer.length < offset + 4) { return offset + 4; } firstSampleFlags = buffer.readUInt32BE(offset); offset += 4; } const bytesPerSample = (bflags.sampleDurationPresent ? 4 : 0) + (bflags.sampleSizePresent ? 4 : 0) + (bflags.sampleFlagsPresent ? 4 : 0) + (bflags.sampleCompositionTimeOffsetsPresent ? 4 : 0); const bytesForSamples = bytesPerSample * sampleCount; if (buffer.length < offset + bytesForSamples) { return offset + bytesForSamples; } const samples = []; for (let i = 0; i < sampleCount; i++) { let duration; let size; let flags; let compositionTimeOffset; if (bflags.sampleDurationPresent) { duration = buffer.readUInt32BE(offset); offset += 4; } if (bflags.sampleSizePresent) { size = buffer.readUInt32BE(offset); offset += 4; } if (bflags.sampleFlagsPresent) { flags = buffer.readUInt32BE(offset); offset += 4; } else if (bflags.firstSampleFlagsPresent && i === 0) { flags = firstSampleFlags; } if (bflags.sampleCompositionTimeOffsetsPresent) { switch (superBox.version) { case 0: compositionTimeOffset = buffer.readUInt32BE(offset); // Unsigned break; case 1: compositionTimeOffset = buffer.readInt32BE(offset); // Signed break; default: throw new Error("Unsupported version of trun box: " + superBox.version); } offset += 4; } samples.push({ duration, size, flags, compositionTimeOffset, }); } this.decodedBytes = offset; return { ...superBox, dataOffset, firstSampleFlags, samples, }; } } export const trun = new TrackRunBoxEncoding();