@blockcast/mmt-container 2.2.0-main.da2e7cd1dd5d → 2.2.0-main.e75bbd7576a6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/dist/browser-runtime.js +472 -36
  2. package/dist/browser-runtime.js.map +2 -2
  3. package/dist/delivery-catalog.js +2 -1
  4. package/dist/delivery-catalog.js.map +2 -2
  5. package/dist/fec-manager.d.ts +30 -0
  6. package/dist/fec-manager.d.ts.map +1 -1
  7. package/dist/fec-manager.js +196 -2
  8. package/dist/fec-manager.js.map +2 -2
  9. package/dist/index.d.ts +1 -1
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js.map +2 -2
  12. package/dist/iso-block-locator.d.ts +9 -0
  13. package/dist/iso-block-locator.d.ts.map +1 -1
  14. package/dist/iso-block-locator.js +17 -0
  15. package/dist/iso-block-locator.js.map +2 -2
  16. package/dist/iso-bmff-timing.d.ts +10 -1
  17. package/dist/iso-bmff-timing.d.ts.map +1 -1
  18. package/dist/iso-bmff-timing.js +36 -2
  19. package/dist/iso-bmff-timing.js.map +2 -2
  20. package/dist/mmtp-container-parser.d.ts +35 -2
  21. package/dist/mmtp-container-parser.d.ts.map +1 -1
  22. package/dist/mmtp-container-parser.js +82 -9
  23. package/dist/mmtp-container-parser.js.map +2 -2
  24. package/dist/mmtp-container-parser.no-modules.js +85 -11
  25. package/dist/mmtp-container-parser.no-modules.js.map +2 -2
  26. package/dist/mmtp-decode-pipeline.js +81 -9
  27. package/dist/mmtp-decode-pipeline.js.map +2 -2
  28. package/dist/mmtp-router.d.ts +18 -1
  29. package/dist/mmtp-router.d.ts.map +1 -1
  30. package/dist/mmtp-router.js +276 -34
  31. package/dist/mmtp-router.js.map +2 -2
  32. package/dist/multicast-manager.js +472 -36
  33. package/dist/multicast-manager.js.map +2 -2
  34. package/dist/multicast-transport.js +2 -1
  35. package/dist/multicast-transport.js.map +2 -2
  36. package/dist/no-modules.js +81 -9
  37. package/dist/no-modules.js.map +2 -2
  38. package/dist/wasm-mmtp-container-parser.js +81 -9
  39. package/dist/wasm-mmtp-container-parser.js.map +2 -2
  40. package/package.json +5 -5
  41. package/src/fec-manager.ts +251 -2
  42. package/src/index.ts +1 -0
  43. package/src/iso-block-locator.ts +19 -0
  44. package/src/iso-bmff-timing.ts +40 -1
  45. package/src/mmtp-container-parser.ts +84 -8
  46. package/src/mmtp-router.ts +346 -30
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/iso-bmff-timing.ts"],
4
- "sourcesContent": ["/**\n * Strict ISO-BMFF timing extraction for the timed-MFU browser path.\n *\n * This intentionally implements only the current single-track MMT profile:\n * one media track in FT=0, and one matching traf/trun in each FT=1. It does\n * not infer timing from packet arrival, MMTP send timestamps, or cadence.\n */\n\nconst U64_MAX = 0xffff_ffff_ffff_ffffn\nconst I64_MIN = -0x8000_0000_0000_0000n\nconst I64_MAX = 0x7fff_ffff_ffff_ffffn\nconst MICROSECONDS_PER_SECOND = 1_000_000n\n\nconst TFHD_BASE_DATA_OFFSET_PRESENT = 0x000001\nconst TFHD_SAMPLE_DESCRIPTION_INDEX_PRESENT = 0x000002\nconst TFHD_DEFAULT_SAMPLE_DURATION_PRESENT = 0x000008\nconst TFHD_DEFAULT_SAMPLE_SIZE_PRESENT = 0x000010\nconst TFHD_DEFAULT_SAMPLE_FLAGS_PRESENT = 0x000020\nconst TFHD_DURATION_IS_EMPTY = 0x010000\nconst TFHD_DEFAULT_BASE_IS_MOOF = 0x020000\nconst TFHD_KNOWN_FLAGS =\n TFHD_BASE_DATA_OFFSET_PRESENT |\n TFHD_SAMPLE_DESCRIPTION_INDEX_PRESENT |\n TFHD_DEFAULT_SAMPLE_DURATION_PRESENT |\n TFHD_DEFAULT_SAMPLE_SIZE_PRESENT |\n TFHD_DEFAULT_SAMPLE_FLAGS_PRESENT |\n TFHD_DURATION_IS_EMPTY |\n TFHD_DEFAULT_BASE_IS_MOOF\n\nconst TRUN_DATA_OFFSET_PRESENT = 0x000001\nconst TRUN_FIRST_SAMPLE_FLAGS_PRESENT = 0x000004\nconst TRUN_SAMPLE_DURATION_PRESENT = 0x000100\nconst TRUN_SAMPLE_SIZE_PRESENT = 0x000200\nconst TRUN_SAMPLE_FLAGS_PRESENT = 0x000400\nconst TRUN_SAMPLE_CTS_OFFSET_PRESENT = 0x000800\nconst TRUN_KNOWN_FLAGS =\n TRUN_DATA_OFFSET_PRESENT |\n TRUN_FIRST_SAMPLE_FLAGS_PRESENT |\n TRUN_SAMPLE_DURATION_PRESENT |\n TRUN_SAMPLE_SIZE_PRESENT |\n TRUN_SAMPLE_FLAGS_PRESENT |\n TRUN_SAMPLE_CTS_OFFSET_PRESENT\n\nexport interface IsoBmffTrackTiming {\n trackId: number\n timescale: number\n defaultSampleDuration?: number\n defaultSampleSize?: number\n}\n\nexport interface IsoBmffSampleTiming {\n /** Exact decode time in mdhd timescale units. */\n decodeTime: bigint\n /** Exact presentation time in mdhd timescale units, including signed CTS. */\n presentationTime: bigint\n /** Exact authored duration in mdhd timescale units. */\n duration: number\n timescale: number\n /** Exact elementary-stream sample size declared by trun/tfhd/trex. */\n size: number\n /** Byte position of the sample relative to the beginning of the moof. */\n bytePosition: bigint\n}\n\nexport interface IsoBmffMovieFragmentTiming {\n movieFragmentSequenceNumber: number\n samples: readonly IsoBmffSampleTiming[]\n}\n\nexport type IsoBmffMovieFragmentRejection = 'invalid' | 'budget'\n\ninterface IsoBox {\n type: string\n start: number\n bodyStart: number\n end: number\n}\n\ninterface FullBox {\n version: number\n flags: number\n bodyStart: number\n}\n\ninterface ParsedTrack {\n trackId: number\n handlerType: string\n timescale: number\n hasEdits: boolean\n}\n\ninterface ParsedTfhd {\n trackId: number\n defaultSampleDuration?: number\n defaultSampleSize?: number\n}\n\ninterface MdatLayout {\n dataStart: bigint\n declaredEnd: bigint\n}\n\nfunction view(data: Uint8Array): DataView {\n return new DataView(data.buffer, data.byteOffset, data.byteLength)\n}\n\nfunction boxType(data: Uint8Array, offset: number): string {\n return String.fromCharCode(\n data[offset]!,\n data[offset + 1]!,\n data[offset + 2]!,\n data[offset + 3]!,\n )\n}\n\nfunction readU64(data: Uint8Array, offset: number): bigint | null {\n if (offset < 0 || offset + 8 > data.length) return null\n const dataView = view(data)\n return (BigInt(dataView.getUint32(offset, false)) << 32n) |\n BigInt(dataView.getUint32(offset + 4, false))\n}\n\nfunction parseBox(data: Uint8Array, start: number, limit: number): IsoBox | null {\n if (start < 0 || limit > data.length || start + 8 > limit) return null\n const dataView = view(data)\n const shortSize = dataView.getUint32(start, false)\n let headerSize = 8\n let size: number\n if (shortSize === 0) {\n size = limit - start\n } else if (shortSize === 1) {\n if (start + 16 > limit) return null\n const extendedSize = readU64(data, start + 8)\n if (extendedSize === null || extendedSize > BigInt(Number.MAX_SAFE_INTEGER)) return null\n headerSize = 16\n size = Number(extendedSize)\n } else {\n size = shortSize\n }\n if (size < headerSize || start + size > limit) return null\n return {\n type: boxType(data, start + 4),\n start,\n bodyStart: start + headerSize,\n end: start + size,\n }\n}\n\nfunction parseBoxes(data: Uint8Array, start: number, end: number): IsoBox[] | null {\n if (start < 0 || end < start || end > data.length) return null\n const boxes: IsoBox[] = []\n let offset = start\n while (offset < end) {\n const box = parseBox(data, offset, end)\n if (!box || box.end <= offset) return null\n boxes.push(box)\n offset = box.end\n }\n return offset === end ? boxes : null\n}\n\nfunction children(data: Uint8Array, parent: IsoBox): IsoBox[] | null {\n return parseBoxes(data, parent.bodyStart, parent.end)\n}\n\nfunction exactlyOne(boxes: readonly IsoBox[], type: string): IsoBox | null {\n const matches = boxes.filter(box => box.type === type)\n return matches.length === 1 ? matches[0]! : null\n}\n\nfunction parseFullBox(data: Uint8Array, box: IsoBox): FullBox | null {\n if (box.bodyStart + 4 > box.end) return null\n const versionAndFlags = view(data).getUint32(box.bodyStart, false)\n return {\n version: versionAndFlags >>> 24,\n flags: versionAndFlags & 0x00ff_ffff,\n bodyStart: box.bodyStart + 4,\n }\n}\n\nfunction parseTkhdTrackId(data: Uint8Array, box: IsoBox): number | null {\n const full = parseFullBox(data, box)\n if (!full || full.flags & ~0x00000f) return null\n const bodyLength = box.end - full.bodyStart\n const trackIdOffset = full.version === 0\n ? full.bodyStart + 8\n : full.version === 1\n ? full.bodyStart + 16\n : -1\n const expectedBodyLength = full.version === 0 ? 80 : full.version === 1 ? 92 : -1\n if (trackIdOffset < 0 || bodyLength !== expectedBodyLength) return null\n return view(data).getUint32(trackIdOffset, false)\n}\n\nfunction parseMdhdTimescale(data: Uint8Array, box: IsoBox): number | null {\n const full = parseFullBox(data, box)\n if (!full || full.flags !== 0) return null\n const bodyLength = box.end - full.bodyStart\n const timescaleOffset = full.version === 0\n ? full.bodyStart + 8\n : full.version === 1\n ? full.bodyStart + 16\n : -1\n const expectedBodyLength = full.version === 0 ? 20 : full.version === 1 ? 32 : -1\n if (timescaleOffset < 0 || bodyLength !== expectedBodyLength) return null\n return view(data).getUint32(timescaleOffset, false)\n}\n\nfunction parseHandlerType(data: Uint8Array, box: IsoBox): string | null {\n const full = parseFullBox(data, box)\n if (!full || full.version !== 0 || full.flags !== 0 || full.bodyStart + 20 > box.end) {\n return null\n }\n return boxType(data, full.bodyStart + 4)\n}\n\nfunction editListHasEntries(data: Uint8Array, box: IsoBox): boolean | null {\n const full = parseFullBox(data, box)\n if (!full || full.flags !== 0 || (full.version !== 0 && full.version !== 1)) return null\n if (full.bodyStart + 4 > box.end) return null\n const entryCount = view(data).getUint32(full.bodyStart, false)\n const entrySize = full.version === 0 ? 12 : 20\n const expectedEnd = full.bodyStart + 4 + entryCount * entrySize\n if (!Number.isSafeInteger(expectedEnd) || expectedEnd !== box.end) return null\n return entryCount !== 0\n}\n\nfunction parseTrack(data: Uint8Array, trak: IsoBox): ParsedTrack | null {\n const trakChildren = children(data, trak)\n if (!trakChildren) return null\n const tkhd = exactlyOne(trakChildren, 'tkhd')\n const mdia = exactlyOne(trakChildren, 'mdia')\n if (!tkhd || !mdia) return null\n const trackId = parseTkhdTrackId(data, tkhd)\n if (trackId === null || trackId === 0) return null\n\n const mdiaChildren = children(data, mdia)\n if (!mdiaChildren) return null\n const mdhd = exactlyOne(mdiaChildren, 'mdhd')\n const hdlr = exactlyOne(mdiaChildren, 'hdlr')\n if (!mdhd || !hdlr) return null\n const timescale = parseMdhdTimescale(data, mdhd)\n const handlerType = parseHandlerType(data, hdlr)\n if (timescale === null || timescale === 0 || handlerType === null) return null\n\n const edtsBoxes = trakChildren.filter(box => box.type === 'edts')\n if (edtsBoxes.length > 1) return null\n let hasEdits = false\n if (edtsBoxes.length === 1) {\n const edtsChildren = children(data, edtsBoxes[0]!)\n if (!edtsChildren) return null\n const editLists = edtsChildren.filter(box => box.type === 'elst')\n if (editLists.length > 1) return null\n if (editLists.length === 1) {\n const result = editListHasEntries(data, editLists[0]!)\n if (result === null) return null\n hasEdits = result\n }\n }\n\n return { trackId, handlerType, timescale, hasEdits }\n}\n\nfunction parseTrex(data: Uint8Array, box: IsoBox): IsoBmffTrackTiming | null {\n const full = parseFullBox(data, box)\n if (!full || full.version !== 0 || full.flags !== 0 || box.end - full.bodyStart !== 20) {\n return null\n }\n const dataView = view(data)\n const trackId = dataView.getUint32(full.bodyStart, false)\n const defaultSampleDuration = dataView.getUint32(full.bodyStart + 8, false)\n const defaultSampleSize = dataView.getUint32(full.bodyStart + 12, false)\n return {\n trackId,\n timescale: 0,\n ...(defaultSampleDuration === 0 ? {} : { defaultSampleDuration }),\n ...(defaultSampleSize === 0 ? {} : { defaultSampleSize }),\n }\n}\n\nexport function parseIsoBmffInitializationTiming(\n data: Uint8Array,\n): IsoBmffTrackTiming | null {\n const topLevel = parseBoxes(data, 0, data.length)\n if (!topLevel) return null\n const ftyp = exactlyOne(topLevel, 'ftyp')\n const moov = exactlyOne(topLevel, 'moov')\n if (!ftyp || !moov || ftyp.start > moov.start) return null\n if (topLevel.some(box => box.type === 'moof' || box.type === 'mdat')) return null\n\n const moovChildren = children(data, moov)\n if (!moovChildren) return null\n const parsedTracks: ParsedTrack[] = []\n for (const trak of moovChildren.filter(box => box.type === 'trak')) {\n const parsed = parseTrack(data, trak)\n if (!parsed) return null\n parsedTracks.push(parsed)\n }\n const mediaTracks = parsedTracks.filter(\n track => track.handlerType === 'vide' || track.handlerType === 'soun',\n )\n if (mediaTracks.length !== 1) return null\n const mediaTrack = mediaTracks[0]!\n if (mediaTrack.hasEdits) return null\n\n const mvex = exactlyOne(moovChildren, 'mvex')\n if (!mvex) return null\n const mvexChildren = children(data, mvex)\n if (!mvexChildren) return null\n const trexEntries: IsoBmffTrackTiming[] = []\n for (const trexBox of mvexChildren.filter(box => box.type === 'trex')) {\n const trex = parseTrex(data, trexBox)\n if (!trex) return null\n trexEntries.push(trex)\n }\n const matchingTrex = trexEntries.filter(trex => trex.trackId === mediaTrack.trackId)\n if (matchingTrex.length !== 1) return null\n const trex = matchingTrex[0]!\n return {\n trackId: mediaTrack.trackId,\n timescale: mediaTrack.timescale,\n ...(trex.defaultSampleDuration === undefined\n ? {}\n : { defaultSampleDuration: trex.defaultSampleDuration }),\n ...(trex.defaultSampleSize === undefined\n ? {}\n : { defaultSampleSize: trex.defaultSampleSize }),\n }\n}\n\nfunction parseMfhdSequence(data: Uint8Array, box: IsoBox): number | null {\n const full = parseFullBox(data, box)\n if (!full || full.version !== 0 || full.flags !== 0 || box.end - full.bodyStart !== 4) {\n return null\n }\n return view(data).getUint32(full.bodyStart, false)\n}\n\nfunction parseTfhd(data: Uint8Array, box: IsoBox): ParsedTfhd | null {\n const full = parseFullBox(data, box)\n if (!full || full.version !== 0 || (full.flags & ~TFHD_KNOWN_FLAGS) !== 0) return null\n if ((full.flags & TFHD_BASE_DATA_OFFSET_PRESENT) !== 0 ||\n (full.flags & TFHD_DEFAULT_BASE_IS_MOOF) === 0 ||\n (full.flags & TFHD_DURATION_IS_EMPTY) !== 0) {\n return null\n }\n const dataView = view(data)\n let offset = full.bodyStart\n if (offset + 4 > box.end) return null\n const trackId = dataView.getUint32(offset, false)\n offset += 4\n if ((full.flags & TFHD_SAMPLE_DESCRIPTION_INDEX_PRESENT) !== 0) {\n if (offset + 4 > box.end) return null\n offset += 4\n }\n let defaultSampleDuration: number | undefined\n if ((full.flags & TFHD_DEFAULT_SAMPLE_DURATION_PRESENT) !== 0) {\n if (offset + 4 > box.end) return null\n defaultSampleDuration = dataView.getUint32(offset, false)\n offset += 4\n }\n let defaultSampleSize: number | undefined\n if ((full.flags & TFHD_DEFAULT_SAMPLE_SIZE_PRESENT) !== 0) {\n if (offset + 4 > box.end) return null\n defaultSampleSize = dataView.getUint32(offset, false)\n offset += 4\n }\n if ((full.flags & TFHD_DEFAULT_SAMPLE_FLAGS_PRESENT) !== 0) {\n if (offset + 4 > box.end) return null\n offset += 4\n }\n if (offset !== box.end) return null\n return {\n trackId,\n ...(defaultSampleDuration === undefined ? {} : { defaultSampleDuration }),\n ...(defaultSampleSize === undefined ? {} : { defaultSampleSize }),\n }\n}\n\nfunction parseTfdt(data: Uint8Array, box: IsoBox): bigint | null {\n const full = parseFullBox(data, box)\n if (!full || full.flags !== 0) return null\n if (full.version === 0 && box.end - full.bodyStart === 4) {\n return BigInt(view(data).getUint32(full.bodyStart, false))\n }\n if (full.version === 1 && box.end - full.bodyStart === 8) {\n return readU64(data, full.bodyStart)\n }\n return null\n}\n\nfunction parseMdatLayout(data: Uint8Array, offset: number): MdatLayout | null {\n if (offset < 0 || offset + 8 > data.length || boxType(data, offset + 4) !== 'mdat') return null\n const dataView = view(data)\n const shortSize = dataView.getUint32(offset, false)\n let headerSize = 8\n let declaredSize: bigint\n if (shortSize === 0) {\n return null\n } else if (shortSize === 1) {\n const extended = readU64(data, offset + 8)\n if (extended === null) return null\n headerSize = 16\n declaredSize = extended\n } else {\n declaredSize = BigInt(shortSize)\n }\n if (declaredSize < BigInt(headerSize) || declaredSize < BigInt(data.length - offset)) {\n return null\n }\n const declaredEnd = BigInt(offset) + declaredSize\n if (declaredEnd > U64_MAX) return null\n return { dataStart: BigInt(offset + headerSize), declaredEnd }\n}\n\nfunction resolvedDefault(\n entryValue: number | undefined,\n tfhdValue: number | undefined,\n trexValue: number | undefined,\n): number | null {\n const value = entryValue ?? tfhdValue ?? trexValue\n return value === undefined || value === 0 ? null : value\n}\n\nfunction parseTrunSamples(\n data: Uint8Array,\n box: IsoBox,\n moofStart: number,\n baseDecodeTime: bigint,\n tfhd: ParsedTfhd,\n track: IsoBmffTrackTiming,\n mdat: MdatLayout,\n maxSamples: number,\n): IsoBmffSampleTiming[] | null {\n const full = parseFullBox(data, box)\n if (!full || (full.version !== 0 && full.version !== 1) ||\n (full.flags & ~TRUN_KNOWN_FLAGS) !== 0 ||\n (full.flags & TRUN_DATA_OFFSET_PRESENT) === 0 ||\n ((full.flags & TRUN_FIRST_SAMPLE_FLAGS_PRESENT) !== 0 &&\n (full.flags & TRUN_SAMPLE_FLAGS_PRESENT) !== 0)) {\n return null\n }\n const dataView = view(data)\n let offset = full.bodyStart\n if (offset + 8 > box.end) return null\n const sampleCount = dataView.getUint32(offset, false)\n offset += 4\n if (sampleCount === 0 || sampleCount > maxSamples) return null\n const relativeDataOffset = dataView.getInt32(offset, false)\n offset += 4\n if (relativeDataOffset < 0) return null\n const dataOffset = BigInt(relativeDataOffset)\n const absoluteDataOffset = BigInt(moofStart) + dataOffset\n if (absoluteDataOffset > BigInt(data.length) || absoluteDataOffset < mdat.dataStart) return null\n if ((full.flags & TRUN_FIRST_SAMPLE_FLAGS_PRESENT) !== 0) {\n if (offset + 4 > box.end) return null\n offset += 4\n }\n\n let decodeTime = baseDecodeTime\n let bytePosition = dataOffset\n const samples: IsoBmffSampleTiming[] = []\n for (let index = 0; index < sampleCount; index++) {\n let entryDuration: number | undefined\n if ((full.flags & TRUN_SAMPLE_DURATION_PRESENT) !== 0) {\n if (offset + 4 > box.end) return null\n entryDuration = dataView.getUint32(offset, false)\n offset += 4\n }\n let entrySize: number | undefined\n if ((full.flags & TRUN_SAMPLE_SIZE_PRESENT) !== 0) {\n if (offset + 4 > box.end) return null\n entrySize = dataView.getUint32(offset, false)\n offset += 4\n }\n if ((full.flags & TRUN_SAMPLE_FLAGS_PRESENT) !== 0) {\n if (offset + 4 > box.end) return null\n offset += 4\n }\n let compositionOffset = 0\n if ((full.flags & TRUN_SAMPLE_CTS_OFFSET_PRESENT) !== 0) {\n if (offset + 4 > box.end) return null\n compositionOffset = full.version === 1\n ? dataView.getInt32(offset, false)\n : dataView.getUint32(offset, false)\n offset += 4\n }\n if (offset > box.end) return null\n\n const duration = resolvedDefault(\n entryDuration,\n tfhd.defaultSampleDuration,\n track.defaultSampleDuration,\n )\n const size = resolvedDefault(entrySize, tfhd.defaultSampleSize, track.defaultSampleSize)\n if (duration === null || size === null) return null\n const sampleEnd = bytePosition + BigInt(size)\n const absoluteSampleEnd = BigInt(moofStart) + sampleEnd\n if (absoluteSampleEnd > mdat.declaredEnd || absoluteSampleEnd > U64_MAX) return null\n const presentationTime = decodeTime + BigInt(compositionOffset)\n if (presentationTime < I64_MIN || presentationTime > I64_MAX) return null\n samples.push({\n decodeTime,\n presentationTime,\n duration,\n timescale: track.timescale,\n size,\n bytePosition,\n })\n decodeTime += BigInt(duration)\n if (decodeTime > U64_MAX) return null\n bytePosition = sampleEnd\n }\n return offset === box.end ? samples : null\n}\n\nexport function parseIsoBmffMovieFragmentTiming(\n data: Uint8Array,\n track: IsoBmffTrackTiming,\n maxSamples: number,\n): IsoBmffMovieFragmentTiming | null {\n if (!Number.isInteger(maxSamples) || maxSamples <= 0) return null\n const first = parseBox(data, 0, data.length)\n if (!first) return null\n const moof = first.type === 'styp'\n ? parseBox(data, first.end, data.length)\n : first\n if (!moof || moof.type !== 'moof' || moof.end >= data.length) return null\n const moofChildren = children(data, moof)\n if (!moofChildren) return null\n const mfhd = exactlyOne(moofChildren, 'mfhd')\n const traf = exactlyOne(moofChildren, 'traf')\n if (!mfhd || !traf) return null\n const movieFragmentSequenceNumber = parseMfhdSequence(data, mfhd)\n if (movieFragmentSequenceNumber === null || movieFragmentSequenceNumber === 0) return null\n\n const trafChildren = children(data, traf)\n if (!trafChildren) return null\n const tfhdBox = exactlyOne(trafChildren, 'tfhd')\n const tfdtBox = exactlyOne(trafChildren, 'tfdt')\n const trunBox = exactlyOne(trafChildren, 'trun')\n if (!tfhdBox || !tfdtBox || !trunBox) return null\n const tfhd = parseTfhd(data, tfhdBox)\n const baseDecodeTime = parseTfdt(data, tfdtBox)\n if (!tfhd || tfhd.trackId !== track.trackId || baseDecodeTime === null) return null\n const mdat = parseMdatLayout(data, moof.end)\n if (!mdat) return null\n const samples = parseTrunSamples(\n data,\n trunBox,\n moof.start,\n baseDecodeTime,\n tfhd,\n track,\n mdat,\n maxSamples,\n )\n if (!samples) return null\n return { movieFragmentSequenceNumber, samples }\n}\n\nfunction sameTrack(a: IsoBmffTrackTiming, b: IsoBmffTrackTiming): boolean {\n return a.trackId === b.trackId &&\n a.timescale === b.timescale &&\n a.defaultSampleDuration === b.defaultSampleDuration &&\n a.defaultSampleSize === b.defaultSampleSize\n}\n\nfunction sameSample(a: IsoBmffSampleTiming, b: IsoBmffSampleTiming): boolean {\n return a.decodeTime === b.decodeTime &&\n a.presentationTime === b.presentationTime &&\n a.duration === b.duration &&\n a.timescale === b.timescale &&\n a.size === b.size &&\n a.bytePosition === b.bytePosition\n}\n\ntype PendingMovieFragment = Array<IsoBmffSampleTiming | null>\n\n/** Bounded per-track FT=0/FT=1 timing state. */\nexport class IsoBmffTimingResolver {\n #track: IsoBmffTrackTiming | null = null\n #fragments = new Map<string, PendingMovieFragment>()\n #pendingSamples = 0\n #evictedSamples = 0\n #lastMovieFragmentRejection: IsoBmffMovieFragmentRejection | null = null\n\n constructor(readonly maxPendingSamples: number) {\n if (!Number.isInteger(maxPendingSamples) || maxPendingSamples <= 0) {\n throw new Error('[IsoBmffTimingResolver] maxPendingSamples must be a positive integer')\n }\n }\n\n get pendingSampleCount(): number {\n return this.#pendingSamples\n }\n\n /**\n * Slots reclaimed by window displacement rather than by delivery or\n * abandonment. Deliberately separate from the combiner's own release count:\n * \"nobody ever saw this sample\" and \"the combiner gave up on it\" are\n * different failures with different owners, and one number cannot say which.\n */\n get evictedSampleCount(): number {\n return this.#evictedSamples\n }\n\n /** Typed reason for the most recent rejected movie fragment. */\n get lastMovieFragmentRejection(): IsoBmffMovieFragmentRejection | null {\n return this.#lastMovieFragmentRejection\n }\n\n addInitialization(data: Uint8Array): boolean {\n const timing = parseIsoBmffInitializationTiming(data)\n if (!timing) return false\n if (this.#track) return sameTrack(this.#track, timing)\n this.#track = timing\n return true\n }\n\n addMovieFragment(\n mpuSequenceNumber: number,\n data: Uint8Array,\n additionalSampleLimit = this.maxPendingSamples,\n ): boolean {\n this.#lastMovieFragmentRejection = null\n if (!Number.isInteger(additionalSampleLimit) || additionalSampleLimit < 0) {\n this.#lastMovieFragmentRejection = 'invalid'\n return false\n }\n if (!this.#track || !isU32(mpuSequenceNumber)) {\n this.#lastMovieFragmentRejection = 'invalid'\n return false\n }\n const parsed = parseIsoBmffMovieFragmentTiming(\n data,\n this.#track,\n this.maxPendingSamples,\n )\n if (!parsed) {\n this.#lastMovieFragmentRejection = 'invalid'\n return false\n }\n const key = fragmentKey(mpuSequenceNumber, parsed.movieFragmentSequenceNumber)\n const existing = this.#fragments.get(key)\n if (existing) {\n return existing.length === parsed.samples.length && existing.every(\n (sample, index) => sample !== null && sameSample(sample, parsed.samples[index]!),\n )\n }\n // Sliding window, not a one-way ratchet. `consumeSample` and\n // `releaseSample` between them cover every sample some component observed\n // -- but a sample whose data units never arrive at all is observed by\n // nobody, so neither path ever runs and its slot is held until `reset()`.\n // Under sustained loss those orphans accumulate until the budget is full\n // of samples that can never arrive, at which point every later moof is\n // refused and media stops permanently with no error.\n //\n // Displacement is the signal no component can raise: once the budget is\n // full and a newer fragment is in hand, the oldest pending fragment's\n // samples are older than the whole window and cannot still be in flight.\n // Reclaiming them keeps the timing that is arriving now and discards the\n // timing that is not; refusing the new fragment does exactly the reverse,\n // which is what wedged the stream. Evicted timing is not silent loss --\n // a late data unit then finds no entry and is dropped against a named\n // reason, which is attributable, bounded, and recoverable.\n let freed = 0\n while (\n this.#fragments.size > 0 &&\n (this.#pendingSamples + parsed.samples.length > this.maxPendingSamples ||\n parsed.samples.length - freed > additionalSampleLimit)\n ) {\n freed += this.#evictOldestFragment()\n }\n // Net new charge against the caller's pool is what it must afford: `freed`\n // slots were already counted there and are handed back by this call.\n if (parsed.samples.length - freed > additionalSampleLimit) {\n this.#lastMovieFragmentRejection = 'budget'\n return false\n }\n if (this.#pendingSamples + parsed.samples.length > this.maxPendingSamples) {\n this.#lastMovieFragmentRejection = 'budget'\n return false\n }\n this.#fragments.set(key, [...parsed.samples])\n this.#pendingSamples += parsed.samples.length\n return true\n }\n\n sampleTiming(\n mpuSequenceNumber: number,\n movieFragmentSequenceNumber: number,\n sampleNumber: number,\n ): IsoBmffSampleTiming | null {\n if (!isU32(mpuSequenceNumber) || !isU32(movieFragmentSequenceNumber) ||\n movieFragmentSequenceNumber === 0 || !isU32(sampleNumber) || sampleNumber === 0) {\n return null\n }\n const samples = this.#fragments.get(\n fragmentKey(mpuSequenceNumber, movieFragmentSequenceNumber),\n )\n return samples?.[sampleNumber - 1] ?? null\n }\n\n consumeSample(\n mpuSequenceNumber: number,\n movieFragmentSequenceNumber: number,\n sampleNumber: number,\n expected: IsoBmffSampleTiming,\n ): boolean {\n const samples = this.#fragments.get(\n fragmentKey(mpuSequenceNumber, movieFragmentSequenceNumber),\n )\n const sample = samples?.[sampleNumber - 1]\n if (!sample || !sameSample(sample, expected)) return false\n return this.#clearSlot(mpuSequenceNumber, movieFragmentSequenceNumber, sampleNumber)\n }\n\n /**\n * Free the budget slot of a sample that will never be delivered.\n *\n * `consumeSample` is the delivery path and is the only decrement on a\n * healthy stream. A sample whose data units never complete is never\n * delivered; window displacement in `addMovieFragment` eventually reclaims\n * it, but only after it has aged out of the whole window. This path frees\n * the slot as soon as the combiner knows the sample is gone, so the budget\n * tracks what is actually in flight rather than what has merely aged.\n *\n * The caller is whoever abandoned the sample, so the release is driven by\n * the abandonment itself rather than by a timer, an LRU, or an age bound --\n * the slot is freed exactly when its sample provably cannot arrive, which\n * is a protocol event the combiner already detects and counts.\n *\n * Deliberately takes no `expected` timing: the caller is discarding, not\n * matching, and requiring it would make the release fail exactly when the\n * timing entry is the thing being reclaimed. Returns false when the slot\n * was already freed, so a double release cannot drive the count negative.\n */\n releaseSample(\n mpuSequenceNumber: number,\n movieFragmentSequenceNumber: number,\n sampleNumber: number,\n ): boolean {\n return this.#clearSlot(mpuSequenceNumber, movieFragmentSequenceNumber, sampleNumber)\n }\n\n /**\n * Drop the oldest pending fragment whole and return the slots it held.\n *\n * Oldest is insertion order, which for a moof stream is arrival order, so\n * this is the least-recently-declared timing -- the entries least likely to\n * still have data units in flight.\n */\n #evictOldestFragment(): number {\n const oldest = this.#fragments.keys().next().value\n if (oldest === undefined) return 0\n const samples = this.#fragments.get(oldest)!\n let live = 0\n for (const sample of samples) if (sample !== null) live++\n this.#fragments.delete(oldest)\n this.#pendingSamples -= live\n this.#evictedSamples += live\n return live\n }\n\n /** Null one slot, decrement the budget, and drop the fragment when empty. */\n #clearSlot(\n mpuSequenceNumber: number,\n movieFragmentSequenceNumber: number,\n sampleNumber: number,\n ): boolean {\n if (!isU32(mpuSequenceNumber) || !isU32(movieFragmentSequenceNumber) ||\n movieFragmentSequenceNumber === 0 || !isU32(sampleNumber) || sampleNumber === 0) {\n return false\n }\n const key = fragmentKey(mpuSequenceNumber, movieFragmentSequenceNumber)\n const samples = this.#fragments.get(key)\n const index = sampleNumber - 1\n if (!samples || !samples[index]) return false\n samples[index] = null\n this.#pendingSamples--\n if (samples.every(value => value === null)) this.#fragments.delete(key)\n return true\n }\n\n reset(): void {\n this.#track = null\n this.#fragments.clear()\n this.#pendingSamples = 0\n }\n}\n\nfunction fragmentKey(mpuSequenceNumber: number, movieFragmentSequenceNumber: number): string {\n return `${mpuSequenceNumber}:${movieFragmentSequenceNumber}`\n}\n\nfunction isU32(value: number): boolean {\n return Number.isInteger(value) && value >= 0 && value <= 0xffff_ffff\n}\n\n/** Convert exact media ticks to microseconds without first narrowing the ticks. */\nexport function mediaTicksToMicroseconds(ticks: bigint, timescale: number): number | null {\n if (!Number.isInteger(timescale) || timescale <= 0) return null\n const numerator = ticks * MICROSECONDS_PER_SECOND\n const scale = BigInt(timescale)\n const whole = numerator / scale\n const remainder = numerator % scale\n if (whole < BigInt(Number.MIN_SAFE_INTEGER) || whole > BigInt(Number.MAX_SAFE_INTEGER)) {\n return null\n }\n const result = Number(whole) + Number(remainder) / timescale\n return Number.isFinite(result) ? result : null\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * Strict ISO-BMFF timing extraction for the timed-MFU browser path.\n *\n * This intentionally implements only the current single-track MMT profile:\n * one media track in FT=0, and one matching traf/trun in each FT=1. It does\n * not infer timing from packet arrival, MMTP send timestamps, or cadence.\n */\n\nconst U64_MAX = 0xffff_ffff_ffff_ffffn\nconst I64_MIN = -0x8000_0000_0000_0000n\nconst I64_MAX = 0x7fff_ffff_ffff_ffffn\nconst MICROSECONDS_PER_SECOND = 1_000_000n\n\nconst TFHD_BASE_DATA_OFFSET_PRESENT = 0x000001\nconst TFHD_SAMPLE_DESCRIPTION_INDEX_PRESENT = 0x000002\nconst TFHD_DEFAULT_SAMPLE_DURATION_PRESENT = 0x000008\nconst TFHD_DEFAULT_SAMPLE_SIZE_PRESENT = 0x000010\nconst TFHD_DEFAULT_SAMPLE_FLAGS_PRESENT = 0x000020\nconst TFHD_DURATION_IS_EMPTY = 0x010000\nconst TFHD_DEFAULT_BASE_IS_MOOF = 0x020000\nconst TFHD_KNOWN_FLAGS =\n TFHD_BASE_DATA_OFFSET_PRESENT |\n TFHD_SAMPLE_DESCRIPTION_INDEX_PRESENT |\n TFHD_DEFAULT_SAMPLE_DURATION_PRESENT |\n TFHD_DEFAULT_SAMPLE_SIZE_PRESENT |\n TFHD_DEFAULT_SAMPLE_FLAGS_PRESENT |\n TFHD_DURATION_IS_EMPTY |\n TFHD_DEFAULT_BASE_IS_MOOF\n\nconst TRUN_DATA_OFFSET_PRESENT = 0x000001\nconst TRUN_FIRST_SAMPLE_FLAGS_PRESENT = 0x000004\nconst TRUN_SAMPLE_DURATION_PRESENT = 0x000100\nconst TRUN_SAMPLE_SIZE_PRESENT = 0x000200\nconst TRUN_SAMPLE_FLAGS_PRESENT = 0x000400\nconst TRUN_SAMPLE_CTS_OFFSET_PRESENT = 0x000800\nconst TRUN_KNOWN_FLAGS =\n TRUN_DATA_OFFSET_PRESENT |\n TRUN_FIRST_SAMPLE_FLAGS_PRESENT |\n TRUN_SAMPLE_DURATION_PRESENT |\n TRUN_SAMPLE_SIZE_PRESENT |\n TRUN_SAMPLE_FLAGS_PRESENT |\n TRUN_SAMPLE_CTS_OFFSET_PRESENT\n\nexport interface IsoBmffTrackTiming {\n trackId: number\n timescale: number\n defaultSampleDuration?: number\n defaultSampleSize?: number\n}\n\nexport interface IsoBmffSampleTiming {\n /** Exact decode time in mdhd timescale units. */\n decodeTime: bigint\n /** Exact presentation time in mdhd timescale units, including signed CTS. */\n presentationTime: bigint\n /** Exact authored duration in mdhd timescale units. */\n duration: number\n timescale: number\n /** Exact elementary-stream sample size declared by trun/tfhd/trex. */\n size: number\n /** Byte position of the sample relative to the beginning of the moof. */\n bytePosition: bigint\n}\n\nexport interface IsoBmffMovieFragmentTiming {\n movieFragmentSequenceNumber: number\n samples: readonly IsoBmffSampleTiming[]\n}\n\nexport type IsoBmffMovieFragmentRejection = 'invalid' | 'budget'\n\ninterface IsoBox {\n type: string\n start: number\n bodyStart: number\n end: number\n}\n\ninterface FullBox {\n version: number\n flags: number\n bodyStart: number\n}\n\ninterface ParsedTrack {\n trackId: number\n handlerType: string\n timescale: number\n hasEdits: boolean\n}\n\ninterface ParsedTfhd {\n trackId: number\n defaultSampleDuration?: number\n defaultSampleSize?: number\n}\n\ninterface MdatLayout {\n dataStart: bigint\n declaredEnd: bigint\n}\n\nfunction view(data: Uint8Array): DataView {\n return new DataView(data.buffer, data.byteOffset, data.byteLength)\n}\n\nfunction boxType(data: Uint8Array, offset: number): string {\n return String.fromCharCode(\n data[offset]!,\n data[offset + 1]!,\n data[offset + 2]!,\n data[offset + 3]!,\n )\n}\n\nfunction readU64(data: Uint8Array, offset: number): bigint | null {\n if (offset < 0 || offset + 8 > data.length) return null\n const dataView = view(data)\n return (BigInt(dataView.getUint32(offset, false)) << 32n) |\n BigInt(dataView.getUint32(offset + 4, false))\n}\n\nfunction parseBox(data: Uint8Array, start: number, limit: number): IsoBox | null {\n if (start < 0 || limit > data.length || start + 8 > limit) return null\n const dataView = view(data)\n const shortSize = dataView.getUint32(start, false)\n let headerSize = 8\n let size: number\n if (shortSize === 0) {\n size = limit - start\n } else if (shortSize === 1) {\n if (start + 16 > limit) return null\n const extendedSize = readU64(data, start + 8)\n if (extendedSize === null || extendedSize > BigInt(Number.MAX_SAFE_INTEGER)) return null\n headerSize = 16\n size = Number(extendedSize)\n } else {\n size = shortSize\n }\n if (size < headerSize || start + size > limit) return null\n return {\n type: boxType(data, start + 4),\n start,\n bodyStart: start + headerSize,\n end: start + size,\n }\n}\n\nfunction parseBoxes(data: Uint8Array, start: number, end: number): IsoBox[] | null {\n if (start < 0 || end < start || end > data.length) return null\n const boxes: IsoBox[] = []\n let offset = start\n while (offset < end) {\n const box = parseBox(data, offset, end)\n if (!box || box.end <= offset) return null\n boxes.push(box)\n offset = box.end\n }\n return offset === end ? boxes : null\n}\n\nfunction children(data: Uint8Array, parent: IsoBox): IsoBox[] | null {\n return parseBoxes(data, parent.bodyStart, parent.end)\n}\n\nfunction exactlyOne(boxes: readonly IsoBox[], type: string): IsoBox | null {\n const matches = boxes.filter(box => box.type === type)\n return matches.length === 1 ? matches[0]! : null\n}\n\nfunction parseFullBox(data: Uint8Array, box: IsoBox): FullBox | null {\n if (box.bodyStart + 4 > box.end) return null\n const versionAndFlags = view(data).getUint32(box.bodyStart, false)\n return {\n version: versionAndFlags >>> 24,\n flags: versionAndFlags & 0x00ff_ffff,\n bodyStart: box.bodyStart + 4,\n }\n}\n\nfunction parseTkhdTrackId(data: Uint8Array, box: IsoBox): number | null {\n const full = parseFullBox(data, box)\n if (!full || full.flags & ~0x00000f) return null\n const bodyLength = box.end - full.bodyStart\n const trackIdOffset = full.version === 0\n ? full.bodyStart + 8\n : full.version === 1\n ? full.bodyStart + 16\n : -1\n const expectedBodyLength = full.version === 0 ? 80 : full.version === 1 ? 92 : -1\n if (trackIdOffset < 0 || bodyLength !== expectedBodyLength) return null\n return view(data).getUint32(trackIdOffset, false)\n}\n\nfunction parseMdhdTimescale(data: Uint8Array, box: IsoBox): number | null {\n const full = parseFullBox(data, box)\n if (!full || full.flags !== 0) return null\n const bodyLength = box.end - full.bodyStart\n const timescaleOffset = full.version === 0\n ? full.bodyStart + 8\n : full.version === 1\n ? full.bodyStart + 16\n : -1\n const expectedBodyLength = full.version === 0 ? 20 : full.version === 1 ? 32 : -1\n if (timescaleOffset < 0 || bodyLength !== expectedBodyLength) return null\n return view(data).getUint32(timescaleOffset, false)\n}\n\nfunction parseHandlerType(data: Uint8Array, box: IsoBox): string | null {\n const full = parseFullBox(data, box)\n if (!full || full.version !== 0 || full.flags !== 0 || full.bodyStart + 20 > box.end) {\n return null\n }\n return boxType(data, full.bodyStart + 4)\n}\n\nfunction editListHasEntries(data: Uint8Array, box: IsoBox): boolean | null {\n const full = parseFullBox(data, box)\n if (!full || full.flags !== 0 || (full.version !== 0 && full.version !== 1)) return null\n if (full.bodyStart + 4 > box.end) return null\n const entryCount = view(data).getUint32(full.bodyStart, false)\n const entrySize = full.version === 0 ? 12 : 20\n const expectedEnd = full.bodyStart + 4 + entryCount * entrySize\n if (!Number.isSafeInteger(expectedEnd) || expectedEnd !== box.end) return null\n return entryCount !== 0\n}\n\nfunction parseTrack(data: Uint8Array, trak: IsoBox): ParsedTrack | null {\n const trakChildren = children(data, trak)\n if (!trakChildren) return null\n const tkhd = exactlyOne(trakChildren, 'tkhd')\n const mdia = exactlyOne(trakChildren, 'mdia')\n if (!tkhd || !mdia) return null\n const trackId = parseTkhdTrackId(data, tkhd)\n if (trackId === null || trackId === 0) return null\n\n const mdiaChildren = children(data, mdia)\n if (!mdiaChildren) return null\n const mdhd = exactlyOne(mdiaChildren, 'mdhd')\n const hdlr = exactlyOne(mdiaChildren, 'hdlr')\n if (!mdhd || !hdlr) return null\n const timescale = parseMdhdTimescale(data, mdhd)\n const handlerType = parseHandlerType(data, hdlr)\n if (timescale === null || timescale === 0 || handlerType === null) return null\n\n const edtsBoxes = trakChildren.filter(box => box.type === 'edts')\n if (edtsBoxes.length > 1) return null\n let hasEdits = false\n if (edtsBoxes.length === 1) {\n const edtsChildren = children(data, edtsBoxes[0]!)\n if (!edtsChildren) return null\n const editLists = edtsChildren.filter(box => box.type === 'elst')\n if (editLists.length > 1) return null\n if (editLists.length === 1) {\n const result = editListHasEntries(data, editLists[0]!)\n if (result === null) return null\n hasEdits = result\n }\n }\n\n return { trackId, handlerType, timescale, hasEdits }\n}\n\nfunction parseTrex(data: Uint8Array, box: IsoBox): IsoBmffTrackTiming | null {\n const full = parseFullBox(data, box)\n if (!full || full.version !== 0 || full.flags !== 0 || box.end - full.bodyStart !== 20) {\n return null\n }\n const dataView = view(data)\n const trackId = dataView.getUint32(full.bodyStart, false)\n const defaultSampleDuration = dataView.getUint32(full.bodyStart + 8, false)\n const defaultSampleSize = dataView.getUint32(full.bodyStart + 12, false)\n return {\n trackId,\n timescale: 0,\n ...(defaultSampleDuration === 0 ? {} : { defaultSampleDuration }),\n ...(defaultSampleSize === 0 ? {} : { defaultSampleSize }),\n }\n}\n\nexport function parseIsoBmffInitializationTiming(\n data: Uint8Array,\n): IsoBmffTrackTiming | null {\n const topLevel = parseBoxes(data, 0, data.length)\n if (!topLevel) return null\n const ftyp = exactlyOne(topLevel, 'ftyp')\n const moov = exactlyOne(topLevel, 'moov')\n if (!ftyp || !moov || ftyp.start > moov.start) return null\n if (topLevel.some(box => box.type === 'moof' || box.type === 'mdat')) return null\n\n const moovChildren = children(data, moov)\n if (!moovChildren) return null\n const parsedTracks: ParsedTrack[] = []\n for (const trak of moovChildren.filter(box => box.type === 'trak')) {\n const parsed = parseTrack(data, trak)\n if (!parsed) return null\n parsedTracks.push(parsed)\n }\n const mediaTracks = parsedTracks.filter(\n track => track.handlerType === 'vide' || track.handlerType === 'soun',\n )\n if (mediaTracks.length !== 1) return null\n const mediaTrack = mediaTracks[0]!\n if (mediaTrack.hasEdits) return null\n\n const mvex = exactlyOne(moovChildren, 'mvex')\n if (!mvex) return null\n const mvexChildren = children(data, mvex)\n if (!mvexChildren) return null\n const trexEntries: IsoBmffTrackTiming[] = []\n for (const trexBox of mvexChildren.filter(box => box.type === 'trex')) {\n const trex = parseTrex(data, trexBox)\n if (!trex) return null\n trexEntries.push(trex)\n }\n const matchingTrex = trexEntries.filter(trex => trex.trackId === mediaTrack.trackId)\n if (matchingTrex.length !== 1) return null\n const trex = matchingTrex[0]!\n return {\n trackId: mediaTrack.trackId,\n timescale: mediaTrack.timescale,\n ...(trex.defaultSampleDuration === undefined\n ? {}\n : { defaultSampleDuration: trex.defaultSampleDuration }),\n ...(trex.defaultSampleSize === undefined\n ? {}\n : { defaultSampleSize: trex.defaultSampleSize }),\n }\n}\n\nfunction parseMfhdSequence(data: Uint8Array, box: IsoBox): number | null {\n const full = parseFullBox(data, box)\n if (!full || full.version !== 0 || full.flags !== 0 || box.end - full.bodyStart !== 4) {\n return null\n }\n return view(data).getUint32(full.bodyStart, false)\n}\n\nfunction parseTfhd(data: Uint8Array, box: IsoBox): ParsedTfhd | null {\n const full = parseFullBox(data, box)\n if (!full || full.version !== 0 || (full.flags & ~TFHD_KNOWN_FLAGS) !== 0) return null\n if ((full.flags & TFHD_BASE_DATA_OFFSET_PRESENT) !== 0 ||\n (full.flags & TFHD_DEFAULT_BASE_IS_MOOF) === 0 ||\n (full.flags & TFHD_DURATION_IS_EMPTY) !== 0) {\n return null\n }\n const dataView = view(data)\n let offset = full.bodyStart\n if (offset + 4 > box.end) return null\n const trackId = dataView.getUint32(offset, false)\n offset += 4\n if ((full.flags & TFHD_SAMPLE_DESCRIPTION_INDEX_PRESENT) !== 0) {\n if (offset + 4 > box.end) return null\n offset += 4\n }\n let defaultSampleDuration: number | undefined\n if ((full.flags & TFHD_DEFAULT_SAMPLE_DURATION_PRESENT) !== 0) {\n if (offset + 4 > box.end) return null\n defaultSampleDuration = dataView.getUint32(offset, false)\n offset += 4\n }\n let defaultSampleSize: number | undefined\n if ((full.flags & TFHD_DEFAULT_SAMPLE_SIZE_PRESENT) !== 0) {\n if (offset + 4 > box.end) return null\n defaultSampleSize = dataView.getUint32(offset, false)\n offset += 4\n }\n if ((full.flags & TFHD_DEFAULT_SAMPLE_FLAGS_PRESENT) !== 0) {\n if (offset + 4 > box.end) return null\n offset += 4\n }\n if (offset !== box.end) return null\n return {\n trackId,\n ...(defaultSampleDuration === undefined ? {} : { defaultSampleDuration }),\n ...(defaultSampleSize === undefined ? {} : { defaultSampleSize }),\n }\n}\n\nfunction parseTfdt(data: Uint8Array, box: IsoBox): bigint | null {\n const full = parseFullBox(data, box)\n if (!full || full.flags !== 0) return null\n if (full.version === 0 && box.end - full.bodyStart === 4) {\n return BigInt(view(data).getUint32(full.bodyStart, false))\n }\n if (full.version === 1 && box.end - full.bodyStart === 8) {\n return readU64(data, full.bodyStart)\n }\n return null\n}\n\nfunction parseMdatLayout(data: Uint8Array, offset: number): MdatLayout | null {\n if (offset < 0 || offset + 8 > data.length || boxType(data, offset + 4) !== 'mdat') return null\n const dataView = view(data)\n const shortSize = dataView.getUint32(offset, false)\n let headerSize = 8\n let declaredSize: bigint\n if (shortSize === 0) {\n return null\n } else if (shortSize === 1) {\n const extended = readU64(data, offset + 8)\n if (extended === null) return null\n headerSize = 16\n declaredSize = extended\n } else {\n declaredSize = BigInt(shortSize)\n }\n if (declaredSize < BigInt(headerSize) || declaredSize < BigInt(data.length - offset)) {\n return null\n }\n const declaredEnd = BigInt(offset) + declaredSize\n if (declaredEnd > U64_MAX) return null\n return { dataStart: BigInt(offset + headerSize), declaredEnd }\n}\n\nfunction resolvedDefault(\n entryValue: number | undefined,\n tfhdValue: number | undefined,\n trexValue: number | undefined,\n): number | null {\n const value = entryValue ?? tfhdValue ?? trexValue\n return value === undefined || value === 0 ? null : value\n}\n\nfunction parseTrunSamples(\n data: Uint8Array,\n box: IsoBox,\n moofStart: number,\n baseDecodeTime: bigint,\n tfhd: ParsedTfhd,\n track: IsoBmffTrackTiming,\n mdat: MdatLayout,\n maxSamples: number,\n): IsoBmffSampleTiming[] | null {\n const full = parseFullBox(data, box)\n if (!full || (full.version !== 0 && full.version !== 1) ||\n (full.flags & ~TRUN_KNOWN_FLAGS) !== 0 ||\n (full.flags & TRUN_DATA_OFFSET_PRESENT) === 0 ||\n ((full.flags & TRUN_FIRST_SAMPLE_FLAGS_PRESENT) !== 0 &&\n (full.flags & TRUN_SAMPLE_FLAGS_PRESENT) !== 0)) {\n return null\n }\n const dataView = view(data)\n let offset = full.bodyStart\n if (offset + 8 > box.end) return null\n const sampleCount = dataView.getUint32(offset, false)\n offset += 4\n if (sampleCount === 0 || sampleCount > maxSamples) return null\n const relativeDataOffset = dataView.getInt32(offset, false)\n offset += 4\n if (relativeDataOffset < 0) return null\n const dataOffset = BigInt(relativeDataOffset)\n const absoluteDataOffset = BigInt(moofStart) + dataOffset\n if (absoluteDataOffset > BigInt(data.length) || absoluteDataOffset < mdat.dataStart) return null\n if ((full.flags & TRUN_FIRST_SAMPLE_FLAGS_PRESENT) !== 0) {\n if (offset + 4 > box.end) return null\n offset += 4\n }\n\n let decodeTime = baseDecodeTime\n let bytePosition = dataOffset\n const samples: IsoBmffSampleTiming[] = []\n for (let index = 0; index < sampleCount; index++) {\n let entryDuration: number | undefined\n if ((full.flags & TRUN_SAMPLE_DURATION_PRESENT) !== 0) {\n if (offset + 4 > box.end) return null\n entryDuration = dataView.getUint32(offset, false)\n offset += 4\n }\n let entrySize: number | undefined\n if ((full.flags & TRUN_SAMPLE_SIZE_PRESENT) !== 0) {\n if (offset + 4 > box.end) return null\n entrySize = dataView.getUint32(offset, false)\n offset += 4\n }\n if ((full.flags & TRUN_SAMPLE_FLAGS_PRESENT) !== 0) {\n if (offset + 4 > box.end) return null\n offset += 4\n }\n let compositionOffset = 0\n if ((full.flags & TRUN_SAMPLE_CTS_OFFSET_PRESENT) !== 0) {\n if (offset + 4 > box.end) return null\n compositionOffset = full.version === 1\n ? dataView.getInt32(offset, false)\n : dataView.getUint32(offset, false)\n offset += 4\n }\n if (offset > box.end) return null\n\n const duration = resolvedDefault(\n entryDuration,\n tfhd.defaultSampleDuration,\n track.defaultSampleDuration,\n )\n const size = resolvedDefault(entrySize, tfhd.defaultSampleSize, track.defaultSampleSize)\n if (duration === null || size === null) return null\n const sampleEnd = bytePosition + BigInt(size)\n const absoluteSampleEnd = BigInt(moofStart) + sampleEnd\n if (absoluteSampleEnd > mdat.declaredEnd || absoluteSampleEnd > U64_MAX) return null\n const presentationTime = decodeTime + BigInt(compositionOffset)\n if (presentationTime < I64_MIN || presentationTime > I64_MAX) return null\n samples.push({\n decodeTime,\n presentationTime,\n duration,\n timescale: track.timescale,\n size,\n bytePosition,\n })\n decodeTime += BigInt(duration)\n if (decodeTime > U64_MAX) return null\n bytePosition = sampleEnd\n }\n return offset === box.end ? samples : null\n}\n\nexport function parseIsoBmffMovieFragmentTiming(\n data: Uint8Array,\n track: IsoBmffTrackTiming,\n maxSamples: number,\n): IsoBmffMovieFragmentTiming | null {\n if (!Number.isInteger(maxSamples) || maxSamples <= 0) return null\n const first = parseBox(data, 0, data.length)\n if (!first) return null\n const moof = first.type === 'styp'\n ? parseBox(data, first.end, data.length)\n : first\n if (!moof || moof.type !== 'moof' || moof.end >= data.length) return null\n const moofChildren = children(data, moof)\n if (!moofChildren) return null\n const mfhd = exactlyOne(moofChildren, 'mfhd')\n const traf = exactlyOne(moofChildren, 'traf')\n if (!mfhd || !traf) return null\n const movieFragmentSequenceNumber = parseMfhdSequence(data, mfhd)\n if (movieFragmentSequenceNumber === null || movieFragmentSequenceNumber === 0) return null\n\n const trafChildren = children(data, traf)\n if (!trafChildren) return null\n const tfhdBox = exactlyOne(trafChildren, 'tfhd')\n const tfdtBox = exactlyOne(trafChildren, 'tfdt')\n const trunBox = exactlyOne(trafChildren, 'trun')\n if (!tfhdBox || !tfdtBox || !trunBox) return null\n const tfhd = parseTfhd(data, tfhdBox)\n const baseDecodeTime = parseTfdt(data, tfdtBox)\n if (!tfhd || tfhd.trackId !== track.trackId || baseDecodeTime === null) return null\n const mdat = parseMdatLayout(data, moof.end)\n if (!mdat) return null\n const samples = parseTrunSamples(\n data,\n trunBox,\n moof.start,\n baseDecodeTime,\n tfhd,\n track,\n mdat,\n maxSamples,\n )\n if (!samples) return null\n return { movieFragmentSequenceNumber, samples }\n}\n\nfunction sameTrack(a: IsoBmffTrackTiming, b: IsoBmffTrackTiming): boolean {\n return a.trackId === b.trackId &&\n a.timescale === b.timescale &&\n a.defaultSampleDuration === b.defaultSampleDuration &&\n a.defaultSampleSize === b.defaultSampleSize\n}\n\nfunction sameSample(a: IsoBmffSampleTiming, b: IsoBmffSampleTiming): boolean {\n return a.decodeTime === b.decodeTime &&\n a.presentationTime === b.presentationTime &&\n a.duration === b.duration &&\n a.timescale === b.timescale &&\n a.size === b.size &&\n a.bytePosition === b.bytePosition\n}\n\ntype PendingMovieFragment = Array<IsoBmffSampleTiming | null>\n\n/** Bounded per-track FT=0/FT=1 timing state. */\nexport class IsoBmffTimingResolver {\n #track: IsoBmffTrackTiming | null = null\n #fragments = new Map<string, PendingMovieFragment>()\n /** First sample of each pending fragment, kept in `#delivered` with its sample count. */\n #firstSamples = new Map<string, IsoBmffSampleTiming>()\n /**\n * First sample and sample count of the newest fragments whose every slot was\n * cleared. Abandonment counts: `releaseSample` clears a slot too, which\n * matches the combiner, since it retires an abandoned sample as well.\n */\n #delivered = new Map<string, { first: IsoBmffSampleTiming, sampleCount: number }>()\n #pendingSamples = 0\n #evictedSamples = 0\n #lastMovieFragmentRejection: IsoBmffMovieFragmentRejection | null = null\n\n constructor(readonly maxPendingSamples: number) {\n if (!Number.isInteger(maxPendingSamples) || maxPendingSamples <= 0) {\n throw new Error('[IsoBmffTimingResolver] maxPendingSamples must be a positive integer')\n }\n }\n\n /** True once an FT=0 has bound the track that FT=1 timing is read against. */\n get initialized(): boolean {\n return this.#track !== null\n }\n\n get pendingSampleCount(): number {\n return this.#pendingSamples\n }\n\n /**\n * Slots reclaimed by window displacement rather than by delivery or\n * abandonment. Deliberately separate from the combiner's own release count:\n * \"nobody ever saw this sample\" and \"the combiner gave up on it\" are\n * different failures with different owners, and one number cannot say which.\n */\n get evictedSampleCount(): number {\n return this.#evictedSamples\n }\n\n /** Typed reason for the most recent rejected movie fragment. */\n get lastMovieFragmentRejection(): IsoBmffMovieFragmentRejection | null {\n return this.#lastMovieFragmentRejection\n }\n\n addInitialization(data: Uint8Array): boolean {\n const timing = parseIsoBmffInitializationTiming(data)\n if (!timing) return false\n if (this.#track) return sameTrack(this.#track, timing)\n this.#track = timing\n return true\n }\n\n /**\n * `recovered` marks an FEC-recovered copy. A recovered block hands back\n * every FT=1 it holds, the received ones included, so a recovered copy of a\n * fragment whose samples are all done is a duplicate: admitting it again\n * would charge stale timing and could displace the live MPU's. A source\n * copy is still admitted again (a rendition switch re-arms timing that way).\n */\n addMovieFragment(\n mpuSequenceNumber: number,\n data: Uint8Array,\n additionalSampleLimit = this.maxPendingSamples,\n recovered = false,\n ): boolean {\n this.#lastMovieFragmentRejection = null\n if (!Number.isInteger(additionalSampleLimit) || additionalSampleLimit < 0) {\n this.#lastMovieFragmentRejection = 'invalid'\n return false\n }\n if (!this.#track || !isU32(mpuSequenceNumber)) {\n this.#lastMovieFragmentRejection = 'invalid'\n return false\n }\n const parsed = parseIsoBmffMovieFragmentTiming(\n data,\n this.#track,\n this.maxPendingSamples,\n )\n if (!parsed) {\n this.#lastMovieFragmentRejection = 'invalid'\n return false\n }\n const key = fragmentKey(mpuSequenceNumber, parsed.movieFragmentSequenceNumber)\n const existing = this.#fragments.get(key)\n if (existing) {\n return existing.length === parsed.samples.length && existing.every(\n (sample, index) => sample !== null && sameSample(sample, parsed.samples[index]!),\n )\n }\n const delivered = recovered ? this.#delivered.get(key) : undefined\n if (delivered && delivered.sampleCount === parsed.samples.length &&\n sameSample(delivered.first, parsed.samples[0]!)) return true\n // Sliding window, not a one-way ratchet. `consumeSample` and\n // `releaseSample` between them cover every sample some component observed\n // -- but a sample whose data units never arrive at all is observed by\n // nobody, so neither path ever runs and its slot is held until `reset()`.\n // Under sustained loss those orphans accumulate until the budget is full\n // of samples that can never arrive, at which point every later moof is\n // refused and media stops permanently with no error.\n //\n // Displacement is the signal no component can raise: once the budget is\n // full and a newer fragment is in hand, the oldest pending fragment's\n // samples are older than the whole window and cannot still be in flight.\n // Reclaiming them keeps the timing that is arriving now and discards the\n // timing that is not; refusing the new fragment does exactly the reverse,\n // which is what wedged the stream. Evicted timing is not silent loss --\n // a late data unit then finds no entry and is dropped against a named\n // reason, which is attributable, bounded, and recoverable.\n let freed = 0\n while (\n this.#fragments.size > 0 &&\n (this.#pendingSamples + parsed.samples.length > this.maxPendingSamples ||\n parsed.samples.length - freed > additionalSampleLimit)\n ) {\n freed += this.#evictOldestFragment()\n }\n // Net new charge against the caller's pool is what it must afford: `freed`\n // slots were already counted there and are handed back by this call.\n if (parsed.samples.length - freed > additionalSampleLimit) {\n this.#lastMovieFragmentRejection = 'budget'\n return false\n }\n if (this.#pendingSamples + parsed.samples.length > this.maxPendingSamples) {\n this.#lastMovieFragmentRejection = 'budget'\n return false\n }\n this.#fragments.set(key, [...parsed.samples])\n this.#firstSamples.set(key, parsed.samples[0]!)\n this.#pendingSamples += parsed.samples.length\n return true\n }\n\n sampleTiming(\n mpuSequenceNumber: number,\n movieFragmentSequenceNumber: number,\n sampleNumber: number,\n ): IsoBmffSampleTiming | null {\n if (!isU32(mpuSequenceNumber) || !isU32(movieFragmentSequenceNumber) ||\n movieFragmentSequenceNumber === 0 || !isU32(sampleNumber) || sampleNumber === 0) {\n return null\n }\n const samples = this.#fragments.get(\n fragmentKey(mpuSequenceNumber, movieFragmentSequenceNumber),\n )\n return samples?.[sampleNumber - 1] ?? null\n }\n\n consumeSample(\n mpuSequenceNumber: number,\n movieFragmentSequenceNumber: number,\n sampleNumber: number,\n expected: IsoBmffSampleTiming,\n ): boolean {\n const samples = this.#fragments.get(\n fragmentKey(mpuSequenceNumber, movieFragmentSequenceNumber),\n )\n const sample = samples?.[sampleNumber - 1]\n if (!sample || !sameSample(sample, expected)) return false\n return this.#clearSlot(mpuSequenceNumber, movieFragmentSequenceNumber, sampleNumber)\n }\n\n /**\n * Free the budget slot of a sample that will never be delivered.\n *\n * `consumeSample` is the delivery path and is the only decrement on a\n * healthy stream. A sample whose data units never complete is never\n * delivered; window displacement in `addMovieFragment` eventually reclaims\n * it, but only after it has aged out of the whole window. This path frees\n * the slot as soon as the combiner knows the sample is gone, so the budget\n * tracks what is actually in flight rather than what has merely aged.\n *\n * The caller is whoever abandoned the sample, so the release is driven by\n * the abandonment itself rather than by a timer, an LRU, or an age bound --\n * the slot is freed exactly when its sample provably cannot arrive, which\n * is a protocol event the combiner already detects and counts.\n *\n * Deliberately takes no `expected` timing: the caller is discarding, not\n * matching, and requiring it would make the release fail exactly when the\n * timing entry is the thing being reclaimed. Returns false when the slot\n * was already freed, so a double release cannot drive the count negative.\n */\n releaseSample(\n mpuSequenceNumber: number,\n movieFragmentSequenceNumber: number,\n sampleNumber: number,\n ): boolean {\n return this.#clearSlot(mpuSequenceNumber, movieFragmentSequenceNumber, sampleNumber)\n }\n\n /**\n * Drop the oldest pending fragment whole and return the slots it held.\n *\n * Oldest is insertion order, which for a moof stream is arrival order, so\n * this is the least-recently-declared timing -- the entries least likely to\n * still have data units in flight.\n */\n #evictOldestFragment(): number {\n const oldest = this.#fragments.keys().next().value\n if (oldest === undefined) return 0\n const samples = this.#fragments.get(oldest)!\n let live = 0\n for (const sample of samples) if (sample !== null) live++\n this.#fragments.delete(oldest)\n this.#firstSamples.delete(oldest)\n this.#pendingSamples -= live\n this.#evictedSamples += live\n return live\n }\n\n /** Null one slot, decrement the budget, and drop the fragment when empty. */\n #clearSlot(\n mpuSequenceNumber: number,\n movieFragmentSequenceNumber: number,\n sampleNumber: number,\n ): boolean {\n if (!isU32(mpuSequenceNumber) || !isU32(movieFragmentSequenceNumber) ||\n movieFragmentSequenceNumber === 0 || !isU32(sampleNumber) || sampleNumber === 0) {\n return false\n }\n const key = fragmentKey(mpuSequenceNumber, movieFragmentSequenceNumber)\n const samples = this.#fragments.get(key)\n const index = sampleNumber - 1\n if (!samples || !samples[index]) return false\n samples[index] = null\n this.#pendingSamples--\n if (samples.every(value => value === null)) {\n this.#fragments.delete(key)\n const first = this.#firstSamples.get(key)!\n this.#firstSamples.delete(key)\n this.#delivered.delete(key)\n this.#delivered.set(key, { first, sampleCount: samples.length })\n // ponytail: the dedupe memory is as wide as the timing budget, in fragments;\n // a recovered copy older than that is admitted again, as before.\n if (this.#delivered.size > this.maxPendingSamples) {\n this.#delivered.delete(this.#delivered.keys().next().value!)\n }\n }\n return true\n }\n\n reset(): void {\n this.#track = null\n this.#fragments.clear()\n this.#firstSamples.clear()\n this.#delivered.clear()\n this.#pendingSamples = 0\n }\n}\n\nfunction fragmentKey(mpuSequenceNumber: number, movieFragmentSequenceNumber: number): string {\n return `${mpuSequenceNumber}:${movieFragmentSequenceNumber}`\n}\n\nfunction isU32(value: number): boolean {\n return Number.isInteger(value) && value >= 0 && value <= 0xffff_ffff\n}\n\n/** Convert exact media ticks to microseconds without first narrowing the ticks. */\nexport function mediaTicksToMicroseconds(ticks: bigint, timescale: number): number | null {\n if (!Number.isInteger(timescale) || timescale <= 0) return null\n const numerator = ticks * MICROSECONDS_PER_SECOND\n const scale = BigInt(timescale)\n const whole = numerator / scale\n const remainder = numerator % scale\n if (whole < BigInt(Number.MIN_SAFE_INTEGER) || whole > BigInt(Number.MAX_SAFE_INTEGER)) {\n return null\n }\n const result = Number(whole) + Number(remainder) / timescale\n return Number.isFinite(result) ? result : null\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["trex"]
7
7
  }
