93 lines
3.2 KiB
C++
93 lines
3.2 KiB
C++
#pragma once
|
|
|
|
#include <memory>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include "frame/frame.h"
|
|
#include "utils/simple_json.h"
|
|
#include "utils/spsc_queue.h"
|
|
|
|
namespace rk3588 {
|
|
|
|
using FramePtr = std::shared_ptr<Frame>;
|
|
|
|
enum class NodeStatus {
|
|
OK, // Normal processing
|
|
DROP, // Drop this frame (e.g., condition not met)
|
|
ERROR // Error occurred, should log
|
|
};
|
|
|
|
struct NodeContext {
|
|
// For nodes with upstream input.
|
|
std::shared_ptr<SpscQueue<FramePtr>> input_queue;
|
|
// For nodes that produce downstream outputs (one queue per outgoing edge).
|
|
std::vector<std::shared_ptr<SpscQueue<FramePtr>>> output_queues;
|
|
};
|
|
|
|
class INode {
|
|
public:
|
|
virtual ~INode() = default;
|
|
virtual std::string Id() const = 0;
|
|
virtual std::string Type() const = 0;
|
|
virtual bool Init(const SimpleJson& config, const NodeContext& ctx) = 0;
|
|
// Initialize resources.
|
|
// Note: For Source nodes, this should start the capture thread.
|
|
// For Filter/Sink nodes, this should ONLY allocate resources; the framework will drive Process().
|
|
virtual bool Start() = 0;
|
|
virtual void Stop() = 0;
|
|
|
|
// Process a single frame (driven by GraphMgr for Filter/Sink nodes).
|
|
// Returns status to indicate if frame was processed or dropped.
|
|
virtual NodeStatus Process(FramePtr /*frame*/) { return NodeStatus::OK; }
|
|
|
|
// Dynamic config update without restart. Returns true if update succeeded.
|
|
virtual bool UpdateConfig(const SimpleJson& /*new_config*/) { return false; }
|
|
|
|
// Optional custom metrics for graph-level aggregation/observability.
|
|
// Return true if out is filled.
|
|
virtual bool GetCustomMetrics(SimpleJson& /*out*/) const { return false; }
|
|
|
|
// Called before Stop() to flush internal buffers (e.g., finish writing files).
|
|
virtual void Drain() {}
|
|
};
|
|
|
|
// ABI version for dynamic node plugins.
|
|
// Bump when plugin-required symbols or contracts change.
|
|
constexpr int kNodeAbiVersion = 3;
|
|
|
|
using CreateNodeFn = INode* (*)();
|
|
using DestroyNodeFn = void (*)(INode*);
|
|
using GetTypeFn = const char* (*)();
|
|
using GetAbiFn = int (*)();
|
|
|
|
struct NodeDeleter {
|
|
DestroyNodeFn destroy = nullptr;
|
|
void operator()(INode* p) const noexcept {
|
|
if (!p) return;
|
|
if (destroy) {
|
|
destroy(p);
|
|
} else {
|
|
delete p;
|
|
}
|
|
}
|
|
};
|
|
|
|
using NodePtr = std::unique_ptr<INode, NodeDeleter>;
|
|
|
|
#define REGISTER_NODE(NodeClass, NodeTypeStr) \
|
|
extern "C" rk3588::INode* CreateNode() { \
|
|
return new NodeClass(); \
|
|
} \
|
|
extern "C" void DestroyNode(rk3588::INode* p) { \
|
|
delete p; \
|
|
} \
|
|
extern "C" const char* GetNodeType() { \
|
|
return NodeTypeStr; \
|
|
} \
|
|
extern "C" int GetAbiVersion() { \
|
|
return rk3588::kNodeAbiVersion; \
|
|
}
|
|
|
|
} // namespace rk3588
|