init commit

This commit is contained in:
Carlos
2026-02-21 10:33:18 +01:00
parent c863a943ed
commit 9d955bf338
9512 changed files with 2015317 additions and 1305 deletions

View File

@@ -0,0 +1,33 @@
import type { RiffSeekingHints } from '../../containers/riff/seeking-hints';
import type { MediaParserController } from '../../controller/media-parser-controller';
import type { PrefetchCache } from '../../fetch';
import type { MediaParserLogLevel } from '../../log';
import type { ParseMediaSrc } from '../../options';
import type { MediaParserReaderInterface } from '../../readers/reader';
export declare const lazyIdx1Fetch: ({ controller, logLevel, readerInterface, src, prefetchCache, contentLength, }: {
controller: MediaParserController;
logLevel: MediaParserLogLevel;
readerInterface: MediaParserReaderInterface;
src: ParseMediaSrc;
prefetchCache: PrefetchCache;
contentLength: number;
}) => {
triggerLoad: (position: number) => Promise<{
entries: import("../../containers/riff/riff-box").Idx1Entry[];
videoTrackIndex: number | null;
}>;
getLoadedIdx1: () => Promise<{
entries: import("../../containers/riff/riff-box").Idx1Entry[];
videoTrackIndex: number | null;
} | null>;
getIfAlreadyLoaded: () => {
entries: import("../../containers/riff/riff-box").Idx1Entry[];
videoTrackIndex: number | null;
} | null;
setFromSeekingHints: (hints: RiffSeekingHints) => void;
waitForLoaded: () => Promise<{
entries: import("../../containers/riff/riff-box").Idx1Entry[];
videoTrackIndex: number | null;
}> | Promise<null>;
};
export type LazyIdx1Fetch = ReturnType<typeof lazyIdx1Fetch>;

View File

@@ -0,0 +1,65 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.lazyIdx1Fetch = void 0;
const fetch_idx1_1 = require("../../containers/riff/seek/fetch-idx1");
const lazyIdx1Fetch = ({ controller, logLevel, readerInterface, src, prefetchCache, contentLength, }) => {
let prom = null;
let result = null;
const triggerLoad = (position) => {
if (result) {
return Promise.resolve(result);
}
if (prom) {
return prom;
}
prom = (0, fetch_idx1_1.fetchIdx1)({
controller,
logLevel,
position,
readerInterface,
src,
prefetchCache,
contentLength,
}).then((entries) => {
prom = null;
result = entries;
return entries;
});
return prom;
};
const getLoadedIdx1 = async () => {
if (!prom) {
return null;
}
const entries = await prom;
return entries;
};
const getIfAlreadyLoaded = () => {
if (result) {
return result;
}
return null;
};
const setFromSeekingHints = (hints) => {
if (hints.idx1Entries) {
result = hints.idx1Entries;
}
};
const waitForLoaded = () => {
if (result) {
return Promise.resolve(result);
}
if (prom) {
return prom;
}
return Promise.resolve(null);
};
return {
triggerLoad,
getLoadedIdx1,
getIfAlreadyLoaded,
setFromSeekingHints,
waitForLoaded,
};
};
exports.lazyIdx1Fetch = lazyIdx1Fetch;

View File

@@ -0,0 +1,20 @@
import type { MediaParserVideoSample } from '../../webcodec-sample-types';
export type QueuedVideoSample = Omit<MediaParserVideoSample, 'decodingTimestamp' | 'timestamp'>;
type QueueItem = {
sample: QueuedVideoSample;
trackId: number;
timescale: number;
};
export declare const queuedBFramesState: () => {
addFrame: ({ frame, maxFramesInBuffer, trackId, timescale, }: {
frame: QueuedVideoSample;
trackId: number;
maxFramesInBuffer: number;
timescale: number;
}) => void;
flush: () => void;
getReleasedFrame: () => QueueItem | null;
hasReleasedFrames: () => boolean;
clear: () => void;
};
export {};

View File

@@ -0,0 +1,39 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.queuedBFramesState = void 0;
const queuedBFramesState = () => {
const queuedFrames = [];
const releasedFrames = [];
const flush = () => {
releasedFrames.push(...queuedFrames);
queuedFrames.length = 0;
};
return {
addFrame: ({ frame, maxFramesInBuffer, trackId, timescale, }) => {
if (frame.type === 'key') {
flush();
releasedFrames.push({ sample: frame, trackId, timescale });
return;
}
queuedFrames.push({ sample: frame, trackId, timescale });
if (queuedFrames.length > maxFramesInBuffer) {
releasedFrames.push(queuedFrames.shift());
}
},
flush,
getReleasedFrame: () => {
if (releasedFrames.length === 0) {
return null;
}
return releasedFrames.shift();
},
hasReleasedFrames: () => {
return releasedFrames.length > 0;
},
clear: () => {
releasedFrames.length = 0;
queuedFrames.length = 0;
},
};
};
exports.queuedBFramesState = queuedBFramesState;

View File

@@ -0,0 +1,10 @@
import type { MediaParserKeyframe } from '../../options';
export type RiffKeyframe = MediaParserKeyframe & {
sampleCounts: Record<number, number>;
};
export declare const riffKeyframesState: () => {
addKeyframe: (keyframe: RiffKeyframe) => void;
getKeyframes: () => RiffKeyframe[];
setFromSeekingHints: (keyframesFromHints: RiffKeyframe[]) => void;
};
export type RiffKeyframesState = ReturnType<typeof riffKeyframesState>;

