Skip to main content

Module previews

Module previews 

Source
Expand description

A bounded preview tier over a track: one shrunk picture every N frames.

ExactFrameReader answers “which frame is this” exactly, and issue #395 measured what that costs at an arbitrary point of a track that codes its frames as one long group of pictures: the reader must decode every sample from the nearest random-access point, and on a 1080p HEVC track with one such point the last frame is over a second of hardware decode away. No arrangement of one decoder reaches 50 ms when the frame depends on 767 others.

What reaches 50 ms is a picture that was decoded already. A PreviewIndex decodes the track once, in the background, on a decoder of its own, and keeps every stride-th frame shrunk by PreviewOptions::scale. A drag then draws the nearest kept picture the moment the pointer moves - a lookup and a clone, no decoding at all - while a reader goes after the exact frame underneath it and replaces the preview when it lands. The two answer different questions: this one is “what is at this point of the movie”, which a scrub asks continuously and needs immediately, and the reader’s is “which frame is the pointer on”, which a committed scrub needs exactly and can wait for.

It is a tier, not a replacement: it costs one decode pass over the track and a bounded amount of memory, it is never frame-exact, and a caller that only ever asks for exact frames should not build one. The pass runs forwards from frame zero, which is the only order that is one pass rather than one walk per preview: each request continues from where the last left the reader. Until it reaches a point, a lookup there falls back to the nearest earlier preview, so the picture is progressively right rather than absent.

§What is portable, and what the driver is

The pass is a loop, and a loop needs somewhere to run. On native that is a thread of its own, which PreviewIndex owns and which is why it is gated to non-wasm32 targets. A browser has no thread to give it, so issue #432 split this module in two. Everything the loop operates on is portable and lives here: PreviewOptions and the stride it derives, the PreviewStore of pictures with its nearest-with-fallback lookup, and the PreviewPass cursor that says which frame the next preview is of and what becomes of the picture once something has decoded it. Only the driver is native-only - PreviewIndex’s thread here, against an idle-callback slice in crate::web_previews for the browser. Both fill the same store, and a PreviewStore is what ExactFrameReader::seek answers from on either target.

Structs§

PreviewIndex
A background pass over a track that keeps a shrunk picture every stride frames.
PreviewOptions
How the index trades memory and pass length against how fine the scrub is.
PreviewPass
The portable half of a preview pass: which frame the next preview is of, and what becomes of the picture once something has decoded it.
PreviewStore
The pictures a preview pass has decoded so far, shared between whatever is filling them in and whatever is answering seeks from them.

Functions§

shrink
Averages scale x scale blocks of an RGBA frame into one pixel each.