MayaFlux 1.0.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
CameraSource.hpp
Go to the documentation of this file.
1#pragma once
2
3namespace MayaFlux::Kakshya {
4class CameraContainer;
5}
6
7namespace MayaFlux::IO {
8
9/**
10 * @struct CameraConfig
11 * @brief Configuration for opening a camera device via FFmpeg.
12 *
13 * Platform device string conventions:
14 * - Linux: "/dev/video0", "/dev/video1", …
15 * - macOS: "0" (AVFoundation device index) or a camera name such as
16 * "FaceTime HD Camera"; frame rate must equal a rate range maximum
17 * - Windows: "video=Integrated Camera" (DirectShow filter name)
18 *
19 * Resolution, frame rate and input format are hints. If the device rejects
20 * them, open() retries without the input format, then without frame rate,
21 * then with device defaults. The negotiated values are available from
22 * FFmpegCameraReader after open().
23 */
24struct MAYAFLUX_API CameraConfig {
25 std::string device_name; ///< Platform device string.
26 uint32_t target_width { 1920 }; ///< Requested width in pixels.
27 uint32_t target_height { 1080 }; ///< Requested height in pixels.
28 double target_fps { 30.0 }; ///< Hint only; device may ignore.
29 std::string format_override; ///< Leave empty to use CAMERA_FORMAT for current platform.
30 int pixel_format { -1 }; ///< Target AVPixelFormat as int; negative selects AV_PIX_FMT_RGBA.
31 std::string display_name; ///< Human-readable device name for a chooser.
32 std::string input_format; ///< Capture format or codec (e.g. "mjpeg"); empty selects mjpeg where the platform supports it.
33};
34
35/**
36 * @struct CameraMode
37 * @brief A requested capture mode offered by a source, for a chooser.
38 *
39 * A mode is a request, not a guarantee: open() falls back to the nearest
40 * mode the device accepts. Modes marked high_end ask for more than most
41 * webcams deliver and are likely to fall back on ordinary cameras.
42 */
43struct MAYAFLUX_API CameraMode {
44 std::string label; ///< Caption for a chooser.
45 uint32_t width {}; ///< Requested width in pixels, 0 leaves it to the device.
46 uint32_t height {}; ///< Requested height in pixels, 0 leaves it to the device.
47 double fps {}; ///< Requested frame rate, 0 leaves it to the device.
48 bool high_end {}; ///< Needs a capable camera.
49
50 /** @brief Write this mode's size and frame rate into @p config. */
51 void apply(CameraConfig& config) const
52 {
53 config.target_width = width;
54 config.target_height = height;
55 config.target_fps = fps;
56 }
57};
58
59/**
60 * @class CameraSource
61 * @brief Abstract interface for a live camera backend hosted by IOManager.
62 *
63 * Enumerates configurations, opens a selected device, then provides
64 * negotiated parameters, frame delivery, and IOService wiring.
65 *
66 * A camera source is a live, unbounded stream: no ring buffer, no seek, no
67 * batch decode. One frame is pulled per process cycle, demand-driven by
68 * CameraContainer::process_default(), never pushed speculatively ahead of
69 * the consumer.
70 *
71 * Two integration paths apply to any implementation:
72 * - Managed: IOManager owns construction and opening (backend-specific),
73 * then calls register_camera_source(), which assigns a
74 * reader_id and wires the container's IOService callback.
75 * - Standalone: the caller drives the same sequence manually —
76 * create_container() → setup_io_service(id) →
77 * set_container() → close() — without IOManager.
78 *
79 * FFmpegCameraReader is the first concrete implementation.
80 */
81class MAYAFLUX_API CameraSource {
82public:
83 virtual ~CameraSource() = default;
84
85 /** @brief Discover ready-to-open camera configurations without starting capture. */
86 [[nodiscard]] virtual std::vector<CameraConfig> enumerate_configs() const = 0;
87
88 /** @brief Capture modes this source offers as defaults, ordered from safest to most demanding. */
89 [[nodiscard]] virtual std::vector<CameraMode> preset_modes() const = 0;
90
91 /** @brief Open a configuration returned by enumerate_configs(). */
92 [[nodiscard]] virtual bool open(const CameraConfig& config) = 0;
93
94 /**
95 * @brief Release device, decode, and scratch resources.
96 */
97 virtual void close() = 0;
98
99 /**
100 * @brief True if the device is open and ready to deliver frames.
101 */
102 [[nodiscard]] virtual bool is_open() const = 0;
103
104 /**
105 * @brief Create a CameraContainer sized to the negotiated device resolution.
106 * @return Initialised container, ready for pull_frame().
107 */
108 [[nodiscard]] virtual std::shared_ptr<Kakshya::CameraContainer> create_container() const = 0;
109
110 /**
111 * @brief Produce one frame into the container.
112 *
113 * Writes pixel data into the container's frame buffer and marks it ready
114 * for processing. Returning false means no frame was available this
115 * cycle, which is not necessarily an error.
116 *
117 * @param container Target CameraContainer.
118 * @return True if a new frame was written.
119 */
120 virtual bool pull_frame(const std::shared_ptr<Kakshya::CameraContainer>& container) = 0;
121
122 /** @brief Negotiated output width in pixels. */
123 [[nodiscard]] virtual uint32_t width() const = 0;
124
125 /** @brief Negotiated output height in pixels. */
126 [[nodiscard]] virtual uint32_t height() const = 0;
127
128 /** @brief Negotiated frame rate in fps. */
129 [[nodiscard]] virtual double frame_rate() const = 0;
130
131 /**
132 * @brief Store a weak reference to the container for IOService dispatch.
133 * @param container CameraContainer created by this source.
134 */
135 virtual void set_container(const std::shared_ptr<Kakshya::CameraContainer>& container) = 0;
136
137 /**
138 * @brief Signal the source to pull one frame.
139 *
140 * Non-blocking. Called by IOManager's dispatch, or a standalone
141 * IOService lambda, when a frame request arrives for this source's
142 * reader_id.
143 */
144 virtual void pull_frame_all() = 0;
145
146 /** @brief Last error string, empty if no error. */
147 [[nodiscard]] virtual const std::string& last_error() const = 0;
148
149 /**
150 * @brief Wire this source into an IOService under the given reader_id.
151 * @param reader_id Id assigned by IOManager, or self-assigned for
152 * standalone use.
153 */
154 virtual void setup_io_service(uint64_t reader_id) = 0;
155};
156
157} // namespace MayaFlux::IO
bool fps
uint32_t width
uint32_t height
virtual std::vector< CameraConfig > enumerate_configs() const =0
Discover ready-to-open camera configurations without starting capture.
virtual bool pull_frame(const std::shared_ptr< Kakshya::CameraContainer > &container)=0
Produce one frame into the container.
virtual void set_container(const std::shared_ptr< Kakshya::CameraContainer > &container)=0
Store a weak reference to the container for IOService dispatch.
virtual void pull_frame_all()=0
Signal the source to pull one frame.
virtual bool is_open() const =0
True if the device is open and ready to deliver frames.
virtual double frame_rate() const =0
Negotiated frame rate in fps.
virtual bool open(const CameraConfig &config)=0
Open a configuration returned by enumerate_configs().
virtual uint32_t width() const =0
Negotiated output width in pixels.
virtual void setup_io_service(uint64_t reader_id)=0
Wire this source into an IOService under the given reader_id.
virtual void close()=0
Release device, decode, and scratch resources.
virtual std::shared_ptr< Kakshya::CameraContainer > create_container() const =0
Create a CameraContainer sized to the negotiated device resolution.
virtual uint32_t height() const =0
Negotiated output height in pixels.
virtual std::vector< CameraMode > preset_modes() const =0
Capture modes this source offers as defaults, ordered from safest to most demanding.
virtual const std::string & last_error() const =0
Last error string, empty if no error.
virtual ~CameraSource()=default
Abstract interface for a live camera backend hosted by IOManager.
std::string device_name
Platform device string.
std::string display_name
Human-readable device name for a chooser.
std::string format_override
Leave empty to use CAMERA_FORMAT for current platform.
std::string input_format
Capture format or codec (e.g. "mjpeg"); empty selects mjpeg where the platform supports it.
uint32_t target_width
Requested width in pixels.
uint32_t target_height
Requested height in pixels.
double target_fps
Hint only; device may ignore.
Configuration for opening a camera device via FFmpeg.
void apply(CameraConfig &config) const
Write this mode's size and frame rate into config.
std::string label
Caption for a chooser.
A requested capture mode offered by a source, for a chooser.