37f02f01d930efbf0425f9eabf992df2ce38fb59
DMF Studio
Node-based visual production platform for the Dynamic Media Facility architecture.
Prerequisites
- CMake 3.24+
- C++20 compiler (GCC 12+, Clang 15+)
- vcpkg (at
~/vcpkgor setCMAKE_TOOLCHAIN_FILE) - GStreamer (for MXL test tools only)
Build
# Configure (from project root)
cmake -B build \
-DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_TOOLCHAIN_FILE=$HOME/vcpkg/scripts/buildsystems/vcpkg.cmake \
-DBUILD_SHARED_LIBS=OFF \
-DBUILD_DOCS=OFF \
-DBUILD_TESTS=OFF \
-DBUILD_TOOLS=OFF \
-DBUILD_UTILS=OFF
# Build all
cmake --build build -j$(nproc)
Binaries end up in:
build/engine/dmf-studio-enginebuild/nodes/passthrough/dmf-node-passthrough
Rebuild after changes
# Full rebuild
cmake --build build -j$(nproc)
# Rebuild only one target (faster)
cmake --build build -j$(nproc) --target dmf-node-passthrough
cmake --build build -j$(nproc) --target dmf-studio-engine
Clean rebuild
rm -rf build
# Then re-run the configure + build steps above
Run unit tests
build/tests/dmf-test-graph
Test with MXL
1. Create MXL domain
mkdir -p /tmp/dmf-mxl
2. Start MXL test source (writes V210 video flow)
Create a flow config file:
cat > /tmp/v210_50p.json << 'EOF'
{
"id": "a0000001-0000-0000-0000-000000000001",
"description": "DMF Studio test video flow",
"format": "urn:x-nmos:format:video",
"label": "DMF Studio Test Video",
"tags": {
"urn:x-nmos:tag:grouphint/v1.0": ["dmf-studio:Video"]
},
"media_type": "video/v210",
"grain_rate": {"numerator": 50, "denominator": 1},
"frame_width": 1920,
"frame_height": 1080,
"interlace_mode": "progressive",
"colorspace": "BT709",
"components": [
{"name": "Y", "width": 1920, "height": 1080, "bit_depth": 10},
{"name": "Cb", "width": 960, "height": 1080, "bit_depth": 10},
{"name": "Cr", "width": 960, "height": 1080, "bit_depth": 10}
]
}
EOF
Start test source (needs GStreamer + MXL tools built separately):
mxl-gst-testsrc -d /tmp/dmf-mxl -v /tmp/v210_50p.json --pattern smpte &
Check active flows:
mxl-info --domain /tmp/dmf-mxl
3. Start passthrough node
build/nodes/passthrough/dmf-node-passthrough \
--node-id pass1 \
--control-port 9100 \
--mxl-domain /tmp/dmf-mxl
Options:
--node-id, -n— Unique node instance ID (required)--control-port, -p— WebSocket control port (required)--mxl-domain, -d— MXL domain path (default:/dev/shm/mxl)--config, -c— Node config as JSON string
4. Start engine
export DMF_STUDIO_BIN_DIR=build/nodes/passthrough
build/engine/dmf-studio-engine --port 8080
5. Control via REST API
# Add nodes
curl -X POST http://localhost:8080/api/graph/nodes \
-H "Content-Type: application/json" \
-d '{"type":"passthrough","id":"pass1"}'
curl -X POST http://localhost:8080/api/graph/nodes \
-H "Content-Type: application/json" \
-d '{"type":"passthrough","id":"pass2"}'
# Connect nodes (creates MXL flow between them)
curl -X POST http://localhost:8080/api/graph/edges \
-H "Content-Type: application/json" \
-d '{"from_node":"pass1","from_port":"video_out","to_node":"pass2","to_port":"video_in"}'
# View graph
curl http://localhost:8080/api/graph
# Start all nodes
curl -X POST http://localhost:8080/api/graph/start
# Stop all nodes
curl -X POST http://localhost:8080/api/graph/stop
# Remove node
curl -X DELETE http://localhost:8080/api/graph/nodes/pass1
# Remove edge
curl -X DELETE http://localhost:8080/api/graph/edges/pass1:video_out->pass2:video_in
6. Control node directly via WebSocket
Connect to ws://localhost:9100 with subprotocol dmf-control:
wscat -c ws://localhost:9100 -s dmf-control
Commands:
{"cmd": "add_reader", "flow_id": "<uuid>", "port_id": "video_in"}
{"cmd": "add_writer", "flow_id": "<uuid>", "port_id": "video_out", "flow_def": {<NMOS flow JSON>}}
{"cmd": "remove_reader", "port_id": "video_in"}
{"cmd": "remove_writer", "port_id": "video_out"}
{"cmd": "configure", "params": {}}
{"cmd": "shutdown"}
Project structure
libs/dmf-node/ — Node skeleton library (interface, WS control, MXL lifecycle)
libs/dmf-engine/ — Engine library (graph model, flow manager, process manager, REST API)
nodes/passthrough/ — Passthrough node (1 MXL in → 1 MXL out, memcpy)
engine/ — Engine binary
tests/ — Unit tests
Description
Languages
C++
92.8%
Shell
3.6%
CMake
3.6%