Keep both halves of a clip file that two play items share

A playlist may point at the same .m2ts from several play items — a
seamless split, a looped segment, multiple angles. The file has one set of
bytes, so it has one span, and the byte a frame was read from therefore
identifies the FILE, not which play item's range it falls in. Placement
took the first of them and judged every frame against its marks, so
everything past that range's end was treated as material the playlist
excludes and dropped: half the clip missing from the rip, with the
timeline still charged for its full duration.

The offset narrows a frame to the run; only its timestamp can finish the
job, and each play item carries its own marks. A frame is now matched
against the marks of the entry it actually falls in, falling back to the
first when it falls in none, which leaves genuinely-excluded material
dropped as before.

The test for this construction asserted only that such a playlist is
trusted, and never placed a frame from the second range — so the loss it
described in prose was invisible to it. It now places one from every range
and requires them all to survive.

The deferred-mux replay of buffered frames wrote them without their source
offset, quietly sending the head of every such title down the timestamp
heuristic the rest of this work exists to retire. It passes the offset
through now, and the frame writer that omits it is compiled out of the
library entirely: no production path can discard provenance any more.

Also: the AC-3 buffer-reuse test could not see the regression it named.
Feeding equal-sized packets, a fresh allocation per call yields the same
capacity as a reused one. It now feeds a large packet then a small one,
where only a reused buffer keeps the larger capacity.
This commit is contained in:
Matthew Jackson
2026-08-08 17:18:35 -07:00
parent dd749132d5
commit 109afcdcf7
4 changed files with 148 additions and 18 deletions
+33 -13
View File
@@ -853,20 +853,40 @@ mod tests {
"the buffer must be handed back to the parser, not dropped"
);
for _ in 0..8 {
parser.parse(&PesPacket {
source: None,
pid: 0x1100,
pts: None,
dts: None,
data: frame.clone(),
discontinuity: false,
});
}
// The discriminator: a LARGE packet, then a small one. A reused buffer
// keeps the large capacity; a fresh `Vec` sized to each packet drops
// back to the small one. Feeding equal-sized packets cannot tell those
// apart — the first version of this test did exactly that and a
// to_vec()-per-call implementation passed it.
let big = [frame.clone(), frame.clone(), frame.clone(), frame.clone()].concat();
parser.parse(&PesPacket {
source: None,
pid: 0x1100,
pts: None,
dts: None,
data: big.clone(),
discontinuity: false,
});
let cap_after_big = parser.scratch.capacity();
assert!(
parser.scratch.capacity() >= cap_after_first,
"capacity must persist across calls; a fresh Vec each time would \
show it dropping back to the last packet's size"
cap_after_big >= big.len(),
"the buffer must have grown to hold the large packet"
);
parser.parse(&PesPacket {
source: None,
pid: 0x1100,
pts: None,
dts: None,
data: frame.clone(),
discontinuity: false,
});
assert_eq!(
parser.scratch.capacity(),
cap_after_big,
"after a small packet the buffer must STILL hold the large \
capacity — a fresh allocation per call would have shrunk to the \
small packet's size"
);
}