Highlights
Manifest header for .sup streams (opt-in)
libpgs stream now accepts a --with-header flag that, for .sup inputs, prepends a single NDJSON record carrying pre-scanned display-set counts:
{"type":"header","total_display_sets":1823,"total_content_display_sets":1456,"total_clear_display_sets":367}This lets downstream consumers show a progress denominator (e.g. 347/1823) from the first record instead of waiting until the stream finishes. The pre-scan walks only 13-byte segment headers (plus tiny PCS payloads) and seeks over other payloads — typically under a second even on multi-GB files. The flag is opt-in so default stream invocations pay no upfront latency.
Containers (MKV, M2TS) ignore the flag: counting there would require a full demux, and MKV already surfaces per-track display_set_count via the existing tracks line when Tags are present.
Faster NDJSON streaming for dense subtitles
Per-line emission in libpgs stream was reworked to assemble each NDJSON line into a reused scratch buffer and issue a single chunked write_all + flush per line. This keeps pipe consumers fast on Windows (where a single large pipe write can block the producer) and collapses many small write! calls into one allocation per line.
New Extractor::with_history(bool) opt-out
Callers that exhaust the iterator in a single pass can now disable the internal history catalog to avoid cloning every yielded display set:
let extractor = Extractor::open(path)?.with_history(false);The libpgs stream CLI uses this internally since it never re-reads history.