Selkies

lib/present-meter

What reaches the screen, counted by the sink that shows the stream while a dashboard has its stats open: the frames handed to the compositor, how long after they arrived, and the frames that never were -- replaced by a newer one before a display refresh took them, or refused by a sink that could not take more.

A <video> sink says so itself: requestVideoFrameCallback reports the frames it hands on (presentationTime), and getVideoPlaybackQuality counts the frames it showed and those it dropped because a newer one replaced them first (watchVideo). Where the playback quality does the counting, the callback is asked for once every DELAY_SAMPLE_MS: each one makes the engine run the page's rendering steps for a frame it would otherwise composite without the page's thread. A canvas says nothing, so a draw counts as handed on at the next animation frame of the thread that drew it, and every draw before the last one ahead of that frame as replaced. Times are epoch milliseconds (performance.timeOrigin plus performance.now()), so an arrival stamped on the socket's thread compares with a presentation on whichever thread showed the frame.

Interfaces

PresentFigures

Defined in: lib/present-meter.js:36

What a meter counted since its last take.

Properties

presented
presented: number;

Defined in: lib/present-meter.js:37

Frames handed to the compositor.

delaySum
delaySum: number;

Defined in: lib/present-meter.js:38

Their receive-to-present delays, summed, in ms, over the delays of them whose arrival was known.

delays
delays: number;

Defined in: lib/present-meter.js:40

superseded
superseded: number;

Defined in: lib/present-meter.js:41

Frames replaced before a refresh took them.

refused
refused: number;

Defined in: lib/present-meter.js:42

Frames the sink refused.


PresentMeter

Defined in: lib/present-meter.js:46

Properties

drawn
drawn: (arg0) => void;

Defined in: lib/present-meter.js:47

A canvas draw of a frame that arrived at the given epoch time, NaN where that is unknown.

Parameters
ParameterType
arg0number
Returns

void

land
land: () => void;

Defined in: lib/present-meter.js:49

Counts the draws so far as handed on now; for a thread that draws inside its own animation frame.

Returns

void

presented
presented: (arg0, arg1) => void;

Defined in: lib/present-meter.js:51

Frames a sink handed on, and the receive-to-present delay of the newest in ms (NaN where unknown).

Parameters
ParameterType
arg0number
arg1number
Returns

void

superseded
superseded: (arg0) => void;

Defined in: lib/present-meter.js:54

Parameters
ParameterType
arg0number
Returns

void

refused
refused: () => void;

Defined in: lib/present-meter.js:55

Returns

void

take
take: () => PresentFigures;

Defined in: lib/present-meter.js:56

Returns

PresentFigures

reset
reset: () => void;

Defined in: lib/present-meter.js:57

Returns

void

Variables

DELAY_SAMPLE_MS

const DELAY_SAMPLE_MS: 100 = 100;

Defined in: lib/present-meter.js:33

Spacing, in ms, of the frames whose receive-to-present delay a <video> is sampled at once its playback quality counts what it shows.

Functions

createPresentMeter()

function createPresentMeter(nextFrame): PresentMeter;

Defined in: lib/present-meter.js:69

The counters one sink keeps. Self-contained by design: the video worker embeds this factory by toString(), so it references nothing in module scope.

Parameters

ParameterTypeDescription
nextFrame(arg0) => voidRuns a callback at the thread's next animation frame, or null where the thread has none, in which case a draw counts as handed on as it is made.

Returns

PresentMeter


watchVideo()

function watchVideo(
   video, 
   meter, 
   delayOf
): object;

Defined in: lib/present-meter.js:128

Follows a <video> sink until stopped. The frames it hands on are reported by requestVideoFrameCallback, whose receive-to-present delay goes to the meter; what it showed and dropped is read from getVideoPlaybackQuality, where a frame replaced by a newer one before a refresh counts as dropped, since Chromium counts such a frame in presentedFrames as well. Once that count moves, the delay is sampled from one frame every DELAY_SAMPLE_MS rather than every frame. Firefox keeps no playback quality for a live stream, so there every frame is followed and the frames the callback reports stand in for the frames shown. A new source restarts the element's counters, which is read as a restart rather than a count going backwards.

Parameters

ParameterTypeDescription
videoHTMLVideoElement-
meterPresentMeter-
delayOf(arg0) => numberThe receive-to-present delay, in ms, of the frame a callback reports; NaN where its arrival is unknown.

Returns

object

reported is whether the element has reported a frame since the call, which an engine without the callback never does; read gives the frames shown and dropped since the last read.

reported
reported: () => boolean;
Returns

boolean

stop
stop: () => void;
Returns

void

read
read: () => object;
Returns

object

shown
shown: number;
dropped
dropped: number;