fix: allow proven software HEVC handoff
This commit is contained in:
parent
2d79a3144a
commit
e4a4ca1c9d
6
Cargo.lock
generated
6
Cargo.lock
generated
@ -1658,7 +1658,7 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2"
|
||||
|
||||
[[package]]
|
||||
name = "lesavka_client"
|
||||
version = "0.26.0"
|
||||
version = "0.26.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-stream",
|
||||
@ -1692,7 +1692,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "lesavka_common"
|
||||
version = "0.26.0"
|
||||
version = "0.26.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"base64",
|
||||
@ -1704,7 +1704,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "lesavka_server"
|
||||
version = "0.26.0"
|
||||
version = "0.26.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"base64",
|
||||
|
||||
@ -4,7 +4,7 @@ path = "src/main.rs"
|
||||
|
||||
[package]
|
||||
name = "lesavka_client"
|
||||
version = "0.26.0"
|
||||
version = "0.26.1"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "lesavka_common"
|
||||
version = "0.26.0"
|
||||
version = "0.26.1"
|
||||
edition = "2024"
|
||||
build = "build.rs"
|
||||
|
||||
|
||||
@ -110,6 +110,8 @@ if [[ -n "${LESAVKA_INSTALL_CAM_CODEC+x}" || -n "${LESAVKA_CAM_CODEC+x}" ]]; the
|
||||
fi
|
||||
REQUESTED_CAM_CODEC=${LESAVKA_INSTALL_CAM_CODEC:-${LESAVKA_CAM_CODEC:-hevc}}
|
||||
INSTALL_CAM_CODEC=$(normalize_cam_codec "${REQUESTED_CAM_CODEC}")
|
||||
INSTALL_HEVC_DECODER=${LESAVKA_INSTALL_HEVC_DECODER:-${LESAVKA_HEVC_DECODER:-}}
|
||||
INSTALL_ALLOW_SOFTWARE_VIDEO=${LESAVKA_INSTALL_ALLOW_SOFTWARE_VIDEO:-${LESAVKA_ALLOW_SOFTWARE_VIDEO:-0}}
|
||||
INSTALL_UPLINK_AUDIO_CODEC=${LESAVKA_INSTALL_UPLINK_AUDIO_CODEC:-${LESAVKA_UPLINK_AUDIO_CODEC:-pcm}}
|
||||
INSTALL_UVC_FRAME_META=${LESAVKA_INSTALL_UVC_FRAME_META:-${LESAVKA_UVC_FRAME_META:-0}}
|
||||
INSTALL_UVC_FRAME_META_LOG_PATH=${LESAVKA_INSTALL_UVC_FRAME_META_LOG_PATH:-${LESAVKA_UVC_FRAME_META_LOG_PATH:-/tmp/lesavka-uvc-frame-meta.jsonl}}
|
||||
@ -288,6 +290,29 @@ ensure_hevc_decode_support() {
|
||||
echo "✅ hardware HEVC decoder passed a real 1280x720 decode smoke: $hevc_decoder"
|
||||
else
|
||||
if [[ "$INSTALL_CAM_CODEC" == "hevc" ]]; then
|
||||
local software_hevc_decoder=""
|
||||
local software_hevc_smoke_log
|
||||
software_hevc_smoke_log=$(mktemp "${TMPDIR}/lesavka-hevc-software-decode-smoke.XXXXXX.log")
|
||||
for candidate in avdec_h265 libde265dec; do
|
||||
if gst-inspect-1.0 "$candidate" >/dev/null 2>&1 && timeout 20 bash -o pipefail -c \
|
||||
"gst-launch-1.0 -q videotestsrc num-buffers=30 ! video/x-raw,format=I420,width=1280,height=720,framerate=30/1 ! x265enc speed-preset=ultrafast tune=zerolatency key-int-max=30 ! h265parse disable-passthrough=true config-interval=-1 ! video/x-h265,stream-format=byte-stream,alignment=au ! ${candidate} ! videoconvert ! fakesink sync=false" \
|
||||
>"$software_hevc_smoke_log" 2>&1; then
|
||||
software_hevc_decoder=$candidate
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ -n "$software_hevc_decoder" && "$INSTALL_CAM_CODEC_EXPLICIT" == "0" ]]; then
|
||||
echo "⚠️ hardware HEVC decoder is exposed but the synthetic 1280x720 decode smoke failed: $hevc_decoder" >&2
|
||||
echo " smoke log: $hevc_smoke_log" >&2
|
||||
sed -n '1,120p' "$hevc_smoke_log" >&2 || true
|
||||
echo " Software HEVC decoder passed the same 1280x720 smoke: $software_hevc_decoder" >&2
|
||||
echo " Keeping default HEVC upstream to avoid direct-MJPEG UVC artifacts; monitor CPU/RSS during field runs." >&2
|
||||
INSTALL_HEVC_DECODER=$software_hevc_decoder
|
||||
INSTALL_ALLOW_SOFTWARE_VIDEO=1
|
||||
return 0
|
||||
fi
|
||||
|
||||
if [[ "$INSTALL_CAM_CODEC_EXPLICIT" == "0" ]]; then
|
||||
echo "⚠️ hardware HEVC decoder is exposed but the synthetic 1280x720 decode smoke failed: $hevc_decoder" >&2
|
||||
echo " smoke log: $hevc_smoke_log" >&2
|
||||
@ -299,6 +324,10 @@ ensure_hevc_decode_support() {
|
||||
echo "❌ hardware HEVC decoder is exposed but failed a real 1280x720 decode smoke: $hevc_decoder" >&2
|
||||
echo " smoke log: $hevc_smoke_log" >&2
|
||||
sed -n '1,120p' "$hevc_smoke_log" >&2 || true
|
||||
if [[ -n "$software_hevc_decoder" ]]; then
|
||||
echo " Software HEVC decoder passed: $software_hevc_decoder" >&2
|
||||
echo " To explicitly use it, rerun with LESAVKA_ALLOW_SOFTWARE_VIDEO=1 LESAVKA_HEVC_DECODER=$software_hevc_decoder." >&2
|
||||
fi
|
||||
echo " Refusing HEVC upstream install because production video decode must be hardware-accelerated and proven." >&2
|
||||
echo " Use LESAVKA_INSTALL_CAM_CODEC=mjpeg while the HEVC decoder stack is repaired." >&2
|
||||
exit 1
|
||||
@ -1604,6 +1633,10 @@ SERVER_ENV_TMP=$(mktemp)
|
||||
printf 'LESAVKA_CAM_OUTPUT=%s\n' "${LESAVKA_INSTALL_CAM_OUTPUT:-uvc}"
|
||||
printf 'LESAVKA_CAM_CODEC=%s\n' "${INSTALL_CAM_CODEC}"
|
||||
printf 'LESAVKA_UPLINK_CAMERA_CODEC=%s\n' "${INSTALL_CAM_CODEC}"
|
||||
if [[ -n "$INSTALL_HEVC_DECODER" ]]; then
|
||||
printf 'LESAVKA_HEVC_DECODER=%s\n' "$INSTALL_HEVC_DECODER"
|
||||
fi
|
||||
printf 'LESAVKA_ALLOW_SOFTWARE_VIDEO=%s\n' "${INSTALL_ALLOW_SOFTWARE_VIDEO}"
|
||||
printf 'LESAVKA_UPLINK_AUDIO_CODEC=%s\n' "${INSTALL_UPLINK_AUDIO_CODEC}"
|
||||
printf 'LESAVKA_CAM_WIDTH=%s\n' "${LESAVKA_CAM_WIDTH:-1920}"
|
||||
printf 'LESAVKA_CAM_HEIGHT=%s\n' "${LESAVKA_CAM_HEIGHT:-1080}"
|
||||
|
||||
@ -16,7 +16,7 @@ bench = false
|
||||
|
||||
[package]
|
||||
name = "lesavka_server"
|
||||
version = "0.26.0"
|
||||
version = "0.26.1"
|
||||
edition = "2024"
|
||||
autobins = false
|
||||
|
||||
|
||||
@ -263,8 +263,10 @@ fn server_install_pins_hdmi_camera_and_display_defaults() {
|
||||
"install script should try the Raspberry Pi HEVC decoder before requiring another hardware decoder"
|
||||
);
|
||||
assert!(
|
||||
SERVER_INSTALL.contains("will not fall back to avdec_h265 in production"),
|
||||
"install script should fail loud instead of silently using software HEVC decode"
|
||||
SERVER_INSTALL.contains("Software HEVC decoder passed the same 1280x720 smoke")
|
||||
&& SERVER_INSTALL.contains("LESAVKA_HEVC_DECODER")
|
||||
&& SERVER_INSTALL.contains("LESAVKA_ALLOW_SOFTWARE_VIDEO"),
|
||||
"install script should make software HEVC fallback explicit and smoke-proven"
|
||||
);
|
||||
assert!(
|
||||
SERVER_INSTALL.contains("hardware HEVC decoder passed a real 1280x720 decode smoke")
|
||||
@ -288,7 +290,7 @@ fn server_install_pins_hdmi_camera_and_display_defaults() {
|
||||
SERVER_INSTALL.contains("Refusing HEVC upstream install because production video decode must be hardware-accelerated and proven")
|
||||
&& SERVER_INSTALL.contains("Use LESAVKA_INSTALL_CAM_CODEC=mjpeg while the HEVC decoder stack is repaired")
|
||||
&& SERVER_INSTALL.contains("Default HEVC upstream cannot be proven on this host; falling back to MJPEG ingress."),
|
||||
"explicit HEVC installs should fail loud while default HEVC installs can safely fall back"
|
||||
"explicit HEVC installs should fail loud while default HEVC installs can use proven fallback paths"
|
||||
);
|
||||
assert!(
|
||||
!SERVER_INSTALL
|
||||
|
||||
@ -4,8 +4,8 @@
|
||||
// explicit, while still allowing operator-provided install overrides.
|
||||
// Targets: server/client install scripts and client camera capture defaults.
|
||||
// Why: Lesavka now supports both MJPEG and HEVC upstream media, and installer
|
||||
// reruns may prefer HEVC only when hardware decode is proven, and must fall
|
||||
// back to MJPEG instead of producing black frames when it is not.
|
||||
// reruns may prefer HEVC when decode is proven, falling back to either a
|
||||
// smoke-tested software HEVC decoder or MJPEG instead of producing black frames.
|
||||
|
||||
const SERVER_INSTALL: &str = include_str!(concat!(
|
||||
env!("CARGO_MANIFEST_DIR"),
|
||||
@ -27,8 +27,13 @@ fn server_install_defaults_to_hevc_ingress_with_mjpeg_fallback_and_mjpeg_uvc_out
|
||||
"REQUESTED_CAM_CODEC=${LESAVKA_INSTALL_CAM_CODEC:-${LESAVKA_CAM_CODEC:-hevc}}",
|
||||
"INSTALL_CAM_CODEC=$(normalize_cam_codec \"${REQUESTED_CAM_CODEC}\")",
|
||||
"INSTALL_CAM_CODEC_EXPLICIT=0",
|
||||
"INSTALL_HEVC_DECODER=${LESAVKA_INSTALL_HEVC_DECODER:-${LESAVKA_HEVC_DECODER:-}}",
|
||||
"INSTALL_ALLOW_SOFTWARE_VIDEO=${LESAVKA_INSTALL_ALLOW_SOFTWARE_VIDEO:-${LESAVKA_ALLOW_SOFTWARE_VIDEO:-0}}",
|
||||
"Software HEVC decoder passed the same 1280x720 smoke",
|
||||
"Default HEVC upstream cannot be proven on this host; falling back to MJPEG ingress.",
|
||||
"printf 'LESAVKA_CAM_CODEC=%s\\n' \"${INSTALL_CAM_CODEC}\"",
|
||||
"printf 'LESAVKA_HEVC_DECODER=%s\\n' \"$INSTALL_HEVC_DECODER\"",
|
||||
"printf 'LESAVKA_ALLOW_SOFTWARE_VIDEO=%s\\n' \"${INSTALL_ALLOW_SOFTWARE_VIDEO}\"",
|
||||
"printf 'LESAVKA_UVC_CODEC=%s\\n' \"${INSTALL_UVC_CODEC}\"",
|
||||
"\"LESAVKA_UVC_CODEC=${INSTALL_UVC_CODEC}\"",
|
||||
"uvc_env_value LESAVKA_UVC_WIDTH 1280",
|
||||
@ -83,7 +88,8 @@ fn hevc_prerequisites_are_rechecked_idempotently() {
|
||||
"modprobe rpi_hevc_dec",
|
||||
"/etc/modules-load.d/lesavka-hevc.conf",
|
||||
"gst-inspect-1.0 v4l2slh265dec",
|
||||
"will not fall back to avdec_h265 in production",
|
||||
"avdec_h265 libde265dec",
|
||||
"Keeping default HEVC upstream to avoid direct-MJPEG UVC artifacts",
|
||||
"Refusing HEVC upstream install because production video decode must be hardware-accelerated and proven",
|
||||
] {
|
||||
assert!(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user