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§
- Preview
Index - A background pass over a track that keeps a shrunk picture every
strideframes. - Preview
Options - How the index trades memory and pass length against how fine the scrub is.
- Preview
Pass - 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.
- Preview
Store - 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
scalexscaleblocks of an RGBA frame into one pixel each.