#include "../SDL_internal.h"
#ifndef SDL_syscamera_h_
#define SDL_syscamera_h_
#include "../video/SDL_surface_c.h"
#define DEBUG_CAMERA 0
extern SDL_Camera *SDL_AddCamera(const char *name, SDL_CameraPosition position, int num_specs, const SDL_CameraSpec *specs, void *handle);
extern void SDL_CameraDisconnected(SDL_Camera *device);
extern SDL_Camera *SDL_FindPhysicalCameraByCallback(bool (*callback)(SDL_Camera *device, void *userdata), void *userdata);
extern void SDL_CameraPermissionOutcome(SDL_Camera *device, bool approved);
extern char *SDL_GetCameraThreadName(SDL_Camera *device, char *buf, size_t buflen);
extern void RefPhysicalCamera(SDL_Camera *device);
extern void UnrefPhysicalCamera(SDL_Camera *device);
extern void SDL_CameraThreadSetup(SDL_Camera *device);
extern bool SDL_CameraThreadIterate(SDL_Camera *device);
extern void SDL_CameraThreadShutdown(SDL_Camera *device);
extern bool SDL_PrepareCameraSurfaces(SDL_Camera *device);
typedef struct CameraFormatAddData
{
SDL_CameraSpec *specs;
int num_specs;
int allocated_specs;
} CameraFormatAddData;
bool SDL_AddCameraFormat(CameraFormatAddData *data, SDL_PixelFormat format, SDL_Colorspace colorspace, int w, int h, int framerate_numerator, int framerate_denominator);
typedef enum SDL_CameraFrameResult
{
SDL_CAMERA_FRAME_ERROR,
SDL_CAMERA_FRAME_SKIP,
SDL_CAMERA_FRAME_READY
} SDL_CameraFrameResult;
typedef struct SurfaceList
{
SDL_Surface *surface;
Uint64 timestampNS;
struct SurfaceList *next;
} SurfaceList;
struct SDL_Camera
{
SDL_Mutex *lock;
char *name;
SDL_CameraPosition position;
SDL_AtomicInt refcount;
bool (*WaitDevice)(SDL_Camera *device);
SDL_CameraFrameResult (*AcquireFrame)(SDL_Camera *device, SDL_Surface *frame, Uint64 *timestampNS, float *rotation);
void (*ReleaseFrame)(SDL_Camera *device, SDL_Surface *frame);
SDL_CameraSpec *all_specs;
int num_specs;
SDL_CameraSpec actual_spec;
SDL_CameraSpec spec;
SDL_CameraID instance_id;
void *handle;
int drop_frames;
Uint64 base_timestamp;
Uint64 adjust_timestamp;
SDL_Surface *acquire_surface;
SDL_Surface *conversion_surface;
SurfaceList output_surfaces[8];
SurfaceList filled_output_surfaces; SurfaceList empty_output_surfaces; SurfaceList app_held_output_surfaces;
Uint8 *zombie_pixels;
int needs_scaling;
bool needs_conversion;
SDL_AtomicInt shutdown;
SDL_AtomicInt zombie;
SDL_Thread *thread;
SDL_PropertiesID props;
SDL_CameraPermissionState permission;
struct SDL_PrivateCameraData *hidden;
};
typedef struct SDL_CameraDriverImpl
{
void (*DetectDevices)(void);
bool (*OpenDevice)(SDL_Camera *device, const SDL_CameraSpec *spec);
void (*CloseDevice)(SDL_Camera *device);
bool (*WaitDevice)(SDL_Camera *device);
SDL_CameraFrameResult (*AcquireFrame)(SDL_Camera *device, SDL_Surface *frame, Uint64 *timestampNS, float *rotation); void (*ReleaseFrame)(SDL_Camera *device, SDL_Surface *frame); void (*FreeDeviceHandle)(SDL_Camera *device); void (*Deinitialize)(void);
bool ProvidesOwnCallbackThread;
} SDL_CameraDriverImpl;
typedef struct SDL_PendingCameraEvent
{
Uint32 type;
SDL_CameraID devid;
struct SDL_PendingCameraEvent *next;
} SDL_PendingCameraEvent;
typedef struct SDL_CameraDriver
{
const char *name; const char *desc; SDL_CameraDriverImpl impl;
SDL_RWLock *device_hash_lock; SDL_HashTable *device_hash; SDL_PendingCameraEvent pending_events;
SDL_PendingCameraEvent *pending_events_tail;
SDL_AtomicInt device_count;
SDL_AtomicInt shutting_down; } SDL_CameraDriver;
typedef struct CameraBootStrap
{
const char *name;
const char *desc;
bool (*init)(SDL_CameraDriverImpl *impl);
bool demand_only; } CameraBootStrap;
extern CameraBootStrap DUMMYCAMERA_bootstrap;
extern CameraBootStrap PIPEWIRECAMERA_bootstrap;
extern CameraBootStrap V4L2_bootstrap;
extern CameraBootStrap COREMEDIA_bootstrap;
extern CameraBootStrap ANDROIDCAMERA_bootstrap;
extern CameraBootStrap EMSCRIPTENCAMERA_bootstrap;
extern CameraBootStrap MEDIAFOUNDATION_bootstrap;
extern CameraBootStrap VITACAMERA_bootstrap;
#endif