update docs
This commit is contained in:
@@ -1,21 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Re-render all Graphviz diagrams to SVG.
|
||||
# Run this after each phase when .dot files are updated.
|
||||
# Usage: ./docs.sh
|
||||
set -euo pipefail
|
||||
|
||||
DOCS_DIR="$(cd "$(dirname "$0")/../docs" && pwd)"
|
||||
|
||||
if ! command -v dot &>/dev/null; then
|
||||
echo "graphviz not found — install with: sudo apt install graphviz" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for f in "$DOCS_DIR"/*.dot; do
|
||||
svg="${f%.dot}.svg"
|
||||
echo "==> $(basename "$f") → $(basename "$svg")"
|
||||
dot -Tsvg "$f" -o "$svg"
|
||||
done
|
||||
|
||||
echo "==> done. Serving at http://localhost:9099 (ctrl-c to stop)"
|
||||
cd "$DOCS_DIR" && python3 -m http.server 9099
|
||||
@@ -1,66 +0,0 @@
|
||||
// Client pipeline data flow
|
||||
// Sender machine (Wayland, VAAPI GPU)
|
||||
digraph client_pipeline {
|
||||
graph [fontname="monospace" bgcolor="#1e1e2e" rankdir=TB pad="0.6" splines=polyline]
|
||||
node [fontname="monospace" fontcolor="#cdd6f4" style=filled shape=box
|
||||
fillcolor="#313244" color="#585b70" margin="0.25,0.12"]
|
||||
edge [color="#585b70" fontname="monospace" fontcolor="#a6adc8" labelfontname="monospace"]
|
||||
|
||||
// Hardware
|
||||
drm [label="/dev/dri/card0\n(KMS scanout)" shape=cylinder fillcolor="#1e3a2f" color="#a6e3a1"]
|
||||
vaapi [label="/dev/dri/renderD128\n(VAAPI)" shape=cylinder fillcolor="#1e3a2f" color="#a6e3a1"]
|
||||
pulse [label="PulseAudio\n─────────────\nmonitor: default_sink.monitor\nmic: default-source" shape=cylinder fillcolor="#1e3a2f" color="#a6e3a1"]
|
||||
net [label="TCP :4447\nmcrndeb" shape=parallelogram fillcolor="#1e2a3e" color="#89b4fa"]
|
||||
|
||||
subgraph cluster_main {
|
||||
label="main thread (tokio async)" fontcolor="#a6adc8" color="#45475a" fontname="monospace"
|
||||
|
||||
wait_server [label="wait_for_server\n─────────────\nretry connect / 2s\nCtrl-C to cancel" fillcolor="#2d2038" color="#cba6f7"]
|
||||
session_start [label="session_start\n─────────────\nid: YYYYMMDD_HHMMSS\nvideo + audio params" fillcolor="#2d2038" color="#cba6f7"]
|
||||
mux [label="select!\npkt_rx | keepalive | ctrl-c" fillcolor="#2d2038" color="#cba6f7"]
|
||||
write [label="BufWriter\nwrite_packet()" fillcolor="#1e2d3e" color="#89b4fa"]
|
||||
shutdown [label="Shutdown\n─────────────\npipeline.stop() (5s timeout)\nSessionStop (2s timeout)\nsingle Ctrl-C" fillcolor="#2d2038" color="#cba6f7"]
|
||||
}
|
||||
|
||||
subgraph cluster_subprocess {
|
||||
label="Subprocess backend (default)" fontcolor="#a6adc8" color="#45475a" fontname="monospace"
|
||||
|
||||
ffmpeg_cli [label="ffmpeg subprocess\n─────────────\nkmsgrab → VAAPI h264\n+ PulseAudio inputs:\n amix(monitor, mic)\noutput: NUT pipe" fillcolor="#1e2d3e" color="#89b4fa"]
|
||||
|
||||
demux [label="NUT Demuxer\n─────────────\nffmpeg-next in-process\nfinds video + audio streams\nsends EncodedPacket\n { data, pts, media_type }" fillcolor="#1e2d3e" color="#89b4fa"]
|
||||
|
||||
chan [label="mpsc::channel(64)\nEncodedPacket" shape=parallelogram fillcolor="#2d2038" color="#cba6f7"]
|
||||
}
|
||||
|
||||
subgraph cluster_direct {
|
||||
label="VaapiDirect backend (experimental)" fontcolor="#6c7086" color="#45475a" fontname="monospace" style=dashed
|
||||
|
||||
capture [label="KmsCapture\n─────────────\nDRM_PRIME frames" fillcolor="#2d1e1e" color="#f38ba8"]
|
||||
encoder [label="VaapiEncoder\n─────────────\nhwmap → scale_vaapi\nh264_vaapi QP=20" fillcolor="#2d1e1e" color="#f38ba8"]
|
||||
}
|
||||
|
||||
// Flow — subprocess
|
||||
drm -> ffmpeg_cli [label="kmsgrab"]
|
||||
vaapi -> ffmpeg_cli [label="h264_vaapi"]
|
||||
pulse -> ffmpeg_cli [label="-f pulse\nmonitor + mic"]
|
||||
ffmpeg_cli -> demux [label="NUT pipe\n(stdout)"]
|
||||
demux -> chan [label="EncodedPacket\n(Video or Audio)"]
|
||||
|
||||
// Flow — direct (dashed, experimental)
|
||||
drm -> capture [style=dashed]
|
||||
vaapi -> encoder [style=dashed]
|
||||
capture -> encoder [style=dashed label="DRM_PRIME"]
|
||||
encoder -> chan [style=dashed]
|
||||
|
||||
// Flow — main
|
||||
chan -> mux
|
||||
wait_server -> session_start
|
||||
session_start -> write
|
||||
mux -> write [label="WirePacket\nVideo | Audio"]
|
||||
write -> net
|
||||
mux -> shutdown [label="Ctrl-C or\nchannel closed"]
|
||||
|
||||
// Types note
|
||||
types [label="WirePacket types\n─────────────\nVideo: H.264 NALUs + keyframe flag\nAudio: AAC frames\nControl: SessionStart/Stop/Keepalive"
|
||||
shape=note fillcolor="#2a2a3e" color="#585b70"]
|
||||
}
|
||||
@@ -1,264 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 14.1.2 (0)
|
||||
-->
|
||||
<!-- Title: client_pipeline Pages: 1 -->
|
||||
<svg width="1291pt" height="1237pt"
|
||||
viewBox="0.00 0.00 1291.00 1237.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(43.2 1194.19)">
|
||||
<title>client_pipeline</title>
|
||||
<polygon fill="#1e1e2e" stroke="none" points="-43.2,43.2 -43.2,-1194.19 1248.2,-1194.19 1248.2,43.2 -43.2,43.2"/>
|
||||
<g id="clust1" class="cluster">
|
||||
<title>cluster_main</title>
|
||||
<polygon fill="#1e1e2e" stroke="#45475a" points="703,-132.56 703,-566.04 1197,-566.04 1197,-132.56 703,-132.56"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="950" y="-548.74" font-family="monospace" font-size="14.00" fill="#a6adc8">main thread (tokio async)</text>
|
||||
</g>
|
||||
<g id="clust2" class="cluster">
|
||||
<title>cluster_subprocess</title>
|
||||
<polygon fill="#1e1e2e" stroke="#45475a" points="313,-429.87 313,-971.85 695,-971.85 695,-429.87 313,-429.87"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="504" y="-954.55" font-family="monospace" font-size="14.00" fill="#a6adc8">Subprocess backend (default)</text>
|
||||
</g>
|
||||
<g id="clust3" class="cluster">
|
||||
<title>cluster_direct</title>
|
||||
<polygon fill="#1e1e2e" stroke="#45475a" stroke-dasharray="5,2" points="8,-635.79 8,-945.97 305,-945.97 305,-635.79 8,-635.79"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="156.5" y="-928.67" font-family="monospace" font-size="14.00" fill="#6c7086">VaapiDirect backend (experimental)</text>
|
||||
</g>
|
||||
<!-- drm -->
|
||||
<g id="node1" class="node">
|
||||
<title>drm</title>
|
||||
<path fill="#1e3a2f" stroke="#a6e3a1" d="M258.75,-1120.79C258.75,-1124.37 224.8,-1127.27 183,-1127.27 141.2,-1127.27 107.25,-1124.37 107.25,-1120.79 107.25,-1120.79 107.25,-1062.54 107.25,-1062.54 107.25,-1058.97 141.2,-1056.07 183,-1056.07 224.8,-1056.07 258.75,-1058.97 258.75,-1062.54 258.75,-1062.54 258.75,-1120.79 258.75,-1120.79"/>
|
||||
<path fill="none" stroke="#a6e3a1" d="M258.75,-1120.79C258.75,-1117.22 224.8,-1114.32 183,-1114.32 141.2,-1114.32 107.25,-1117.22 107.25,-1120.79"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="183" y="-1095.62" font-family="monospace" font-size="14.00" fill="#cdd6f4">/dev/dri/card0</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="183" y="-1078.37" font-family="monospace" font-size="14.00" fill="#cdd6f4">(KMS scanout)</text>
|
||||
</g>
|
||||
<!-- ffmpeg_cli -->
|
||||
<g id="node10" class="node">
|
||||
<title>ffmpeg_cli</title>
|
||||
<polygon fill="#1e2d3e" stroke="#89b4fa" points="529.5,-938.6 328.5,-938.6 328.5,-817.82 529.5,-817.82 529.5,-938.6"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="429" y="-916.66" font-family="monospace" font-size="14.00" fill="#cdd6f4">ffmpeg subprocess</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="429" y="-899.41" font-family="monospace" font-size="14.00" fill="#cdd6f4">─────────────</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="429" y="-882.16" font-family="monospace" font-size="14.00" fill="#cdd6f4">kmsgrab → VAAPI h264</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="429" y="-864.91" font-family="monospace" font-size="14.00" fill="#cdd6f4">+ PulseAudio inputs:</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="429" y="-847.66" font-family="monospace" font-size="14.00" fill="#cdd6f4">  amix(monitor, mic)</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="429" y="-830.41" font-family="monospace" font-size="14.00" fill="#cdd6f4">output: NUT pipe</text>
|
||||
</g>
|
||||
<!-- drm->ffmpeg_cli -->
|
||||
<g id="edge1" class="edge">
|
||||
<title>drm->ffmpeg_cli</title>
|
||||
<path fill="none" stroke="#585b70" d="M223.62,-1055.75C258.09,-1026.12 308.54,-982.76 350.81,-946.42"/>
|
||||
<polygon fill="#585b70" stroke="#585b70" points="352.97,-949.18 358.27,-940.01 348.41,-943.87 352.97,-949.18"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="334.88" y="-992.42" font-family="monospace" font-size="14.00" fill="#a6adc8">kmsgrab</text>
|
||||
</g>
|
||||
<!-- capture -->
|
||||
<g id="node13" class="node">
|
||||
<title>capture</title>
|
||||
<polygon fill="#2d1e1e" stroke="#f38ba8" points="267,-912.72 99,-912.72 99,-843.69 267,-843.69 267,-912.72"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="183" y="-890.78" font-family="monospace" font-size="14.00" fill="#cdd6f4">KmsCapture</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="183" y="-873.53" font-family="monospace" font-size="14.00" fill="#cdd6f4">─────────────</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="183" y="-856.28" font-family="monospace" font-size="14.00" fill="#cdd6f4">DRM_PRIME frames</text>
|
||||
</g>
|
||||
<!-- drm->capture -->
|
||||
<g id="edge6" class="edge">
|
||||
<title>drm->capture</title>
|
||||
<path fill="none" stroke="#585b70" stroke-dasharray="5,2" d="M183,-1055.75C183,-1019.85 183,-963.78 183,-924.49"/>
|
||||
<polygon fill="#585b70" stroke="#585b70" points="186.5,-924.64 183,-914.64 179.5,-924.64 186.5,-924.64"/>
|
||||
</g>
|
||||
<!-- vaapi -->
|
||||
<g id="node2" class="node">
|
||||
<title>vaapi</title>
|
||||
<path fill="#1e3a2f" stroke="#a6e3a1" d="M469.38,-1120.79C469.38,-1124.37 426.18,-1127.27 373,-1127.27 319.82,-1127.27 276.62,-1124.37 276.62,-1120.79 276.62,-1120.79 276.62,-1062.54 276.62,-1062.54 276.62,-1058.97 319.82,-1056.07 373,-1056.07 426.18,-1056.07 469.38,-1058.97 469.38,-1062.54 469.38,-1062.54 469.38,-1120.79 469.38,-1120.79"/>
|
||||
<path fill="none" stroke="#a6e3a1" d="M469.38,-1120.79C469.38,-1117.22 426.18,-1114.32 373,-1114.32 319.82,-1114.32 276.62,-1117.22 276.62,-1120.79"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="373" y="-1095.62" font-family="monospace" font-size="14.00" fill="#cdd6f4">/dev/dri/renderD128</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="373" y="-1078.37" font-family="monospace" font-size="14.00" fill="#cdd6f4">(VAAPI)</text>
|
||||
</g>
|
||||
<!-- vaapi->ffmpeg_cli -->
|
||||
<g id="edge2" class="edge">
|
||||
<title>vaapi->ffmpeg_cli</title>
|
||||
<path fill="none" stroke="#585b70" d="M382.25,-1055.75C389.85,-1027.05 400.86,-985.46 410.29,-949.86"/>
|
||||
<polygon fill="#585b70" stroke="#585b70" points="413.6,-951.04 412.77,-940.48 406.83,-949.25 413.6,-951.04"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="442.25" y="-992.42" font-family="monospace" font-size="14.00" fill="#a6adc8">h264_vaapi</text>
|
||||
</g>
|
||||
<!-- encoder -->
|
||||
<g id="node14" class="node">
|
||||
<title>encoder</title>
|
||||
<polygon fill="#2d1e1e" stroke="#f38ba8" points="297.38,-730.07 104.62,-730.07 104.62,-643.79 297.38,-643.79 297.38,-730.07"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="201" y="-708.13" font-family="monospace" font-size="14.00" fill="#cdd6f4">VaapiEncoder</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="201" y="-690.88" font-family="monospace" font-size="14.00" fill="#cdd6f4">─────────────</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="201" y="-673.63" font-family="monospace" font-size="14.00" fill="#cdd6f4">hwmap → scale_vaapi</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="201" y="-656.38" font-family="monospace" font-size="14.00" fill="#cdd6f4">h264_vaapi QP=20</text>
|
||||
</g>
|
||||
<!-- vaapi->encoder -->
|
||||
<g id="edge7" class="edge">
|
||||
<title>vaapi->encoder</title>
|
||||
<path fill="none" stroke="#585b70" stroke-dasharray="5,2" d="M354.14,-1055.66C335.27,-1020.61 309,-971.85 309,-971.85 309,-971.85 272,-765.32 272,-765.32 272,-765.32 260.89,-753.21 247.47,-738.58"/>
|
||||
<polygon fill="#585b70" stroke="#585b70" points="250.19,-736.37 240.85,-731.36 245.03,-741.1 250.19,-736.37"/>
|
||||
</g>
|
||||
<!-- pulse -->
|
||||
<g id="node3" class="node">
|
||||
<title>pulse</title>
|
||||
<path fill="#1e3a2f" stroke="#a6e3a1" d="M762.62,-1140.2C762.62,-1146.15 700.94,-1150.99 625,-1150.99 549.06,-1150.99 487.38,-1146.15 487.38,-1140.2 487.38,-1140.2 487.38,-1043.13 487.38,-1043.13 487.38,-1037.18 549.06,-1032.35 625,-1032.35 700.94,-1032.35 762.62,-1037.18 762.62,-1043.13 762.62,-1043.13 762.62,-1140.2 762.62,-1140.2"/>
|
||||
<path fill="none" stroke="#a6e3a1" d="M762.62,-1140.2C762.62,-1134.25 700.94,-1129.41 625,-1129.41 549.06,-1129.41 487.38,-1134.25 487.38,-1140.2"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="625" y="-1112.87" font-family="monospace" font-size="14.00" fill="#cdd6f4">PulseAudio</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="625" y="-1095.62" font-family="monospace" font-size="14.00" fill="#cdd6f4">─────────────</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="625" y="-1078.37" font-family="monospace" font-size="14.00" fill="#cdd6f4">monitor: default_sink.monitor</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="625" y="-1061.12" font-family="monospace" font-size="14.00" fill="#cdd6f4">mic: default-source</text>
|
||||
</g>
|
||||
<!-- pulse->ffmpeg_cli -->
|
||||
<g id="edge3" class="edge">
|
||||
<title>pulse->ffmpeg_cli</title>
|
||||
<path fill="none" stroke="#585b70" d="M570.66,-1032.05C546.33,-1005.79 517.48,-974.67 492.19,-947.38"/>
|
||||
<polygon fill="#585b70" stroke="#585b70" points="494.86,-945.11 485.49,-940.16 489.73,-949.87 494.86,-945.11"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="603.94" y="-1001.05" font-family="monospace" font-size="14.00" fill="#a6adc8">-f pulse</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="603.94" y="-983.8" font-family="monospace" font-size="14.00" fill="#a6adc8">monitor + mic</text>
|
||||
</g>
|
||||
<!-- net -->
|
||||
<g id="node4" class="node">
|
||||
<title>net</title>
|
||||
<polygon fill="#1e2a3e" stroke="#89b4fa" points="1195.3,-103.56 1013.47,-103.56 966.7,0 1148.53,0 1195.3,-103.56"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="1081" y="-55.73" font-family="monospace" font-size="14.00" fill="#cdd6f4">TCP :4447</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="1081" y="-38.48" font-family="monospace" font-size="14.00" fill="#cdd6f4">mcrndeb</text>
|
||||
</g>
|
||||
<!-- wait_server -->
|
||||
<g id="node5" class="node">
|
||||
<title>wait_server</title>
|
||||
<polygon fill="#2d2038" stroke="#cba6f7" points="1180.25,-532.79 995.75,-532.79 995.75,-446.51 1180.25,-446.51 1180.25,-532.79"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="1088" y="-510.85" font-family="monospace" font-size="14.00" fill="#cdd6f4">wait_for_server</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="1088" y="-493.6" font-family="monospace" font-size="14.00" fill="#cdd6f4">─────────────</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="1088" y="-476.35" font-family="monospace" font-size="14.00" fill="#cdd6f4">retry connect / 2s</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="1088" y="-459.1" font-family="monospace" font-size="14.00" fill="#cdd6f4">Ctrl-C to cancel</text>
|
||||
</g>
|
||||
<!-- session_start -->
|
||||
<g id="node6" class="node">
|
||||
<title>session_start</title>
|
||||
<polygon fill="#2d2038" stroke="#cba6f7" points="1188.5,-400.87 987.5,-400.87 987.5,-314.59 1188.5,-314.59 1188.5,-400.87"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="1088" y="-378.93" font-family="monospace" font-size="14.00" fill="#cdd6f4">session_start</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="1088" y="-361.68" font-family="monospace" font-size="14.00" fill="#cdd6f4">─────────────</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="1088" y="-344.43" font-family="monospace" font-size="14.00" fill="#cdd6f4">id: YYYYMMDD_HHMMSS</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="1088" y="-327.18" font-family="monospace" font-size="14.00" fill="#cdd6f4">video + audio params</text>
|
||||
</g>
|
||||
<!-- wait_server->session_start -->
|
||||
<g id="edge11" class="edge">
|
||||
<title>wait_server->session_start</title>
|
||||
<path fill="none" stroke="#585b70" d="M1088,-446.11C1088,-435.45 1088,-423.88 1088,-412.75"/>
|
||||
<polygon fill="#585b70" stroke="#585b70" points="1091.5,-412.88 1088,-402.88 1084.5,-412.88 1091.5,-412.88"/>
|
||||
</g>
|
||||
<!-- write -->
|
||||
<g id="node8" class="node">
|
||||
<title>write</title>
|
||||
<polygon fill="#1e2d3e" stroke="#89b4fa" points="1156.75,-218.22 1005.25,-218.22 1005.25,-166.43 1156.75,-166.43 1156.75,-218.22"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="1081" y="-196.27" font-family="monospace" font-size="14.00" fill="#cdd6f4">BufWriter</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="1081" y="-179.02" font-family="monospace" font-size="14.00" fill="#cdd6f4">write_packet()</text>
|
||||
</g>
|
||||
<!-- session_start->write -->
|
||||
<g id="edge12" class="edge">
|
||||
<title>session_start->write</title>
|
||||
<path fill="none" stroke="#585b70" d="M1086.65,-314.12C1085.85,-289 1085,-262.09 1085,-262.09 1085,-262.09 1084.08,-246.3 1083.12,-229.85"/>
|
||||
<polygon fill="#585b70" stroke="#585b70" points="1086.63,-229.83 1082.55,-220.05 1079.64,-230.24 1086.63,-229.83"/>
|
||||
</g>
|
||||
<!-- mux -->
|
||||
<g id="node7" class="node">
|
||||
<title>mux</title>
|
||||
<polygon fill="#2d2038" stroke="#cba6f7" points="969.38,-383.62 710.62,-383.62 710.62,-331.84 969.38,-331.84 969.38,-383.62"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="840" y="-361.68" font-family="monospace" font-size="14.00" fill="#cdd6f4">select!</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="840" y="-344.43" font-family="monospace" font-size="14.00" fill="#cdd6f4">pkt_rx | keepalive | ctrl-c</text>
|
||||
</g>
|
||||
<!-- mux->write -->
|
||||
<g id="edge13" class="edge">
|
||||
<title>mux->write</title>
|
||||
<path fill="none" stroke="#585b70" d="M888.44,-331.4C919.87,-314.96 955,-296.59 955,-296.59 955,-296.59 973.75,-262.09 973.75,-262.09 973.75,-262.09 1003.87,-242.78 1032.19,-224.62"/>
|
||||
<polygon fill="#585b70" stroke="#585b70" points="1033.87,-227.7 1040.4,-219.36 1030.09,-221.81 1033.87,-227.7"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="1027.38" y="-283.29" font-family="monospace" font-size="14.00" fill="#a6adc8">WirePacket</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="1027.38" y="-266.04" font-family="monospace" font-size="14.00" fill="#a6adc8">Video | Audio</text>
|
||||
</g>
|
||||
<!-- shutdown -->
|
||||
<g id="node9" class="node">
|
||||
<title>shutdown</title>
|
||||
<polygon fill="#2d2038" stroke="#cba6f7" points="978.5,-244.09 711.5,-244.09 711.5,-140.56 978.5,-140.56 978.5,-244.09"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="845" y="-222.15" font-family="monospace" font-size="14.00" fill="#cdd6f4">Shutdown</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="845" y="-204.9" font-family="monospace" font-size="14.00" fill="#cdd6f4">─────────────</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="845" y="-187.65" font-family="monospace" font-size="14.00" fill="#cdd6f4">pipeline.stop() (5s timeout)</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="845" y="-170.4" font-family="monospace" font-size="14.00" fill="#cdd6f4">SessionStop (2s timeout)</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="845" y="-153.15" font-family="monospace" font-size="14.00" fill="#cdd6f4">single Ctrl-C</text>
|
||||
</g>
|
||||
<!-- mux->shutdown -->
|
||||
<g id="edge15" class="edge">
|
||||
<title>mux->shutdown</title>
|
||||
<path fill="none" stroke="#585b70" d="M839.79,-331.57C839.65,-315.09 839.5,-296.59 839.5,-296.59 839.5,-296.59 839.5,-262.09 839.5,-262.09 839.5,-262.09 839.69,-259.69 840,-255.79"/>
|
||||
<polygon fill="#585b70" stroke="#585b70" points="843.49,-256.14 840.8,-245.89 836.51,-255.58 843.49,-256.14"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="897.25" y="-283.29" font-family="monospace" font-size="14.00" fill="#a6adc8">Ctrl-C or</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="897.25" y="-266.04" font-family="monospace" font-size="14.00" fill="#a6adc8">channel closed</text>
|
||||
</g>
|
||||
<!-- write->net -->
|
||||
<g id="edge14" class="edge">
|
||||
<title>write->net</title>
|
||||
<path fill="none" stroke="#585b70" d="M1081,-166.24C1081,-151.9 1081,-133.24 1081,-115.2"/>
|
||||
<polygon fill="#585b70" stroke="#585b70" points="1084.5,-115.31 1081,-105.31 1077.5,-115.31 1084.5,-115.31"/>
|
||||
</g>
|
||||
<!-- demux -->
|
||||
<g id="node11" class="node">
|
||||
<title>demux</title>
|
||||
<polygon fill="#1e2d3e" stroke="#89b4fa" points="603.38,-747.32 344.62,-747.32 344.62,-626.54 603.38,-626.54 603.38,-747.32"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="474" y="-725.38" font-family="monospace" font-size="14.00" fill="#cdd6f4">NUT Demuxer</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="474" y="-708.13" font-family="monospace" font-size="14.00" fill="#cdd6f4">─────────────</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="474" y="-690.88" font-family="monospace" font-size="14.00" fill="#cdd6f4">ffmpeg-next in-process</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="474" y="-673.63" font-family="monospace" font-size="14.00" fill="#cdd6f4">finds video + audio streams</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="474" y="-656.38" font-family="monospace" font-size="14.00" fill="#cdd6f4">sends EncodedPacket</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="474" y="-639.13" font-family="monospace" font-size="14.00" fill="#cdd6f4">  { data, pts, media_type }</text>
|
||||
</g>
|
||||
<!-- ffmpeg_cli->demux -->
|
||||
<g id="edge4" class="edge">
|
||||
<title>ffmpeg_cli->demux</title>
|
||||
<path fill="none" stroke="#585b70" d="M443.24,-817.32C447.65,-798.76 452.56,-778.13 457.13,-758.89"/>
|
||||
<polygon fill="#585b70" stroke="#585b70" points="460.52,-759.77 459.43,-749.23 453.71,-758.15 460.52,-759.77"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="488.53" y="-786.52" font-family="monospace" font-size="14.00" fill="#a6adc8">NUT pipe</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="488.53" y="-769.27" font-family="monospace" font-size="14.00" fill="#a6adc8">(stdout)</text>
|
||||
</g>
|
||||
<!-- chan -->
|
||||
<g id="node12" class="node">
|
||||
<title>chan</title>
|
||||
<polygon fill="#2d2038" stroke="#cba6f7" points="686.73,-541.43 396.05,-541.43 321.27,-437.87 611.95,-437.87 686.73,-541.43"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="504" y="-493.6" font-family="monospace" font-size="14.00" fill="#cdd6f4">mpsc::channel(64)</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="504" y="-476.35" font-family="monospace" font-size="14.00" fill="#cdd6f4">EncodedPacket</text>
|
||||
</g>
|
||||
<!-- demux->chan -->
|
||||
<g id="edge5" class="edge">
|
||||
<title>demux->chan</title>
|
||||
<path fill="none" stroke="#585b70" d="M483.16,-626.28C486.73,-603.05 490.82,-576.42 494.43,-552.94"/>
|
||||
<polygon fill="#585b70" stroke="#585b70" points="497.87,-553.61 495.93,-543.19 490.95,-552.55 497.87,-553.61"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="556.8" y="-595.24" font-family="monospace" font-size="14.00" fill="#a6adc8">EncodedPacket</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="556.8" y="-577.99" font-family="monospace" font-size="14.00" fill="#a6adc8">(Video or Audio)</text>
|
||||
</g>
|
||||
<!-- chan->mux -->
|
||||
<g id="edge10" class="edge">
|
||||
<title>chan->mux</title>
|
||||
<path fill="none" stroke="#585b70" d="M617.29,-444.85C665.69,-426.13 720.89,-404.79 764.23,-388.03"/>
|
||||
<polygon fill="#585b70" stroke="#585b70" points="765.22,-391.4 773.28,-384.53 762.69,-384.87 765.22,-391.4"/>
|
||||
</g>
|
||||
<!-- capture->encoder -->
|
||||
<g id="edge8" class="edge">
|
||||
<title>capture->encoder</title>
|
||||
<path fill="none" stroke="#585b70" stroke-dasharray="5,2" d="M186.22,-843.37C188.9,-815.12 192.78,-774.33 195.89,-741.63"/>
|
||||
<polygon fill="#585b70" stroke="#585b70" points="199.35,-742.23 196.81,-731.94 192.38,-741.56 199.35,-742.23"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="230.74" y="-777.89" font-family="monospace" font-size="14.00" fill="#a6adc8">DRM_PRIME</text>
|
||||
</g>
|
||||
<!-- encoder->chan -->
|
||||
<g id="edge9" class="edge">
|
||||
<title>encoder->chan</title>
|
||||
<path fill="none" stroke="#585b70" stroke-dasharray="5,2" d="M267.12,-643.32C310.45,-615.39 367.62,-578.54 414.94,-548.05"/>
|
||||
<polygon fill="#585b70" stroke="#585b70" points="416.79,-551.02 423.3,-542.66 413,-545.13 416.79,-551.02"/>
|
||||
</g>
|
||||
<!-- types -->
|
||||
<g id="node15" class="node">
|
||||
<title>types</title>
|
||||
<polygon fill="#2a2a3e" stroke="#585b70" points="1107.5,-1143.43 780.5,-1143.43 780.5,-1039.9 1113.5,-1039.9 1113.5,-1137.43 1107.5,-1143.43"/>
|
||||
<polyline fill="none" stroke="#585b70" points="1107.5,-1143.43 1107.5,-1137.43"/>
|
||||
<polyline fill="none" stroke="#585b70" points="1113.5,-1137.43 1107.5,-1137.43"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="947" y="-1121.49" font-family="monospace" font-size="14.00" fill="#cdd6f4">WirePacket types</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="947" y="-1104.24" font-family="monospace" font-size="14.00" fill="#cdd6f4">─────────────</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="947" y="-1086.99" font-family="monospace" font-size="14.00" fill="#cdd6f4">Video:   H.264 NALUs + keyframe flag</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="947" y="-1069.74" font-family="monospace" font-size="14.00" fill="#cdd6f4">Audio:   AAC frames</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="947" y="-1052.49" font-family="monospace" font-size="14.00" fill="#cdd6f4">Control: SessionStart/Stop/Keepalive</text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 21 KiB |
@@ -1,53 +0,0 @@
|
||||
// Cargo workspace crate dependency graph
|
||||
digraph crates {
|
||||
graph [fontname="monospace" bgcolor="#1e1e2e" pad="0.5"]
|
||||
node [fontname="monospace" fontcolor="#cdd6f4" style=filled shape=box
|
||||
fillcolor="#313244" color="#585b70" margin="0.2,0.1"]
|
||||
edge [color="#585b70" fontname="monospace" fontcolor="#a6adc8"]
|
||||
|
||||
// External
|
||||
ffmpeg_next [label="ffmpeg-next 8\n(client: NUT demux)" shape=component fillcolor="#1e3a2f" color="#a6e3a1"]
|
||||
tokio [label="tokio 1 (full)\n(async runtime)" shape=component fillcolor="#1e2a3e" color="#89b4fa"]
|
||||
serde [label="serde / serde_json" shape=component fillcolor="#2a2a3e" color="#cba6f7"]
|
||||
tracing [label="tracing\ntracing-subscriber" shape=component fillcolor="#2a2a3e" color="#cba6f7"]
|
||||
anyhow [label="anyhow" shape=component fillcolor="#2a2a3e" color="#cba6f7"]
|
||||
libc_crate [label="libc 0.2" shape=component fillcolor="#2a2a3e" color="#cba6f7"]
|
||||
nix_crate [label="nix 0.29\n(signal, process)" shape=component fillcolor="#2a2a3e" color="#cba6f7"]
|
||||
|
||||
// Workspace crates
|
||||
common [label="cht-common\n─────────────\nprotocol.rs (WirePacket framing)\n PacketType: Video|Audio|Control\n ControlMessage: Start|Stop|...\nlogging.rs (tracing init)"
|
||||
fillcolor="#2d2038" color="#cba6f7"]
|
||||
|
||||
client [label="cht-client [sender, Wayland]\n─────────────────────────────\nbackends/subprocess.rs ffmpeg CLI + PulseAudio\n NUT demux → EncodedPacket\nbackends/mod.rs Backend enum\ncapture.rs KmsCapture (direct backend)\nencoder.rs VaapiEncoder + MediaType\npipeline.rs capture→encode thread\nmain.rs wait_for_server, transport,\n YYYYMMDD_HHMMSS session IDs"
|
||||
fillcolor="#1e2d3e" color="#89b4fa"]
|
||||
|
||||
server [label="cht-server [receiver, mcrndeb]\n─────────────────────────────\nmain.rs TCP listener\n routes Video/Audio/Control\nsession.rs ffmpeg subprocess:\n fMP4 + UDP relay\n ADTS audio writer\n Scene relay (Unix socket)\n keyframe buffering"
|
||||
fillcolor="#1e2d3e" color="#89b4fa"]
|
||||
|
||||
// Deps
|
||||
client -> common
|
||||
server -> common
|
||||
|
||||
common -> serde
|
||||
common -> tokio
|
||||
common -> tracing
|
||||
common -> anyhow
|
||||
|
||||
client -> ffmpeg_next
|
||||
client -> tokio
|
||||
client -> tracing
|
||||
client -> anyhow
|
||||
client -> libc_crate
|
||||
client -> nix_crate
|
||||
|
||||
server -> tokio
|
||||
server -> tracing
|
||||
server -> anyhow
|
||||
|
||||
// Legend
|
||||
subgraph cluster_legend {
|
||||
label="Legend" fontcolor="#a6adc8" color="#585b70" fontname="monospace"
|
||||
l1 [label="implemented" fillcolor="#1e2d3e" color="#89b4fa" shape=box]
|
||||
l3 [label="external crate" fillcolor="#1e3a2f" color="#a6e3a1" shape=component]
|
||||
}
|
||||
}
|
||||
@@ -1,222 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 14.1.2 (0)
|
||||
-->
|
||||
<!-- Title: crates Pages: 1 -->
|
||||
<svg width="1507pt" height="498pt"
|
||||
viewBox="0.00 0.00 1507.00 498.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(36 461.7)">
|
||||
<title>crates</title>
|
||||
<polygon fill="#1e1e2e" stroke="none" points="-36,36 -36,-461.7 1470.82,-461.7 1470.82,36 -36,36"/>
|
||||
<g id="clust1" class="cluster">
|
||||
<title>cluster_legend</title>
|
||||
<polygon fill="#1e1e2e" stroke="#585b70" points="1128.82,-306.25 1128.82,-383.5 1426.82,-383.5 1426.82,-306.25 1128.82,-306.25"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="1277.82" y="-366.2" font-family="monospace" font-size="14.00" fill="#a6adc8">Legend</text>
|
||||
</g>
|
||||
<!-- ffmpeg_next -->
|
||||
<g id="node1" class="node">
|
||||
<title>ffmpeg_next</title>
|
||||
<polygon fill="#1e3a2f" stroke="#a6e3a1" points="518.6,-168.3 333.05,-168.3 333.05,-164.3 329.05,-164.3 329.05,-160.3 333.05,-160.3 333.05,-127.4 329.05,-127.4 329.05,-123.4 333.05,-123.4 333.05,-119.4 518.6,-119.4 518.6,-168.3"/>
|
||||
<polyline fill="none" stroke="#a6e3a1" points="333.05,-164.3 337.05,-164.3 337.05,-160.3 333.05,-160.3"/>
|
||||
<polyline fill="none" stroke="#a6e3a1" points="333.05,-127.4 337.05,-127.4 337.05,-123.4 333.05,-123.4"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="425.82" y="-147.8" font-family="monospace" font-size="14.00" fill="#cdd6f4">ffmpeg-next 8</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="425.82" y="-130.55" font-family="monospace" font-size="14.00" fill="#cdd6f4">(client: NUT demux)</text>
|
||||
</g>
|
||||
<!-- tokio -->
|
||||
<g id="node2" class="node">
|
||||
<title>tokio</title>
|
||||
<polygon fill="#1e2a3e" stroke="#89b4fa" points="642.1,-48.9 489.55,-48.9 489.55,-44.9 485.55,-44.9 485.55,-40.9 489.55,-40.9 489.55,-8 485.55,-8 485.55,-4 489.55,-4 489.55,0 642.1,0 642.1,-48.9"/>
|
||||
<polyline fill="none" stroke="#89b4fa" points="489.55,-44.9 493.55,-44.9 493.55,-40.9 489.55,-40.9"/>
|
||||
<polyline fill="none" stroke="#89b4fa" points="489.55,-8 493.55,-8 493.55,-4 489.55,-4"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="565.82" y="-28.4" font-family="monospace" font-size="14.00" fill="#cdd6f4">tokio 1  (full)</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="565.82" y="-11.15" font-family="monospace" font-size="14.00" fill="#cdd6f4">(async runtime)</text>
|
||||
</g>
|
||||
<!-- serde -->
|
||||
<g id="node3" class="node">
|
||||
<title>serde</title>
|
||||
<polygon fill="#2a2a3e" stroke="#cba6f7" points="837.47,-42.45 660.17,-42.45 660.17,-38.45 656.17,-38.45 656.17,-34.45 660.17,-34.45 660.17,-14.45 656.17,-14.45 656.17,-10.45 660.17,-10.45 660.17,-6.45 837.47,-6.45 837.47,-42.45"/>
|
||||
<polyline fill="none" stroke="#cba6f7" points="660.17,-38.45 664.17,-38.45 664.17,-34.45 660.17,-34.45"/>
|
||||
<polyline fill="none" stroke="#cba6f7" points="660.17,-14.45 664.17,-14.45 664.17,-10.45 660.17,-10.45"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="748.82" y="-19.78" font-family="monospace" font-size="14.00" fill="#cdd6f4">serde / serde_json</text>
|
||||
</g>
|
||||
<!-- tracing -->
|
||||
<g id="node4" class="node">
|
||||
<title>tracing</title>
|
||||
<polygon fill="#2a2a3e" stroke="#cba6f7" points="1032.47,-48.9 855.17,-48.9 855.17,-44.9 851.17,-44.9 851.17,-40.9 855.17,-40.9 855.17,-8 851.17,-8 851.17,-4 855.17,-4 855.17,0 1032.47,0 1032.47,-48.9"/>
|
||||
<polyline fill="none" stroke="#cba6f7" points="855.17,-44.9 859.17,-44.9 859.17,-40.9 855.17,-40.9"/>
|
||||
<polyline fill="none" stroke="#cba6f7" points="855.17,-8 859.17,-8 859.17,-4 855.17,-4"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="943.82" y="-28.4" font-family="monospace" font-size="14.00" fill="#cdd6f4">tracing</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="943.82" y="-11.15" font-family="monospace" font-size="14.00" fill="#cdd6f4">tracing-subscriber</text>
|
||||
</g>
|
||||
<!-- anyhow -->
|
||||
<g id="node5" class="node">
|
||||
<title>anyhow</title>
|
||||
<polygon fill="#2a2a3e" stroke="#cba6f7" points="1128.97,-42.45 1050.67,-42.45 1050.67,-38.45 1046.67,-38.45 1046.67,-34.45 1050.67,-34.45 1050.67,-14.45 1046.67,-14.45 1046.67,-10.45 1050.67,-10.45 1050.67,-6.45 1128.97,-6.45 1128.97,-42.45"/>
|
||||
<polyline fill="none" stroke="#cba6f7" points="1050.67,-38.45 1054.67,-38.45 1054.67,-34.45 1050.67,-34.45"/>
|
||||
<polyline fill="none" stroke="#cba6f7" points="1050.67,-14.45 1054.67,-14.45 1054.67,-10.45 1050.67,-10.45"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="1089.82" y="-19.78" font-family="monospace" font-size="14.00" fill="#cdd6f4">anyhow</text>
|
||||
</g>
|
||||
<!-- libc_crate -->
|
||||
<g id="node6" class="node">
|
||||
<title>libc_crate</title>
|
||||
<polygon fill="#2a2a3e" stroke="#cba6f7" points="128.22,-161.85 33.42,-161.85 33.42,-157.85 29.42,-157.85 29.42,-153.85 33.42,-153.85 33.42,-133.85 29.42,-133.85 29.42,-129.85 33.42,-129.85 33.42,-125.85 128.22,-125.85 128.22,-161.85"/>
|
||||
<polyline fill="none" stroke="#cba6f7" points="33.42,-157.85 37.42,-157.85 37.42,-153.85 33.42,-153.85"/>
|
||||
<polyline fill="none" stroke="#cba6f7" points="33.42,-133.85 37.42,-133.85 37.42,-129.85 33.42,-129.85"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="80.82" y="-139.18" font-family="monospace" font-size="14.00" fill="#cdd6f4">libc 0.2</text>
|
||||
</g>
|
||||
<!-- nix_crate -->
|
||||
<g id="node7" class="node">
|
||||
<title>nix_crate</title>
|
||||
<polygon fill="#2a2a3e" stroke="#cba6f7" points="315.35,-168.3 146.3,-168.3 146.3,-164.3 142.3,-164.3 142.3,-160.3 146.3,-160.3 146.3,-127.4 142.3,-127.4 142.3,-123.4 146.3,-123.4 146.3,-119.4 315.35,-119.4 315.35,-168.3"/>
|
||||
<polyline fill="none" stroke="#cba6f7" points="146.3,-164.3 150.3,-164.3 150.3,-160.3 146.3,-160.3"/>
|
||||
<polyline fill="none" stroke="#cba6f7" points="146.3,-127.4 150.3,-127.4 150.3,-123.4 146.3,-123.4"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="230.82" y="-147.8" font-family="monospace" font-size="14.00" fill="#cdd6f4">nix 0.29</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="230.82" y="-130.55" font-family="monospace" font-size="14.00" fill="#cdd6f4">(signal, process)</text>
|
||||
</g>
|
||||
<!-- common -->
|
||||
<g id="node8" class="node">
|
||||
<title>common</title>
|
||||
<polygon fill="#2d2038" stroke="#cba6f7" points="1004.72,-202.8 612.92,-202.8 612.92,-84.9 1004.72,-84.9 1004.72,-202.8"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="808.82" y="-182.3" font-family="monospace" font-size="14.00" fill="#cdd6f4">cht-common</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="808.82" y="-165.05" font-family="monospace" font-size="14.00" fill="#cdd6f4">─────────────</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="808.82" y="-147.8" font-family="monospace" font-size="14.00" fill="#cdd6f4">protocol.rs  (WirePacket framing)</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="808.82" y="-130.55" font-family="monospace" font-size="14.00" fill="#cdd6f4">             PacketType: Video|Audio|Control</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="808.82" y="-113.3" font-family="monospace" font-size="14.00" fill="#cdd6f4">             ControlMessage: Start|Stop|...</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="808.82" y="-96.05" font-family="monospace" font-size="14.00" fill="#cdd6f4">logging.rs   (tracing init)</text>
|
||||
</g>
|
||||
<!-- common->tokio -->
|
||||
<g id="edge4" class="edge">
|
||||
<title>common->tokio</title>
|
||||
<path fill="none" stroke="#585b70" d="M688.04,-84.49C666.33,-74.01 644.59,-63.5 625.59,-54.33"/>
|
||||
<polygon fill="#585b70" stroke="#585b70" points="627.23,-51.23 616.7,-50.03 624.18,-57.53 627.23,-51.23"/>
|
||||
</g>
|
||||
<!-- common->serde -->
|
||||
<g id="edge3" class="edge">
|
||||
<title>common->serde</title>
|
||||
<path fill="none" stroke="#585b70" d="M779,-84.49C773.36,-73.46 767.71,-62.4 762.85,-52.89"/>
|
||||
<polygon fill="#585b70" stroke="#585b70" points="766.1,-51.55 758.43,-44.24 759.86,-54.74 766.1,-51.55"/>
|
||||
</g>
|
||||
<!-- common->tracing -->
|
||||
<g id="edge5" class="edge">
|
||||
<title>common->tracing</title>
|
||||
<path fill="none" stroke="#585b70" d="M875.93,-84.49C886.87,-74.98 897.83,-65.45 907.65,-56.91"/>
|
||||
<polygon fill="#585b70" stroke="#585b70" points="909.93,-59.57 915.17,-50.36 905.33,-54.29 909.93,-59.57"/>
|
||||
</g>
|
||||
<!-- common->anyhow -->
|
||||
<g id="edge6" class="edge">
|
||||
<title>common->anyhow</title>
|
||||
<path fill="none" stroke="#585b70" d="M958.02,-84.53C986.02,-73.07 1014.93,-60.87 1041.82,-48.9 1042.75,-48.49 1043.69,-48.07 1044.63,-47.64"/>
|
||||
<polygon fill="#585b70" stroke="#585b70" points="1045.86,-50.93 1053.46,-43.54 1042.92,-44.58 1045.86,-50.93"/>
|
||||
</g>
|
||||
<!-- client -->
|
||||
<g id="node9" class="node">
|
||||
<title>client</title>
|
||||
<polygon fill="#1e2d3e" stroke="#89b4fa" points="650.6,-425.7 201.05,-425.7 201.05,-238.8 650.6,-238.8 650.6,-425.7"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="425.82" y="-405.2" font-family="monospace" font-size="14.00" fill="#cdd6f4">cht-client  [sender, Wayland]</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="425.82" y="-387.95" font-family="monospace" font-size="14.00" fill="#cdd6f4">─────────────────────────────</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="425.82" y="-370.7" font-family="monospace" font-size="14.00" fill="#cdd6f4">backends/subprocess.rs  ffmpeg CLI + PulseAudio</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="425.82" y="-353.45" font-family="monospace" font-size="14.00" fill="#cdd6f4">                        NUT demux → EncodedPacket</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="425.82" y="-336.2" font-family="monospace" font-size="14.00" fill="#cdd6f4">backends/mod.rs         Backend enum</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="425.82" y="-318.95" font-family="monospace" font-size="14.00" fill="#cdd6f4">capture.rs              KmsCapture (direct backend)</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="425.82" y="-301.7" font-family="monospace" font-size="14.00" fill="#cdd6f4">encoder.rs              VaapiEncoder + MediaType</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="425.82" y="-284.45" font-family="monospace" font-size="14.00" fill="#cdd6f4">pipeline.rs             capture→encode thread</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="425.82" y="-267.2" font-family="monospace" font-size="14.00" fill="#cdd6f4">main.rs                 wait_for_server, transport,</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="425.82" y="-249.95" font-family="monospace" font-size="14.00" fill="#cdd6f4">                        YYYYMMDD_HHMMSS session IDs</text>
|
||||
</g>
|
||||
<!-- client->ffmpeg_next -->
|
||||
<g id="edge7" class="edge">
|
||||
<title>client->ffmpeg_next</title>
|
||||
<path fill="none" stroke="#585b70" d="M425.82,-238.32C425.82,-217.48 425.82,-196.62 425.82,-179.92"/>
|
||||
<polygon fill="#585b70" stroke="#585b70" points="429.32,-180.06 425.82,-170.06 422.32,-180.06 429.32,-180.06"/>
|
||||
</g>
|
||||
<!-- client->tokio -->
|
||||
<g id="edge8" class="edge">
|
||||
<title>client->tokio</title>
|
||||
<path fill="none" stroke="#585b70" d="M200.68,-283.69C122.23,-262.21 47.96,-234.5 24.82,-202.8 -6.06,-160.47 -10.15,-123.92 24.82,-84.9 54.48,-51.81 332.63,-35.25 478.09,-28.79"/>
|
||||
<polygon fill="#585b70" stroke="#585b70" points="477.84,-32.31 487.67,-28.38 477.53,-25.32 477.84,-32.31"/>
|
||||
</g>
|
||||
<!-- client->tracing -->
|
||||
<g id="edge9" class="edge">
|
||||
<title>client->tracing</title>
|
||||
<path fill="none" stroke="#585b70" d="M501.29,-238.42C510.41,-226.56 519.45,-214.49 527.82,-202.8 564.14,-152.13 551.43,-118.68 603.82,-84.9 692.54,-27.7 736.68,-66.94 843.59,-49.32"/>
|
||||
<polygon fill="#585b70" stroke="#585b70" points="844.12,-52.78 853.34,-47.56 842.88,-45.89 844.12,-52.78"/>
|
||||
</g>
|
||||
<!-- client->anyhow -->
|
||||
<g id="edge10" class="edge">
|
||||
<title>client->anyhow</title>
|
||||
<path fill="none" stroke="#585b70" d="M651.04,-262.97C684.64,-254.07 719,-245.67 751.82,-238.8 809.35,-226.75 967.08,-238.42 1013.82,-202.8 1061.51,-166.46 1079.67,-94.24 1086.28,-54.08"/>
|
||||
<polygon fill="#585b70" stroke="#585b70" points="1089.73,-54.62 1087.75,-44.22 1082.81,-53.59 1089.73,-54.62"/>
|
||||
</g>
|
||||
<!-- client->libc_crate -->
|
||||
<g id="edge11" class="edge">
|
||||
<title>client->libc_crate</title>
|
||||
<path fill="none" stroke="#585b70" d="M200.61,-241.57C178.39,-229.68 156.73,-216.73 136.82,-202.8 123.98,-193.81 111.65,-181.59 101.85,-170.69"/>
|
||||
<polygon fill="#585b70" stroke="#585b70" points="104.76,-168.71 95.56,-163.46 99.48,-173.3 104.76,-168.71"/>
|
||||
</g>
|
||||
<!-- client->nix_crate -->
|
||||
<g id="edge12" class="edge">
|
||||
<title>client->nix_crate</title>
|
||||
<path fill="none" stroke="#585b70" d="M328.61,-238.32C305.11,-215.86 281.6,-193.38 263.52,-176.1"/>
|
||||
<polygon fill="#585b70" stroke="#585b70" points="266.35,-173.97 256.7,-169.59 261.51,-179.03 266.35,-173.97"/>
|
||||
</g>
|
||||
<!-- client->common -->
|
||||
<g id="edge1" class="edge">
|
||||
<title>client->common</title>
|
||||
<path fill="none" stroke="#585b70" d="M616.76,-238.32C637.67,-228.15 658.58,-217.97 678.5,-208.28"/>
|
||||
<polygon fill="#585b70" stroke="#585b70" points="680.01,-211.44 687.47,-203.91 676.94,-205.14 680.01,-211.44"/>
|
||||
</g>
|
||||
<!-- server -->
|
||||
<g id="node10" class="node">
|
||||
<title>server</title>
|
||||
<polygon fill="#1e2d3e" stroke="#89b4fa" points="1119.22,-417.07 760.42,-417.07 760.42,-247.43 1119.22,-247.43 1119.22,-417.07"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="939.82" y="-396.57" font-family="monospace" font-size="14.00" fill="#cdd6f4">cht-server  [receiver, mcrndeb]</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="939.82" y="-379.32" font-family="monospace" font-size="14.00" fill="#cdd6f4">─────────────────────────────</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="939.82" y="-362.07" font-family="monospace" font-size="14.00" fill="#cdd6f4">main.rs       TCP listener</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="939.82" y="-344.82" font-family="monospace" font-size="14.00" fill="#cdd6f4">              routes Video/Audio/Control</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="939.82" y="-327.57" font-family="monospace" font-size="14.00" fill="#cdd6f4">session.rs    ffmpeg subprocess:</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="939.82" y="-310.32" font-family="monospace" font-size="14.00" fill="#cdd6f4">                fMP4 + UDP relay</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="939.82" y="-293.07" font-family="monospace" font-size="14.00" fill="#cdd6f4">              ADTS audio writer</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="939.82" y="-275.82" font-family="monospace" font-size="14.00" fill="#cdd6f4">              Scene relay (Unix socket)</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="939.82" y="-258.57" font-family="monospace" font-size="14.00" fill="#cdd6f4">                keyframe buffering</text>
|
||||
</g>
|
||||
<!-- server->tokio -->
|
||||
<g id="edge13" class="edge">
|
||||
<title>server->tokio</title>
|
||||
<path fill="none" stroke="#585b70" d="M760.26,-270.87C686.61,-244.58 615.68,-216.64 603.82,-202.8 569.66,-162.92 563.88,-99.75 564,-60.55"/>
|
||||
<polygon fill="#585b70" stroke="#585b70" points="567.5,-60.78 564.18,-50.72 560.5,-60.65 567.5,-60.78"/>
|
||||
</g>
|
||||
<!-- server->tracing -->
|
||||
<g id="edge14" class="edge">
|
||||
<title>server->tracing</title>
|
||||
<path fill="none" stroke="#585b70" d="M996.34,-247.25C1003.55,-232.95 1009.8,-217.84 1013.82,-202.8 1027.36,-152.18 1035.83,-132.46 1013.82,-84.9 1008.85,-74.15 1000.87,-64.64 992.05,-56.55"/>
|
||||
<polygon fill="#585b70" stroke="#585b70" points="994.46,-53.99 984.56,-50.21 989.93,-59.34 994.46,-53.99"/>
|
||||
</g>
|
||||
<!-- server->anyhow -->
|
||||
<g id="edge15" class="edge">
|
||||
<title>server->anyhow</title>
|
||||
<path fill="none" stroke="#585b70" d="M1054.86,-247.12C1066.85,-233.63 1077.35,-218.8 1084.82,-202.8 1107.37,-154.53 1101.74,-90.54 1095.71,-54.1"/>
|
||||
<polygon fill="#585b70" stroke="#585b70" points="1099.17,-53.57 1093.95,-44.35 1092.28,-54.81 1099.17,-53.57"/>
|
||||
</g>
|
||||
<!-- server->common -->
|
||||
<g id="edge2" class="edge">
|
||||
<title>server->common</title>
|
||||
<path fill="none" stroke="#585b70" d="M880.65,-247.05C872.49,-235.44 864.2,-223.64 856.29,-212.39"/>
|
||||
<polygon fill="#585b70" stroke="#585b70" points="859.23,-210.49 850.62,-204.32 853.5,-214.51 859.23,-210.49"/>
|
||||
</g>
|
||||
<!-- l1 -->
|
||||
<g id="node11" class="node">
|
||||
<title>l1</title>
|
||||
<polygon fill="#1e2d3e" stroke="#89b4fa" points="1256.6,-350.25 1137.05,-350.25 1137.05,-314.25 1256.6,-314.25 1256.6,-350.25"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="1196.82" y="-327.57" font-family="monospace" font-size="14.00" fill="#cdd6f4">implemented</text>
|
||||
</g>
|
||||
<!-- l3 -->
|
||||
<g id="node12" class="node">
|
||||
<title>l3</title>
|
||||
<polygon fill="#1e3a2f" stroke="#a6e3a1" points="1418.97,-350.25 1274.67,-350.25 1274.67,-346.25 1270.67,-346.25 1270.67,-342.25 1274.67,-342.25 1274.67,-322.25 1270.67,-322.25 1270.67,-318.25 1274.67,-318.25 1274.67,-314.25 1418.97,-314.25 1418.97,-350.25"/>
|
||||
<polyline fill="none" stroke="#a6e3a1" points="1274.67,-346.25 1278.67,-346.25 1278.67,-342.25 1274.67,-342.25"/>
|
||||
<polyline fill="none" stroke="#a6e3a1" points="1274.67,-322.25 1278.67,-322.25 1278.67,-318.25 1274.67,-318.25"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="1346.82" y="-327.57" font-family="monospace" font-size="14.00" fill="#cdd6f4">external crate</text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 18 KiB |
@@ -1,193 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Media Transport — Architecture</title>
|
||||
<style>
|
||||
* { box-sizing: border-box; margin: 0; padding: 0; }
|
||||
|
||||
body {
|
||||
display: flex;
|
||||
height: 100vh;
|
||||
font-family: monospace;
|
||||
background: #1e1e2e;
|
||||
color: #cdd6f4;
|
||||
}
|
||||
|
||||
nav {
|
||||
width: 220px;
|
||||
min-width: 220px;
|
||||
background: #181825;
|
||||
border-right: 1px solid #313244;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 1rem 0;
|
||||
}
|
||||
|
||||
nav h1 {
|
||||
font-size: 0.75rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.1em;
|
||||
color: #6c7086;
|
||||
padding: 0 1rem 0.75rem;
|
||||
border-bottom: 1px solid #313244;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
nav a {
|
||||
display: block;
|
||||
padding: 0.5rem 1rem;
|
||||
color: #cdd6f4;
|
||||
text-decoration: none;
|
||||
font-size: 0.85rem;
|
||||
border-left: 3px solid transparent;
|
||||
transition: background 0.1s, border-color 0.1s;
|
||||
}
|
||||
|
||||
nav a:hover { background: #313244; }
|
||||
nav a.active { border-left-color: #89b4fa; color: #89b4fa; background: #1e2d3e; }
|
||||
|
||||
nav .subtitle {
|
||||
font-size: 0.7rem;
|
||||
color: #6c7086;
|
||||
padding: 0 1rem;
|
||||
margin-top: 0.25rem;
|
||||
}
|
||||
|
||||
nav .phase-badge {
|
||||
font-size: 0.65rem;
|
||||
color: #a6e3a1;
|
||||
float: right;
|
||||
}
|
||||
|
||||
nav .section {
|
||||
font-size: 0.65rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.08em;
|
||||
color: #6c7086;
|
||||
padding: 1rem 1rem 0.25rem;
|
||||
}
|
||||
|
||||
main {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
header {
|
||||
padding: 0.75rem 1.25rem;
|
||||
background: #181825;
|
||||
border-bottom: 1px solid #313244;
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
header h2 { font-size: 0.95rem; }
|
||||
header .desc { font-size: 0.75rem; color: #6c7086; }
|
||||
|
||||
.viewer {
|
||||
flex: 1;
|
||||
overflow: auto;
|
||||
padding: 1.5rem;
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: center;
|
||||
background: #1e1e2e;
|
||||
}
|
||||
|
||||
.viewer object,
|
||||
.viewer img {
|
||||
max-width: 100%;
|
||||
border-radius: 6px;
|
||||
box-shadow: 0 4px 24px rgba(0,0,0,0.5);
|
||||
}
|
||||
|
||||
.placeholder {
|
||||
color: #6c7086;
|
||||
font-size: 0.85rem;
|
||||
margin-top: 4rem;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<nav>
|
||||
<h1>Media Transport</h1>
|
||||
|
||||
<div class="section">Workspace</div>
|
||||
<a href="#" data-svg="crates.svg" data-title="Crate Dependency Graph" data-desc="Workspace members and external deps">
|
||||
Crate graph
|
||||
</a>
|
||||
|
||||
<div class="section">Client (sender)</div>
|
||||
<a href="#" data-svg="client-pipeline.svg" data-title="Client Pipeline" data-desc="KMS capture + PulseAudio → VAAPI H.264 + AAC → TCP transport">
|
||||
Pipeline
|
||||
</a>
|
||||
|
||||
<div class="section">Server (receiver)</div>
|
||||
<a href="#" data-svg="server-pipeline.svg" data-title="Server Pipeline" data-desc="fMP4 recording, UDP live relay, scene detection (UDS → Python), audio extraction">
|
||||
Pipeline
|
||||
</a>
|
||||
|
||||
<div class="section">Status</div>
|
||||
<a href="#" data-svg="" data-title="Current State (2026-04-10)" data-desc="Architecture status and known regressions"
|
||||
onclick="event.preventDefault(); document.querySelectorAll('nav a').forEach(l=>l.classList.remove('active')); this.classList.add('active'); document.getElementById('title').textContent=this.dataset.title; document.getElementById('desc').textContent=this.dataset.desc; document.getElementById('viewer').innerHTML=document.getElementById('status-content').innerHTML; return false;">
|
||||
State & regressions
|
||||
</a>
|
||||
</nav>
|
||||
|
||||
<template id="status-content">
|
||||
<div style="max-width:720px; font-size:0.85rem; line-height:1.6; color:#cdd6f4">
|
||||
<h3 style="color:#f38ba8; margin-bottom:0.5rem">Scene detection regressed</h3>
|
||||
<p>In the Python-only pipeline, scene detection was a branch of the <b>same ffmpeg process</b> that records (fMP4 + UDP relay + CUDA decode + select filter). The flush trick worked because all outputs shared one decoder.</p>
|
||||
<p style="margin-top:0.5rem">After Rust took over transport, scene detection became a <b>separate ffmpeg</b> fed via <code>scene.sock</code> Unix socket relay. Different buffering semantics broke the "one behind" flush fix, and <code>try_send</code> drops cause decoder corruption until the next keyframe.</p>
|
||||
<h3 style="color:#a6e3a1; margin:1rem 0 0.5rem">Working fallback</h3>
|
||||
<p>The Python-only path (<code>StreamRecorder</code> + <code>SessionProcessor</code>) still exists. <code>lifecycle.start(rust_transport=False)</code> bypasses Rust transport entirely. Plan: restore this as the default, keep Rust opt-in.</p>
|
||||
<h3 style="color:#89b4fa; margin:1rem 0 0.5rem">What Rust transport got right</h3>
|
||||
<ul style="padding-left:1.2rem">
|
||||
<li>Connect time: 20s → 3s</li>
|
||||
<li>Session reload: 1-2s</li>
|
||||
<li>Custom framed protocol with reconnection support</li>
|
||||
<li>Clean fMP4 recording + UDP live relay</li>
|
||||
</ul>
|
||||
<h3 style="color:#cba6f7; margin:1rem 0 0.5rem">Next: scene detection back into server ffmpeg</h3>
|
||||
<p>Add scene detection as a third output of the Rust server's ffmpeg command (decode + select filter + MJPEG pipe) instead of relaying raw H.264 to a separate process. See <code>def/10-scene-detect-to-rust.md</code>.</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<main>
|
||||
<header>
|
||||
<h2 id="title">Select a diagram</h2>
|
||||
<span class="desc" id="desc"></span>
|
||||
</header>
|
||||
<div class="viewer" id="viewer">
|
||||
<p class="placeholder">← pick a diagram from the sidebar</p>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<script>
|
||||
const viewer = document.getElementById('viewer');
|
||||
const titleEl = document.getElementById('title');
|
||||
const descEl = document.getElementById('desc');
|
||||
|
||||
document.querySelectorAll('nav a').forEach(link => {
|
||||
link.addEventListener('click', e => {
|
||||
e.preventDefault();
|
||||
document.querySelectorAll('nav a').forEach(l => l.classList.remove('active'));
|
||||
link.classList.add('active');
|
||||
|
||||
titleEl.textContent = link.dataset.title;
|
||||
descEl.textContent = link.dataset.desc;
|
||||
|
||||
// Use <object> so SVG internal text/links work
|
||||
viewer.innerHTML = `<object type="image/svg+xml" data="${link.dataset.svg}"></object>`;
|
||||
});
|
||||
});
|
||||
|
||||
// Auto-select first
|
||||
document.querySelector('nav a').click();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,76 +0,0 @@
|
||||
// Server pipeline — current implementation
|
||||
// Receiver machine (mcrndeb: X11, RTX 3080, NVDEC)
|
||||
digraph server_pipeline {
|
||||
graph [fontname="monospace" bgcolor="#1e1e2e" rankdir=TB pad="0.6" splines=polyline]
|
||||
node [fontname="monospace" fontcolor="#cdd6f4" style=filled shape=box
|
||||
fillcolor="#313244" color="#585b70" margin="0.25,0.12"]
|
||||
edge [color="#585b70" fontname="monospace" fontcolor="#a6adc8"]
|
||||
|
||||
net [label="TCP :4447\n(WirePacket)" shape=parallelogram fillcolor="#1e2a3e" color="#89b4fa"]
|
||||
python [label="Python GUI\n(cht app)" shape=parallelogram fillcolor="#2a2a3e" color="#cba6f7"]
|
||||
|
||||
subgraph cluster_rust {
|
||||
label="cht-server (Rust)" fontcolor="#a6e3a1" color="#a6e3a1" fontname="monospace"
|
||||
|
||||
listener [label="Listener\n─────────────\nTCP accept\nreads WirePacket\nroutes by type:\n Video → ffmpeg + scene relay\n Audio → ADTS file\n Control → session lifecycle"
|
||||
fillcolor="#1e2d3e" color="#89b4fa"]
|
||||
|
||||
ffmpeg_rec [label="ffmpeg subprocess\n─────────────\nH.264 pipe:0 → 2 outputs:\n 1. fMP4 (frag_keyframe)\n 2. UDP :4445 (mpegts)"
|
||||
fillcolor="#1e2d3e" color="#89b4fa"]
|
||||
|
||||
scene_relay [label="Scene Relay\n─────────────\nUnix socket (scene.sock)\nbuffers latest keyframe\nbest-effort: drops if slow\n100ms write timeout"
|
||||
fillcolor="#1e2d3e" color="#89b4fa"]
|
||||
|
||||
audio_writer [label="Audio Writer\n─────────────\nADTS header + raw AAC\n→ stream/audio.aac"
|
||||
fillcolor="#1e2d3e" color="#89b4fa"]
|
||||
|
||||
active_session [label="active-session\n─────────────\nfile at data/active-session\nPython polls to discover\nsession dir" shape=note
|
||||
fillcolor="#2a2a3e" color="#585b70"]
|
||||
}
|
||||
|
||||
subgraph cluster_python {
|
||||
label="Python (cht app)" fontcolor="#cba6f7" color="#cba6f7" fontname="monospace"
|
||||
|
||||
scene_ffmpeg [label="Scene Detector\n─────────────\nconnects to scene.sock\npipes H.264 → ffmpeg:\n CUDA decode\n select=gt(scene,thresh)\n showinfo → timestamps\n MJPEG → JPEG frames"
|
||||
fillcolor="#2d2038" color="#cba6f7"]
|
||||
|
||||
audio_extract [label="Audio Extractor\n─────────────\nreads audio.aac\nffmpeg → 16kHz mono WAV\nchunks + transcript WAVs"
|
||||
fillcolor="#2d2038" color="#cba6f7"]
|
||||
|
||||
transcriber [label="Transcriber\n─────────────\nfaster-whisper (CUDA)\nsegment grouping\nslider: chunk size + lines/group"
|
||||
fillcolor="#2d2038" color="#cba6f7"]
|
||||
}
|
||||
|
||||
// Flow — Rust server
|
||||
net -> listener [label="WirePacket"]
|
||||
listener -> ffmpeg_rec [label="H.264 video"]
|
||||
listener -> scene_relay [label="H.264 copy\n+ keyframe flag"]
|
||||
listener -> audio_writer [label="AAC audio"]
|
||||
listener -> active_session [style=dashed label="on SessionStart"]
|
||||
|
||||
// Flow — Python scene detection
|
||||
scene_relay -> scene_ffmpeg [label="raw H.264\n(Unix socket)" color="#a6e3a1"]
|
||||
|
||||
// Outputs
|
||||
fmp4 [label="stream/\nrecording_000.mp4\n(fragmented MP4)" shape=folder fillcolor="#2a2a3e" color="#585b70"]
|
||||
udp_live [label="UDP :4445\n(mpegts → mpv)" shape=parallelogram fillcolor="#2a2a3e" color="#585b70"]
|
||||
aac_file [label="stream/\naudio.aac\n(ADTS-wrapped)" shape=folder fillcolor="#2a2a3e" color="#585b70"]
|
||||
frames [label="frames/\nindex.json + *.jpg" shape=folder fillcolor="#2a2a3e" color="#585b70"]
|
||||
audio_dir [label="audio/\nchunk_*.wav\ntranscript_*.wav" shape=folder fillcolor="#2a2a3e" color="#585b70"]
|
||||
|
||||
ffmpeg_rec -> fmp4 [label="copy"]
|
||||
ffmpeg_rec -> udp_live [label="copy"]
|
||||
audio_writer -> aac_file
|
||||
scene_ffmpeg -> frames [label="JPEG on\nscene change"]
|
||||
audio_extract -> audio_dir
|
||||
audio_dir -> transcriber [label="WAV chunks"]
|
||||
|
||||
// Python reads files
|
||||
aac_file -> audio_extract [label="reads" style=dashed]
|
||||
active_session -> python [label="discovers\nsession dir" style=dashed]
|
||||
|
||||
// Known regression (2026-04-10)
|
||||
regression [label="⚠ REGRESSED\n─────────────\nScene relay (separate pipe)\nbreaks 'one behind' flush.\ntry_send drops → decoder\ncorruption until keyframe.\n\nFix: move scene detection\ninto server ffmpeg as 3rd\noutput branch (10-scene-\ndetect-to-rust.md)"
|
||||
shape=note fillcolor="#3d1e1e" color="#f38ba8" fontcolor="#f38ba8"]
|
||||
scene_relay -> regression [style=dashed color="#f38ba8"]
|
||||
}
|
||||
@@ -1,286 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 14.1.2 (0)
|
||||
-->
|
||||
<!-- Title: server_pipeline Pages: 1 -->
|
||||
<svg width="1677pt" height="1243pt"
|
||||
viewBox="0.00 0.00 1677.00 1243.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(43.2 1200.16)">
|
||||
<title>server_pipeline</title>
|
||||
<polygon fill="#1e1e2e" stroke="none" points="-43.2,43.2 -43.2,-1200.16 1633.33,-1200.16 1633.33,43.2 -43.2,43.2"/>
|
||||
<g id="clust1" class="cluster">
|
||||
<title>cluster_rust</title>
|
||||
<polygon fill="#1e1e2e" stroke="#a6e3a1" points="284.12,-622.34 284.12,-1010.15 1314.12,-1010.15 1314.12,-622.34 284.12,-622.34"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="799.12" y="-992.85" font-family="monospace" font-size="14.00" fill="#a6e3a1">cht-server (Rust)</text>
|
||||
</g>
|
||||
<g id="clust2" class="cluster">
|
||||
<title>cluster_python</title>
|
||||
<polygon fill="#1e1e2e" stroke="#cba6f7" points="754.12,-114.28 754.12,-310.81 1582.12,-310.81 1582.12,-114.28 754.12,-114.28"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="1168.12" y="-293.51" font-family="monospace" font-size="14.00" fill="#cba6f7">Python (cht app)</text>
|
||||
</g>
|
||||
<!-- net -->
|
||||
<g id="node1" class="node">
|
||||
<title>net</title>
|
||||
<polygon fill="#1e2a3e" stroke="#89b4fa" points="915.09,-1156.96 692.44,-1156.96 635.16,-1053.4 857.81,-1053.4 915.09,-1156.96"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="775.12" y="-1109.13" font-family="monospace" font-size="14.00" fill="#cdd6f4">TCP :4447</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="775.12" y="-1091.88" font-family="monospace" font-size="14.00" fill="#cdd6f4">(WirePacket)</text>
|
||||
</g>
|
||||
<!-- listener -->
|
||||
<g id="node3" class="node">
|
||||
<title>listener</title>
|
||||
<polygon fill="#1e2d3e" stroke="#89b4fa" points="916.88,-976.9 633.38,-976.9 633.38,-821.62 916.88,-821.62 916.88,-976.9"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="775.12" y="-954.96" font-family="monospace" font-size="14.00" fill="#cdd6f4">Listener</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="775.12" y="-937.71" font-family="monospace" font-size="14.00" fill="#cdd6f4">─────────────</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="775.12" y="-920.46" font-family="monospace" font-size="14.00" fill="#cdd6f4">TCP accept</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="775.12" y="-903.21" font-family="monospace" font-size="14.00" fill="#cdd6f4">reads WirePacket</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="775.12" y="-885.96" font-family="monospace" font-size="14.00" fill="#cdd6f4">routes by type:</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="775.12" y="-868.71" font-family="monospace" font-size="14.00" fill="#cdd6f4">  Video → ffmpeg + scene relay</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="775.12" y="-851.46" font-family="monospace" font-size="14.00" fill="#cdd6f4">  Audio → ADTS file</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="775.12" y="-834.21" font-family="monospace" font-size="14.00" fill="#cdd6f4">  Control → session lifecycle</text>
|
||||
</g>
|
||||
<!-- net->listener -->
|
||||
<g id="edge1" class="edge">
|
||||
<title>net->listener</title>
|
||||
<path fill="none" stroke="#585b70" d="M775.12,-1052.99C775.12,-1033.5 775.12,-1010.68 775.12,-988.72"/>
|
||||
<polygon fill="#585b70" stroke="#585b70" points="778.63,-988.85 775.13,-978.85 771.63,-988.85 778.63,-988.85"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="816.38" y="-1022.1" font-family="monospace" font-size="14.00" fill="#a6adc8">WirePacket</text>
|
||||
</g>
|
||||
<!-- python -->
|
||||
<g id="node2" class="node">
|
||||
<title>python</title>
|
||||
<polygon fill="#2a2a3e" stroke="#cba6f7" points="1361.98,-508.73 1166.55,-508.73 1116.27,-405.17 1311.7,-405.17 1361.98,-508.73"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="1239.12" y="-460.9" font-family="monospace" font-size="14.00" fill="#cdd6f4">Python GUI</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="1239.12" y="-443.65" font-family="monospace" font-size="14.00" fill="#cdd6f4">(cht app)</text>
|
||||
</g>
|
||||
<!-- ffmpeg_rec -->
|
||||
<g id="node4" class="node">
|
||||
<title>ffmpeg_rec</title>
|
||||
<polygon fill="#1e2d3e" stroke="#89b4fa" points="534.25,-742.49 292,-742.49 292,-638.96 534.25,-638.96 534.25,-742.49"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="413.12" y="-720.55" font-family="monospace" font-size="14.00" fill="#cdd6f4">ffmpeg subprocess</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="413.12" y="-703.3" font-family="monospace" font-size="14.00" fill="#cdd6f4">─────────────</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="413.12" y="-686.05" font-family="monospace" font-size="14.00" fill="#cdd6f4">H.264 pipe:0 → 2 outputs:</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="413.12" y="-668.8" font-family="monospace" font-size="14.00" fill="#cdd6f4">  1. fMP4 (frag_keyframe)</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="413.12" y="-651.55" font-family="monospace" font-size="14.00" fill="#cdd6f4">  2. UDP :4445 (mpegts)</text>
|
||||
</g>
|
||||
<!-- listener->ffmpeg_rec -->
|
||||
<g id="edge2" class="edge">
|
||||
<title>listener->ffmpeg_rec</title>
|
||||
<path fill="none" stroke="#585b70" d="M640.07,-821.21C597.84,-797.12 552.04,-770.98 512.71,-748.55"/>
|
||||
<polygon fill="#585b70" stroke="#585b70" points="514.59,-745.59 504.17,-743.67 511.12,-751.67 514.59,-745.59"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="650.35" y="-781.69" font-family="monospace" font-size="14.00" fill="#a6adc8">H.264 video</text>
|
||||
</g>
|
||||
<!-- scene_relay -->
|
||||
<g id="node5" class="node">
|
||||
<title>scene_relay</title>
|
||||
<polygon fill="#1e2d3e" stroke="#89b4fa" points="802.38,-751.12 551.88,-751.12 551.88,-630.34 802.38,-630.34 802.38,-751.12"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="677.12" y="-729.18" font-family="monospace" font-size="14.00" fill="#cdd6f4">Scene Relay</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="677.12" y="-711.93" font-family="monospace" font-size="14.00" fill="#cdd6f4">─────────────</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="677.12" y="-694.68" font-family="monospace" font-size="14.00" fill="#cdd6f4">Unix socket (scene.sock)</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="677.12" y="-677.43" font-family="monospace" font-size="14.00" fill="#cdd6f4">buffers latest keyframe</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="677.12" y="-660.18" font-family="monospace" font-size="14.00" fill="#cdd6f4">best-effort: drops if slow</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="677.12" y="-642.93" font-family="monospace" font-size="14.00" fill="#cdd6f4">100ms write timeout</text>
|
||||
</g>
|
||||
<!-- listener->scene_relay -->
|
||||
<g id="edge3" class="edge">
|
||||
<title>listener->scene_relay</title>
|
||||
<path fill="none" stroke="#585b70" d="M738.63,-821.36C729.36,-801.82 719.45,-780.93 710.35,-761.75"/>
|
||||
<polygon fill="#585b70" stroke="#585b70" points="713.63,-760.49 706.18,-752.96 707.3,-763.5 713.63,-760.49"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="790.94" y="-790.32" font-family="monospace" font-size="14.00" fill="#a6adc8">H.264 copy</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="790.94" y="-773.07" font-family="monospace" font-size="14.00" fill="#a6adc8">+ keyframe flag</text>
|
||||
</g>
|
||||
<!-- audio_writer -->
|
||||
<g id="node6" class="node">
|
||||
<title>audio_writer</title>
|
||||
<polygon fill="#1e2d3e" stroke="#89b4fa" points="1029.75,-733.87 820.5,-733.87 820.5,-647.59 1029.75,-647.59 1029.75,-733.87"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="925.12" y="-711.93" font-family="monospace" font-size="14.00" fill="#cdd6f4">Audio Writer</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="925.12" y="-694.68" font-family="monospace" font-size="14.00" fill="#cdd6f4">─────────────</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="925.12" y="-677.43" font-family="monospace" font-size="14.00" fill="#cdd6f4">ADTS header + raw AAC</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="925.12" y="-660.18" font-family="monospace" font-size="14.00" fill="#cdd6f4">→ stream/audio.aac</text>
|
||||
</g>
|
||||
<!-- listener->audio_writer -->
|
||||
<g id="edge4" class="edge">
|
||||
<title>listener->audio_writer</title>
|
||||
<path fill="none" stroke="#585b70" d="M841.7,-821.42C850.82,-810.9 857.12,-803.62 857.12,-803.62 857.12,-803.62 875.59,-773.23 893.28,-744.13"/>
|
||||
<polygon fill="#585b70" stroke="#585b70" points="896.23,-746.01 898.44,-735.64 890.25,-742.37 896.23,-746.01"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="914.34" y="-781.69" font-family="monospace" font-size="14.00" fill="#a6adc8">AAC audio</text>
|
||||
</g>
|
||||
<!-- active_session -->
|
||||
<g id="node7" class="node">
|
||||
<title>active_session</title>
|
||||
<polygon fill="#2a2a3e" stroke="#585b70" points="1300.5,-742.49 1047.75,-742.49 1047.75,-638.96 1306.5,-638.96 1306.5,-736.49 1300.5,-742.49"/>
|
||||
<polyline fill="none" stroke="#585b70" points="1300.5,-742.49 1300.5,-736.49"/>
|
||||
<polyline fill="none" stroke="#585b70" points="1306.5,-736.49 1300.5,-736.49"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="1177.12" y="-720.55" font-family="monospace" font-size="14.00" fill="#cdd6f4">active-session</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="1177.12" y="-703.3" font-family="monospace" font-size="14.00" fill="#cdd6f4">─────────────</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="1177.12" y="-686.05" font-family="monospace" font-size="14.00" fill="#cdd6f4">file at data/active-session</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="1177.12" y="-668.8" font-family="monospace" font-size="14.00" fill="#cdd6f4">Python polls to discover</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="1177.12" y="-651.55" font-family="monospace" font-size="14.00" fill="#cdd6f4">session dir</text>
|
||||
</g>
|
||||
<!-- listener->active_session -->
|
||||
<g id="edge5" class="edge">
|
||||
<title>listener->active_session</title>
|
||||
<path fill="none" stroke="#585b70" stroke-dasharray="5,2" d="M917.14,-825.3C966.5,-799.94 1021.08,-771.9 1067.43,-748.09"/>
|
||||
<polygon fill="#585b70" stroke="#585b70" points="1068.85,-751.29 1076.14,-743.61 1065.65,-745.07 1068.85,-751.29"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="1085.83" y="-781.69" font-family="monospace" font-size="14.00" fill="#a6adc8">on SessionStart</text>
|
||||
</g>
|
||||
<!-- fmp4 -->
|
||||
<g id="node11" class="node">
|
||||
<title>fmp4</title>
|
||||
<polygon fill="#2a2a3e" stroke="#585b70" points="176.25,-491.46 173.25,-495.46 152.25,-495.46 149.25,-491.46 0,-491.46 0,-422.44 176.25,-422.44 176.25,-491.46"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="88.12" y="-469.52" font-family="monospace" font-size="14.00" fill="#cdd6f4">stream/</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="88.12" y="-452.27" font-family="monospace" font-size="14.00" fill="#cdd6f4">recording_000.mp4</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="88.12" y="-435.02" font-family="monospace" font-size="14.00" fill="#cdd6f4">(fragmented MP4)</text>
|
||||
</g>
|
||||
<!-- ffmpeg_rec->fmp4 -->
|
||||
<g id="edge7" class="edge">
|
||||
<title>ffmpeg_rec->fmp4</title>
|
||||
<path fill="none" stroke="#585b70" d="M323.34,-638.58C259.54,-602.23 185.12,-559.84 185.12,-559.84 185.12,-559.84 154.9,-528.09 128.2,-500.04"/>
|
||||
<polygon fill="#585b70" stroke="#585b70" points="130.9,-497.8 121.47,-492.97 125.83,-502.63 130.9,-497.8"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="288.5" y="-590.41" font-family="monospace" font-size="14.00" fill="#a6adc8">copy</text>
|
||||
</g>
|
||||
<!-- udp_live -->
|
||||
<g id="node12" class="node">
|
||||
<title>udp_live</title>
|
||||
<polygon fill="#2a2a3e" stroke="#585b70" points="508.19,-508.73 258.33,-508.73 194.06,-405.17 443.92,-405.17 508.19,-508.73"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="351.12" y="-460.9" font-family="monospace" font-size="14.00" fill="#cdd6f4">UDP :4445</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="351.12" y="-443.65" font-family="monospace" font-size="14.00" fill="#cdd6f4">(mpegts → mpv)</text>
|
||||
</g>
|
||||
<!-- ffmpeg_rec->udp_live -->
|
||||
<g id="edge8" class="edge">
|
||||
<title>ffmpeg_rec->udp_live</title>
|
||||
<path fill="none" stroke="#585b70" d="M399.44,-638.58C390.06,-603.51 377.57,-556.8 367.63,-519.67"/>
|
||||
<polygon fill="#585b70" stroke="#585b70" points="371.13,-519.19 365.16,-510.43 364.37,-521 371.13,-519.19"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="407.8" y="-590.41" font-family="monospace" font-size="14.00" fill="#a6adc8">copy</text>
|
||||
</g>
|
||||
<!-- scene_ffmpeg -->
|
||||
<g id="node8" class="node">
|
||||
<title>scene_ffmpeg</title>
|
||||
<polygon fill="#2d2038" stroke="#cba6f7" points="1004.25,-277.56 762,-277.56 762,-122.28 1004.25,-122.28 1004.25,-277.56"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="883.12" y="-255.62" font-family="monospace" font-size="14.00" fill="#cdd6f4">Scene Detector</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="883.12" y="-238.37" font-family="monospace" font-size="14.00" fill="#cdd6f4">─────────────</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="883.12" y="-221.12" font-family="monospace" font-size="14.00" fill="#cdd6f4">connects to scene.sock</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="883.12" y="-203.87" font-family="monospace" font-size="14.00" fill="#cdd6f4">pipes H.264 → ffmpeg:</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="883.12" y="-186.62" font-family="monospace" font-size="14.00" fill="#cdd6f4">  CUDA decode</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="883.12" y="-169.37" font-family="monospace" font-size="14.00" fill="#cdd6f4">  select=gt(scene,thresh)</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="883.12" y="-152.12" font-family="monospace" font-size="14.00" fill="#cdd6f4">  showinfo → timestamps</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="883.12" y="-134.87" font-family="monospace" font-size="14.00" fill="#cdd6f4">  MJPEG → JPEG frames</text>
|
||||
</g>
|
||||
<!-- scene_relay->scene_ffmpeg -->
|
||||
<g id="edge6" class="edge">
|
||||
<title>scene_relay->scene_ffmpeg</title>
|
||||
<path fill="none" stroke="#a6e3a1" d="M620.55,-630.11C588.15,-595.96 553.88,-559.84 553.88,-559.84 553.88,-559.84 553.88,-354.06 553.88,-354.06 553.88,-354.06 659.95,-304.72 751.68,-262.06"/>
|
||||
<polygon fill="#a6e3a1" stroke="#a6e3a1" points="752.96,-265.32 760.55,-257.93 750.01,-258.97 752.96,-265.32"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="607.5" y="-460.9" font-family="monospace" font-size="14.00" fill="#a6adc8">raw H.264</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="607.5" y="-443.65" font-family="monospace" font-size="14.00" fill="#a6adc8">(Unix socket)</text>
|
||||
</g>
|
||||
<!-- regression -->
|
||||
<g id="node16" class="node">
|
||||
<title>regression</title>
|
||||
<polygon fill="#3d1e1e" stroke="#f38ba8" points="922.5,-559.84 669.75,-559.84 669.75,-354.06 928.5,-354.06 928.5,-553.84 922.5,-559.84"/>
|
||||
<polyline fill="none" stroke="#f38ba8" points="922.5,-559.84 922.5,-553.84"/>
|
||||
<polyline fill="none" stroke="#f38ba8" points="928.5,-553.84 922.5,-553.84"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="799.12" y="-537.9" font-family="monospace" font-size="14.00" fill="#f38ba8">⚠ REGRESSED</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="799.12" y="-520.65" font-family="monospace" font-size="14.00" fill="#f38ba8">─────────────</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="799.12" y="-503.4" font-family="monospace" font-size="14.00" fill="#f38ba8">Scene relay (separate pipe)</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="799.12" y="-486.15" font-family="monospace" font-size="14.00" fill="#f38ba8">breaks 'one behind' flush.</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="799.12" y="-468.9" font-family="monospace" font-size="14.00" fill="#f38ba8">try_send drops → decoder</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="799.12" y="-451.65" font-family="monospace" font-size="14.00" fill="#f38ba8">corruption until keyframe.</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="799.12" y="-418.4" font-family="monospace" font-size="14.00" fill="#f38ba8">Fix: move scene detection</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="799.12" y="-401.15" font-family="monospace" font-size="14.00" fill="#f38ba8">into server ffmpeg as 3rd</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="799.12" y="-383.9" font-family="monospace" font-size="14.00" fill="#f38ba8">output branch (10-scene-</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="799.12" y="-366.65" font-family="monospace" font-size="14.00" fill="#f38ba8">detect-to-rust.md)</text>
|
||||
</g>
|
||||
<!-- scene_relay->regression -->
|
||||
<g id="edge15" class="edge">
|
||||
<title>scene_relay->regression</title>
|
||||
<path fill="none" stroke="#f38ba8" stroke-dasharray="5,2" d="M708.54,-630.04C718.19,-611.71 729.14,-590.91 740.01,-570.26"/>
|
||||
<polygon fill="#f38ba8" stroke="#f38ba8" points="743.07,-571.97 744.63,-561.49 736.87,-568.71 743.07,-571.97"/>
|
||||
</g>
|
||||
<!-- aac_file -->
|
||||
<g id="node13" class="node">
|
||||
<title>aac_file</title>
|
||||
<polygon fill="#2a2a3e" stroke="#585b70" points="1097.88,-491.46 1094.88,-495.46 1073.88,-495.46 1070.88,-491.46 946.38,-491.46 946.38,-422.44 1097.88,-422.44 1097.88,-491.46"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="1022.12" y="-469.52" font-family="monospace" font-size="14.00" fill="#cdd6f4">stream/</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="1022.12" y="-452.27" font-family="monospace" font-size="14.00" fill="#cdd6f4">audio.aac</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="1022.12" y="-435.02" font-family="monospace" font-size="14.00" fill="#cdd6f4">(ADTS-wrapped)</text>
|
||||
</g>
|
||||
<!-- audio_writer->aac_file -->
|
||||
<g id="edge9" class="edge">
|
||||
<title>audio_writer->aac_file</title>
|
||||
<path fill="none" stroke="#585b70" d="M942.92,-647.22C960.12,-606.1 986.09,-544.05 1003.56,-502.32"/>
|
||||
<polygon fill="#585b70" stroke="#585b70" points="1006.7,-503.88 1007.33,-493.3 1000.24,-501.18 1006.7,-503.88"/>
|
||||
</g>
|
||||
<!-- active_session->python -->
|
||||
<g id="edge14" class="edge">
|
||||
<title>active_session->python</title>
|
||||
<path fill="none" stroke="#585b70" stroke-dasharray="5,2" d="M1190.81,-638.58C1200.19,-603.51 1212.68,-556.8 1222.62,-519.67"/>
|
||||
<polygon fill="#585b70" stroke="#585b70" points="1225.88,-521 1225.09,-510.43 1219.12,-519.19 1225.88,-521"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="1251.64" y="-599.04" font-family="monospace" font-size="14.00" fill="#a6adc8">discovers</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="1251.64" y="-581.79" font-family="monospace" font-size="14.00" fill="#a6adc8">session dir</text>
|
||||
</g>
|
||||
<!-- frames -->
|
||||
<g id="node14" class="node">
|
||||
<title>frames</title>
|
||||
<polygon fill="#2a2a3e" stroke="#585b70" points="975.38,-51.78 972.38,-55.78 951.38,-55.78 948.38,-51.78 790.88,-51.78 790.88,0 975.38,0 975.38,-51.78"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="883.12" y="-29.84" font-family="monospace" font-size="14.00" fill="#cdd6f4">frames/</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="883.12" y="-12.59" font-family="monospace" font-size="14.00" fill="#cdd6f4">index.json + *.jpg</text>
|
||||
</g>
|
||||
<!-- scene_ffmpeg->frames -->
|
||||
<g id="edge10" class="edge">
|
||||
<title>scene_ffmpeg->frames</title>
|
||||
<path fill="none" stroke="#585b70" d="M883.12,-121.96C883.12,-101.46 883.12,-80.27 883.12,-63.11"/>
|
||||
<polygon fill="#585b70" stroke="#585b70" points="886.63,-63.45 883.13,-53.45 879.63,-63.45 886.63,-63.45"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="932.62" y="-90.98" font-family="monospace" font-size="14.00" fill="#a6adc8">JPEG on</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="932.62" y="-73.73" font-family="monospace" font-size="14.00" fill="#a6adc8">scene change</text>
|
||||
</g>
|
||||
<!-- audio_extract -->
|
||||
<g id="node9" class="node">
|
||||
<title>audio_extract</title>
|
||||
<polygon fill="#2d2038" stroke="#cba6f7" points="1256.12,-251.69 1022.12,-251.69 1022.12,-148.16 1256.12,-148.16 1256.12,-251.69"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="1139.12" y="-229.75" font-family="monospace" font-size="14.00" fill="#cdd6f4">Audio Extractor</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="1139.12" y="-212.5" font-family="monospace" font-size="14.00" fill="#cdd6f4">─────────────</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="1139.12" y="-195.25" font-family="monospace" font-size="14.00" fill="#cdd6f4">reads audio.aac</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="1139.12" y="-178" font-family="monospace" font-size="14.00" fill="#cdd6f4">ffmpeg → 16kHz mono WAV</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="1139.12" y="-160.75" font-family="monospace" font-size="14.00" fill="#cdd6f4">chunks + transcript WAVs</text>
|
||||
</g>
|
||||
<!-- audio_dir -->
|
||||
<g id="node15" class="node">
|
||||
<title>audio_dir</title>
|
||||
<polygon fill="#2a2a3e" stroke="#585b70" points="1548.12,-491.46 1545.12,-495.46 1524.12,-495.46 1521.12,-491.46 1380.12,-491.46 1380.12,-422.44 1548.12,-422.44 1548.12,-491.46"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="1464.12" y="-469.52" font-family="monospace" font-size="14.00" fill="#cdd6f4">audio/</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="1464.12" y="-452.27" font-family="monospace" font-size="14.00" fill="#cdd6f4">chunk_*.wav</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="1464.12" y="-435.02" font-family="monospace" font-size="14.00" fill="#cdd6f4">transcript_*.wav</text>
|
||||
</g>
|
||||
<!-- audio_extract->audio_dir -->
|
||||
<g id="edge11" class="edge">
|
||||
<title>audio_extract->audio_dir</title>
|
||||
<path fill="none" stroke="#585b70" d="M1197.7,-252C1230.6,-280.7 1265.12,-310.81 1265.12,-310.81 1265.12,-310.81 1371.12,-354.06 1371.12,-354.06 1371.12,-354.06 1400.1,-385.81 1425.7,-413.86"/>
|
||||
<polygon fill="#585b70" stroke="#585b70" points="1422.81,-415.88 1432.14,-420.9 1427.98,-411.16 1422.81,-415.88"/>
|
||||
</g>
|
||||
<!-- transcriber -->
|
||||
<g id="node10" class="node">
|
||||
<title>transcriber</title>
|
||||
<polygon fill="#2d2038" stroke="#cba6f7" points="1574.12,-251.69 1274.12,-251.69 1274.12,-148.16 1574.12,-148.16 1574.12,-251.69"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="1424.12" y="-229.75" font-family="monospace" font-size="14.00" fill="#cdd6f4">Transcriber</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="1424.12" y="-212.5" font-family="monospace" font-size="14.00" fill="#cdd6f4">─────────────</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="1424.12" y="-195.25" font-family="monospace" font-size="14.00" fill="#cdd6f4">faster-whisper (CUDA)</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="1424.12" y="-178" font-family="monospace" font-size="14.00" fill="#cdd6f4">segment grouping</text>
|
||||
<text xml:space="preserve" text-anchor="middle" x="1424.12" y="-160.75" font-family="monospace" font-size="14.00" fill="#cdd6f4">slider: chunk size + lines/group</text>
|
||||
</g>
|
||||
<!-- aac_file->audio_extract -->
|
||||
<g id="edge13" class="edge">
|
||||
<title>aac_file->audio_extract</title>
|
||||
<path fill="none" stroke="#585b70" stroke-dasharray="5,2" d="M1037.66,-422.08C1056.29,-381.48 1087.87,-312.64 1110.86,-262.52"/>
|
||||
<polygon fill="#585b70" stroke="#585b70" points="1114.01,-264.06 1115,-253.51 1107.65,-261.14 1114.01,-264.06"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="1104.76" y="-322.76" font-family="monospace" font-size="14.00" fill="#a6adc8">reads</text>
|
||||
</g>
|
||||
<!-- audio_dir->transcriber -->
|
||||
<g id="edge12" class="edge">
|
||||
<title>audio_dir->transcriber</title>
|
||||
<path fill="none" stroke="#585b70" d="M1458.81,-422.08C1452.48,-381.73 1441.78,-313.5 1433.94,-263.47"/>
|
||||
<polygon fill="#585b70" stroke="#585b70" points="1437.4,-262.96 1432.39,-253.63 1430.48,-264.05 1437.4,-262.96"/>
|
||||
<text xml:space="preserve" text-anchor="middle" x="1485.38" y="-322.76" font-family="monospace" font-size="14.00" fill="#a6adc8">WAV chunks</text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 24 KiB |
Reference in New Issue
Block a user