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