feat: scaffold project framework with engine, node skeleton, and passthrough node
- CMake build system with vcpkg dependency management - libdmf-node: Node interface, port definitions, WebSocket control server, node runner with MXL lifecycle management - libdmf-engine: Graph model (nodes/edges CRUD, serialization), FlowManager (UUID + V210 NMOS flow definitions), ProcessManager (fork/exec node processes), ApiServer (REST API for graph control) - Passthrough node: reads V210 grains from MXL, copies, writes to MXL - Unit tests for Graph and FlowManager (6 cases, 21 assertions) - MXL SDK as git submodule (symlinked from extern/mxl)
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
|
||||
#include <dmf-node/node.hpp>
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
struct lws;
|
||||
|
||||
namespace dmf_node {
|
||||
|
||||
using CommandHandler = std::function<void(const nlohmann::json& payload)>;
|
||||
using StatusCallback = std::function<void(const nlohmann::json& event)>;
|
||||
|
||||
class ControlServer {
|
||||
public:
|
||||
ControlServer(uint16_t port, StatusCallback on_event);
|
||||
~ControlServer();
|
||||
|
||||
ControlServer(const ControlServer&) = delete;
|
||||
ControlServer& operator=(const ControlServer&) = delete;
|
||||
|
||||
void register_command(const std::string& cmd, CommandHandler handler);
|
||||
void send_event(const nlohmann::json& event);
|
||||
|
||||
void poll(int timeout_ms);
|
||||
|
||||
private:
|
||||
struct Impl;
|
||||
std::unique_ptr<Impl> impl_;
|
||||
};
|
||||
|
||||
} // namespace dmf_node
|
||||
@@ -0,0 +1,32 @@
|
||||
#pragma once
|
||||
|
||||
#include <dmf-node/port.hpp>
|
||||
#include <dmf-node/types.hpp>
|
||||
|
||||
#include <mxl/flow.h>
|
||||
#include <mxl/mxl.h>
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace dmf_node {
|
||||
|
||||
class Node {
|
||||
public:
|
||||
virtual ~Node() = default;
|
||||
|
||||
virtual std::string type() const = 0;
|
||||
virtual std::vector<PortDef> input_ports() const = 0;
|
||||
virtual std::vector<PortDef> output_ports() const = 0;
|
||||
virtual void configure(const nlohmann::json& params) = 0;
|
||||
virtual void on_add_writer(const std::string& port_id, mxlFlowWriter writer) = 0;
|
||||
virtual void on_add_reader(const std::string& port_id, mxlFlowReader reader) = 0;
|
||||
virtual void on_remove_writer(const std::string& port_id) = 0;
|
||||
virtual void on_remove_reader(const std::string& port_id) = 0;
|
||||
virtual void process() = 0;
|
||||
virtual nlohmann::json status() const = 0;
|
||||
};
|
||||
|
||||
} // namespace dmf_node
|
||||
@@ -0,0 +1,39 @@
|
||||
#pragma once
|
||||
|
||||
#include <dmf-node/node.hpp>
|
||||
#include <dmf-node/control_server.hpp>
|
||||
|
||||
#include <mxl/mxl.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
namespace dmf_node {
|
||||
|
||||
class NodeRunner {
|
||||
public:
|
||||
template <typename NodeType>
|
||||
static int run(int argc, char* argv[]) {
|
||||
NodeRunner runner;
|
||||
if (!runner.parse_args(argc, argv)) {
|
||||
return 1;
|
||||
}
|
||||
auto node = std::make_unique<NodeType>();
|
||||
return runner.exec(std::move(node));
|
||||
}
|
||||
|
||||
private:
|
||||
bool parse_args(int argc, char* argv[]);
|
||||
int exec(std::unique_ptr<Node> node);
|
||||
|
||||
std::string node_id_;
|
||||
uint16_t control_port_ = 0;
|
||||
std::string mxl_domain_ = "/dev/shm/mxl";
|
||||
std::string config_str_;
|
||||
|
||||
mxlInstance mxl_instance_ = nullptr;
|
||||
std::atomic<bool> running_{false};
|
||||
};
|
||||
|
||||
} // namespace dmf_node
|
||||
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
namespace dmf_node {
|
||||
|
||||
enum class MediaType : uint8_t {
|
||||
VideoV210,
|
||||
AudioFloat32,
|
||||
AncData,
|
||||
};
|
||||
|
||||
enum class PortDirection : uint8_t {
|
||||
Input,
|
||||
Output,
|
||||
};
|
||||
|
||||
struct PortDef {
|
||||
std::string id;
|
||||
PortDirection direction;
|
||||
MediaType media_type;
|
||||
};
|
||||
|
||||
} // namespace dmf_node
|
||||
@@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace dmf_node {
|
||||
|
||||
using NodeId = std::string;
|
||||
using PortId = std::string;
|
||||
using FlowId = std::string;
|
||||
|
||||
} // namespace dmf_node
|
||||
Reference in New Issue
Block a user