View File

@@ -0,0 +1,27 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.riffKeyframesState = void 0;
const riffKeyframesState = () => {
const keyframes = [];
const addKeyframe = (keyframe) => {
if (keyframes.find((k) => k.positionInBytes === keyframe.positionInBytes)) {
return;
}
keyframes.push(keyframe);
keyframes.sort((a, b) => a.positionInBytes - b.positionInBytes);
};
const getKeyframes = () => {
return keyframes;
};
const setFromSeekingHints = (keyframesFromHints) => {
for (const keyframe of keyframesFromHints) {
addKeyframe(keyframe);
}
};
return {
addKeyframe,
getKeyframes,
setFromSeekingHints,
};
};
exports.riffKeyframesState = riffKeyframesState;

View File

@@ -0,0 +1,26 @@
import type { MediaParserAudioSample, MediaParserVideoSample } from '../../webcodec-sample-types';
import type { QueuedVideoSample } from './queued-frames';
export declare const riffSampleCounter: () => {
onAudioSample: (trackId: number, audioSample: MediaParserAudioSample) => void;
onVideoSample: ({ trackId, videoSample, }: {
videoSample: MediaParserVideoSample;
trackId: number;
}) => void;
getSampleCountForTrack: ({ trackId }: {
trackId: number;
}) => number;
setSamplesFromSeek: (samples: Record<number, number>) => void;
riffKeys: {
addKeyframe: (keyframe: import("./riff-keyframes").RiffKeyframe) => void;
getKeyframes: () => import("./riff-keyframes").RiffKeyframe[];
setFromSeekingHints: (keyframesFromHints: import("./riff-keyframes").RiffKeyframe[]) => void;
};
setPocAtKeyframeOffset: ({ keyframeOffset, poc, }: {
keyframeOffset: number;
poc: number;
}) => void;
getPocAtKeyframeOffset: ({ keyframeOffset, }: {
keyframeOffset: number;
}) => number[];
getKeyframeAtOffset: (sample: QueuedVideoSample) => number | null;
};

View File

@@ -0,0 +1,80 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.riffSampleCounter = void 0;
const webcodecs_timescale_1 = require("../../webcodecs-timescale");
const riff_keyframes_1 = require("./riff-keyframes");
const riffSampleCounter = () => {
const samplesForTrack = {};
// keyframe offset -> poc[]
const pocsAtKeyframeOffset = {};
const riffKeys = (0, riff_keyframes_1.riffKeyframesState)();
const onAudioSample = (trackId, audioSample) => {
if (typeof samplesForTrack[trackId] === 'undefined') {
samplesForTrack[trackId] = 0;
}
if (audioSample.data.length > 0) {
samplesForTrack[trackId]++;
}
samplesForTrack[trackId]++;
};
const onVideoSample = ({ trackId, videoSample, }) => {
if (typeof samplesForTrack[trackId] === 'undefined') {
samplesForTrack[trackId] = 0;
}
if (videoSample.type === 'key') {
riffKeys.addKeyframe({
trackId,
decodingTimeInSeconds: videoSample.decodingTimestamp / webcodecs_timescale_1.WEBCODECS_TIMESCALE,
positionInBytes: videoSample.offset,
presentationTimeInSeconds: videoSample.timestamp / webcodecs_timescale_1.WEBCODECS_TIMESCALE,
sizeInBytes: videoSample.data.length,
sampleCounts: { ...samplesForTrack },
});
}
if (videoSample.data.length > 0) {
samplesForTrack[trackId]++;
}
};
const getSampleCountForTrack = ({ trackId }) => {
var _a;
return (_a = samplesForTrack[trackId]) !== null && _a !== void 0 ? _a : 0;
};
const setSamplesFromSeek = (samples) => {
for (const trackId in samples) {
samplesForTrack[trackId] = samples[trackId];
}
};
const setPocAtKeyframeOffset = ({ keyframeOffset, poc, }) => {
if (typeof pocsAtKeyframeOffset[keyframeOffset] === 'undefined') {
pocsAtKeyframeOffset[keyframeOffset] = [];
}
if (pocsAtKeyframeOffset[keyframeOffset].includes(poc)) {
return;
}
pocsAtKeyframeOffset[keyframeOffset].push(poc);
pocsAtKeyframeOffset[keyframeOffset].sort((a, b) => a - b);
};
const getPocAtKeyframeOffset = ({ keyframeOffset, }) => {
return pocsAtKeyframeOffset[keyframeOffset];
};
const getKeyframeAtOffset = (sample) => {
var _a, _b;
if (sample.type === 'key') {
return sample.offset;
}
return ((_b = (_a = riffKeys
.getKeyframes()
.findLast((k) => k.positionInBytes <= sample.offset)) === null || _a === void 0 ? void 0 : _a.positionInBytes) !== null && _b !== void 0 ? _b : null);
};
return {
onAudioSample,
onVideoSample,
getSampleCountForTrack,
setSamplesFromSeek,
riffKeys,
setPocAtKeyframeOffset,
getPocAtKeyframeOffset,
getKeyframeAtOffset,
};
};
exports.riffSampleCounter = riffSampleCounter;