1 /* 2 DSDL 3 Copyright (C) 2025 Inochi2D Project <luna@foxgirls.gay> 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 ========================================================================== 22 23 Simple DirectMedia Layer 24 Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org> 25 26 This software is provided 'as-is', without any express or implied 27 warranty. In no event will the authors be held liable for any damages 28 arising from the use of this software. 29 30 Permission is granted to anyone to use this software for any purpose, 31 including commercial applications, and to alter it and redistribute it 32 freely, subject to the following restrictions: 33 34 1. The origin of this software must not be misrepresented; you must not 35 claim that you wrote the original software. If you use this software 36 in a product, an acknowledgment in the product documentation would be 37 appreciated but is not required. 38 2. Altered source versions must be plainly marked as such, and must not be 39 misrepresented as being the original software. 40 3. This notice may not be removed or altered from any source distribution. 41 */ 42 43 /** 44 SDL Camera Handling 45 46 See_Also: 47 $(LINK2 https://wiki.libsdl.org/SDL3/CategoryCamera, SDL3 Camera Documentation) 48 49 Copyright: © 2025 Inochi2D Project, © 1997-2025 Sam Lantinga 50 License: Subject to the terms of the Zlib License, as written in the LICENSE file. 51 Authors: 52 Luna Nielsen 53 */ 54 module sdl.camera; 55 import sdl.pixels; 56 import sdl.surface; 57 import sdl.properties; 58 import sdl.stdc; 59 60 extern(C) nothrow @nogc: 61 62 /** 63 This is a unique ID for a camera device for the time it is connected to the 64 system, and is never reused for the lifetime of the application. 65 66 If the device is disconnected and reconnected, it will get a new ID. 67 68 The value 0 is an invalid ID. 69 70 See_Also: 71 $(D SDL_GetCameras) 72 */ 73 alias SDL_CameraID = Uint32; 74 75 /** 76 The opaque structure used to identify an opened SDL camera. 77 */ 78 struct SDL_Camera; 79 80 /** 81 The details of an output format for a camera device. 82 83 Cameras often support multiple formats; each one will be encapsulated in 84 this struct. 85 86 \since This struct is available since SDL 3.2.0. 87 88 See_Also: 89 $(D SDL_GetCameraSupportedFormats) 90 $(D SDL_GetCameraFormat) 91 */ 92 struct SDL_CameraSpec { 93 94 /** 95 Frame format 96 */ 97 SDL_PixelFormat format; 98 99 /** 100 Frame colorspace 101 */ 102 SDL_Colorspace colorspace; 103 104 /** 105 Frame width 106 */ 107 int width; 108 109 /** 110 Frame height 111 */ 112 int height; 113 114 /** 115 Frame rate numerator ((num / denom) == FPS, (denom / num) == duration in seconds) 116 */ 117 int framerate_numerator; 118 119 /** 120 Frame rate demoninator ((num / denom) == FPS, (denom / num) == duration in seconds) 121 */ 122 int framerate_denominator; 123 } 124 125 /** 126 The position of camera in relation to system device. 127 128 See_Also: 129 $(D SDL_GetCameraPosition) 130 */ 131 enum SDL_CameraPosition { 132 SDL_CAMERA_POSITION_UNKNOWN, 133 SDL_CAMERA_POSITION_FRONT_FACING, 134 SDL_CAMERA_POSITION_BACK_FACING 135 } 136 137 138 /** 139 Use this function to get the number of built-in camera drivers. 140 141 This function returns a hardcoded number. This never returns a negative 142 value; if there are no drivers compiled into this build of SDL, this 143 function returns zero. The presence of a driver in this list does not mean 144 it will function, it just means SDL is capable of interacting with that 145 interface. For example, a build of SDL might have v4l2 support, but if 146 there's no kernel support available, SDL's v4l2 driver would fail if used. 147 148 By default, SDL tries all drivers, in its preferred order, until one is 149 found to be usable. 150 151 Returns: 152 the number of built-in camera drivers. 153 154 Threadsafety: 155 It is safe to call this function from any thread. 156 157 See_Also: 158 $(D SDL_GetCameraDriver) 159 */ 160 extern int SDL_GetNumCameraDrivers(); 161 162 /** 163 Use this function to get the name of a built in camera driver. 164 165 The list of camera drivers is given in the order that they are normally 166 initialized by default; the drivers that seem more reasonable to choose 167 first (as far as the SDL developers believe) are earlier in the list. 168 169 The names of drivers are all simple, low-ASCII identifiers, like "v4l2", 170 "coremedia" or "android". These never have Unicode characters, and are not 171 meant to be proper names. 172 173 Params: 174 index = the index of the camera driver; the value ranges from 0 to 175 SDL_GetNumCameraDrivers() - 1. 176 177 Returns: 178 the name of the camera driver at the requested index, or NULL if 179 an invalid index was specified. 180 181 Threadsafety: 182 It is safe to call this function from any thread. 183 184 See_Also: 185 $(D SDL_GetNumCameraDrivers) 186 */ 187 extern const(char)* SDL_GetCameraDriver(int index); 188 189 /** 190 Get the name of the current camera driver. 191 192 The names of drivers are all simple, low-ASCII identifiers, like "v4l2", 193 "coremedia" or "android". These never have Unicode characters, and are not 194 meant to be proper names. 195 196 Returns: 197 the name of the current camera driver or NULL if no driver has 198 been initialized. 199 200 Threadsafety: 201 It is safe to call this function from any thread. 202 */ 203 extern const(char)* SDL_GetCurrentCameraDriver(); 204 205 /** 206 Get a list of currently connected camera devices. 207 208 Params: 209 count = a pointer filled in with the number of cameras returned, may 210 be NULL. 211 212 Returns: 213 a 0 terminated array of camera instance IDs or NULL on failure; 214 call SDL_GetError() for more information. This should be freed 215 with SDL_free() when it is no longer needed. 216 217 Threadsafety: 218 It is safe to call this function from any thread. 219 220 See_Also: 221 $(D SDL_OpenCamera) 222 */ 223 extern SDL_CameraID* SDL_GetCameras(int *count); 224 225 /** 226 Get the list of native formats/sizes a camera supports. 227 228 This returns a list of all formats and frame sizes that a specific camera 229 can offer. This is useful if your app can accept a variety of image formats 230 and sizes and so want to find the optimal spec that doesn't require 231 conversion. 232 233 This function isn't strictly required; if you call SDL_OpenCamera with a 234 NULL spec, SDL will choose a native format for you, and if you instead 235 specify a desired format, it will transparently convert to the requested 236 format on your behalf. 237 238 If `count` is not NULL, it will be filled with the number of elements in 239 the returned array. 240 241 Note that it's legal for a camera to supply an empty list. This is what 242 will happen on Emscripten builds, since that platform won't tell _anything_ 243 about available cameras until you've opened one, and won't even tell if 244 there _is_ a camera until the user has given you permission to check 245 through a scary warning popup. 246 247 Params: 248 instance_id = the camera device instance ID. 249 count = a pointer filled in with the number of elements in the list, 250 may be NULL. 251 252 Returns: 253 a NULL terminated array of pointers to SDL_CameraSpec or NULL on 254 failure; call SDL_GetError() for more information. This is a 255 single allocation that should be freed with SDL_free() when it is 256 no longer needed. 257 258 Threadsafety: 259 It is safe to call this function from any thread. 260 261 See_Also: 262 $(D SDL_GetCameras) 263 $(D SDL_OpenCamera) 264 */ 265 extern SDL_CameraSpec** SDL_GetCameraSupportedFormats(SDL_CameraID instance_id, int* count); 266 267 /** 268 Get the human-readable device name for a camera. 269 270 Params: 271 instance_id = the camera device instance ID. 272 273 Returns: 274 a human-readable device name or NULL on failure; call 275 SDL_GetError() for more information. 276 277 Threadsafety: 278 It is safe to call this function from any thread. 279 280 See_Also: 281 $(D SDL_GetCameras) 282 */ 283 extern const(char)* SDL_GetCameraName(SDL_CameraID instance_id); 284 285 /** 286 Get the position of the camera in relation to the system. 287 288 Most platforms will report UNKNOWN, but mobile devices, like phones, can 289 often make a distinction between cameras on the front of the device (that 290 points towards the user, for taking "selfies") and cameras on the back (for 291 filming in the direction the user is facing). 292 293 Params: 294 instance_id = the camera device instance ID. 295 296 Returns: 297 The position of the camera on the system hardware. 298 299 Threadsafety: 300 It is safe to call this function from any thread. 301 302 See_Also: 303 $(D SDL_GetCameras) 304 */ 305 extern SDL_CameraPosition SDL_GetCameraPosition(SDL_CameraID instance_id); 306 307 /** 308 Open a video recording device (a "camera"). 309 310 You can open the device with any reasonable spec, and if the hardware can't 311 directly support it, it will convert data seamlessly to the requested 312 format. This might incur overhead, including scaling of image data. 313 314 If you would rather accept whatever format the device offers, you can pass 315 a NULL spec here and it will choose one for you (and you can use 316 SDL_Surface's conversion/scaling functions directly if necessary). 317 318 You can call SDL_GetCameraFormat() to get the actual data format if passing 319 a NULL spec here. You can see the exact specs a device can support without 320 conversion with SDL_GetCameraSupportedFormats(). 321 322 SDL will not attempt to emulate framerate; it will try to set the hardware 323 to the rate closest to the requested speed, but it won't attempt to limit 324 or duplicate frames artificially; call SDL_GetCameraFormat() to see the 325 actual framerate of the opened the device, and check your timestamps if 326 this is crucial to your app! 327 328 Note that the camera is not usable until the user approves its use! On some 329 platforms, the operating system will prompt the user to permit access to 330 the camera, and they can choose Yes or No at that point. Until they do, the 331 camera will not be usable. The app should either wait for an 332 SDL_EVENT_CAMERA_DEVICE_APPROVED (or SDL_EVENT_CAMERA_DEVICE_DENIED) event, 333 or poll SDL_GetCameraPermissionState() occasionally until it returns 334 non-zero. On platforms that don't require explicit user approval (and 335 perhaps in places where the user previously permitted access), the approval 336 event might come immediately, but it might come seconds, minutes, or hours 337 later! 338 339 Params: 340 instance_id = the camera device instance ID. 341 spec = the desired format for data the device will provide. Can be 342 NULL. 343 344 Returns: 345 an SDL_Camera object or NULL on failure; call SDL_GetError() for 346 more information. 347 348 Threadsafety: 349 It is safe to call this function from any thread. 350 351 See_Also: 352 $(D SDL_GetCameras) 353 $(D SDL_GetCameraFormat) 354 */ 355 extern SDL_Camera* SDL_OpenCamera(SDL_CameraID instance_id, const SDL_CameraSpec *spec); 356 357 /** 358 Query if camera access has been approved by the user. 359 360 Cameras will not function between when the device is opened by the app and 361 when the user permits access to the hardware. On some platforms, this 362 presents as a popup dialog where the user has to explicitly approve access; 363 on others the approval might be implicit and not alert the user at all. 364 365 This function can be used to check the status of that approval. It will 366 return 0 if still waiting for user response, 1 if the camera is approved 367 for use, and -1 if the user denied access. 368 369 Instead of polling with this function, you can wait for a 370 SDL_EVENT_CAMERA_DEVICE_APPROVED (or SDL_EVENT_CAMERA_DEVICE_DENIED) event 371 in the standard SDL event loop, which is guaranteed to be sent once when 372 permission to use the camera is decided. 373 374 If a camera is declined, there's nothing to be done but call 375 SDL_CloseCamera() to dispose of it. 376 377 Params: 378 camera = the opened camera device to query. 379 380 Returns: 381 -1 if user denied access to the camera, 1 if user approved access, 382 0 if no decision has been made yet. 383 384 Threadsafety: 385 It is safe to call this function from any thread. 386 387 See_Also: 388 $(D SDL_OpenCamera) 389 $(D SDL_CloseCamera) 390 */ 391 extern int SDL_GetCameraPermissionState(SDL_Camera* camera); 392 393 /** 394 Get the instance ID of an opened camera. 395 396 Params: 397 camera = an SDL_Camera to query. 398 399 Returns: 400 the instance ID of the specified camera on success or 0 on 401 failure; call SDL_GetError() for more information. 402 403 Threadsafety: 404 It is safe to call this function from any thread. 405 406 See_Also: 407 $(D SDL_OpenCamera) 408 */ 409 extern SDL_CameraID SDL_GetCameraID(SDL_Camera* camera); 410 411 /** 412 Get the properties associated with an opened camera. 413 414 Params: 415 camera = the SDL_Camera obtained from SDL_OpenCamera(). 416 417 Returns: 418 a valid property ID on success or 0 on failure; call 419 SDL_GetError() for more information. 420 421 Threadsafety: 422 It is safe to call this function from any thread. 423 */ 424 extern SDL_PropertiesID SDL_GetCameraProperties(SDL_Camera* camera); 425 426 /** 427 Get the spec that a camera is using when generating images. 428 429 Note that this might not be the native format of the hardware, as SDL might 430 be converting to this format behind the scenes. 431 432 If the system is waiting for the user to approve access to the camera, as 433 some platforms require, this will return false, but this isn't necessarily 434 a fatal error; you should either wait for an 435 SDL_EVENT_CAMERA_DEVICE_APPROVED (or SDL_EVENT_CAMERA_DEVICE_DENIED) event, 436 or poll SDL_GetCameraPermissionState() occasionally until it returns 437 non-zero. 438 439 Params: 440 camera = opened camera device. 441 spec = the SDL_CameraSpec to be initialized by this function. 442 443 Returns: 444 true on success or false on failure; call SDL_GetError() for more 445 information. 446 447 Threadsafety: 448 It is safe to call this function from any thread. 449 450 See_Also: 451 $(D SDL_OpenCamera) 452 */ 453 extern bool SDL_GetCameraFormat(SDL_Camera* camera, SDL_CameraSpec* spec); 454 455 /** 456 Acquire a frame. 457 458 The frame is a memory pointer to the image data, whose size and format are 459 given by the spec requested when opening the device. 460 461 This is a non blocking API. If there is a frame available, a non-NULL 462 surface is returned, and timestampNS will be filled with a non-zero value. 463 464 Note that an error case can also return NULL, but a NULL by itself is 465 normal and just signifies that a new frame is not yet available. Note that 466 even if a camera device fails outright (a USB camera is unplugged while in 467 use, etc), SDL will send an event separately to notify the app, but 468 continue to provide blank frames at ongoing intervals until 469 SDL_CloseCamera() is called, so real failure here is almost always an out 470 of memory condition. 471 472 After use, the frame should be released with SDL_ReleaseCameraFrame(). If 473 you don't do this, the system may stop providing more video! 474 475 Do not call SDL_DestroySurface() on the returned surface! It must be given 476 back to the camera subsystem with SDL_ReleaseCameraFrame! 477 478 If the system is waiting for the user to approve access to the camera, as 479 some platforms require, this will return NULL (no frames available); you 480 should either wait for an SDL_EVENT_CAMERA_DEVICE_APPROVED (or 481 SDL_EVENT_CAMERA_DEVICE_DENIED) event, or poll 482 SDL_GetCameraPermissionState() occasionally until it returns non-zero. 483 484 Params: 485 camera = opened camera device. 486 timestampNS = a pointer filled in with the frame's timestamp, or 0 on 487 error. Can be NULL. 488 489 Returns: 490 a new frame of video on success, NULL if none is currently 491 available. 492 493 Threadsafety: 494 It is safe to call this function from any thread. 495 496 See_Also: 497 $(D SDL_ReleaseCameraFrame) 498 */ 499 extern SDL_Surface* SDL_AcquireCameraFrame(SDL_Camera* camera, Uint64* timestampNS); 500 501 /** 502 Release a frame of video acquired from a camera. 503 504 Let the back-end re-use the internal buffer for camera. 505 506 This function _must_ be called only on surface objects returned by 507 SDL_AcquireCameraFrame(). This function should be called as quickly as 508 possible after acquisition, as SDL keeps a small FIFO queue of surfaces for 509 video frames; if surfaces aren't released in a timely manner, SDL may drop 510 upcoming video frames from the camera. 511 512 If the app needs to keep the surface for a significant time, they should 513 make a copy of it and release the original. 514 515 The app should not use the surface again after calling this function; 516 assume the surface is freed and the pointer is invalid. 517 518 Params: 519 camera = opened camera device. 520 frame = the video frame surface to release. 521 522 Threadsafety: 523 It is safe to call this function from any thread. 524 525 See_Also: 526 $(D SDL_AcquireCameraFrame) 527 */ 528 extern void SDL_ReleaseCameraFrame(SDL_Camera* camera, SDL_Surface* frame); 529 530 /** 531 Use this function to shut down camera processing and close the camera 532 device. 533 534 Params: 535 camera = opened camera device. 536 537 Threadsafety: 538 It is safe to call this function from any thread, but no 539 thread may reference `device` once this function is called. 540 541 See_Also: 542 $(D SDL_OpenCamera) 543 */ 544 extern void SDL_CloseCamera(SDL_Camera* camera);