MayaFlux 0.5.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
VisionProcessor.hpp
Go to the documentation of this file.
1#pragma once
2
4
6
7namespace MayaFlux::Vruta {
8template <typename T>
9class BroadcastSource;
10}
11
12namespace MayaFlux::Kakshya {
13
14/**
15 * @class VisionProcessor
16 * @brief DataProcessor executing a Kinesis::Vision pipeline on pixel container data.
17 *
18 * Compatible with three container types, each accessed via its native normalised
19 * float path:
20 * - VideoStreamContainer: processed_frame_as_float(0) on processed_data
21 * - WindowContainer: processed_frame_as_float(0) on processed_data
22 * - TextureContainer: as_normalised_float(0) on m_data
23 *
24 * on_attach throws std::invalid_argument for any other container type.
25 * Runs the configured VisionSequence through VisionExecutor and stores the
26 * VisionResult as member state for polling via get_result().
27 *
28 * Width and height are read from get_structure() at on_attach time.
29 * m_float_storage is reused across calls to avoid per-frame allocation.
30 *
31 * @see FrameAccessProcessor, WindowAccessProcessor, VisionExecutor, VisionSequence
32 */
33class MAYAFLUX_API VisionProcessor : public DataProcessor {
34public:
35 /**
36 * @brief Construct with the vision pipeline to execute each process() call.
37 * @param sequence Ordered VisionSteps describing the pipeline.
38 */
39 explicit VisionProcessor(Kinesis::Vision::VisionSequence sequence, bool force_cpu = false);
40
41 ~VisionProcessor() override = default;
42
43 /**
44 * @brief Cache frame geometry from get_structure(). Resets executor state.
45 *
46 * Called automatically by DataProcessingChain::add_processor.
47 *
48 * @param container The SignalSourceContainer to attach to.
49 */
50 void on_attach(const std::shared_ptr<SignalSourceContainer>& container) override;
51
52 /**
53 * @brief Clear cached geometry and reset executor state.
54 * @param container The SignalSourceContainer being detached.
55 */
56 void on_detach(const std::shared_ptr<SignalSourceContainer>& container) override;
57
58 /**
59 * @brief Execute the VisionSequence on processed_data[0].
60 *
61 * No-op when processed_data is empty, the pixel span normalises to empty,
62 * or geometry was not cached at on_attach time.
63 *
64 * @param container The container to read processed_data[0] from.
65 */
66 void process(const std::shared_ptr<SignalSourceContainer>& container) override;
67
68 [[nodiscard]] bool is_processing() const override
69 {
70 return m_is_processing.load(std::memory_order_acquire);
71 }
72
73 /**
74 * @brief Replace the pipeline and reset inter-frame executor state.
75 *
76 * Not thread-safe relative to process(). Call only when process() is idle.
77 *
78 * @param sequence Replacement VisionSequence.
79 */
80 void set_sequence(Kinesis::Vision::VisionSequence sequence);
81
82 /**
83 * @brief The result of the last successful process() call.
84 *
85 * Default-initialised until the first process() call completes.
86 *
87 * @return Most recent VisionResult.
88 */
89 [[nodiscard]] const Kinesis::Vision::VisionResult& get_result() const { return m_result; }
90
91 /**
92 * @brief Shared BroadcastSource signalled with each VisionResult after a
93 * successful process() call.
94 *
95 * Created on first call. Wire with Kriya::on_signal to consume results
96 * from a coroutine without polling get_result().
97 *
98 * One coroutine per source. For multiple consumers create one
99 * VisionProcessor per consumer or poll get_result() directly.
100 *
101 * @return Shared pointer to the BroadcastSource, never null after first call.
102 */
103 [[nodiscard]] std::shared_ptr<Vruta::BroadcastSource<Kinesis::Vision::VisionResult>> get_result_source();
104
105private:
107 std::unique_ptr<Yantra::VisionGpuExecutor> m_executor;
109 bool m_force_cpu {};
110
111 std::shared_ptr<Buffers::VKBuffer> m_upload_staging;
112 std::shared_ptr<Core::VKImage> m_gpu_frame;
114
115 uint32_t m_width {};
116 uint32_t m_height {};
117
118 mutable std::vector<float> m_float_storage;
119
120 std::atomic<bool> m_is_processing { false };
121 std::shared_ptr<Vruta::BroadcastSource<Kinesis::Vision::VisionResult>> m_result_source;
122};
123
124} // namespace MayaFlux::Kakshya
GPU execution layer for Kinesis::Vision::VisionSequence.
Interface for processing data within SignalSourceContainer objects.
std::shared_ptr< Buffers::VKBuffer > m_upload_staging
Kinesis::Vision::VisionExecutor m_cpu_executor
std::shared_ptr< Vruta::BroadcastSource< Kinesis::Vision::VisionResult > > m_result_source
Kinesis::Vision::VisionSequence m_sequence
std::unique_ptr< Yantra::VisionGpuExecutor > m_executor
std::shared_ptr< Core::VKImage > m_gpu_frame
const Kinesis::Vision::VisionResult & get_result() const
The result of the last successful process() call.
~VisionProcessor() override=default
bool is_processing() const override
Checks if the processor is currently performing processing.
Kinesis::Vision::VisionResult m_result
DataProcessor executing a Kinesis::Vision pipeline on pixel container data.
Stateful executor for a VisionSequence.
Result of executing a VisionSequence on one frame.
Ordered sequence of VisionSteps describing a complete vision pipeline.
Definition VisionOp.hpp:163