Sweep the pinned toolchain to Rust 1.97
The Windows UI needs current winsafe, whose real minimum is 1.89 (its manifest under-declares 1.87 while it uses NonNull::from_ref). Rather than stop at the minimum, this goes to current stable and fixes what that costs. The counter-intuitive result: 1.97 is CHEAPER than 1.89. libfreemkv had 54 clippy errors at 1.89 and 6 at 1.97, because clippy tightened the noisy collapsible_if lint in between. Stopping at the minimum would have been the most expensive choice available. Roughly 47 lints across the eight repos, the large majority auto-fixed: libfreemkv 6, freemkv-engine 14, bdemu 8, freemkv-keysources 7, autorip 6, freemkv-unlock 3, freemkv-i18n 3. The hand-fixed ones are a descending sort to sort_by_key(Reverse), four manual checked-division sites, a loop counter replaced by enumerate, and a loop whose first let-else became a while-let. Worth recording for whoever bumps next: clippy is MSRV-AWARE. Those 54 lints only appear once the crate DECLARES 1.89 or later, because let-chains become available. A bare `cargo +1.89 clippy` against a manifest still pinned at 1.87 reports clean and is meaningless — gate with the real precommit script, which is also the only thing that covers build scripts. The pin still sits below the Mac default, so it keeps doing its job: catching lint drift locally before CI sees it.
This commit is contained in:
@@ -195,11 +195,11 @@ impl Ac3Parser {
|
||||
// First access unit that starts in this PES's own bytes: adopt
|
||||
// this PES's timestamp so a genuine PTS jump is followed instead
|
||||
// of the running cadence drifting past it.
|
||||
if let Some(a) = &anchor {
|
||||
if start >= a.at {
|
||||
frame_pts_ns = a.pts_ns;
|
||||
anchor = None;
|
||||
}
|
||||
if let Some(a) = &anchor
|
||||
&& start >= a.at
|
||||
{
|
||||
frame_pts_ns = a.pts_ns;
|
||||
anchor = None;
|
||||
}
|
||||
let duration_ns = frame_duration_ns(remaining, bsid);
|
||||
pending = Some(PendingAu {
|
||||
|
||||
+11
-11
@@ -365,17 +365,17 @@ impl CodecParser for H264Parser {
|
||||
const HIGH_PROFILES: [u8; 14] = [
|
||||
100, 110, 122, 144, 244, 44, 83, 86, 118, 128, 138, 139, 134, 135,
|
||||
];
|
||||
if HIGH_PROFILES.contains(&profile_idc) {
|
||||
if let Some((chroma_fmt, depth_luma, depth_chroma)) = parse_sps_high_profile_ext(sps) {
|
||||
// byte 0: 111111xx — reserved(6) + chroma_format_idc(2)
|
||||
record.push(0xFC | (chroma_fmt & 0x03));
|
||||
// byte 1: 11111xxx — reserved(5) + bit_depth_luma_minus8(3)
|
||||
record.push(0xF8 | (depth_luma & 0x07));
|
||||
// byte 2: 11111xxx — reserved(5) + bit_depth_chroma_minus8(3)
|
||||
record.push(0xF8 | (depth_chroma & 0x07));
|
||||
// byte 3: num_of_sequence_parameter_set_ext (0 = none)
|
||||
record.push(0x00);
|
||||
}
|
||||
if HIGH_PROFILES.contains(&profile_idc)
|
||||
&& let Some((chroma_fmt, depth_luma, depth_chroma)) = parse_sps_high_profile_ext(sps)
|
||||
{
|
||||
// byte 0: 111111xx — reserved(6) + chroma_format_idc(2)
|
||||
record.push(0xFC | (chroma_fmt & 0x03));
|
||||
// byte 1: 11111xxx — reserved(5) + bit_depth_luma_minus8(3)
|
||||
record.push(0xF8 | (depth_luma & 0x07));
|
||||
// byte 2: 11111xxx — reserved(5) + bit_depth_chroma_minus8(3)
|
||||
record.push(0xF8 | (depth_chroma & 0x07));
|
||||
// byte 3: num_of_sequence_parameter_set_ext (0 = none)
|
||||
record.push(0x00);
|
||||
}
|
||||
|
||||
Some(record)
|
||||
|
||||
+18
-19
@@ -307,11 +307,10 @@ impl HevcParser {
|
||||
};
|
||||
let rbsp = strip_emulation_prevention(raw);
|
||||
let mut i = 0usize;
|
||||
loop {
|
||||
// payloadType: sum of 0xFF run + final byte.
|
||||
let Some(payload_type) = read_sei_ff_value(&rbsp, &mut i) else {
|
||||
break;
|
||||
};
|
||||
// payloadType: sum of 0xFF run + final byte. Exhausting the RBSP ends the
|
||||
// walk; the remaining `let ... else break` arms below handle a TRUNCATED
|
||||
// message, which is a different condition from a clean end.
|
||||
while let Some(payload_type) = read_sei_ff_value(&rbsp, &mut i) {
|
||||
// payloadSize: same ff-extension coding.
|
||||
let Some(payload_size) = read_sei_ff_value(&rbsp, &mut i) else {
|
||||
break;
|
||||
@@ -504,11 +503,11 @@ impl CodecParser for HevcParser {
|
||||
// 33-bit counter wrapped: add another period and re-check, rather
|
||||
// than treat the wrap as a backward clip reset.
|
||||
let mut unwrapped = raw_pts + self.pts_wrap_offset;
|
||||
if let Some(high) = self.high_pts {
|
||||
if high - unwrapped > PTS_WRAP_PERIOD / 2 {
|
||||
self.pts_wrap_offset += PTS_WRAP_PERIOD;
|
||||
unwrapped += PTS_WRAP_PERIOD;
|
||||
}
|
||||
if let Some(high) = self.high_pts
|
||||
&& high - unwrapped > PTS_WRAP_PERIOD / 2
|
||||
{
|
||||
self.pts_wrap_offset += PTS_WRAP_PERIOD;
|
||||
unwrapped += PTS_WRAP_PERIOD;
|
||||
}
|
||||
match self.high_pts {
|
||||
Some(high) if unwrapped < high - BACKSTEP_TICKS => {
|
||||
@@ -564,18 +563,18 @@ impl CodecParser for HevcParser {
|
||||
// `num_extra_slice_header_bits` — and thus the bit offset to
|
||||
// `slice_type` — is EXACT. With no PPS we decline rather than
|
||||
// guess, leaving coding `None` (honestly absent).
|
||||
if coding_type.is_none() && nal_type <= NAL_VCL_MAX {
|
||||
if let Some(num_extra) = self
|
||||
if coding_type.is_none()
|
||||
&& nal_type <= NAL_VCL_MAX
|
||||
&& let Some(num_extra) = self
|
||||
.cur_pps
|
||||
.as_deref()
|
||||
.and_then(hevc_num_extra_slice_header_bits)
|
||||
{
|
||||
coding_type = hevc_first_slice_coding_type(
|
||||
&data[nal_start..end],
|
||||
nal_type,
|
||||
num_extra,
|
||||
);
|
||||
}
|
||||
{
|
||||
coding_type = hevc_first_slice_coding_type(
|
||||
&data[nal_start..end],
|
||||
nal_type,
|
||||
num_extra,
|
||||
);
|
||||
}
|
||||
|
||||
match nal_type {
|
||||
|
||||
@@ -196,10 +196,10 @@ impl Mpeg2Parser {
|
||||
if let Some(h) = extract_seq_header(&data) {
|
||||
self.progressive_sequence = parse_progressive_sequence(&h);
|
||||
self.seq_header = Some(h);
|
||||
if let Some((num, den)) = self.frame_rate() {
|
||||
if num > 0 {
|
||||
self.frame_duration_ns = 1_000_000_000i64 * den as i64 / num as i64;
|
||||
}
|
||||
if let Some((num, den)) = self.frame_rate()
|
||||
&& num > 0
|
||||
{
|
||||
self.frame_duration_ns = 1_000_000_000i64 * den as i64 / num as i64;
|
||||
}
|
||||
}
|
||||
// A GOP header (0xB8) or a fresh sequence header (0xB3) starts a new GOP,
|
||||
|
||||
@@ -168,12 +168,12 @@ impl SparsePtsReorder {
|
||||
// (assumes both anchors sit at a similar relative display slot),
|
||||
// but each GOP re-locks its own origin, so the estimate only sets
|
||||
// intra-GOP spacing.
|
||||
if self.dur_ns == 0 {
|
||||
if let (Some((p_held, _)), Some((p_next, _))) = (held.anchor, gop.anchor) {
|
||||
let span = p_next - p_held;
|
||||
if span > 0 && held.count > 0 {
|
||||
self.dur_ns = (span / held.count).max(1);
|
||||
}
|
||||
if self.dur_ns == 0
|
||||
&& let (Some((p_held, _)), Some((p_next, _))) = (held.anchor, gop.anchor)
|
||||
{
|
||||
let span = p_next - p_held;
|
||||
if span > 0 && held.count > 0 {
|
||||
self.dur_ns = (span / held.count).max(1);
|
||||
}
|
||||
}
|
||||
out = self.emit_gop(held);
|
||||
|
||||
+43
-43
@@ -344,49 +344,49 @@ impl CodecParser for TrueHdParser {
|
||||
// mid-AU would snap that AU's PTS backward/forward and break the
|
||||
// monotonic +AU_DURATION_NS cadence (A/V drift). Once the buffer is empty
|
||||
// the next PES legitimately begins a new AU and seeds the base.
|
||||
if self.buf.is_empty() {
|
||||
if let Some(pts) = pes.pts {
|
||||
// Resync to the authoritative PES PTS. TrueHD AUs are a fixed
|
||||
// sample count (40 @ 48 kHz), so the per-AU `+AU_DURATION_NS`
|
||||
// cadence is sample-accurate — more so than the disc's per-PES
|
||||
// PTS, which carries the source muxer's own rounding jitter.
|
||||
//
|
||||
// Two distinct backward steps must be handled OPPOSITELY:
|
||||
//
|
||||
// 1. Small backward jitter (sub-second PES rounding): when the
|
||||
// buffer empties exactly on a PES boundary and that PES's PTS
|
||||
// lands a few ticks *below* the running cadence, an
|
||||
// unconditional reset would set the next AU's timestamp below
|
||||
// the AU just emitted, producing non-monotonic block
|
||||
// timestamps a muxer rejects. CLAMP to the running position so
|
||||
// output stays strictly monotonic.
|
||||
//
|
||||
// 2. Large backward step (> DISCONTINUITY_BACKSTEP_NS): this is a
|
||||
// clip-boundary PTS reset — the title's clips are read as one
|
||||
// concatenated stream and a non-seamless boundary resets the
|
||||
// source PES PTS near zero. This is NOT jitter and must NOT be
|
||||
// clamped: clamping strands the audio at the previous clip's
|
||||
// tail cadence, so when `TimelineContinuity` later bumps the
|
||||
// global offset for the new epoch (driven by the video
|
||||
// back-jump) the stranded-high audio PTS is flung ~a whole
|
||||
// clip past the frontier, producing the non-monotonic
|
||||
// audio-DTS band on multi-clip titles (Dune: Part Two, Top
|
||||
// Gun). ADOPT the raw reset so the per-track raw PTS that
|
||||
// reaches `TimelineContinuity` carries the true boundary, and
|
||||
// the corrector rebases it exactly as it already does for the
|
||||
// DTS / AC-3 parsers (which never clamp). Same threshold the
|
||||
// timeline corrector uses to classify a discontinuity.
|
||||
//
|
||||
// A genuine forward gap/discontinuity is always adopted by the
|
||||
// `.max()`.
|
||||
let new = pts_to_ns(pts);
|
||||
if new < self.next_pts_ns - DISCONTINUITY_BACKSTEP_NS {
|
||||
// Clip-boundary reset: take the raw PTS, restart the cadence.
|
||||
self.next_pts_ns = new;
|
||||
} else {
|
||||
// Within-clip jitter (or forward progression): stay monotonic.
|
||||
self.next_pts_ns = self.next_pts_ns.max(new);
|
||||
}
|
||||
if self.buf.is_empty()
|
||||
&& let Some(pts) = pes.pts
|
||||
{
|
||||
// Resync to the authoritative PES PTS. TrueHD AUs are a fixed
|
||||
// sample count (40 @ 48 kHz), so the per-AU `+AU_DURATION_NS`
|
||||
// cadence is sample-accurate — more so than the disc's per-PES
|
||||
// PTS, which carries the source muxer's own rounding jitter.
|
||||
//
|
||||
// Two distinct backward steps must be handled OPPOSITELY:
|
||||
//
|
||||
// 1. Small backward jitter (sub-second PES rounding): when the
|
||||
// buffer empties exactly on a PES boundary and that PES's PTS
|
||||
// lands a few ticks *below* the running cadence, an
|
||||
// unconditional reset would set the next AU's timestamp below
|
||||
// the AU just emitted, producing non-monotonic block
|
||||
// timestamps a muxer rejects. CLAMP to the running position so
|
||||
// output stays strictly monotonic.
|
||||
//
|
||||
// 2. Large backward step (> DISCONTINUITY_BACKSTEP_NS): this is a
|
||||
// clip-boundary PTS reset — the title's clips are read as one
|
||||
// concatenated stream and a non-seamless boundary resets the
|
||||
// source PES PTS near zero. This is NOT jitter and must NOT be
|
||||
// clamped: clamping strands the audio at the previous clip's
|
||||
// tail cadence, so when `TimelineContinuity` later bumps the
|
||||
// global offset for the new epoch (driven by the video
|
||||
// back-jump) the stranded-high audio PTS is flung ~a whole
|
||||
// clip past the frontier, producing the non-monotonic
|
||||
// audio-DTS band on multi-clip titles (Dune: Part Two, Top
|
||||
// Gun). ADOPT the raw reset so the per-track raw PTS that
|
||||
// reaches `TimelineContinuity` carries the true boundary, and
|
||||
// the corrector rebases it exactly as it already does for the
|
||||
// DTS / AC-3 parsers (which never clamp). Same threshold the
|
||||
// timeline corrector uses to classify a discontinuity.
|
||||
//
|
||||
// A genuine forward gap/discontinuity is always adopted by the
|
||||
// `.max()`.
|
||||
let new = pts_to_ns(pts);
|
||||
if new < self.next_pts_ns - DISCONTINUITY_BACKSTEP_NS {
|
||||
// Clip-boundary reset: take the raw PTS, restart the cadence.
|
||||
self.next_pts_ns = new;
|
||||
} else {
|
||||
// Within-clip jitter (or forward progression): stay monotonic.
|
||||
self.next_pts_ns = self.next_pts_ns.max(new);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -216,12 +216,11 @@ impl CodecParser for Vc1Parser {
|
||||
let end = find_next_sc(data, i + 4).unwrap_or(data.len());
|
||||
let sh = &data[i..end];
|
||||
// Try to parse resolution from advanced profile sequence header
|
||||
if self.seq_header.is_none() {
|
||||
if let Some((w, h)) = parse_vc1_resolution(sh) {
|
||||
if self.seq_header.is_none()
|
||||
&& let Some((w, h)) = parse_vc1_resolution(sh) {
|
||||
self.width = w;
|
||||
self.height = h;
|
||||
}
|
||||
}
|
||||
// Collect into a scratch Vec so handle_header can
|
||||
// append; we discard the Vec and only keep the flag.
|
||||
let mut scratch = Vec::new();
|
||||
@@ -250,12 +249,11 @@ impl CodecParser for Vc1Parser {
|
||||
}
|
||||
has_entry_point = true;
|
||||
}
|
||||
SC_FRAME => {
|
||||
SC_FRAME
|
||||
// Frame data starts at this start code
|
||||
if frame_start.is_none() {
|
||||
if frame_start.is_none() => {
|
||||
frame_start = Some(i);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
i += 4;
|
||||
|
||||
Reference in New Issue
Block a user