vdi-cloud/tools/bench-mouse-stream.sh

75 lines
3.1 KiB
Bash

#!/bin/bash
# Temporary benchmark stream only. Refuses to replace an existing user stream.
# Run after launching the scoped Windows input benchmark, with VDD mode matched.
set -euo pipefail
task_root="${VDI_RKMPP_BUILD_ROOT:-$HOME/vdi-build/rkmpp-experiment}"
label="${1:?label required}"
fps="${2:?FPS required}"
priority="${3:-0}"
[[ "$label" =~ ^[a-zA-Z0-9-]+$ ]] || exit 2
[[ "$fps" = 30 || "$fps" = 60 ]] || exit 2
[[ "$priority" = 0 || "$priority" = 1 ]] || exit 2
exec 9>"$task_root/mouse-bench.lock"
flock -n 9 || { echo 'Another benchmark is active'; exit 1; }
if pgrep -f '^/home/armbian/vdi-build/rkmpp-experiment/build/moonlight/app/moonlight.* stream ' >/dev/null; then
echo 'A stream is already active; exit it normally before benchmarking' >&2
exit 1
fi
export DISPLAY=:0 XAUTHORITY="$HOME/.Xauthority"
export LD_LIBRARY_PATH="$task_root/runtime/lib:$task_root/deps/usr/lib/aarch64-linux-gnu"
export QML2_IMPORT_PATH="$task_root/deps/usr/lib/aarch64-linux-gnu/qt5/qml"
export QT_PLUGIN_PATH="$task_root/deps/usr/lib/aarch64-linux-gnu/qt5/plugins"
export H264_DECODER_HINT=h264_rkmpp HEVC_DECODER_HINT=hevc_rkmpp
export VDI_LATEST_FRAME=1 VDI_INPUT_TIMING=1 VDI_INPUT_PRIORITY="$priority"
export GL_IS_SLOW=0 SDL_RENDER_DRIVER=opengles2 SDL_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR=1
client="${VDI_RKMPP_CLIENT:-$task_root/build/moonlight/app/moonlight}"
mkdir -p "$task_root/mouse-bench"
log="$task_root/mouse-bench/$label.log"
test ! -e "$log" || { echo 'Label already used; preserve existing evidence'; exit 1; }
child=""
cleanup() {
if [ -n "$child" ] && kill -0 "$child" 2>/dev/null; then
kill -TERM "$child" 2>/dev/null || true
for ((j=0;j<5;j++)); do
kill -0 "$child" 2>/dev/null || break
sleep 1
done
kill -KILL "$child" 2>/dev/null || true
wait "$child" 2>/dev/null || true
fi
}
trap cleanup EXIT
trap 'exit 130' INT
trap 'exit 143' TERM
"$client" stream 192.168.1.70 Desktop --resolution 2560x1440 --fps "$fps" \
--bitrate 30000 --display-mode fullscreen --video-codec H.264 \
--video-decoder hardware --absolute-mouse --keep-awake --no-vsync \
--no-frame-pacing --audio-on-host > "$log" 2>&1 &
child=$!
ready=0
for ((i=0;i<35;i++)); do
if grep -q 'egl_overlay.frag' "$log"; then ready=1; break; fi
kill -0 "$child" || { tail -20 "$log"; exit 1; }
sleep 1
done
test "$ready" = 1 || { echo 'No video readiness'; exit 1; }
echo "Ready: $label; injecting motion"
python3 "$task_root/mouse-bench/inject-mouse-sweep.py"
python3 "$task_root/mouse-bench/inject-input-burst.py"
sleep 12
# Do not send the exit chord into an unrelated foreground application.
focus_pid=$(xdotool getwindowfocus getwindowpid 2>/dev/null || true)
if [ "$focus_pid" != "$child" ]; then
echo 'Stream lost foreground; terminate only benchmark child' >&2
exit 1
fi
xdotool key ctrl+alt+shift+q
for ((i=0;i<15;i++)); do
kill -0 "$child" 2>/dev/null || break
sleep 1
done
kill -0 "$child" 2>/dev/null && { echo 'Stream exit timed out'; exit 1; }
wait "$child"
child=""
grep -E 'VDI input|VDI main-thread|frame rate|Host processing|Frames dropped|Average .*time|Average network|queue delay' "$log"