media: avoid bulk clamp on non-bulk uvc kernels
This commit is contained in:
parent
eb3b029071
commit
3318900d96
6
Cargo.lock
generated
6
Cargo.lock
generated
@ -1652,7 +1652,7 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2"
|
||||
|
||||
[[package]]
|
||||
name = "lesavka_client"
|
||||
version = "0.22.31"
|
||||
version = "0.22.32"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-stream",
|
||||
@ -1686,7 +1686,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "lesavka_common"
|
||||
version = "0.22.31"
|
||||
version = "0.22.32"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"base64",
|
||||
@ -1698,7 +1698,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "lesavka_server"
|
||||
version = "0.22.31"
|
||||
version = "0.22.32"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"base64",
|
||||
|
||||
@ -4,7 +4,7 @@ path = "src/main.rs"
|
||||
|
||||
[package]
|
||||
name = "lesavka_client"
|
||||
version = "0.22.31"
|
||||
version = "0.22.32"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "lesavka_common"
|
||||
version = "0.22.31"
|
||||
version = "0.22.32"
|
||||
edition = "2024"
|
||||
build = "build.rs"
|
||||
|
||||
|
||||
@ -313,7 +313,7 @@ from `LESAVKA_CLIENT_PKI_SSH_SOURCE` over SSH. Runtime clients require the insta
|
||||
| `LESAVKA_UVC_APP_MAX_BYTES` | server UVC appsrc memory guard; defaults to `4194304` queued bytes |
|
||||
| `LESAVKA_UVC_APP_MAX_TIME_NS` | server UVC appsrc memory guard; defaults to `200000000` ns of queued media |
|
||||
| `LESAVKA_UVC_BLOCKING` | server hardware/device override |
|
||||
| `LESAVKA_UVC_BULK` | UVC transfer-mode override; defaults to `1` so patched kernels prefer reliable bulk transfer over lossy isochronous MJPEG. Set `0` to force classic isochronous descriptors |
|
||||
| `LESAVKA_UVC_BULK` | UVC transfer-mode override; defaults to `1` so patched kernels prefer reliable bulk transfer over lossy isochronous MJPEG. If the live kernel does not expose `streaming_bulk`, Lesavka falls back to isochronous descriptors without the 512-byte bulk clamp. Set `0` to force classic isochronous descriptors |
|
||||
| `LESAVKA_UVC_BUFFER_COUNT` | UVC helper freshness override; number of queued gadget output buffers, defaults to `2` for live-call freshness |
|
||||
| `LESAVKA_UVC_BY_PATH_ROOT` | server hardware/device override |
|
||||
| `LESAVKA_UVC_CODEC` | server hardware/device override |
|
||||
|
||||
@ -181,8 +181,10 @@ flag_enabled() {
|
||||
esac
|
||||
}
|
||||
if flag_enabled "${LESAVKA_UVC_BULK:-1}"; then
|
||||
UVC_BULK_REQUESTED=1
|
||||
UVC_BULK=1
|
||||
else
|
||||
UVC_BULK_REQUESTED=
|
||||
UVC_BULK=
|
||||
fi
|
||||
UVC_CODEC=${LESAVKA_UVC_CODEC:-mjpeg}
|
||||
@ -294,18 +296,20 @@ compute_uvc_payload_cap() {
|
||||
UVC_PAYLOAD_CAP=$((bytes * pct / 100))
|
||||
}
|
||||
|
||||
compute_uvc_payload_cap
|
||||
if [[ -n $UVC_PAYLOAD_CAP && $UVC_PAYLOAD_CAP -gt 0 ]]; then
|
||||
log "UVC fifo periodic=${UVC_FIFO_PERIODIC:-?} np=${UVC_FIFO_NP:-?} cap=${UVC_PAYLOAD_CAP}B pct=${UVC_PAYLOAD_PCT:-?} src=${UVC_PAYLOAD_SRC:-?} udc=${UVC_UDC:-?}"
|
||||
if ((UVC_MAXPACKET > UVC_PAYLOAD_CAP)); then
|
||||
log "clamping UVC maxpacket $UVC_MAXPACKET -> $UVC_PAYLOAD_CAP"
|
||||
UVC_MAXPACKET=$UVC_PAYLOAD_CAP
|
||||
apply_uvc_payload_limits() {
|
||||
compute_uvc_payload_cap
|
||||
if [[ -n $UVC_PAYLOAD_CAP && $UVC_PAYLOAD_CAP -gt 0 ]]; then
|
||||
log "UVC fifo periodic=${UVC_FIFO_PERIODIC:-?} np=${UVC_FIFO_NP:-?} cap=${UVC_PAYLOAD_CAP}B pct=${UVC_PAYLOAD_PCT:-?} src=${UVC_PAYLOAD_SRC:-?} udc=${UVC_UDC:-?}"
|
||||
if ((UVC_MAXPACKET > UVC_PAYLOAD_CAP)); then
|
||||
log "clamping UVC maxpacket $UVC_MAXPACKET -> $UVC_PAYLOAD_CAP"
|
||||
UVC_MAXPACKET=$UVC_PAYLOAD_CAP
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
if [[ -n $UVC_BULK && $UVC_MAXPACKET -gt 512 ]]; then
|
||||
log "clamping UVC maxpacket $UVC_MAXPACKET -> 512 (bulk)"
|
||||
UVC_MAXPACKET=512
|
||||
fi
|
||||
if [[ -n $UVC_BULK && $UVC_MAXPACKET -gt 512 ]]; then
|
||||
log "clamping UVC maxpacket $UVC_MAXPACKET -> 512 (bulk)"
|
||||
UVC_MAXPACKET=512
|
||||
fi
|
||||
}
|
||||
if [[ -n ${LESAVKA_UVC_MJPEG:-} ]]; then
|
||||
UVC_CODEC=mjpeg
|
||||
fi
|
||||
@ -588,6 +592,19 @@ if [[ -z $DISABLE_UVC ]]; then
|
||||
# ----------------------- UVC function (usb‑video) ------------------
|
||||
mkdir -p "$G/functions/uvc.usb0"
|
||||
F="$G/functions/uvc.usb0"
|
||||
if [[ -n $UVC_BULK_REQUESTED ]]; then
|
||||
if [[ -e "$F/streaming_bulk" ]]; then
|
||||
UVC_BULK=1
|
||||
else
|
||||
# Some kernels do not expose the patched bulk-transfer knob. Falling
|
||||
# back to isochronous must also avoid the 512-byte bulk packet clamp;
|
||||
# otherwise MJPEG frames are much more likely to arrive truncated.
|
||||
log "UVC bulk requested but this kernel lacks streaming_bulk; using isochronous descriptors"
|
||||
UVC_BULK=
|
||||
UVC_MAXPACKET=${LESAVKA_UVC_MAXPACKET:-1024}
|
||||
fi
|
||||
fi
|
||||
apply_uvc_payload_limits
|
||||
echo "$UVC_STREAMING_INTERVAL" >"$F/streaming_interval"
|
||||
echo "$UVC_MAXPACKET" >"$F/streaming_maxpacket"
|
||||
echo "$UVC_MAXBURST" >"$F/streaming_maxburst"
|
||||
|
||||
@ -10,7 +10,7 @@ bench = false
|
||||
|
||||
[package]
|
||||
name = "lesavka_server"
|
||||
version = "0.22.31"
|
||||
version = "0.22.32"
|
||||
edition = "2024"
|
||||
autobins = false
|
||||
|
||||
|
||||
@ -669,7 +669,17 @@ fn uvc_frame_size_guard_enabled() -> bool {
|
||||
}
|
||||
|
||||
fn uvc_bulk_transfer_enabled() -> bool {
|
||||
env_flag_enabled("LESAVKA_UVC_BULK", true)
|
||||
if !env_flag_enabled("LESAVKA_UVC_BULK", true) {
|
||||
return false;
|
||||
}
|
||||
let base = std::path::Path::new(CONFIGFS_UVC_BASE);
|
||||
if base.exists() && !base.join("streaming_bulk").exists() {
|
||||
eprintln!(
|
||||
"[lesavka-uvc] UVC bulk requested but live configfs has no streaming_bulk; using isochronous payload sizing"
|
||||
);
|
||||
return false;
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
fn uvc_frame_size_for_active_mode(width: u32, height: u32, fps: u32) -> u32 {
|
||||
|
||||
@ -19,6 +19,8 @@ const UVC_DATA_SIZE: usize = 60;
|
||||
const UVC_STRING_CONTROL_IDX: u8 = 0;
|
||||
#[cfg(coverage)]
|
||||
const UVC_STRING_STREAMING_IDX: u8 = 1;
|
||||
#[cfg(coverage)]
|
||||
const CONFIGFS_UVC_BASE: &str = "/sys/kernel/config/usb_gadget/lesavka/functions/uvc.usb0";
|
||||
|
||||
#[cfg(coverage)]
|
||||
const USB_DIR_IN: u8 = 0x80;
|
||||
|
||||
@ -222,7 +222,14 @@ fn uvc_frame_size_guard_enabled() -> bool {
|
||||
|
||||
#[cfg(coverage)]
|
||||
fn uvc_bulk_transfer_enabled() -> bool {
|
||||
env_flag_enabled("LESAVKA_UVC_BULK", true)
|
||||
if !env_flag_enabled("LESAVKA_UVC_BULK", true) {
|
||||
return false;
|
||||
}
|
||||
let base = std::path::Path::new(CONFIGFS_UVC_BASE);
|
||||
if base.exists() && !base.join("streaming_bulk").exists() {
|
||||
return false;
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
#[cfg(coverage)]
|
||||
|
||||
@ -97,6 +97,9 @@ fn core_script_keeps_uvc_output_on_supported_mjpeg_descriptor() {
|
||||
"UVC codec '$UVC_CODEC' is not supported by the MJPEG UVC helper; using mjpeg",
|
||||
"UVC_CODEC=mjpeg",
|
||||
"flag_enabled \"${LESAVKA_UVC_BULK:-1}\"",
|
||||
"UVC bulk requested but this kernel lacks streaming_bulk; using isochronous descriptors",
|
||||
"apply_uvc_payload_limits",
|
||||
"UVC_MAXPACKET=${LESAVKA_UVC_MAXPACKET:-1024}",
|
||||
"uvc_mjpeg_frame_size_for_fps()",
|
||||
"UVC_MJPEG_BUDGET_BYTES_PER_SEC=${LESAVKA_UVC_MJPEG_BUDGET_BYTES_PER_SEC:-10000000}",
|
||||
"UVC_FRAME_SIZE=\"$(uvc_mjpeg_frame_size_for_fps \"$UVC_FPS\")\"",
|
||||
|
||||
@ -341,6 +341,14 @@ mod uvc_binary {
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn uvc_bulk_mode_is_tied_to_live_configfs_support() {
|
||||
let source = include_str!("../../../../server/src/bin/lesavka-uvc.real.inc");
|
||||
|
||||
assert!(source.contains("base.exists() && !base.join(\"streaming_bulk\").exists()"));
|
||||
assert!(source.contains("using isochronous payload sizing"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[serial]
|
||||
fn uvc_stats_snapshot_can_be_disabled_or_written() {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user