Files
DMF-Studio/README.md
2026-05-26 01:42:44 +03:00

4.4 KiB

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 ~/vcpkg or set CMAKE_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-engine
  • build/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