Stamp the last frames that were still leaving without provenance

A real rip caught these. The warning added for a track placed from
timestamps under a seam plan fired once, on one subtitle track of a
23-clip title, eighteen minutes in — a display set that arrives as a lone
non-PCS segment is emitted straight through rather than accumulated, and
that path still built its frame with source: None.

Auditing the rest the same way found four more: flac, lpcm, mpegaudio and
the passthrough parser. All are one-PES-one-frame, so the packet's own
facts are the unit's facts.

Every Frame construction in every codec parser now carries a source,
checked by walking balanced braces rather than by eye — the earlier
count was taken with a regex that cannot see a block containing nested
braces, which is how these survived the first pass.
This commit is contained in:
Matthew Jackson
2026-08-07 10:01:39 -07:00
parent 991977f297
commit 8ec71834dd
5 changed files with 31 additions and 5 deletions
+1 -1
View File
@@ -118,7 +118,7 @@ impl CodecParser for FlacParser {
vec![Frame { vec![Frame {
discontinuity: pes.discontinuity, discontinuity: pes.discontinuity,
coding: None, coding: None,
source: None, source: super::pesbuf::PesFacts::of(pes).source,
pts_ns, pts_ns,
keyframe: true, keyframe: true,
data: pes.data.clone(), data: pes.data.clone(),
+1 -1
View File
@@ -74,7 +74,7 @@ impl CodecParser for LpcmParser {
vec![Frame { vec![Frame {
discontinuity: false, discontinuity: false,
coding: None, coding: None,
source: None, source: super::pesbuf::PesFacts::of(pes).source,
pts_ns, pts_ns,
keyframe: true, keyframe: true,
data: pes.data[offset..].to_vec(), data: pes.data[offset..].to_vec(),
+1 -1
View File
@@ -154,7 +154,7 @@ impl CodecParser for PassthroughParser {
// parsers must instead defer the flag to the next emitted frame.) // parsers must instead defer the flag to the next emitted frame.)
vec![Frame { vec![Frame {
coding: None, coding: None,
source: None, source: pesbuf::PesFacts::of(pes).source,
pts_ns, pts_ns,
keyframe: self.keyframe, keyframe: self.keyframe,
discontinuity: pes.discontinuity, discontinuity: pes.discontinuity,
+1 -1
View File
@@ -116,7 +116,7 @@ impl CodecParser for MpegAudioParser {
vec![Frame { vec![Frame {
discontinuity: pes.discontinuity, discontinuity: pes.discontinuity,
coding: None, coding: None,
source: None, source: super::pesbuf::PesFacts::of(pes).source,
pts_ns, pts_ns,
keyframe: true, keyframe: true,
data: pes.data.clone(), data: pes.data.clone(),
+27 -1
View File
@@ -366,7 +366,10 @@ impl CodecParser for PgsParser {
out.push(Frame { out.push(Frame {
discontinuity: false, discontinuity: false,
coding: None, coding: None,
source: None, // Emitted straight from THIS packet, so its facts are
// this packet's -- the same rule as a pending set,
// which takes the facts of the packet that opened it.
source: super::pesbuf::PesFacts::of(pes).source,
pts_ns: pts.unwrap_or(0), pts_ns: pts.unwrap_or(0),
keyframe: true, keyframe: true,
data: pes.data.clone(), data: pes.data.clone(),
@@ -914,4 +917,27 @@ mod tests {
assert_eq!(t.facts().displays, u32::MAX); assert_eq!(t.facts().displays, u32::MAX);
assert_eq!(t.facts().forced_displays, u32::MAX); assert_eq!(t.facts().forced_displays, u32::MAX);
} }
/// A lone non-PCS segment with a PTS is emitted straight through rather
/// than accumulated, and it must still carry provenance. This path was
/// missed on the first pass and showed up on a real disc as a subtitle
/// track with no source offset -- the one track out of forty that could
/// not be placed by byte.
#[test]
fn a_lone_segment_emitted_directly_still_carries_provenance() {
let mut parser = PgsParser::new();
// A non-PCS segment (type 0x15 = ODS) with a PTS and no pending set.
let mut p = make_pes(vec![0x15, 0x00, 0x00, 0x00, 0x04, 1, 2, 3, 4], Some(90_000));
p.source = Some(crate::pes::SourcePos::at_byte(7_777));
let frames = parser.parse(&p);
assert!(
!frames.is_empty(),
"a lone segment with a PTS is passed through"
);
assert_eq!(
frames[0].source.map(|s| s.byte),
Some(7_777),
"emitted straight from this packet, so it carries this packet's offset"
);
}
} }