Atlas - SDL_syscamera.h
Home / ext / SDL / src / camera Lines: 1 | Size: 9236 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)][FILE BEGIN]1/* 2 Simple DirectMedia Layer 3 Copyright (C) 1997-2025 Sam Lantinga <[email protected]> 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(). */ 33extern 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. */ 37extern 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. 40extern 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. 43extern 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. 46extern char *SDL_GetCameraThreadName(SDL_Camera *device, char *buf, size_t buflen); 47 48// Backends can call these to change a device's refcount. 49extern void RefPhysicalCamera(SDL_Camera *device); 50extern 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. 53extern void SDL_CameraThreadSetup(SDL_Camera *device); 54extern bool SDL_CameraThreadIterate(SDL_Camera *device); 55extern 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! 58extern bool SDL_PrepareCameraSurfaces(SDL_Camera *device); 59 60 61// common utility functionality to gather up camera specs. Not required! 62typedef struct CameraFormatAddData 63{ 64 SDL_CameraSpec *specs; 65 int num_specs; 66 int allocated_specs; 67} CameraFormatAddData; 68 69bool SDL_AddCameraFormat(CameraFormatAddData *data, SDL_PixelFormat format, SDL_Colorspace colorspace, int w, int h, int framerate_numerator, int framerate_denominator); 70 71typedef enum SDL_CameraFrameResult 72{ 73 SDL_CAMERA_FRAME_ERROR, 74 SDL_CAMERA_FRAME_SKIP, 75 SDL_CAMERA_FRAME_READY 76} SDL_CameraFrameResult; 77 78typedef struct SurfaceList 79{ 80 SDL_Surface *surface; 81 Uint64 timestampNS; 82 struct SurfaceList *next; 83} SurfaceList; 84 85// Define the SDL camera driver structure 86struct 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, float *rotation); 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 // Current state of user permission check. 164 SDL_CameraPermissionState permission; 165 166 // Data private to this driver, used when device is opened and running. 167 struct SDL_PrivateCameraData *hidden; 168}; 169 170 171// Note that for AcquireFrame, `rotation` is degrees, with positive values rotating clockwise. This is the amount to rotate an image so it would be right-side up. 172// Rotations should be in 90 degree increments at this time (landscape to portrait, or upside down to right side up, etc). 173// Most platforms won't care about this, but mobile devices might need to deal with the device itself being physically rotated, causing the fixed-orientation camera to be presenting sideways images. 174 175typedef struct SDL_CameraDriverImpl 176{ 177 void (*DetectDevices)(void); 178 bool (*OpenDevice)(SDL_Camera *device, const SDL_CameraSpec *spec); 179 void (*CloseDevice)(SDL_Camera *device); 180 bool (*WaitDevice)(SDL_Camera *device); 181 SDL_CameraFrameResult (*AcquireFrame)(SDL_Camera *device, SDL_Surface *frame, Uint64 *timestampNS, float *rotation); // set frame->pixels, frame->pitch, *timestampNS, and *rotation! 182 void (*ReleaseFrame)(SDL_Camera *device, SDL_Surface *frame); // Reclaim frame->pixels and frame->pitch! 183 void (*FreeDeviceHandle)(SDL_Camera *device); // SDL is done with this device; free the handle from SDL_AddCamera() 184 void (*Deinitialize)(void); 185 186 bool ProvidesOwnCallbackThread; 187} SDL_CameraDriverImpl; 188 189typedef struct SDL_PendingCameraEvent 190{ 191 Uint32 type; 192 SDL_CameraID devid; 193 struct SDL_PendingCameraEvent *next; 194} SDL_PendingCameraEvent; 195 196typedef struct SDL_CameraDriver 197{ 198 const char *name; // The name of this camera driver 199 const char *desc; // The description of this camera driver 200 SDL_CameraDriverImpl impl; // the backend's interface 201 202 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. 203 SDL_HashTable *device_hash; // the collection of currently-available camera devices 204 SDL_PendingCameraEvent pending_events; 205 SDL_PendingCameraEvent *pending_events_tail; 206 207 SDL_AtomicInt device_count; 208 SDL_AtomicInt shutting_down; // non-zero during SDL_Quit, so we known not to accept any last-minute device hotplugs. 209} SDL_CameraDriver; 210 211typedef struct CameraBootStrap 212{ 213 const char *name; 214 const char *desc; 215 bool (*init)(SDL_CameraDriverImpl *impl); 216 bool demand_only; // if true: request explicitly, or it won't be available. 217} CameraBootStrap; 218 219// Not all of these are available in a given build. Use #ifdefs, etc. 220extern CameraBootStrap DUMMYCAMERA_bootstrap; 221extern CameraBootStrap PIPEWIRECAMERA_bootstrap; 222extern CameraBootStrap V4L2_bootstrap; 223extern CameraBootStrap COREMEDIA_bootstrap; 224extern CameraBootStrap ANDROIDCAMERA_bootstrap; 225extern CameraBootStrap EMSCRIPTENCAMERA_bootstrap; 226extern CameraBootStrap MEDIAFOUNDATION_bootstrap; 227extern CameraBootStrap VITACAMERA_bootstrap; 228 229#endif // SDL_syscamera_h_ 230[FILE END](C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.