# 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 ```bash # 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 ```bash # 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 ```bash rm -rf build # Then re-run the configure + build steps above ``` ## Run unit tests ```bash build/tests/dmf-test-graph ``` ## Test with MXL ### 1. Create MXL domain ```bash mkdir -p /tmp/dmf-mxl ``` ### 2. Start MXL test source (writes V210 video flow) Create a flow config file: ```bash 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): ```bash mxl-gst-testsrc -d /tmp/dmf-mxl -v /tmp/v210_50p.json --pattern smpte & ``` Check active flows: ```bash mxl-info --domain /tmp/dmf-mxl ``` ### 3. Start passthrough node ```bash 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 ```bash export DMF_STUDIO_BIN_DIR=build/nodes/passthrough build/engine/dmf-studio-engine --port 8080 ``` ### 5. Control via REST API ```bash # 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`: ```bash wscat -c ws://localhost:9100 -s dmf-control ``` Commands: ```json {"cmd": "add_reader", "flow_id": "", "port_id": "video_in"} {"cmd": "add_writer", "flow_id": "", "port_id": "video_out", "flow_def": {}} {"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 ```