@@ -299,9 +299,20 @@ export type MmtpFeedDropReason =
299
299
  /** MPU present but not a timed MFU, so no media payload to reassemble. */
300
300
  | 'untimed-mpu' | 'init-unexpected-fragmentation' | 'init-normalize-failed'
301
301
  /** No timing resolver, or it refused the initialization segment. */
302
- | 'init-timing-refused' | 'fragment-unexpected-fragmentation' | 'fragment-no-resolver'
302
+ | 'init-timing-refused' | 'fragment-unexpected-fragmentation'
303
+ /** FT=1 before an FT=0 has bound the stream's timing track. */
304
+ | 'fragment-no-resolver'
303
305
  /** addMovieFragment refused — includes the pending-timing-sample budget. */
304
- | 'fragment-timing-refused' | 'unknown-fragment-type' | 'mfu-no-resolver' | 'mfu-empty-payload' | 'mfu-du-header-missing' | 'mfu-sample-timing-missing' | 'mfu-offset-out-of-range' | 'mfu-size-mismatch' | 'assembled-identity-missing' | 'assembled-timing-missing' | 'assembled-mpu-mismatch'
306
+ | 'fragment-timing-refused' | 'unknown-fragment-type'
307
+ /** Stable code, no longer produced: an FT=2 with no timing (before the
308
+ * stream's first FT=0, or after setTrack dropped it) now waits for its
309
+ * timing like one whose FT=1 has not arrived. A head counts as
310
+ * `drop:mfu-sample-timing-missing` (parked) and a FI=2/FI=3 continuation
311
+ * as the `pending` record. A continuation that completes a head the
312
+ * reassembler buffered before the timing was dropped counts as
313
+ * `drop:assembled-timing-missing`. A panel keyed on this code reads zero:
314
+ * a re-attribution, not lost coverage. Re-key on both drop codes. */
315
+ | 'mfu-no-resolver' | 'mfu-empty-payload' | 'mfu-du-header-missing' | 'mfu-sample-timing-missing' | 'mfu-offset-out-of-range' | 'mfu-size-mismatch' | 'assembled-identity-missing' | 'assembled-timing-missing' | 'assembled-mpu-mismatch'
305
316
  /**
306
317
  * Refusals inside the combined-sample delivery step, which runs after the
307
318
  * combiner has already produced a whole sample. These are distinct from
@@ -395,6 +406,26 @@ export interface ParseHeaderOptions {
395
406
  /** FEC source block this packet belongs to (FEC-protected packets only). */
