← Video Compression · Bench Notes 01

I, P and B frames

A compressed video is not a stack of pictures. It is one picture plus a long list of instructions for changing it. Everything else — GOP size, B-frame count, seek behaviour, latency, why a dropped packet smears green across your screen — falls out of that one idea. Turn the knobs below and watch it happen.

codec-agnostic model
{{ fpsLabel }} · {{ totalLabel }} frames
gstreamer mappings included
I intra · keyframe

Coded entirely from itself. No other frame is consulted, so it is the only frame you can hand a decoder cold.

Analogy: the full JPEG. Expensive to store, but it is the door into the stream.

≈ {{ statI }} · {{ shareI }} of all bits
P predicted · forward

Stores only what changed since earlier frames: block motion vectors plus a small residual for what motion could not explain.

Analogy: a diff against the last commit. Useless without the commit it was diffed against.

≈ {{ statP }} · {{ shareP }} of all bits
B bi-predicted · both ways

Predicts from a past and a future frame, averaging the two. Cheapest frame in the stream by a wide margin.

Analogy: interpolating between two known states. To do it, the encoder must send the future first — which costs latency.

≈ {{ statB }} · {{ shareB }} of all bits

01 · Encoder controls

every panel below reacts to these
{{ sl.label }} {{ sl.display }}
{{ sl.hint }}
rate control
{{ rcHint }}

02 · The GOP

bar height = coded size of that frame · click any frame to inspect it
{{ modeBlurb }}
{{ g.label }}
{{ f.type }}
{{ f.i }}
{{ f.flag }}
{{ r.label }}
{{ r.value }}
{{ r.note }}

03 · Decode order ≠ display order

step the decoder and watch the reorder buffer fill
{{ row.label }} {{ row.sub }}
{{ c.text }}
dts {{ dtsLabel }} → pts {{ ptsLabel }} · buffer holds {{ bufNow }} frame(s) now, {{ bufMax }} at peak
{{ latencyNote }}
why it must be this way

A B frame leans on a frame that comes after it on screen. So the encoder ships that future anchor early, and the decoder holds finished pictures back until their turn arrives.

That hold is why every container carries two clocks: DTS for when to decode, PTS for when to show.

Set B frames to 0 and the two orders collapse into one — the configuration every low-latency conferencing pipeline ships.

04 · Inside frame {{ selIdx }}

motion vectors and residual for the frame you selected above
reference {{ refLabel }}
frame {{ selIdx }} · {{ selType }} · source
{{ resTitle }}
{{ selSize }}
coded size

{{ inspectorText }}

refs: {{ selRefs }}
coded intra: {{ selIntra }}
referenced by: {{ selDeps }}
motion vector per 32px block bright residual = motion could not explain it, so those coefficients cost bits synthetic scene · a real scene cut happens at frame {{ cutFrame }}

05 · The same settings, as a pipeline

these strings track the controls above — copy and run
{{ p.name }}
{{ p.cmd }}
concept
x264enc
nvh264enc
what it costs you
{{ r.concept }}
{{ r.sw }}
{{ r.nv }}
{{ r.cost }}
Take one

GOP size is a trade between bitrate and entry points. Long GOP is efficient and cheap; it also means a player joining mid-stream waits, and a lost frame stays broken until the next I.

Take two

B frames buy you bitrate with latency. Great for VOD and streaming ladders, wrong for conferencing, remote desktop, or anything a human steers in real time.

Take three

Frame type decides what a dropped packet destroys. Lose a B and nobody notices; lose an anchor and everything leaning on it smears until the next refresh.