MayaFlux 0.5.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
VisionProcessor.cpp
Go to the documentation of this file.
1#include "VisionProcessor.hpp"
2
7
10
11namespace MayaFlux::Kakshya {
12
14 : m_sequence(std::move(sequence))
15 , m_force_cpu(force_cpu)
16{
17 if (!m_force_cpu)
18 m_executor = std::make_unique<Yantra::VisionGpuExecutor>();
19}
20
21void VisionProcessor::on_attach(const std::shared_ptr<SignalSourceContainer>& container)
22{
23 if (!container)
24 return;
25
26 const bool valid = std::dynamic_pointer_cast<VideoStreamContainer>(container)
27 || std::dynamic_pointer_cast<WindowContainer>(container)
28 || std::dynamic_pointer_cast<TextureContainer>(container);
29
30 if (!valid) {
31 error<std::invalid_argument>(
34 std::source_location::current(),
35 "VisionProcessor requires a VideoStreamContainer, WindowContainer, "
36 "or TextureContainer; got {}",
37 typeid(*container).name());
38 }
39
40 const auto& structure = container->get_structure();
41 m_width = static_cast<uint32_t>(structure.get_width());
42 m_height = static_cast<uint32_t>(structure.get_height());
43
44 if (m_force_cpu) {
46 } else if (m_width > 0 && m_height > 0) {
47 if (!m_executor)
48 m_executor = std::make_unique<Yantra::VisionGpuExecutor>();
49
53 }
54
55 if (m_width == 0 || m_height == 0) {
57 "VisionProcessor attached to container with zero spatial dimensions");
58 } else {
60 "VisionProcessor attached: {}x{}", m_width, m_height);
61 }
62}
63
64void VisionProcessor::on_detach(const std::shared_ptr<SignalSourceContainer>& /*container*/)
65{
66 m_width = 0;
67 m_height = 0;
68
69 if (m_force_cpu)
71
72 m_gpu_frame.reset();
73}
74
75void VisionProcessor::process(const std::shared_ptr<SignalSourceContainer>& container)
76{
77 if (m_width == 0 || m_height == 0 || !container)
78 return;
79
80 m_is_processing.store(true, std::memory_order_release);
81
82 if (m_force_cpu) {
83 std::span<const float> frame;
84 if (auto vc = std::dynamic_pointer_cast<VideoStreamContainer>(container)) {
85 frame = vc->processed_frame_as_float(0);
86 vc->invalidate_float_frame_cache(0);
87 } else if (auto wc = std::dynamic_pointer_cast<WindowContainer>(container)) {
88 frame = wc->processed_frame_as_float(0);
89 wc->invalidate_float_frame_cache(0);
90 } else if (auto tc = std::dynamic_pointer_cast<TextureContainer>(container)) {
91 frame = tc->as_normalised_float(0);
92 }
93 if (!frame.empty())
95 } else if (m_gpu_frame) {
96 const void* raw = container->get_raw_data();
97 if (raw) {
99 loom.upload_data(m_gpu_frame, raw, m_gpu_frame->get_size_bytes(), m_upload_staging);
101 }
102 }
103
104 if (m_result_source)
105 m_result_source->signal(m_result);
106
107 m_is_processing.store(false, std::memory_order_release);
108}
109
111{
112 m_sequence = std::move(sequence);
113 m_executor.reset();
114}
115
116std::shared_ptr<Vruta::BroadcastSource<Kinesis::Vision::VisionResult>> VisionProcessor::get_result_source()
117{
118 if (!m_result_source)
119 m_result_source = std::make_shared<Vruta::BroadcastSource<Kinesis::Vision::VisionResult>>();
120 return m_result_source;
121}
122} // namespace MayaFlux::Kakshya
#define MF_INFO(comp, ctx,...)
#define MF_WARN(comp, ctx,...)
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
void on_attach(const std::shared_ptr< SignalSourceContainer > &container) override
Cache frame geometry from get_structure().
Kinesis::Vision::VisionSequence m_sequence
std::unique_ptr< Yantra::VisionGpuExecutor > m_executor
std::shared_ptr< Core::VKImage > m_gpu_frame
void on_detach(const std::shared_ptr< SignalSourceContainer > &container) override
Clear cached geometry and reset executor state.
void set_sequence(Kinesis::Vision::VisionSequence sequence)
Replace the pipeline and reset inter-frame executor state.
void process(const std::shared_ptr< SignalSourceContainer > &container) override
Execute the VisionSequence on processed_data[0].
VisionProcessor(Kinesis::Vision::VisionSequence sequence, bool force_cpu=false)
Construct with the vision pipeline to execute each process() call.
std::shared_ptr< Vruta::BroadcastSource< Kinesis::Vision::VisionResult > > get_result_source()
Shared BroadcastSource signalled with each VisionResult after a successful process() call.
Kinesis::Vision::VisionResult m_result
void reset()
Clear stored inter-frame state.
VisionResult run(const VisionSequence &sequence, std::span< const float > frame, uint32_t w, uint32_t h)
Execute a VisionSequence on one frame.
std::shared_ptr< VKBuffer > create_image_staging_buffer(size_t size)
Allocate a persistent host-visible staging buffer sized for repeated streaming uploads to an image of...
@ ContainerProcessing
Container operations (Kakshya - file/stream/region processing)
@ Kakshya
Containers[Signalsource, Stream, File], Regions, DataProcessors.
Ordered sequence of VisionSteps describing a complete vision pipeline.
Definition VisionOp.hpp:163