396
407
  fecSbn?: number;
397
408
  }
409
+ /** Authored decode-time adjacency: the next frame starts where this one ends. */
410
+ export declare function authoredAdjacent(before: Pick<FrameMeta, 'authoredTiming'>, after: Pick<FrameMeta, 'authoredTiming'>): boolean;
411
+ /** FEC-recovered heads that went through the awaiting-timing queue. Every
412
+ * count but `pending` is cumulative. A held head is pending or has left the
413
+ * queue exactly once, so `held - expired - discarded - superseded - pending`
414
+ * is the number fed again once their FT=1 landed. That feed can still refuse
415
+ * one (size, offset, dispose from a frame callback); the refusal is counted in
416
+ * `feedStats.deferredOutcomes`, not here. */
417
+ export interface MmtpRecoveredHeadTimingStats {
418
+ /** Held because their sample's FT=1 had not arrived yet. */
419
+ held: number;
420
+ /** Left without timing: the reassembler-timeout deadline, or pushed out by the queue's capacity. */
421
+ expired: number;
422
+ /** Dropped with their stream (track reconfigure, reset or retire) or by dispose(). */
423
+ discarded: number;
424
+ /** Gave way to their arriving source copy, which takes their place in the queue. */
425
+ superseded: number;
426
+ /** In the queue now; current occupancy, not cumulative. */
427
+ pending: number;
428
+ }
398
429
  export declare class MmtpContainerParser {
399
430
  #private;
400
431
  constructor(config?: MmtpParserConfig);
@@ -424,6 +455,8 @@ export declare class MmtpContainerParser {
424
455
  * state by parsing logs.
425
456
  */
426
457
  get timingBudgetStats(): Readonly<MmtpTimingBudgetStats>;
458
+ /** Recovered heads parked for FT=1 timing (BLO-53369). Survives dispose(). */
459
+ get recoveredHeadsAwaitingTiming(): Readonly<MmtpRecoveredHeadTimingStats>;
427
460
  get reorderStats(): Readonly<MmtpReorderStats>;
428
461
  /**
429
462
  * Install (or remove) the in-order release policy for FEC-protected
@@ -1 +1 @@
1
- {"version":3,"file":"mmtp-container-parser.d.ts","sourceRoot":"","sources":["../src/mmtp-container-parser.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,UAAU,EAChB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAEL,kBAAkB,EAElB,KAAK,qBAAqB,EAC1B,KAAK,cAAc,EACnB,KAAK,sBAAsB,EAE5B,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAEL,kBAAkB,EAIlB,KAAK,mBAAmB,EACzB,MAAM,sBAAsB,CAAA;AAO7B,OAAO,EAGL,KAAK,mBAAmB,EACzB,MAAM,4BAA4B,CAAA;AAMnC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAC1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAA;AAIzD,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,OAAO,GAAG,OAAO,CAAA;IACvB,KAAK,EAAE,MAAM,CAAA;IACb,0EAA0E;IAC1E,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,wEAAwE;IACxE,eAAe,CAAC,EAAE,MAAM,CAAA;CACzB;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;IAC/B,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB;;8CAE0C;IAC1C,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC5B;mFAC+E;IAC/E,gBAAgB,CAAC,EAAE,mBAAmB,CAAA;IACtC,iFAAiF;IACjF,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB;;;;;;;OAOG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B;+CAC2C;IAC3C,WAAW,CAAC,EAAE,qBAAqB,CAAA;IACnC;;;gFAG4E;IAC5E,YAAY,CAAC,EAAE,SAAS,CAAA;IACxB,8EAA8E;IAC9E,cAAc,CAAC,EAAE,cAAc,CAAA;CAChC;AAED;;uEAEuE;AACvE,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;IAClB,SAAS,EAAE,MAAM,CAAA;IACjB,gFAAgF;IAChF,WAAW,EAAE,MAAM,CAAA;IACnB,cAAc,EAAE,MAAM,CAAA;IACtB,OAAO,EAAE,OAAO,CAAA;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,uFAAuF;IACvF,YAAY,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAA;IACrC,yDAAyD;IACzD,QAAQ,EAAE,OAAO,CAAA;CAClB;AAED;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAA;IACzB,4DAA4D;IAC5D,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAA;IAC3B,0EAA0E;IAC1E,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAA;CACnC;AAED,MAAM,WAAW,SAAS;IACxB,qEAAqE;IACrE,SAAS,EAAE,MAAM,CAAA;IACjB,+DAA+D;IAC/D,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,mEAAmE;IACnE,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,0DAA0D;IAC1D,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,gEAAgE;IAChE,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,uDAAuD;IACvD,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,wDAAwD;IACxD,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,gFAAgF;IAChF,cAAc,CAAC,EAAE,cAAc,CAAA;IAC/B,QAAQ,EAAE,OAAO,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,OAAO,GAAG,OAAO,GAAG,IAAI,CAAA;IACnC,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B,8EAA8E;IAC9E,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAA;IAChC,4DAA4D;IAC5D,6BAA6B,CAAC,EAAE,MAAM,EAAE,CAAA;IACxC,8EAA8E;IAC9E,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,gFAAgF;IAChF,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,2BAA2B,CAAC,EAAE,MAAM,CAAA;IACpC,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,4EAA4E;IAC5E,mBAAmB,CAAC,EAAE,OAAO,CAAA;IAC7B,wEAAwE;IACxE,MAAM,CAAC,EAAE,cAAc,CAAA;IACvB;;;;;;;;OAQG;IACH,kBAAkB,CAAC,EAAE,sBAAsB,CAAA;IAC3C;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IACf;;;;OAIG;IACH,SAAS,CAAC,EAAE,gBAAgB,CAAA;CAC7B;AAED;;;GAGG;AACH,MAAM,WAAW,oBAAoB;IACnC,iBAAiB,EAAE,MAAM,CAAA;IACzB,iFAAiF;IACjF,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,2BAA2B,CAAC,EAAE,MAAM,CAAA;IACpC,8EAA8E;IAC9E,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,6DAA6D;IAC7D,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,gBAAgB,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;IAC3D;;;;;;;OAOG;IACH,YAAY,CACV,QAAQ,EAAE,MAAM,EAChB,gBAAgB,EAAE,MAAM,GAAG,SAAS,EACpC,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,GAClB,SAAS,MAAM,EAAE,GAAG,IAAI,CAAA;IAC3B;;;;;OAKG;IACH,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,gBAAgB,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IAChE,qEAAqE;IACrE,MAAM,CACJ,MAAM,EAAE;QAAE,IAAI,EAAE,UAAU,CAAC;QAAC,IAAI,EAAE,SAAS,CAAA;KAAE,EAC7C,KAAK,EAAE;QAAE,IAAI,EAAE,UAAU,CAAC;QAAC,IAAI,EAAE,SAAS,CAAA;KAAE,EAC5C,UAAU,EAAE,SAAS,MAAM,EAAE,EAC7B,aAAa,EAAE,OAAO,GACrB,gBAAgB,CAAA;IACnB,yDAAyD;IACzD,UAAU,CAAC,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,GAAG,IAAI,CAAA;IACpD;;;;OAIG;IACH,KAAK,CAAC,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,GAAG,OAAO,CAAA;IAClD,qEAAqE;IACrE,KAAK,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CACnF;AAED,6EAA6E;AAC7E,MAAM,WAAW,qBAAqB;IACpC,mEAAmE;IACnE,OAAO,EAAE,MAAM,CAAA;IACf,4EAA4E;IAC5E,QAAQ,EAAE,MAAM,CAAA;IAChB,+EAA+E;IAC/E,SAAS,EAAE,MAAM,CAAA;IACjB;;;;;OAKG;IACH,OAAO,EAAE,MAAM,CAAA;IACf,gFAAgF;IAChF,sBAAsB,EAAE,MAAM,CAAA;CAC/B;AAED,MAAM,WAAW,gBAAgB;IAC/B,4BAA4B,EAAE,MAAM,CAAA;IACpC,gCAAgC,EAAE,MAAM,CAAA;IACxC,YAAY,EAAE,MAAM,CAAA;IACpB,mBAAmB,EAAE,MAAM,CAAA;IAC3B,oBAAoB,EAAE,MAAM,CAAA;IAC5B,eAAe,EAAE,MAAM,CAAA;IACvB,uBAAuB,EAAE,MAAM,CAAA;IAC/B,cAAc,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,2BAA2B;IAC1C,WAAW,EAAE,MAAM,CAAA;IACnB,QAAQ,EAAE,OAAO,CAAA;IACjB,cAAc,EAAE,MAAM,CAAA;IACtB,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B,2BAA2B,CAAC,EAAE,MAAM,CAAA;IACpC,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,EAAE,MAAM,CAAA;IAChB,cAAc,EAAE,MAAM,CAAA;IACtB,WAAW,EAAE,2BAA2B,GAAG,IAAI,CAAA;IAC/C,eAAe,EAAE,2BAA2B,GAAG,IAAI,CAAA;IACnD,IAAI,EAAE,2BAA2B,EAAE,CAAA;IACnC,IAAI,EAAE,2BAA2B,EAAE,CAAA;IACnC,SAAS,EAAE,2BAA2B,EAAE,CAAA;CACzC;AAED,MAAM,MAAM,gBAAgB,GACxB;IACE,IAAI,EAAE,QAAQ,GAAG,WAAW,CAAA;IAC5B,MAAM,EAAE,UAAU,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;CACnB,GACD;IACE,IAAI,EAAE,MAAM,GAAG,UAAU,CAAA;IACzB,MAAM,EAAE,UAAU,CAAA;IAClB,IAAI,EAAE,UAAU,CAAA;IAChB,iBAAiB,EAAE,MAAM,CAAA;IACzB,sBAAsB,EAAE,MAAM,CAAA;IAC9B,eAAe,EAAE,MAAM,CAAA;CACxB,GACD;IACE,IAAI,EAAE,SAAS,CAAA;IACf,MAAM,EAAE,UAAU,CAAA;IAClB,iBAAiB,EAAE,MAAM,CAAA;IACzB,sBAAsB,EAAE,MAAM,CAAA;IAC9B,eAAe,EAAE,MAAM,CAAA;CACxB,GACD;IACE,IAAI,EAAE,UAAU,CAAA;IAChB,MAAM,EAAE,UAAU,CAAA;IAClB,iBAAiB,EAAE,MAAM,CAAA;IACzB,sBAAsB,EAAE,MAAM,CAAA;IAC9B,eAAe,EAAE,MAAM,CAAA;IACvB,KAAK,EAAE;QACL;;;;;WAKG;QACH,IAAI,EAAE,kBAAkB,CAAC,MAAM,CAAC,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAA;QAC7D,OAAO,EAAE,MAAM,CAAA;KAChB,CAAA;CACF,GACD;IACE,IAAI,EAAE,OAAO,CAAA;IACb,MAAM,EAAE,UAAU,CAAA;IAClB,IAAI,EAAE,UAAU,CAAA;IAChB,IAAI,EAAE,SAAS,CAAA;IACf,iBAAiB,EAAE,MAAM,CAAA;IACzB,aAAa,EAAE,MAAM,CAAA;IACrB,OAAO,EAAE,OAAO,CAAA;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB,CAAA;AAEL;;;;;;;;;GASG;AACH,MAAM,MAAM,kBAAkB;AAC5B,+EAA+E;AAC7E,UAAU,GACV,qBAAqB,GACrB,oBAAoB;AACtB,0EAA0E;GACxE,aAAa,GACb,+BAA+B,GAC/B,uBAAuB;AACzB,oEAAoE;GAClE,qBAAqB,GACrB,mCAAmC,GACnC,sBAAsB;AACxB,4EAA4E;GAC1E,yBAAyB,GACzB,uBAAuB,GACvB,iBAAiB,GACjB,mBAAmB,GACnB,uBAAuB,GACvB,2BAA2B,GAC3B,yBAAyB,GACzB,mBAAmB,GACnB,4BAA4B,GAC5B,0BAA0B,GAC1B,wBAAwB;AAC1B;;;;;;;GAOG;GACD,yBAAyB,GACzB,wBAAwB;AAC1B;2EAC2E;GACzE,4BAA4B,GAC5B,iCAAiC;AACnC;oCACoC;GAClC,OAAO,CAAA;AAEX;;;;;;GAMG;AACH,MAAM,MAAM,kBAAkB,GAC1B,gBAAgB,CAAC,MAAM,CAAC,GACxB,QAAQ,kBAAkB,EAAE,CAAA;AAEhC;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,mBAAmB;IAClC,mEAAmE;IACnE,UAAU,EAAE,MAAM,CAAA;IAClB;;;;;;;;OAQG;IACH,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,kBAAkB,EAAE,MAAM,CAAC,CAAC,CAAA;IACrD;;;;OAIG;IACH,gBAAgB,EAAE,OAAO,CAAC,MAAM,CAAC,kBAAkB,EAAE,MAAM,CAAC,CAAC,CAAA;CAC9D;AAED,KAAK,aAAa,GAAG,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,KAAK,IAAI,CAAA;AAChE,KAAK,YAAY,GAAG,CAAC,IAAI,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,gBAAgB,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;AAe3F,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAElF;AAED;;;;;;;;;;;;;;;gEAegE;AAChE,KAAK,oBAAoB,GAAG,CAC1B,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,UAAU,KAClB,IAAI,CAAA;AAET,MAAM,WAAW,kBAAkB;IACjC,wFAAwF;IACxF,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,6DAA6D;IAC7D,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,4EAA4E;IAC5E,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,2DAA2D;IAC3D,MAAM,CAAC,EAAE,cAAc,CAAA;IACvB;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,sBAAsB,CAAA;IAC3C,4EAA4E;IAC5E,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAqlBD,qBAAa,mBAAmB;;gBA+HlB,MAAM,CAAC,EAAE,gBAAgB;IA0ErC;;;;;4EAKwE;IACxE,IAAI,WAAW,IAAI,qBAAqB,CAEvC;IAED;;;;;;;OAOG;IACH,IAAI,mBAAmB,IAAI,QAAQ,CAAC,mBAAmB,CAAC,CAUvD;IAED;;;;;;;;OAQG;IACH,IAAI,iBAAiB,IAAI,QAAQ,CAAC,qBAAqB,CAAC,CAQvD;IAED,IAAI,YAAY,IAAI,QAAQ,CAAC,gBAAgB,CAAC,CAI7C;IAED;;;;OAIG;IACH,iBAAiB,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI,GAAG,IAAI;IAcpD;;;;OAIG;IACH,eAAe,CAAC,IAAI,EAAE,MAAM,IAAI,GAAG,IAAI;IAQvC,qDAAqD;IACrD,0BAA0B,CAAC,QAAQ,EAAE,MAAM,EAAE,gBAAgB,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAI3F,2EAA2E;IAC3E,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO;IAIjG,2DAA2D;IAC3D,cAAc,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI;IAOlE;;;OAGG;IACH,oBAAoB,CAAC,QAAQ,EAAE,MAAM,EAAE,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI;IAIvE;;;OAGG;IACH,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAIrC;;;;;OAKG;IACH,MAAM,CAAC,oBAAoB,CAAC,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,GAAG,oBAAoB,GAAG,IAAI;IAkBhG;;;;;;;OAOG;IACH,IAAI,SAAS,IAAI,QAAQ,CAAC,mBAAmB,CAAC,CAM7C;IAED;;;;;;OAMG;IACH,IAAI,eAAe,IAAI,kBAAkB,GAAG,IAAI,CAE/C;IAED;mFAC+E;IAC/E,IAAI,oBAAoB,IAAI,MAAM,CAEjC;IAED;;;;;OAKG;IACH,IAAI,uBAAuB,IAAI,MAAM,CAEpC;IAED,8DAA8D;IAC9D,IAAI,4BAA4B,IAAI,MAAM,CAEzC;IA6BD,IAAI,kBAAkB,IAAI,aAAa,CAAC,4BAA4B,CAAC,CAMpE;IAED;;;;;;OAMG;IACH,eAAe,IAAI,IAAI;IAcvB;;;;;OAKG;IACH,WAAW,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,UAAU,GAAG,IAAI;IAIhF;;;;;;OAMG;IACH,WAAW,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,gBAAgB,GAAG,IAAI;IA2BtF,gFAAgF;IAChF,IAAI,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,CAAC,EAAE,kBAAkB,GAAG,gBAAgB,GAAG,IAAI;IAI/E;;;;;OAKG;IACH,UAAU,CACR,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,gBAAgB,EACxB,OAAO,CAAC,EAAE,kBAAkB,GAC3B,gBAAgB,GAAG,IAAI;IA0X1B,MAAM,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI;IAI9B,OAAO,CAAC,EAAE,EAAE,aAAa,GAAG,IAAI;IAIhC;;;;;;;;;;;;6DAYyD;IACzD,cAAc,CAAC,EAAE,EAAE,oBAAoB,GAAG,IAAI;IAI9C,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,aAAa,GAAG,IAAI;IAIvD,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,IAAI;IAsBjD,6EAA6E;IAC7E,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,GAAG,IAAI;IAoB5D;;;;;;;;;;OAUG;IACH,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,iBAAiB,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,IAAI;IA4BxE,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAKxC,mBAAmB,CAAC,MAAM,EAAE,mBAAmB,GAAG,IAAI;IAStD,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAW1C;;iEAE6D;IAC7D,UAAU,CAAC,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,GAAG,IAAI;IAwBnD,4EAA4E;IAC5E,oBAAoB,CAClB,QAAQ,EAAE,MAAM,EAChB,iBAAiB,EAAE,MAAM,EACzB,2BAA2B,EAAE,MAAM,EACnC,YAAY,EAAE,MAAM,EACpB,gBAAgB,CAAC,EAAE,MAAM,GACxB,OAAO;IAKV;;;;;;OAMG;IACH,wBAAwB,CACtB,QAAQ,EAAE,MAAM,EAChB,iBAAiB,EAAE,MAAM,EACzB,2BAA2B,EAAE,MAAM,GAAG,SAAS,EAC/C,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,gBAAgB,CAAC,EAAE,MAAM,GACxB,cAAc,GAAG,IAAI;IA4CxB;iFAC6E;IAC7E,KAAK,IAAI,IAAI;IAMb,OAAO,IAAI,IAAI;IAsLf,kFAAkF;IAClF,kBAAkB,EAAE,MAAM,GAAG,SAAS,CAAY;IAWlD,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,SAAK,GAAG,OAAO;CAgF3E"}
1
+ {"version":3,"file":"mmtp-container-parser.d.ts","sourceRoot":"","sources":["../src/mmtp-container-parser.ts"],"names":[],"mappings":"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"}
@@ -4851,9 +4851,21 @@ var IsoBmffTimingResolver = class {
4851
4851
  }
4852
4852
  #track = null;
4853
4853
  #fragments = /* @__PURE__ */ new Map();
4854
+ /** First sample of each pending fragment, kept in `#delivered` with its sample count. */
4855
+ #firstSamples = /* @__PURE__ */ new Map();
4856
+ /**
4857
+ * First sample and sample count of the newest fragments whose every slot was
4858
+ * cleared. Abandonment counts: `releaseSample` clears a slot too, which
4859
+ * matches the combiner, since it retires an abandoned sample as well.
4860
+ */
4861
+ #delivered = /* @__PURE__ */ new Map();
4854
4862
  #pendingSamples = 0;
4855
4863
  #evictedSamples = 0;
4856
4864
  #lastMovieFragmentRejection = null;
4865
+ /** True once an FT=0 has bound the track that FT=1 timing is read against. */
4866
+ get initialized() {
4867
+ return this.#track !== null;
4868
+ }
4857
4869
  get pendingSampleCount() {
4858
4870
  return this.#pendingSamples;
4859
4871
  }
@@ -4877,7 +4889,14 @@ var IsoBmffTimingResolver = class {
4877
4889
  this.#track = timing;
4878
4890
  return true;
4879
4891
  }
4880
- addMovieFragment(mpuSequenceNumber, data, additionalSampleLimit = this.maxPendingSamples) {
4892
+ /**
4893
+ * `recovered` marks an FEC-recovered copy. A recovered block hands back
4894
+ * every FT=1 it holds, the received ones included, so a recovered copy of a
4895
+ * fragment whose samples are all done is a duplicate: admitting it again
4896
+ * would charge stale timing and could displace the live MPU's. A source
4897
+ * copy is still admitted again (a rendition switch re-arms timing that way).
4898
+ */
4899
+ addMovieFragment(mpuSequenceNumber, data, additionalSampleLimit = this.maxPendingSamples, recovered = false) {
4881
4900
  this.#lastMovieFragmentRejection = null;
4882
4901
  if (!Number.isInteger(additionalSampleLimit) || additionalSampleLimit < 0) {
4883
4902
  this.#lastMovieFragmentRejection = "invalid";
@@ -4903,6 +4922,8 @@ var IsoBmffTimingResolver = class {
4903
4922
  (sample, index) => sample !== null && sameSample(sample, parsed.samples[index])
4904
4923
  );
4905
4924
  }
4925
+ const delivered = recovered ? this.#delivered.get(key) : void 0;
4926
+ if (delivered && delivered.sampleCount === parsed.samples.length && sameSample(delivered.first, parsed.samples[0])) return true;
4906
4927
  let freed = 0;
4907
4928
  while (this.#fragments.size > 0 && (this.#pendingSamples + parsed.samples.length > this.maxPendingSamples || parsed.samples.length - freed > additionalSampleLimit)) {
4908
4929
  freed += this.#evictOldestFragment();
@@ -4916,6 +4937,7 @@ var IsoBmffTimingResolver = class {
4916
4937
  return false;
4917
4938
  }
4918
4939
  this.#fragments.set(key, [...parsed.samples]);
4940
+ this.#firstSamples.set(key, parsed.samples[0]);
4919
4941
  this.#pendingSamples += parsed.samples.length;
4920
4942
  return true;
4921
4943
  }
@@ -4973,6 +4995,7 @@ var IsoBmffTimingResolver = class {
4973
4995
  let live = 0;
4974
4996
  for (const sample of samples) if (sample !== null) live++;
4975
4997
  this.#fragments.delete(oldest);
4998
+ this.#firstSamples.delete(oldest);
4976
4999
  this.#pendingSamples -= live;
4977
5000
  this.#evictedSamples += live;
4978
5001
  return live;
@@ -4988,12 +5011,23 @@ var IsoBmffTimingResolver = class {
4988
5011
  if (!samples || !samples[index]) return false;
4989
5012
  samples[index] = null;
4990
5013
  this.#pendingSamples--;
4991
- if (samples.every((value) => value === null)) this.#fragments.delete(key);
5014
+ if (samples.every((value) => value === null)) {
5015
+ this.#fragments.delete(key);
5016
+ const first = this.#firstSamples.get(key);
5017
+ this.#firstSamples.delete(key);
5018
+ this.#delivered.delete(key);
5019
+ this.#delivered.set(key, { first, sampleCount: samples.length });
5020
+ if (this.#delivered.size > this.maxPendingSamples) {
5021
+ this.#delivered.delete(this.#delivered.keys().next().value);
5022
+ }
5023
+ }
4992
5024
  return true;
4993
5025
  }
4994
5026
  reset() {
4995
5027
  this.#track = null;
4996
5028
  this.#fragments.clear();
5029
+ this.#firstSamples.clear();
5030
+ this.#delivered.clear();
4997
5031
  this.#pendingSamples = 0;
4998
5032
  }
4999
5033
  };
@@ -5475,6 +5509,12 @@ var MmtpContainerParser = class _MmtpContainerParser {
5475
5509
  this.#reclaimedTimingSamples = 0;
5476
5510
  this.#evictedTimingSamples = 0;
5477
5511
  this.#rejectedMovieFragments = 0;
5512
+ this.#recoveredHeadsAwaitingTiming = {
5513
+ held: 0,
5514
+ expired: 0,
5515
+ discarded: 0,
5516
+ superseded: 0
5517
+ };
5478
5518
  this.#sequencers = /* @__PURE__ */ new Map();
5479
5519
  this.#fecGate = null;
5480
5520
  this.#fecSequencer = null;
@@ -5583,6 +5623,7 @@ var MmtpContainerParser = class _MmtpContainerParser {
5583
5623
  #reclaimedTimingSamples;
5584
5624
  #evictedTimingSamples;
5585
5625
  #rejectedMovieFragments;
5626
+ #recoveredHeadsAwaitingTiming;
5586
5627
  #sequencers;
5587
5628
  #fecGate;
5588
5629
  #fecSequencer;
@@ -5703,6 +5744,14 @@ var MmtpContainerParser = class _MmtpContainerParser {
5703
5744
  rejectedMovieFragments: this.#rejectedMovieFragments
5704
5745
  };
5705
5746
  }
5747
+ /** Recovered heads parked for FT=1 timing (BLO-53369). Survives dispose(). */
5748
+ get recoveredHeadsAwaitingTiming() {
5749
+ let pending = 0;
5750
+ for (const { awaitingTiming } of this.#timingStreams.values()) {
5751
+ for (const head of awaitingTiming) if (head.options?.recovered) pending++;
5752
+ }
5753
+ return { ...this.#recoveredHeadsAwaitingTiming, pending };
5754
+ }
5706
5755
  get reorderStats() {
5707
5756
  let bufferedFrames = this.#fecSequencer?.buffered ?? 0;
5708
5757
  for (const { sequencer } of this.#sequencers.values()) bufferedFrames += sequencer.buffered;
@@ -5876,7 +5925,7 @@ var MmtpContainerParser = class _MmtpContainerParser {
5876
5925
  const now = Date.now();
5877
5926
  for (const { awaitingTiming } of this.#timingStreams.values()) {
5878
5927
  while (awaitingTiming.length > 0 && now - awaitingTiming[0].arrivedAt > timeoutMs) {
5879
- awaitingTiming.shift();
5928
+ this.#leaveAwaitingTiming(awaitingTiming.shift(), "expired");
5880
5929
  }
5881
5930
  }
5882
5931
  }
@@ -5994,11 +6043,16 @@ var MmtpContainerParser = class _MmtpContainerParser {
5994
6043
  if (mpu.fragmentationIndicator !== 0 || mpu.fragmentCounter !== 0)
5995
6044
  return this.#drop("fragment-unexpected-fragmentation");
5996
6045
  const resolver2 = this.#timingResolver(streamKey, info.packetId, false);
5997
- if (!resolver2) return this.#drop("fragment-no-resolver");
6046
+ if (!resolver2?.initialized) return this.#drop("fragment-no-resolver");
5998
6047
  const pendingBefore = resolver2.pendingSampleCount;
5999
6048
  const evictedBefore = resolver2.evictedSampleCount;
6000
6049
  const remaining = this.#maxPendingTimingSamples - this.#pendingTimingSamples;
6001
- const admitted = resolver2.addMovieFragment(mpu.mpuSequenceNumber, data, remaining);
6050
+ const admitted = resolver2.addMovieFragment(
6051
+ mpu.mpuSequenceNumber,
6052
+ data,
6053
+ remaining,
6054
+ options?.recovered === true
6055
+ );
6002
6056
  this.#pendingTimingSamples += resolver2.pendingSampleCount - pendingBefore;
6003
6057
  this.#evictedTimingSamples += resolver2.evictedSampleCount - evictedBefore;
6004
6058
  if (!admitted) {
@@ -6018,7 +6072,7 @@ var MmtpContainerParser = class _MmtpContainerParser {
6018
6072
  };
6019
6073
  }
6020
6074
  if (fragmentType !== 2) return this.#drop("unknown-fragment-type");
6021
- const resolver = this.#timingResolver(streamKey, info.packetId, false);
6075
+ const resolver = this.#timingResolver(streamKey, info.packetId, true);
6022
6076
  if (!resolver) return this.#drop("mfu-no-resolver");
6023
6077
  if (!Number.isSafeInteger(data.byteLength) || data.byteLength <= 0)
6024
6078
  return this.#drop("mfu-empty-payload");
@@ -6039,6 +6093,7 @@ var MmtpContainerParser = class _MmtpContainerParser {
6039
6093
  mpuSequenceNumber: mpu.mpuSequenceNumber,
6040
6094
  movieFragmentSequenceNumber: mfuDuHeader.movieFragmentSequenceNumber,
6041
6095
  sampleNumber: mfuDuHeader.sampleNumber,
6096
+ sequenceNumber: info.sequenceNumber,
6042
6097
  arrivedAt: Date.now()
6043
6098
  });
6044
6099
  return this.#drop("mfu-sample-timing-missing");
@@ -6427,6 +6482,9 @@ var MmtpContainerParser = class _MmtpContainerParser {
6427
6482
  for (const { sequencer } of this.#sequencers.values()) sequencer.discard();
6428
6483
  this.#sequencers.clear();
6429
6484
  this.#fecSequencer?.discard();
6485
+ for (const { awaitingTiming } of this.#timingStreams.values()) {
6486
+ for (const head of awaitingTiming) this.#leaveAwaitingTiming(head, "discarded");
6487
+ }
6430
6488
  this.#timingStreams.clear();
6431
6489
  this.#pendingTimingSamples = 0;
6432
6490
  this.#reliableMoqStartupGate.clear();
@@ -6445,10 +6503,23 @@ var MmtpContainerParser = class _MmtpContainerParser {
6445
6503
  return resolver;
6446
6504
  }
6447
6505
  #awaitTiming(streamKey, head) {
6448
- const awaitingTiming = this.#timingStreams.get(streamKey)?.awaitingTiming;
6449
- if (!awaitingTiming) return;
6506
+ const state = this.#timingStreams.get(streamKey);
6507
+ if (!state) return;
6508
+ if (!head.options?.recovered) {
6509
+ const kept = state.awaitingTiming.filter((queued) => !queued.options?.recovered || queued.sequenceNumber !== head.sequenceNumber);
6510
+ this.#recoveredHeadsAwaitingTiming.superseded += state.awaitingTiming.length - kept.length;
6511
+ state.awaitingTiming = kept;
6512
+ }
6513
+ const awaitingTiming = state.awaitingTiming;
6450
6514
  awaitingTiming.push(head);
6451
- if (awaitingTiming.length > MAX_AWAITING_TIMING_HEADS) awaitingTiming.shift();
6515
+ if (head.options?.recovered) this.#recoveredHeadsAwaitingTiming.held++;
6516
+ if (awaitingTiming.length > MAX_AWAITING_TIMING_HEADS) {
6517
+ this.#leaveAwaitingTiming(awaitingTiming.shift(), "expired");
6518
+ }
6519
+ }
6520
+ /** Count a recovered head leaving the queue other than by replay or its source copy. */
6521
+ #leaveAwaitingTiming(head, outcome) {
6522
+ if (head.options?.recovered) this.#recoveredHeadsAwaitingTiming[outcome]++;
6452
6523
  }
6453
6524
  /**
6454
6525
  * Feed again the heads whose timing the FT=1 just admitted declares. That
@@ -6476,6 +6547,7 @@ var MmtpContainerParser = class _MmtpContainerParser {
6476
6547
  const state = this.#timingStreams.get(streamKey);
6477
6548
  if (!state) return;
6478
6549
  this.#timingStreams.delete(streamKey);
6550
+ for (const head of state.awaitingTiming) this.#leaveAwaitingTiming(head, "discarded");
6479
6551
  this.#pendingTimingSamples -= state.resolver.pendingSampleCount;
6480
6552
  if (this.#pendingTimingSamples < 0) {
6481
6553
  throw new Error("[MmtpContainerParser] pending timing sample accounting underflow");
@@ -6707,6 +6779,7 @@ function findAnnexBStart(data, offset) {
6707
6779
  }
6708
6780
  export {
6709
6781
  MmtpContainerParser,
6782
+ authoredAdjacent,
6710
6783
  isMfuKeyframeMetadata
6711
6784
  };
6712
6785
  //# sourceMappingURL=mmtp-container-parser.js.map