feat(spf): skip relocation for near-zero-PTS origins (spike)

Add NEAR_ZERO_ORIGIN_THRESHOLD (1s, absolute) to the derive: a shared/per-type
origin below the threshold — including negatives — resolves to 0, so ordinary
~0-PTS VOD is left on its native timeline and no timestampOffset is set (the
loader stamp already no-ops on a derived 0). Relocation stays targeted at
streams with an intentional large origin (instant clips, bipbop @10s).

Absolute basis, not proportional: the DTS-below-zero / edge-ripple risk scales
with the origin's absolute size, not the presentation's duration.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Christian Pillsbury
2026-07-14 07:59:26 -07:00
co-authored by Claude Opus 4.8
parent be8d28d687
commit 4c272f1890
2 changed files with 80 additions and 4 deletions
@@ -74,6 +74,25 @@ function ownOrigin(data: MediaContainerData | undefined): number | undefined {
: undefined;
}
/**
* Origins below this magnitude (seconds) are treated as `0` — the derive returns `0`, so
* the presentation is left on its native (~0-based) timeline and no `timestampOffset` is
* set (the loader stamp no-ops on a derived `0`). Ordinary VOD carries a small nonzero
* encode origin (audio priming, first-frame CTS, edit lists); relocating by a sub-second
* amount is pointless, and setting `timestampOffset` at all can ripple edge segments.
* Relocation targets streams with an intentional large origin (instant clips, bipbop @10s).
*
* Absolute basis, not proportional: the DTS-below-zero / ripple risk scales with the
* origin's absolute size, not with the presentation's duration. Also snaps negatives to
* `0` — a negative origin would relocate *forward*, which is never the intent.
*/
export const NEAR_ZERO_ORIGIN_THRESHOLD = 1;
/** Snap a below-threshold (incl. negative) origin to `0` so it isn't relocated. */
function thresholdOrigin(origin: number): number {
return origin < NEAR_ZERO_ORIGIN_THRESHOLD ? 0 : origin;
}
/**
* The **default** — relocate the whole presentation by one shared origin: the `min`
* across the *selected* A/V tracks' own origins, denormalized onto every type. This
@@ -87,7 +106,8 @@ function ownOrigin(data: MediaContainerData | undefined): number | undefined {
* Returns `undefined` for every type until all *selected* types have a complete origin
* (the shared-`min` barrier). Which types must contribute is read from `ctx` (the
* selected v/a ids); with no selection context it coordinates across whatever types
* have data.
* have data. A shared origin below {@link NEAR_ZERO_ORIGIN_THRESHOLD} is returned as `0`
* (native — ordinary ~0-PTS VOD isn't relocated).
*/
export const deriveSharedMinStartMediaTime: DeriveStartMediaTime = (containerData, ctx) => {
const contributingTypes: string[] = [];
@@ -99,7 +119,7 @@ export const deriveSharedMinStartMediaTime: DeriveStartMediaTime = (containerDat
// Barrier: not ready until every contributing type has a complete origin.
if (origins.length === 0 || origins.some((origin) => origin === undefined)) return {};
const shared = Math.min(...(origins as number[]));
const shared = thresholdOrigin(Math.min(...(origins as number[])));
const out: Record<string, number | undefined> = {};
for (const type of Object.keys(containerData)) out[type] = shared;
return out;
@@ -113,7 +133,10 @@ export const deriveSharedMinStartMediaTime: DeriveStartMediaTime = (containerDat
*/
export const derivePerTypeStartMediaTime: DeriveStartMediaTime = (containerData) => {
const out: Record<string, number | undefined> = {};
for (const [type, data] of Object.entries(containerData)) out[type] = ownOrigin(data);
for (const [type, data] of Object.entries(containerData)) {
const origin = ownOrigin(data);
out[type] = origin === undefined ? undefined : thresholdOrigin(origin);
}
return out;
};
@@ -1,5 +1,9 @@
import { describe, expect, it } from 'vitest';
import { derivePerTypeStartMediaTime, deriveSharedMinStartMediaTime } from '../establish-start-media-time';
import {
derivePerTypeStartMediaTime,
deriveSharedMinStartMediaTime,
NEAR_ZERO_ORIGIN_THRESHOLD,
} from '../establish-start-media-time';
describe('deriveSharedMinStartMediaTime', () => {
const sel = { selectedVideoTrackId: 'v', selectedAudioTrackId: 'a' };
@@ -73,6 +77,43 @@ describe('deriveSharedMinStartMediaTime', () => {
)
).toEqual({ video: 9.956, audio: 9.956 });
});
it('leaves ordinary ~0-PTS VOD native: a shared origin below the threshold returns 0', () => {
// Both types carry a sub-second (0.5s) encode offset → not relocated.
expect(
deriveSharedMinStartMediaTime(
{
video: { timescale: 90000, baseMediaDecodeTime: 45000, segmentStartTime: 0 },
audio: { timescale: 48000, baseMediaDecodeTime: 24000, segmentStartTime: 0 },
},
sel
)
).toEqual({ video: 0, audio: 0 });
});
it('relocates at/above the threshold (the boundary is exclusive)', () => {
const atThreshold = {
video: { timescale: 90000, baseMediaDecodeTime: 90000 * NEAR_ZERO_ORIGIN_THRESHOLD, segmentStartTime: 0 },
audio: { timescale: 48000, baseMediaDecodeTime: 48000 * NEAR_ZERO_ORIGIN_THRESHOLD, segmentStartTime: 0 },
};
expect(deriveSharedMinStartMediaTime(atThreshold, sel)).toEqual({
video: NEAR_ZERO_ORIGIN_THRESHOLD,
audio: NEAR_ZERO_ORIGIN_THRESHOLD,
});
});
it('snaps a negative shared origin to 0 (never relocates forward)', () => {
// segmentStartTime > bmdt/ts → negative own origin.
expect(
deriveSharedMinStartMediaTime(
{
video: { timescale: 90000, baseMediaDecodeTime: 0, segmentStartTime: 5 },
audio: { timescale: 48000, baseMediaDecodeTime: 0, segmentStartTime: 5 },
},
sel
)
).toEqual({ video: 0, audio: 0 });
});
});
describe('derivePerTypeStartMediaTime', () => {
@@ -103,4 +144,16 @@ describe('derivePerTypeStartMediaTime', () => {
audio: undefined,
});
});
it('snaps a below-threshold origin to 0 independently per type', () => {
expect(
derivePerTypeStartMediaTime(
{
video: { timescale: 90000, baseMediaDecodeTime: 45000, segmentStartTime: 0 }, // 0.5s → 0
audio: { timescale: 48000, baseMediaDecodeTime: 48000 * 60, segmentStartTime: 0 }, // 60s → 60
},
{}
)
).toEqual({ video: 0, audio: 60 });
});
});