Documents what the rig proved and what it found, adds the hardware sign-off script for the Hyprland machine and an (untested) Windows validation script, and updates CI to build the cached OBS runtime, run tests and lint the Windows code paths.
85 lines
3.5 KiB
Bash
Executable File
85 lines
3.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Hardware sign-off for Linux: run from a real desktop session (Hyprland,
|
|
# another Wayland compositor, or X11) on the machine being validated.
|
|
#
|
|
# scripts/validate/linux-hardware.sh [output-dir]
|
|
#
|
|
# Records at 1440p60 with every usable hardware codec, checks the segments,
|
|
# confirms the portal restores its selection without asking again, and
|
|
# records a window. Writes report.txt in the output directory.
|
|
set -uo pipefail
|
|
|
|
repo="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
|
out="${1:-${TMPDIR:-/tmp}/clipbin-hardware}"
|
|
probe="${repo}/target/debug/clipbin-probe"
|
|
report="${out}/report.txt"
|
|
rm -rf "${out}" && mkdir -p "${out}"
|
|
format=(--width 2560 --height 1440 --fps 60 --bitrate 40000)
|
|
|
|
cargo build --locked -p clipbin-probe --manifest-path "${repo}/Cargo.toml" || exit 1
|
|
|
|
log() { echo "$*" | tee -a "${report}"; }
|
|
ask() {
|
|
local answer
|
|
read -r -p "$1 [y/n] " answer
|
|
log "answer: $1 -> ${answer}"
|
|
}
|
|
|
|
log "Clipbin hardware validation $(date -Is)"
|
|
log "host: $(uname -r) session=${XDG_SESSION_TYPE:-?} desktop=${XDG_CURRENT_DESKTOP:-?}"
|
|
log "gpu: $(lspci 2>/dev/null | grep -iE 'vga|display' | cut -d: -f3- | xargs)"
|
|
|
|
"${probe}" encoders --verify "${format[@]}" --out "${out}/encoders" > "${out}/encoders.log" 2> "${out}/encoders.obs.log"
|
|
log "$(grep -E '^(obs_version|usable\.|verify\.)' "${out}/encoders.log")"
|
|
|
|
token=""
|
|
for codec in h264 hevc av1; do
|
|
if grep -q "^usable\.${codec}=none" "${out}/encoders.log"; then
|
|
log "SKIP ${codec}: no usable hardware encoder"
|
|
continue
|
|
fi
|
|
if [[ -z "${token}" ]]; then
|
|
echo
|
|
echo "Recording a monitor for 20 seconds with ${codec}. The portal will ask"
|
|
echo "you to pick a monitor: pick one and keep some motion on screen."
|
|
fi
|
|
dir="${out}/monitor-${codec}"
|
|
restore=()
|
|
[[ -n "${token}" ]] && restore=(--restore-token "${token}")
|
|
"${probe}" record --target monitor --codec "${codec}" "${restore[@]}" --seconds 20 "${format[@]}" \
|
|
--out "${dir}" > "${dir}.log" 2> "${dir}.obs.log"
|
|
record_exit=$?
|
|
"${probe}" check --codec "${codec}" --out "${dir}" >> "${dir}.log" 2>&1
|
|
check_exit=$?
|
|
log "monitor-${codec}: record_exit=${record_exit} check_exit=${check_exit} $(grep -E '^(encoder|recorded|check)=' "${dir}.log" | tr '\n' ' ')"
|
|
log "$(grep -E 'status=' "${dir}.log" | tr '\n' ' ')"
|
|
if [[ -z "${token}" ]]; then
|
|
token="$(sed -n 's/^restore_token=//p' "${dir}.log")"
|
|
log "restore token received: $([[ -n "${token}" ]] && echo yes || echo no)"
|
|
else
|
|
ask "Did ${codec} start WITHOUT showing the portal picker again?"
|
|
fi
|
|
done
|
|
|
|
echo
|
|
echo "Now recording a window for 20 seconds. Start a game (or any moving"
|
|
echo "window) first, then pick it in the portal."
|
|
read -r -p "Press Enter when ready. " _
|
|
dir="${out}/window-h264"
|
|
"${probe}" record --target window --seconds 20 "${format[@]}" --out "${dir}" > "${dir}.log" 2> "${dir}.obs.log"
|
|
record_exit=$?
|
|
"${probe}" check --out "${dir}" >> "${dir}.log" 2>&1
|
|
log "window-h264: record_exit=${record_exit} check_exit=$? $(grep -E '^(recorded|check)=' "${dir}.log" | tr '\n' ' ')"
|
|
|
|
echo
|
|
echo "Last: source loss. Record a window again, then close that window"
|
|
echo "about 5 seconds in. The probe should report a failure."
|
|
read -r -p "Press Enter when ready. " _
|
|
dir="${out}/window-closed"
|
|
"${probe}" record --target window --seconds 20 "${format[@]}" --out "${dir}" > "${dir}.log" 2> "${dir}.obs.log"
|
|
log "window-closed: exit=$? $(grep -E 'status=failed' "${dir}.log" | head -1)"
|
|
|
|
echo
|
|
echo "Report: ${report}"
|
|
echo "Recordings and logs: ${out}"
|