docs: add build and test instructions
This commit is contained in:
@@ -0,0 +1,187 @@
|
|||||||
|
# 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": "<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
|
||||||
|
```
|
||||||
Reference in New Issue
Block a user