diff options
| author | 3gg <3gg@shellblade.net> | 2025-12-27 12:03:39 -0800 |
|---|---|---|
| committer | 3gg <3gg@shellblade.net> | 2025-12-27 12:03:39 -0800 |
| commit | 5a079a2d114f96d4847d1ee305d5b7c16eeec50e (patch) | |
| tree | 8926ab44f168acf787d8e19608857b3af0f82758 /contrib/SDL-3.2.8/src/camera/SDL_syscamera.h | |
Initial commit
Diffstat (limited to 'contrib/SDL-3.2.8/src/camera/SDL_syscamera.h')
| -rw-r--r-- | contrib/SDL-3.2.8/src/camera/SDL_syscamera.h | 224 |
1 files changed, 224 insertions, 0 deletions
diff --git a/contrib/SDL-3.2.8/src/camera/SDL_syscamera.h b/contrib/SDL-3.2.8/src/camera/SDL_syscamera.h new file mode 100644 index 0000000..30a02f3 --- /dev/null +++ b/contrib/SDL-3.2.8/src/camera/SDL_syscamera.h | |||
| @@ -0,0 +1,224 @@ | |||
| 1 | /* | ||
| 2 | Simple DirectMedia Layer | ||
| 3 | Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org> | ||
| 4 | |||
| 5 | This software is provided 'as-is', without any express or implied | ||
| 6 | warranty. In no event will the authors be held liable for any damages | ||
| 7 | arising from the use of this software. | ||
| 8 | |||
| 9 | Permission is granted to anyone to use this software for any purpose, | ||
| 10 | including commercial applications, and to alter it and redistribute it | ||
| 11 | freely, subject to the following restrictions: | ||
| 12 | |||
| 13 | 1. The origin of this software must not be misrepresented; you must not | ||
| 14 | claim that you wrote the original software. If you use this software | ||
| 15 | in a product, an acknowledgment in the product documentation would be | ||
| 16 | appreciated but is not required. | ||
| 17 | 2. Altered source versions must be plainly marked as such, and must not be | ||
| 18 | misrepresented as being the original software. | ||
| 19 | 3. This notice may not be removed or altered from any source distribution. | ||
| 20 | */ | ||
| 21 | #include "../SDL_internal.h" | ||
| 22 | |||
| 23 | #ifndef SDL_syscamera_h_ | ||
| 24 | #define SDL_syscamera_h_ | ||
| 25 | |||
| 26 | #include "../video/SDL_surface_c.h" | ||
| 27 | |||
| 28 | #define DEBUG_CAMERA 0 | ||
| 29 | |||
| 30 | /* Backends should call this as devices are added to the system (such as | ||
| 31 | a USB camera being plugged in), and should also be called for | ||
| 32 | for every device found during DetectDevices(). */ | ||
| 33 | extern SDL_Camera *SDL_AddCamera(const char *name, SDL_CameraPosition position, int num_specs, const SDL_CameraSpec *specs, void *handle); | ||
| 34 | |||
| 35 | /* Backends should call this if an opened camera device is lost. | ||
| 36 | This can happen due to i/o errors, or a device being unplugged, etc. */ | ||
| 37 | extern void SDL_CameraDisconnected(SDL_Camera *device); | ||
| 38 | |||
| 39 | // Find an SDL_Camera, selected by a callback. NULL if not found. DOES NOT LOCK THE DEVICE. | ||
| 40 | extern SDL_Camera *SDL_FindPhysicalCameraByCallback(bool (*callback)(SDL_Camera *device, void *userdata), void *userdata); | ||
| 41 | |||
| 42 | // Backends should call this when the user has approved/denied access to a camera. | ||
| 43 | extern void SDL_CameraPermissionOutcome(SDL_Camera *device, bool approved); | ||
| 44 | |||
| 45 | // Backends can call this to get a standardized name for a thread to power a specific camera device. | ||
| 46 | extern char *SDL_GetCameraThreadName(SDL_Camera *device, char *buf, size_t buflen); | ||
| 47 | |||
| 48 | // Backends can call these to change a device's refcount. | ||
| 49 | extern void RefPhysicalCamera(SDL_Camera *device); | ||
| 50 | extern void UnrefPhysicalCamera(SDL_Camera *device); | ||
| 51 | |||
| 52 | // These functions are the heart of the camera threads. Backends can call them directly if they aren't using the SDL-provided thread. | ||
| 53 | extern void SDL_CameraThreadSetup(SDL_Camera *device); | ||
| 54 | extern bool SDL_CameraThreadIterate(SDL_Camera *device); | ||
| 55 | extern void SDL_CameraThreadShutdown(SDL_Camera *device); | ||
| 56 | |||
| 57 | // Backends can call this if they have to finish initializing later, like Emscripten. Most backends should _not_ call this directly! | ||
| 58 | extern bool SDL_PrepareCameraSurfaces(SDL_Camera *device); | ||
| 59 | |||
| 60 | |||
| 61 | // common utility functionality to gather up camera specs. Not required! | ||
| 62 | typedef struct CameraFormatAddData | ||
| 63 | { | ||
| 64 | SDL_CameraSpec *specs; | ||
| 65 | int num_specs; | ||
| 66 | int allocated_specs; | ||
| 67 | } CameraFormatAddData; | ||
| 68 | |||
| 69 | bool SDL_AddCameraFormat(CameraFormatAddData *data, SDL_PixelFormat format, SDL_Colorspace colorspace, int w, int h, int framerate_numerator, int framerate_denominator); | ||
| 70 | |||
| 71 | typedef enum SDL_CameraFrameResult | ||
| 72 | { | ||
| 73 | SDL_CAMERA_FRAME_ERROR, | ||
| 74 | SDL_CAMERA_FRAME_SKIP, | ||
| 75 | SDL_CAMERA_FRAME_READY | ||
| 76 | } SDL_CameraFrameResult; | ||
| 77 | |||
| 78 | typedef struct SurfaceList | ||
| 79 | { | ||
| 80 | SDL_Surface *surface; | ||
| 81 | Uint64 timestampNS; | ||
| 82 | struct SurfaceList *next; | ||
| 83 | } SurfaceList; | ||
| 84 | |||
| 85 | // Define the SDL camera driver structure | ||
| 86 | struct SDL_Camera | ||
| 87 | { | ||
| 88 | // A mutex for locking | ||
| 89 | SDL_Mutex *lock; | ||
| 90 | |||
| 91 | // Human-readable device name. | ||
| 92 | char *name; | ||
| 93 | |||
| 94 | // Position of camera (front-facing, back-facing, etc). | ||
| 95 | SDL_CameraPosition position; | ||
| 96 | |||
| 97 | // When refcount hits zero, we destroy the device object. | ||
| 98 | SDL_AtomicInt refcount; | ||
| 99 | |||
| 100 | // These are, initially, set from camera_driver, but we might swap them out with Zombie versions on disconnect/failure. | ||
| 101 | bool (*WaitDevice)(SDL_Camera *device); | ||
| 102 | SDL_CameraFrameResult (*AcquireFrame)(SDL_Camera *device, SDL_Surface *frame, Uint64 *timestampNS); | ||
| 103 | void (*ReleaseFrame)(SDL_Camera *device, SDL_Surface *frame); | ||
| 104 | |||
| 105 | // All supported formats/dimensions for this device. | ||
| 106 | SDL_CameraSpec *all_specs; | ||
| 107 | |||
| 108 | // Elements in all_specs. | ||
| 109 | int num_specs; | ||
| 110 | |||
| 111 | // The device's actual specification that the camera is outputting, before conversion. | ||
| 112 | SDL_CameraSpec actual_spec; | ||
| 113 | |||
| 114 | // The device's current camera specification, after conversions. | ||
| 115 | SDL_CameraSpec spec; | ||
| 116 | |||
| 117 | // Unique value assigned at creation time. | ||
| 118 | SDL_CameraID instance_id; | ||
| 119 | |||
| 120 | // Driver-specific hardware data on how to open device (`hidden` is driver-specific data _when opened_). | ||
| 121 | void *handle; | ||
| 122 | |||
| 123 | // Dropping the first frame(s) after open seems to help timing on some platforms. | ||
| 124 | int drop_frames; | ||
| 125 | |||
| 126 | // Backend timestamp of first acquired frame, so we can keep these meaningful regardless of epoch. | ||
| 127 | Uint64 base_timestamp; | ||
| 128 | |||
| 129 | // SDL timestamp of first acquired frame, so we can roughly convert to SDL ticks. | ||
| 130 | Uint64 adjust_timestamp; | ||
| 131 | |||
| 132 | // Pixel data flows from the driver into these, then gets converted for the app if necessary. | ||
| 133 | SDL_Surface *acquire_surface; | ||
| 134 | |||
| 135 | // acquire_surface converts or scales to this surface before landing in output_surfaces, if necessary. | ||
| 136 | SDL_Surface *conversion_surface; | ||
| 137 | |||
| 138 | // A queue of surfaces that buffer converted/scaled frames of video until the app claims them. | ||
| 139 | SurfaceList output_surfaces[8]; | ||
| 140 | SurfaceList filled_output_surfaces; // this is FIFO | ||
| 141 | SurfaceList empty_output_surfaces; // this is LIFO | ||
| 142 | SurfaceList app_held_output_surfaces; | ||
| 143 | |||
| 144 | // A fake video frame we allocate if the camera fails/disconnects. | ||
| 145 | Uint8 *zombie_pixels; | ||
| 146 | |||
| 147 | // non-zero if acquire_surface needs to be scaled for final output. | ||
| 148 | int needs_scaling; // -1: downscale, 0: no scaling, 1: upscale | ||
| 149 | |||
| 150 | // true if acquire_surface needs to be converted for final output. | ||
| 151 | bool needs_conversion; | ||
| 152 | |||
| 153 | // Current state flags | ||
| 154 | SDL_AtomicInt shutdown; | ||
| 155 | SDL_AtomicInt zombie; | ||
| 156 | |||
| 157 | // A thread to feed the camera device | ||
| 158 | SDL_Thread *thread; | ||
| 159 | |||
| 160 | // Optional properties. | ||
| 161 | SDL_PropertiesID props; | ||
| 162 | |||
| 163 | // -1: user denied permission, 0: waiting for user response, 1: user approved permission. | ||
| 164 | int permission; | ||
| 165 | |||
| 166 | // Data private to this driver, used when device is opened and running. | ||
| 167 | struct SDL_PrivateCameraData *hidden; | ||
| 168 | }; | ||
| 169 | |||
| 170 | typedef struct SDL_CameraDriverImpl | ||
| 171 | { | ||
| 172 | void (*DetectDevices)(void); | ||
| 173 | bool (*OpenDevice)(SDL_Camera *device, const SDL_CameraSpec *spec); | ||
| 174 | void (*CloseDevice)(SDL_Camera *device); | ||
| 175 | bool (*WaitDevice)(SDL_Camera *device); | ||
| 176 | SDL_CameraFrameResult (*AcquireFrame)(SDL_Camera *device, SDL_Surface *frame, Uint64 *timestampNS); // set frame->pixels, frame->pitch, and *timestampNS! | ||
| 177 | void (*ReleaseFrame)(SDL_Camera *device, SDL_Surface *frame); // Reclaim frame->pixels and frame->pitch! | ||
| 178 | void (*FreeDeviceHandle)(SDL_Camera *device); // SDL is done with this device; free the handle from SDL_AddCamera() | ||
| 179 | void (*Deinitialize)(void); | ||
| 180 | |||
| 181 | bool ProvidesOwnCallbackThread; | ||
| 182 | } SDL_CameraDriverImpl; | ||
| 183 | |||
| 184 | typedef struct SDL_PendingCameraEvent | ||
| 185 | { | ||
| 186 | Uint32 type; | ||
| 187 | SDL_CameraID devid; | ||
| 188 | struct SDL_PendingCameraEvent *next; | ||
| 189 | } SDL_PendingCameraEvent; | ||
| 190 | |||
| 191 | typedef struct SDL_CameraDriver | ||
| 192 | { | ||
| 193 | const char *name; // The name of this camera driver | ||
| 194 | const char *desc; // The description of this camera driver | ||
| 195 | SDL_CameraDriverImpl impl; // the backend's interface | ||
| 196 | |||
| 197 | SDL_RWLock *device_hash_lock; // A rwlock that protects `device_hash` // !!! FIXME: device_hash _also_ has a rwlock, see if we still need this one. | ||
| 198 | SDL_HashTable *device_hash; // the collection of currently-available camera devices | ||
| 199 | SDL_PendingCameraEvent pending_events; | ||
| 200 | SDL_PendingCameraEvent *pending_events_tail; | ||
| 201 | |||
| 202 | SDL_AtomicInt device_count; | ||
| 203 | SDL_AtomicInt shutting_down; // non-zero during SDL_Quit, so we known not to accept any last-minute device hotplugs. | ||
| 204 | } SDL_CameraDriver; | ||
| 205 | |||
| 206 | typedef struct CameraBootStrap | ||
| 207 | { | ||
| 208 | const char *name; | ||
| 209 | const char *desc; | ||
| 210 | bool (*init)(SDL_CameraDriverImpl *impl); | ||
| 211 | bool demand_only; // if true: request explicitly, or it won't be available. | ||
| 212 | } CameraBootStrap; | ||
| 213 | |||
| 214 | // Not all of these are available in a given build. Use #ifdefs, etc. | ||
| 215 | extern CameraBootStrap DUMMYCAMERA_bootstrap; | ||
| 216 | extern CameraBootStrap PIPEWIRECAMERA_bootstrap; | ||
| 217 | extern CameraBootStrap V4L2_bootstrap; | ||
| 218 | extern CameraBootStrap COREMEDIA_bootstrap; | ||
| 219 | extern CameraBootStrap ANDROIDCAMERA_bootstrap; | ||
| 220 | extern CameraBootStrap EMSCRIPTENCAMERA_bootstrap; | ||
| 221 | extern CameraBootStrap MEDIAFOUNDATION_bootstrap; | ||
| 222 | extern CameraBootStrap VITACAMERA_bootstrap; | ||
| 223 | |||
| 224 | #endif // SDL_syscamera_h_ | ||
