ci(lesavka): restore UVC guard hygiene baseline
This commit is contained in:
parent
b82694125e
commit
1d4077ab4f
@ -371,6 +371,7 @@ from `LESAVKA_CLIENT_PKI_SSH_SOURCE` over SSH. Runtime clients require the insta
|
||||
| `LESAVKA_UVC_MJPEG_PIXEL_GUARD_PARTIAL_SEAM_COVERAGE_PCT` | server MJPEG pixel-artifact guard threshold; minimum sampled-row coverage for partial-width mosaic/tile seams, default `32` |
|
||||
| `LESAVKA_UVC_MJPEG_PIXEL_GUARD_PARTIAL_SEAM_DELTA` | server MJPEG pixel-artifact guard threshold; sampled luma jump for partial-width mosaic/tile seams, default `28` |
|
||||
| `LESAVKA_UVC_MJPEG_PIXEL_GUARD_PARTIAL_SEAM_RUN_PCT` | server MJPEG pixel-artifact guard threshold; minimum contiguous sampled-row run for partial-width mosaic/tile seams, default `12` |
|
||||
| `LESAVKA_UVC_MJPEG_PIXEL_GUARD_PARTIAL_SEAM_BLOCK_STDDEV` | server MJPEG pixel-artifact guard threshold; maximum sampled-block luma variation for partial-width mosaic/tile seams, default `14` |
|
||||
| `LESAVKA_UVC_MJPEG_PIXEL_GUARD_SAMPLE_WIDTH` | server MJPEG pixel-artifact guard sampling width; defaults to `160` pixels and is clamped to `64..320` |
|
||||
| `LESAVKA_UVC_MJPEG_PIXEL_GUARD_SEAM_COVERAGE_PCT` | server MJPEG pixel-artifact guard threshold; minimum sampled-row coverage for hard horizontal tile seams, default `42` |
|
||||
| `LESAVKA_UVC_MJPEG_PIXEL_GUARD_SEAM_DELTA` | server MJPEG pixel-artifact guard threshold; sampled luma jump that marks a row as suspicious, default `34` |
|
||||
|
||||
@ -1308,7 +1308,7 @@
|
||||
"server/src/video_sinks/hevc_mjpeg_guard.rs": {
|
||||
"clippy_warnings": 0,
|
||||
"doc_debt": 0,
|
||||
"loc": 385
|
||||
"loc": 436
|
||||
},
|
||||
"server/src/video_sinks/hevc_mjpeg_guard/mjpeg_frame_inspection.rs": {
|
||||
"clippy_warnings": 0,
|
||||
@ -1323,22 +1323,17 @@
|
||||
"server/src/video_sinks/hevc_mjpeg_guard/mjpeg_visual_seams.rs": {
|
||||
"clippy_warnings": 0,
|
||||
"doc_debt": 0,
|
||||
"loc": 311
|
||||
},
|
||||
"server/src/video_sinks/hevc_mjpeg_guard/tests.rs": {
|
||||
"clippy_warnings": 0,
|
||||
"doc_debt": 7,
|
||||
"loc": 471
|
||||
"loc": 404
|
||||
},
|
||||
"server/src/video_sinks/mjpeg_spool.rs": {
|
||||
"clippy_warnings": 0,
|
||||
"doc_debt": 4,
|
||||
"loc": 396
|
||||
"loc": 443
|
||||
},
|
||||
"server/src/video_sinks/mjpeg_spool/audit.rs": {
|
||||
"clippy_warnings": 0,
|
||||
"doc_debt": 1,
|
||||
"loc": 226
|
||||
"doc_debt": 0,
|
||||
"loc": 287
|
||||
},
|
||||
"server/src/video_sinks/mjpeg_spool/tests.rs": {
|
||||
"clippy_warnings": 0,
|
||||
@ -1358,7 +1353,7 @@
|
||||
"server/src/video_sinks/webcam_sink/frame_handoff.rs": {
|
||||
"clippy_warnings": 0,
|
||||
"doc_debt": 4,
|
||||
"loc": 347
|
||||
"loc": 357
|
||||
},
|
||||
"server/src/video_sinks/webcam_sink/tests.rs": {
|
||||
"clippy_warnings": 0,
|
||||
|
||||
@ -311,6 +311,11 @@ pub(super) fn should_freeze_decoded_mjpeg(previous_bytes: u64, next_bytes: usize
|
||||
next_bytes < threshold_bytes
|
||||
}
|
||||
|
||||
/// Return the size-collapse reason for a decoded HEVC->MJPEG frame.
|
||||
///
|
||||
/// Inputs: last accepted decoded frame size and next frame size. Output: the
|
||||
/// collapse reason when the next frame is too small. Why: callers need the
|
||||
/// exact threshold for operator-visible diagnostics instead of a boolean.
|
||||
fn decoded_size_collapse_reason(
|
||||
previous_bytes: u64,
|
||||
next_bytes: usize,
|
||||
@ -427,5 +432,5 @@ pub(super) fn direct_mjpeg_reject_reason(
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "hevc_mjpeg_guard/tests.rs"]
|
||||
#[path = "hevc_mjpeg_guard/tests/mod.rs"]
|
||||
mod tests;
|
||||
|
||||
@ -138,6 +138,11 @@ fn row_bounds(frame: &SampledFrame) -> std::ops::Range<usize> {
|
||||
start..end.min(frame.height)
|
||||
}
|
||||
|
||||
/// Measure sampled luma variation inside a bounded rectangle.
|
||||
///
|
||||
/// Inputs: sampled frame and exclusive x/y bounds. Output: luma standard
|
||||
/// deviation, or `None` for empty regions. Why: partial seam detection should
|
||||
/// reject smooth fake tile blocks without punishing naturally textured edges.
|
||||
fn region_luma_stddev(
|
||||
frame: &SampledFrame,
|
||||
row_start: usize,
|
||||
@ -169,6 +174,11 @@ fn region_luma_stddev(
|
||||
Some((sum_sq / count_f - mean * mean).max(0.0).sqrt())
|
||||
}
|
||||
|
||||
/// Measure texture around a candidate partial-width seam.
|
||||
///
|
||||
/// Inputs: sampled frame, seam row, and candidate horizontal run. Output:
|
||||
/// standard deviation for the lower suspect block. Why: real scene detail can
|
||||
/// have a sharp edge, but damaged UVC tiles tend to be broad low-texture slabs.
|
||||
fn partial_seam_block_stddev(
|
||||
frame: &SampledFrame,
|
||||
row: usize,
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
//! Unit coverage for HEVC and direct-MJPEG corruption guard decisions.
|
||||
|
||||
#[test]
|
||||
fn hevc_jpeg_quality_defaults_to_moderate_transport_pressure() {
|
||||
temp_env::with_var_unset("LESAVKA_UVC_HEVC_JPEG_QUALITY", || {
|
||||
@ -128,6 +128,10 @@ pub(super) fn mjpeg_spool_audit_log_path(dir: &Path) -> PathBuf {
|
||||
.unwrap_or_else(|| dir.join("spool-audit.jsonl"))
|
||||
}
|
||||
|
||||
/// Hash an audited frame payload into a compact stable identifier.
|
||||
///
|
||||
/// Inputs: frame bytes. Output: lowercase FNV-1a hex digest. Why: audit JSONL
|
||||
/// should correlate frame files without embedding large binary payloads.
|
||||
fn fnv1a64_hex(data: &[u8]) -> String {
|
||||
let mut hash = FNV1A64_OFFSET;
|
||||
for byte in data {
|
||||
@ -199,6 +203,11 @@ fn format_audit_record(
|
||||
)
|
||||
}
|
||||
|
||||
/// Format one guard-rejected frame audit record.
|
||||
///
|
||||
/// Inputs: sequence, saved slot, rejected bytes, timing, filename, and reason.
|
||||
/// Output: one JSONL row. Why: rejected frames need the same timing/hash
|
||||
/// evidence as accepted frames so guard tuning can compare both paths.
|
||||
fn format_rejected_audit_record(
|
||||
sequence: u64,
|
||||
slot: u64,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user