Skip to content

Scrub stills on the software VOD path, and index-driven stills over a single connection #605

Description

@AttiK22

What should the engine do?

Follow-up to #544, which gave the live software path a scrub still from the DVR packet ring: this asks for the same on the VOD software path, plus index-driven stills outside the resident window.

Serve scrubThumbnail(atSeconds:) for VOD in two cases it currently returns nil for, without ever opening a second connection to the origin:

Software-path VOD, from the packet cache. 7.2.0 gave the live software path a scrub still decoded from the DVR packet ring. A software VOD session has the same kind of resident data ([SWHost] packet cache seek … result=hit resident_bytes=189835379 in my logs) but supportsCacheBackedStills is false and scrubThumbnail has no arm for it, so every VOD the device cannot hardware-decode (MPEG-4 Part 2, MPEG-2, interlaced H.264, and everything on the iOS Simulator where VideoToolbox has no HW decoder) scrubs blind.

Positions outside the resident window, over the same connection. The container index the session already parsed (mp4 moov sample tables, Matroska Cues) gives the byte range of the keyframe nearest any time. When the host asks for a still at a time the cache does not hold, the reader could fetch just that keyframe's bytes as a detour on the existing connection (the way seeks already do) and decode it: ~200-400 KB and one request, so ~300-600 ms to a frame. Optionally, while the pump is parked with a full forward buffer, the same mechanism could fill a keyframe index in the background (one keyframe every N seconds, byte-budgeted), so later scrubs are instant. A LoadOptions policy (off / on demand / background) and a byte budget would let hosts on metered links keep it off.

FrameExtractor cannot be the answer here: it opens its own demuxer, i.e. a second request, and IPTV accounts are commonly capped at one connection (maxConcurrentSourceRequests = 1, [OriginBudget] … one request budget for both (limit 1)), so a second request drops the main stream.

Motivating media or use case

KIPTV plays Xtream Codes VOD over HTTP/1.1 (one request per connection, per-account connection cap). We just shipped a YouTube-style seek bar with a scrub preview fed by scrubThumbnail on the native path; It works good but the two gaps above are what stop it from being "preview anywhere on the timeline": the software path shows nothing at all, and the native path only covers residentRanges (~40 s ahead by default). Raising forwardBufferSegments to cover the whole film would mean downloading 20 GB for a film the user may abandon after ten minutes, which is the wrong tool for a preview.

Sample: any H.264 1080p mp4 on the Simulator reproduces gap 1 ([VTProbe] canHardwareDecode codec=27 -> false (status=-12906) → software route). Engine 7.12.0, iOS 26/27 / tvOS 26/27.

Area

Public API surface

Host app / integration context

KIPTV (iOS / tvOS), Xtream Codes VOD over HTTP/1.1

Would you be willing to open a PR?

No

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions