Decode the dependencies before selecting the clip
Separate demuxing, packet/frame flow, random-access entry points, reordering, decoder draining, and presentation-time clip selection.
On this page
The question for today
What you’ll understand
- Explain why a selected frame can require compressed data outside the target clip.
- Distinguish seeking to an entry point from returning the exact target frame.
- Test reordered and delayed output without assuming one packet produces one image.
Compressed video stores dependencies rather than a bag of independently readable images. Extracting a short clip can require seeking earlier, decoding reference pictures, and reading later-presented references before the desired images are available. A pipeline that counts packets as frames or stops at a timestamp boundary too early can omit or corrupt valid samples. Build the extraction contract around actual decoder behavior and presentation timestamps, while recording how much extra work random access requires.
Demux packets and receive all available decoded frames
A demuxer separates encoded packets by stream. A decoder consumes those packets under its API contract and can produce zero, one, or several frames in response; it can also buffer frames before output. FFmpeg 7.1 documents send/receive behavior and end-of-stream draining. PyAV v14.2.0's decode path iterates over packet decoding results and includes flushing packets at the end. An implementation that assumes exactly one image for each packet is therefore structurally wrong even before considering sampling policy.
Keep compressed-byte I/O, CPU decode, color conversion, resizing, and model transfer as separate measured stages. A slow extraction can be caused by remote seeks or repeated reference decoding rather than by the model. Hardware and software decoders can have different support and numerical image outputs, so record the selected path and relevant color/range/orientation handling. A successful frame count does not prove that the pixel interpretation or timing matches the intended dataset.
Seek to a valid entry point, then decode to the target
PyAV's pinned seek documentation describes offsets in stream timebase units when a stream is supplied, otherwise in the container's defined unit, followed by decoding toward the desired position. The seek result is not a promise that the next image has exactly the requested PTS. Start from an appropriate random-access entry point supported by the format and codec, rebuild the required state, and select decoded frames by the stated presentation-time rule.
GOP structure matters because some pictures reference others outside the requested presentation interval. A validated closed independent segment is different from an arbitrary I-picture or keyframe flag in an open dependency structure. Do not claim that every such flag guarantees independent extraction across all codecs. Test the actual source class, seek behavior, and boundary artifacts. When the target is near the end, drain delayed decoder output according to its API rather than assuming the final packet has already yielded every relevant frame.
Compare random-access extraction with a sequential oracle
Use a small source with known reordered pictures, a long interval between independent entry points, and a clip beginning between them. Compare random-access extraction with a complete sequential decode using the same frame-selection rule and pixel oracle. Record actual selected PTS values and whether delayed frames were drained. Repeated extraction should also expose leaked decoder state after a seek, unsupported streams, and corrupt-input handling instead of returning silently shortened clips.
The cache lab isolates repeated working-set access as one reason locality can matter. Reset, set both C=4,s=4, predict twelve hits in sixteen initial requests, then Play or Step. Reset and set both C=3,s=4 for zero initial hits. The stream caps at 4,096 requests and edits retain time. It contains no codec, GOP, seek, decode dependencies, or pixel conversion; its automatic LRU eviction does not imply real reference pictures can be discarded without correctness or recomputation costs.
Work it through
Decode references outside the selected presentation interval
A fictional independent four-picture segment presents [I0,B1,B2,P3]. B1 and B2 each require I0 and P3; packet decode order is [I0,P3,B1,B2]. A sequential extraction fixture decodes all four and drains output before selecting pictures presented at ordinals one and two.
The desired output is B1 and B2, but their stated reference dependencies include I0 and P3. P3 lies after them in presentation order and still must be decoded first.
Following the stipulated input order consumes four picture-bearing packets in this simplified fixture. It is not valid to feed only the two desired B pictures or reorder input to presentation order.
After decoding and draining as required, select B1 and B2 by their presentation identifiers. This fixture decodes four pictures to return two; it does not assert that every real packet contains exactly one picture.
The selected two pictures depend on work outside their presentation interval. Random-access cost and decode correctness cannot be inferred from desired output count alone.
The living notebook
Explore the model
Interactive lab · cache
Inspect locality without treating the model as a decoder
Fresh Reset → set both C=4,s=4 predicts twelve initial hits; Reset → set both C=3,s=4 predicts zero. Play or Step extends the sixteen-request trace up to 4,096. This LRU model has no packets, GOP boundaries, references, seeks, or decoder draining.
- Hits / requests
- 0 / 16
- Hit rate
- 0%
- Address-stream period
- 16 addresses
A fully associative LRU cache starts empty and requests address (i·s) mod 16. Hits move an address to the newest position; misses evict the oldest when full. Playback starts with 16 requests and adds two per second, capped at 4096 explicitly simulated requests. This toy stream is not a processor-cache benchmark. Parameter changes pause playback and recompute the model at the current elapsed time. Reset restores both parameters and returns time to zero. Playback starts paused. Adjust either parameter, then choose Play or Step.
Look forRepeated access can change work, but compressed-video dependencies require their own validated extraction path.
Pause & reason
Check your understanding
Your turn
Try it yourself
A validated independent entry point is at media time 8 s, while the desired clip is [9.2,9.6) s. A decoder returns frames before 9.2 after the seek. Are they necessarily a bug, and what should the extractor compare against its sequential oracle?
Take a moment to make a prediction or work it out on paper. Open a hint when you need one.
Give me a hint
Entry-point decoding and selected presentation interval are different sets. The oracle should use the same source-time rule.
Compare with the solution
Earlier returned frames are expected when decoding forward from the eight-second entry point to reconstruct state. The extractor should retain only frames satisfying the declared [9.2,9.6) presentation rule, while consuming any additional dependencies needed to produce them. Compare their actual PTS/timebase pairs and the chosen pixel-equivalence criterion with sequential decoding. Simply dropping early encoded packets before decoding could destroy the references needed by the target frames.
Keep the idea
Take it with you
- Packets, decoded frames, and selected clip images are different units.
- Random access must rebuild actual codec dependencies before exact presentation-time selection.
- Sequential fixtures should verify seeking, reordering, draining, and pixel/timestamp interpretation.
Read further
Original sources and deeper explanations to follow at your own pace.
Optional progress, saved in this browser when available. Revisit any lesson at any time.
Lesson not marked complete.