MayaFlux 0.2.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
CameraContainer.hpp
Go to the documentation of this file.
1#pragma once
2
4
6struct IOService;
7}
8
9namespace MayaFlux::Kakshya {
10
11/**
12 * @class CameraContainer
13 * @brief Single-slot live video container for camera device streams.
14 *
15 * CameraContainer is a VideoStreamContainer specialisation for live
16 * camera input. Unlike VideoFileContainer it has no ring buffer, no
17 * seek capability, and no total_frames — the container always holds
18 * exactly one frame: the most recently decoded one.
19 *
20 * The container is pure storage. CameraReader writes decoded RGBA pixels
21 * directly into m_data[0] via mutable_frame_ptr(), exactly as
22 * VideoFileReader writes into mutable_slot_ptr() for ring buffer slots.
23 * FrameAccessProcessor reads from the container via get_frame_pixels(0)
24 * during the normal process_default() cycle.
25 *
26 * Data flow is driven by CameraIOService. After each process() cycle
27 * the overridden update_read_position_for_channel() calls
28 * IOService::request_frame(reader_id). IOManager dispatches this
29 * to CameraReader::pull_frame_all(), which writes the next decoded frame
30 * into mutable_frame_ptr() and marks the container READY.
31 *
32 * Dimensions follow VIDEO_COLOR convention:
33 * dims[0] → TIME (always 1)
34 * dims[1] → SPATIAL_Y (height)
35 * dims[2] → SPATIAL_X (width)
36 * dims[3] → CHANNEL (4 for RGBA)
37 */
38class MAYAFLUX_API CameraContainer : public VideoStreamContainer {
39public:
40 /**
41 * @brief Construct a CameraContainer with specified resolution.
42 * @param width Frame width in pixels.
43 * @param height Frame height in pixels.
44 * @param channels Colour channels per pixel (default 4 for RGBA).
45 * @param frame_rate Device frame rate in fps.
46 */
47 CameraContainer(uint32_t width, uint32_t height,
48 uint32_t channels = 4, double frame_rate = 30.0);
49
50 ~CameraContainer() override = default;
51
52 /**
53 * @brief Mutable pointer into m_data[0] for the caller to write decoded pixels.
54 *
55 * Mirrors VideoStreamContainer::mutable_slot_ptr() for ring mode, but
56 * operates on the single flat-mode frame. The caller (CameraReader)
57 * writes width * height * channels bytes at this address, then calls
58 * mark_ready_for_processing(true).
59 *
60 * @return Pointer to the start of the frame pixel buffer, or nullptr if
61 * the container is not properly initialised.
62 */
63 [[nodiscard]] uint8_t* mutable_frame_ptr();
64
65 /**
66 * @brief Wire the CameraIOService callback for demand-driven frame pulls.
67 *
68 * Retrieves the CameraIOService from BackendRegistry and stores the
69 * reader_id. After this call, update_read_position_for_channel() will
70 * call request_frame(reader_id) each time FrameAccessProcessor
71 * completes a process cycle.
72 *
73 * @param reader_id Opaque id assigned by IOManager, matching the
74 * CameraReader registered in dispatch.
75 */
76 void setup_io(uint64_t reader_id);
77
78 /**
79 * @brief Always returns 1 — camera containers hold exactly one frame.
80 */
81 [[nodiscard]] uint64_t get_num_frames() const override { return 1; }
82
83 /**
84 * @brief Always returns false — camera containers do not loop.
85 */
86 [[nodiscard]] bool is_looping() const override { return false; }
87
88 /**
89 * @brief Create FrameAccessProcessor with auto_advance disabled.
90 */
91 void create_default_processor() override;
92
93 /**
94 * @brief Override to fire request_frame after each processor cycle.
95 *
96 * VideoStreamContainer::process_default() drives state through
97 * PROCESSING → PROCESSED but never calls update_read_position_for_channel,
98 * because FrameAccessProcessor::auto_advance is disabled for live input.
99 * Without auto_advance there is no call site for update_read_position_for_channel,
100 * so IOService::request_frame never fires and CameraReader never pulls a new frame.
101 *
102 * This override calls the base implementation then immediately issues
103 * request_frame, replacing the position-advance trigger with a direct
104 * post-process trigger that is semantically correct for a single-slot
105 * live container: every completed process cycle is a demand for the next frame.
106 */
107 void process_default() override;
108
109private:
110 Registry::Service::IOService* m_io_service { nullptr };
111};
112
113} // namespace MayaFlux::Kakshya
bool is_looping() const override
Always returns false — camera containers do not loop.
~CameraContainer() override=default
uint64_t get_num_frames() const override
Always returns 1 — camera containers hold exactly one frame.
Single-slot live video container for camera device streams.
Concrete base implementation for streaming video containers.
Backend IO streaming service interface.
Definition IOService.hpp:18