Document the forced-probe redesign in the changelog
This commit is contained in:
@@ -4,6 +4,37 @@
|
|||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
|
- **Content-based forced-subtitle detection never observed anything on a
|
||||||
|
feature-length disc.** The PGS probe spent its entire 256 MiB budget on the
|
||||||
|
first sectors of a title, where a feature has no subtitles at all — it hit
|
||||||
|
the budget, observed zero display sets, and contributed nothing to any
|
||||||
|
verdict, so the vendor label was always the only input. The same budget is
|
||||||
|
now SPREAD across each extent as ~16 MiB sample windows sized in proportion
|
||||||
|
to the extent (still on the AACS aligned-unit grid, still bounded by the same
|
||||||
|
ceiling): a track is disproven by any single non-forced display set anywhere,
|
||||||
|
and a genuine forced track is small enough to be caught by the spread. Cost
|
||||||
|
is unchanged; placement is not. The probe also stops spending budget on a
|
||||||
|
track the moment it is disproven, and skips an extent that owes evidence only
|
||||||
|
for such tracks.
|
||||||
|
- **A partially-read extent's evidence was memoised as if the whole extent had
|
||||||
|
been read.** A budget-cut (and now sampled) read covers a fraction of an
|
||||||
|
extent, but its result was filed under the extent's full key and replayed to
|
||||||
|
every other playlist sharing the clip — turning a prefix into an absence
|
||||||
|
claim about the whole extent. Cache entries now carry the coverage behind
|
||||||
|
them, and an entry only answers for a run that intended to read no more than
|
||||||
|
it did. Positive evidence (a non-forced display set was seen) still answers
|
||||||
|
regardless, being irretractable.
|
||||||
|
- **Content could never correct a wrong vendor forced label.** The muxer only
|
||||||
|
ever promoted `FlagForced` 0 → 1, so a track labelled forced stayed forced in
|
||||||
|
the output even when the mux had seen every one of its two thousand display
|
||||||
|
sets and not one was forced. Content may now clear the flag too — in the
|
||||||
|
muxer and in the scan-time probe — behind a single shared guard: the absence
|
||||||
|
of `forced_on_flag` means nothing on a disc whose authoring never sets it, so
|
||||||
|
a demotion requires that some other track demonstrably uses the flag AND that
|
||||||
|
the track have the shape of a full dialogue track rather than of a
|
||||||
|
forced-narrative one. Where no track on the disc uses the flag, nothing is
|
||||||
|
demotable.
|
||||||
|
|
||||||
- **An `.fvi` index named itself as its own source.** The `fvi://` sink was
|
- **An `.fvi` index named itself as its own source.** The `fvi://` sink was
|
||||||
handed the DESTINATION path as its `source_path`, so every index reported
|
handed the DESTINATION path as its `source_path`, so every index reported
|
||||||
`source.path` as the file it was writing. `source.medium` was always `file`
|
`source.path` as the file it was writing. `source.medium` was always `file`
|
||||||
|
|||||||
@@ -6,11 +6,24 @@
|
|||||||
//! streams and feeding them through the one shared classifier
|
//! streams and feeding them through the one shared classifier
|
||||||
//! ([`crate::mux::codec::pgs::ForcedTracker`]) — so the two never diverge.
|
//! ([`crate::mux::codec::pgs::ForcedTracker`]) — so the two never diverge.
|
||||||
//!
|
//!
|
||||||
//! Cost: a track is only confirmed forced once EVERY display set is seen to be
|
//! WHERE it reads is the whole design. A track is forced iff EVERY display set
|
||||||
//! forced, so a disc that has a forced track is read through — the
|
//! carries `forced_on_flag`, so one non-forced set disproves forced for good,
|
||||||
//! accuracy-over-speed tradeoff `info` opts into. Full tracks early-exit as soon
|
//! while proving forced needs the whole track — and the tracks that are
|
||||||
//! as they show a single non-forced subtitle, and a whole run stops early once
|
//! expensive to prove are the cheap ones to read (a forced-narrative track is
|
||||||
//! every track has settled.
|
//! tens of display sets; a full dialogue track is thousands). A bounded budget
|
||||||
|
//! spent on the title's HEAD therefore learns nothing at all: a feature's
|
||||||
|
//! subtitles begin minutes in, past the end of any affordable prefix. The budget
|
||||||
|
//! ([`PROBE_BUDGET_SECTORS`]) is instead SPREAD over each extent as sample
|
||||||
|
//! windows ([`plan_windows`]), so every window is an independent chance to catch
|
||||||
|
//! a display set.
|
||||||
|
//!
|
||||||
|
//! Cost: the budget is a hard ceiling per call. A run stops early once no track
|
||||||
|
//! can still change its outcome — disproven, and with no wrong forced label left
|
||||||
|
//! to correct.
|
||||||
|
//!
|
||||||
|
//! Contradicting a label: content may CLEAR a vendor forced flag as well as set
|
||||||
|
//! one, but only behind [`crate::mux::codec::pgs::demotable`] — an absence of
|
||||||
|
//! `forced_on_flag` proves nothing on a disc whose authoring never sets it.
|
||||||
//!
|
//!
|
||||||
//! Encrypted content: the probe reuses whatever [`SectorSource`] the scan holds.
|
//! Encrypted content: the probe reuses whatever [`SectorSource`] the scan holds.
|
||||||
//! With a decrypting source it sees real PGS; without keys it reads ciphertext
|
//! With a decrypting source it sees real PGS; without keys it reads ciphertext
|
||||||
|
|||||||
Reference in New Issue
Block a user