OrangePi3588Media/include/node.h
2026-01-12 20:51:27 +08:00

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