Wayland: VAAPI H.264 + in-process HTTP server, drop ffmpeg
The previous ffmpeg-as-HTTP-server pipeline shape held back two improvements at once. ffmpeg as the runtime server lost a one-shot `-listen 1` accept to a probe-and-discard health check, and forced us to size analyze/probe budgets carefully so ffmpeg would serve before our deadline. Replacing it with a small tokio task that accepts once, drains the HTTP request, writes a fixed 200 OK, then `tokio::io::copy`s gst stdout to the socket removes all of that. VAAPI H.264 (vah264enc) drops CPU encode from ~50% of a core to single-digit %. An earlier attempt at vaav1enc had to be abandoned: libavformat cannot demux AV1-in-MPEG-TS with the custom mapping even with a 20MB probe budget — mpv reports video=eof. H.264 keeps the hardware win on the well-trodden demuxer path. scripts/smoke-pipeline.sh mirrors the runtime pipeline with videotestsrc/audiotestsrc into a file and asserts that mpv reports `video=playing` (not video=eof). The naive --frames=10 check was a false positive when no video stream is recognized; the verbose grep is the real gate. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Executable
+53
@@ -0,0 +1,53 @@
|
||||
#!/usr/bin/env bash
|
||||
# Pipeline-only smoke test: mirrors host/wayland.rs's gst pipeline but
|
||||
# substitutes videotestsrc/audiotestsrc for pipewiresrc/pulsesrc and writes
|
||||
# to a file instead of fdsink, so it runs without the portal/PipeWire and
|
||||
# without an HTTP/iroh client. Catches AV1 encode + mpegtsmux + AAC mux
|
||||
# regressions in ~5 seconds without any user interaction.
|
||||
#
|
||||
# Usage: scripts/smoke-pipeline.sh
|
||||
# Exits 0 on pass, non-zero with diagnostic on fail.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
OUT="${TMPDIR:-/tmp}/pixelpass-smoke-$$.ts"
|
||||
trap 'rm -f "$OUT"' EXIT
|
||||
|
||||
echo "[smoke] running gst pipeline (videotestsrc + audiotestsrc, ~2s) -> $OUT"
|
||||
gst-launch-1.0 -q \
|
||||
mpegtsmux name=mux \
|
||||
! queue ! filesink location="$OUT" \
|
||||
videotestsrc num-buffers=60 is-live=false \
|
||||
! video/x-raw,width=640,height=360,framerate=30/1 \
|
||||
! videoconvert ! video/x-raw,format=NV12 \
|
||||
! vah264enc rate-control=cbr bitrate=2000 key-int-max=60 \
|
||||
! h264parse config-interval=-1 \
|
||||
! video/x-h264,stream-format=byte-stream,alignment=au \
|
||||
! mux. \
|
||||
audiotestsrc num-buffers=94 is-live=false \
|
||||
! audioconvert ! audioresample \
|
||||
! audio/x-raw,rate=48000,channels=2 \
|
||||
! avenc_aac bitrate=128000 ! aacparse ! mux.
|
||||
|
||||
[[ -s "$OUT" ]] || { echo "[smoke] FAIL: output file empty or missing"; exit 1; }
|
||||
echo "[smoke] output size: $(stat -c %s "$OUT") bytes"
|
||||
|
||||
echo "[smoke] ffprobe stream listing"
|
||||
ffprobe -v error -show_entries stream=index,codec_type,codec_name "$OUT" \
|
||||
| sed 's/^/ /'
|
||||
|
||||
# Real gate: mpv must actually decode video. The previous --frames=10 check was
|
||||
# a false positive — if there's no video stream, --frames silently does nothing
|
||||
# and mpv exits 0 after playing the audio. We instead grep mpv -v output for
|
||||
# "video=playing"; "video=eof" means mpv saw no video track.
|
||||
echo "[smoke] mpv video-decode probe (-v, asserting 'video=playing')"
|
||||
MPV_LOG=$(mpv --no-config -v --vo=null --ao=null --frames=10 "$OUT" 2>&1)
|
||||
echo "$MPV_LOG" | grep -E 'video=(playing|eof)' | sed 's/^/ /'
|
||||
if echo "$MPV_LOG" | grep -q 'video=playing'; then
|
||||
echo "[smoke] PASS — pipeline produces an mpv-decodable video + audio stream"
|
||||
else
|
||||
echo "[smoke] FAIL: mpv did not decode video (saw video=eof or no video state)"
|
||||
echo "[smoke] last 30 lines of mpv output:"
|
||||
echo "$MPV_LOG" | tail -30 | sed 's/^/ /'
|
||||
exit 1
|
||||
fi
|
||||
Reference in New Issue
Block a user