MayaFlux 0.2.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
VideoContainerBuffer.hpp
Go to the documentation of this file.
1#pragma once
2
5
6namespace MayaFlux::Buffers {
7
8/**
9 * @class VideoStreamReader
10 * @brief Adapter bridging VideoStreamContainer processed data to TextureBuffer pixel storage.
11 *
12 * VideoStreamReader is the video counterpart of SoundStreamReader. Where
13 * SoundStreamReader extracts per-channel audio samples from a container's
14 * processed_data into an AudioBuffer, VideoStreamReader extracts full-frame
15 * RGBA pixel data from a container's processed_data into a TextureBuffer's
16 * pixel storage, marking it dirty for GPU upload.
17 *
18 * The pipeline mirrors audio exactly:
19 *
20 * VideoStreamContainer
21 * → FrameAccessProcessor (extracts frame into processed_data)
22 * → VideoStreamReader (copies processed_data into TextureBuffer pixels)
23 * → TextureProcessor (uploads dirty pixels to GPU VKImage)
24 * → RenderProcessor (draws textured quad)
25 *
26 * VideoStreamReader triggers the container's default processor
27 * (FrameAccessProcessor) if the container is in READY state, then copies
28 * the resulting uint8_t RGBA data into the TextureBuffer via
29 * set_pixel_data(). This marks the texture dirty, causing TextureProcessor
30 * to re-upload on the next frame.
31 *
32 * Unlike SoundStreamReader, there is no channel selection — video frames are
33 * atomic spatial units. The reader always extracts the entire frame surface.
34 *
35 * @see SoundStreamReader, FrameAccessProcessor, TextureBuffer, VideoStreamContainer
36 */
37class MAYAFLUX_API VideoStreamReader : public BufferProcessor {
38public:
39 /**
40 * @brief Construct a VideoStreamReader for the given container.
41 * @param container The video StreamContainer to read from.
42 */
43 explicit VideoStreamReader(const std::shared_ptr<Kakshya::StreamContainer>& container);
44
45 /**
46 * @brief Extract the current frame from the container into the TextureBuffer.
47 *
48 * Triggers the container's default processor if needed, extracts the
49 * processed uint8_t RGBA data, and copies it into the TextureBuffer's
50 * pixel storage via set_pixel_data().
51 *
52 * @param buffer The TextureBuffer to write pixels into.
53 */
54 void processing_function(const std::shared_ptr<Buffer>& buffer) override;
55
56 /**
57 * @brief Attach the reader to a TextureBuffer.
58 *
59 * Registers as a dimension reader on the container, validates that the
60 * container is ready, and performs an initial frame extraction.
61 *
62 * @param buffer The TextureBuffer to attach to.
63 */
64 void on_attach(const std::shared_ptr<Buffer>& buffer) override;
65
66 /**
67 * @brief Detach the reader from its TextureBuffer.
68 *
69 * Unregisters from the container and cleans up state.
70 *
71 * @param buffer The TextureBuffer to detach from.
72 */
73 void on_detach(const std::shared_ptr<Buffer>& buffer) override;
74
75 /**
76 * @brief Replace the backing container.
77 * @param container New StreamContainer to read from.
78 */
79 void set_container(const std::shared_ptr<Kakshya::StreamContainer>& container);
80
81 /**
82 * @brief Get the backing container.
83 * @return Current StreamContainer.
84 */
85 std::shared_ptr<Kakshya::StreamContainer> get_container() const { return m_container; }
86
87 /**
88 * @brief Enable or disable automatic buffer state flag updates.
89 *
90 * When enabled, the reader will mark the buffer for processing or
91 * removal based on container state transitions.
92 *
93 * @param update true to enable state flag updates.
94 */
95 void set_update_flags(bool update) { m_update_flags = update; }
96
97 /**
98 * @brief Get the current state flag update setting.
99 * @return true if state flag updates are enabled.
100 */
101 [[nodiscard]] bool get_update_flags() const { return m_update_flags; }
102
103private:
104 std::shared_ptr<Kakshya::StreamContainer> m_container;
105
106 uint32_t m_reader_id {};
107 bool m_update_flags { true };
108
109 /**
110 * @brief Extract frame pixel data from processed_data into the TextureBuffer.
111 * @param texture_buffer The TextureBuffer to write into.
112 */
113 void extract_frame_data(const std::shared_ptr<TextureBuffer>& texture_buffer);
114
115 /**
116 * @brief Respond to container state changes.
117 *
118 * Mirrors SoundStreamReader's state callback pattern for lifecycle
119 * synchronisation between container and buffer.
120 *
121 * @param container The container whose state changed.
122 * @param state The new processing state.
123 */
124 void on_container_state_change(const std::shared_ptr<Kakshya::SignalSourceContainer>& container,
126};
127
128/**
129 * @class VideoContainerBuffer
130 * @brief TextureBuffer implementation backed by a VideoStreamContainer.
131 *
132 * VideoContainerBuffer is the video counterpart of SoundContainerBuffer. It
133 * bridges the Kakshya container system and the Vulkan rendering pipeline by
134 * wiring a VideoStreamReader as the default processor and repositioning the
135 * inherited TextureProcessor as the chain preprocessor.
136 *
137 * Execution order per frame cycle (via process_complete):
138 * 1. Default processor → VideoStreamReader pulls frame from container,
139 * writes RGBA pixels into TextureBuffer via
140 * set_pixel_data(), marks texture dirty.
141 * 2. Preprocessor → TextureProcessor detects dirty flag, uploads
142 * pixels to GPU VKImage, updates quad geometry.
143 * 3. Chain processors → User-added effects, compute shaders, etc.
144 * 4. Postprocessor → (available for user)
145 * 5. Final processor → RenderProcessor draws textured quad to window.
146 *
147 * This mirrors the audio pipeline exactly:
148 *
149 * Audio: SoundStreamContainer → ContiguousAccessProcessor
150 * → SoundStreamReader → AudioBuffer → speakers
151 *
152 * Video: VideoStreamContainer → FrameAccessProcessor
153 * → VideoStreamReader → VideoContainerBuffer
154 * → TextureProcessor → RenderProcessor → window
155 *
156 * The buffer inherits all TextureBuffer capabilities: pixel storage with
157 * dirty tracking, quad geometry with transform support, GPU texture access,
158 * and RenderProcessor integration via setup_rendering().
159 *
160 * @see SoundContainerBuffer, VideoStreamReader, FrameAccessProcessor, TextureBuffer
161 */
162class MAYAFLUX_API VideoContainerBuffer : public TextureBuffer {
163public:
164 /**
165 * @brief Construct a VideoContainerBuffer from a video container.
166 *
167 * Extracts width, height, and pixel format from the container's structure
168 * and initialises the TextureBuffer base with matching dimensions.
169 * Creates a pending VideoStreamReader that is wired on initialize().
170 *
171 * @param container Backing video StreamContainer (must carry VIDEO_COLOR data).
172 * @param format Pixel format (default RGBA8 matching container convention).
173 */
175 const std::shared_ptr<Kakshya::StreamContainer>& container,
176 Portal::Graphics::ImageFormat format = Portal::Graphics::ImageFormat::RGBA8);
177
178 ~VideoContainerBuffer() override = default;
179
180 /**
181 * @brief Override to wire VideoStreamReader as default and
182 * TextureProcessor as preprocessor.
183 *
184 * @param token Processing token (typically GRAPHICS_BACKEND).
185 */
186 void setup_processors(ProcessingToken token) override;
187
188 /**
189 * @brief Get the backing video container.
190 * @return Current StreamContainer.
191 */
192 [[nodiscard]] std::shared_ptr<Kakshya::StreamContainer> get_container() const { return m_container; }
193
194 /**
195 * @brief Replace the backing container at runtime.
196 *
197 * Updates the VideoStreamReader's source. Does not resize the
198 * TextureBuffer — caller is responsible for ensuring dimension
199 * compatibility or recreating the buffer.
200 *
201 * @param container New StreamContainer to read from.
202 */
203 void set_container(const std::shared_ptr<Kakshya::StreamContainer>& container);
204
205 /**
206 * @brief Get the VideoStreamReader processor.
207 * @return The reader processor, or nullptr if not yet initialised.
208 */
209 [[nodiscard]] std::shared_ptr<VideoStreamReader> get_video_reader() const { return m_video_reader; }
210
211private:
212 std::shared_ptr<Kakshya::StreamContainer> m_container;
213 std::shared_ptr<VideoStreamReader> m_video_reader;
214};
215
216} // namespace MayaFlux::Buffers
Central computational transformation interface for continuous buffer processing.
A hybrid buffer managing both a textured quad geometry and its pixel data.
std::shared_ptr< Kakshya::StreamContainer > m_container
std::shared_ptr< Kakshya::StreamContainer > get_container() const
Get the backing video container.
std::shared_ptr< VideoStreamReader > get_video_reader() const
Get the VideoStreamReader processor.
std::shared_ptr< VideoStreamReader > m_video_reader
TextureBuffer implementation backed by a VideoStreamContainer.
bool get_update_flags() const
Get the current state flag update setting.
std::shared_ptr< Kakshya::StreamContainer > get_container() const
Get the backing container.
std::shared_ptr< Kakshya::StreamContainer > m_container
void set_update_flags(bool update)
Enable or disable automatic buffer state flag updates.
Adapter bridging VideoStreamContainer processed data to TextureBuffer pixel storage.
ProcessingToken
Bitfield enum defining processing characteristics and backend requirements for buffer operations.
ProcessingState
Represents the current processing lifecycle state of a container.
ImageFormat
User-friendly image format enum.