mirror of https://github.com/libsdl-org/SDL
camera: Massive code reworking.
- Simplified public API, simplified backend interface. - Camera device hotplug events. - Thread code is split up so it backends that provide own threads can use it. - Added "dummy" backend. Note that CoreMedia (Apple) and Android backends need to be updated, as does the testcamera app (testcameraminimal works).
This commit is contained in:
parent
3d2d5d18f3
commit
d3e6ef3cc6
|
@ -49,23 +49,16 @@ typedef Uint32 SDL_CameraDeviceID;
|
|||
|
||||
|
||||
/**
|
||||
* The structure used to identify an SDL camera device
|
||||
* The structure used to identify an opened SDL camera
|
||||
*/
|
||||
struct SDL_CameraDevice;
|
||||
typedef struct SDL_CameraDevice SDL_CameraDevice;
|
||||
|
||||
#define SDL_CAMERA_ALLOW_ANY_CHANGE 1
|
||||
struct SDL_Camera;
|
||||
typedef struct SDL_Camera SDL_Camera;
|
||||
|
||||
/**
|
||||
* SDL_CameraSpec structure
|
||||
*
|
||||
* Only those field can be 'desired' when configuring the device:
|
||||
* - format
|
||||
* - width
|
||||
* - height
|
||||
*
|
||||
* \sa SDL_GetCameraFormat
|
||||
* \sa SDL_GetCameraFrameSize
|
||||
* \sa SDL_GetCameraDeviceSupportedSpecs
|
||||
* \sa SDL_GetCameraSpec
|
||||
*
|
||||
*/
|
||||
typedef struct SDL_CameraSpec
|
||||
|
@ -75,39 +68,6 @@ typedef struct SDL_CameraSpec
|
|||
int height; /**< Frame height */
|
||||
} SDL_CameraSpec;
|
||||
|
||||
/**
|
||||
* SDL Camera Status
|
||||
*
|
||||
* Change states but calling the function in this order:
|
||||
*
|
||||
* SDL_OpenCamera()
|
||||
* SDL_SetCameraSpec() -> Init
|
||||
* SDL_StartCamera() -> Playing
|
||||
* SDL_StopCamera() -> Stopped
|
||||
* SDL_CloseCamera()
|
||||
*
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
SDL_CAMERA_FAIL = -1, /**< Failed */
|
||||
SDL_CAMERA_INIT = 0, /**< Init, spec hasn't been set */
|
||||
SDL_CAMERA_STOPPED, /**< Stopped */
|
||||
SDL_CAMERA_PLAYING /**< Playing */
|
||||
} SDL_CameraStatus;
|
||||
|
||||
/**
|
||||
* SDL Video Capture Status
|
||||
*/
|
||||
typedef struct SDL_CameraFrame
|
||||
{
|
||||
Uint64 timestampNS; /**< Frame timestamp in nanoseconds when read from the driver */
|
||||
int num_planes; /**< Number of planes */
|
||||
Uint8 *data[3]; /**< Pointer to data of i-th plane */
|
||||
int pitch[3]; /**< Pitch of i-th plane */
|
||||
void *internal; /**< Private field */
|
||||
} SDL_CameraFrame;
|
||||
|
||||
|
||||
/**
|
||||
* Use this function to get the number of built-in camera drivers.
|
||||
*
|
||||
|
@ -176,11 +136,13 @@ extern DECLSPEC const char *SDLCALL SDL_GetCurrentCameraDriver(void);
|
|||
/**
|
||||
* Get a list of currently connected camera devices.
|
||||
*
|
||||
* \param count a pointer filled in with the number of camera devices
|
||||
* \param count a pointer filled in with the number of camera devices. Can be NULL.
|
||||
* \returns a 0 terminated array of camera instance IDs which should be
|
||||
* freed with SDL_free(), or NULL on error; call SDL_GetError() for
|
||||
* more details.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.0.0.
|
||||
*
|
||||
* \sa SDL_OpenCamera
|
||||
|
@ -188,237 +150,202 @@ extern DECLSPEC const char *SDLCALL SDL_GetCurrentCameraDriver(void);
|
|||
extern DECLSPEC SDL_CameraDeviceID *SDLCALL SDL_GetCameraDevices(int *count);
|
||||
|
||||
/**
|
||||
* Open a Video Capture device
|
||||
* Get the list of native formats/sizes a camera supports.
|
||||
*
|
||||
* This returns a list of all formats and frame sizes that a specific
|
||||
* camera can offer. This is useful if your app can accept a variety
|
||||
* of image formats and sizes and so want to find the optimal spec
|
||||
* that doesn't require conversion.
|
||||
*
|
||||
* This function isn't strictly required; if you call SDL_OpenCameraDevice
|
||||
* with a NULL spec, SDL will choose a native format for you, and if you
|
||||
* instead specify a desired format, it will transparently convert to the
|
||||
* requested format on your behalf.
|
||||
*
|
||||
* If `count` is not NULL, it will be filled with the number of elements
|
||||
* in the returned array. Additionally, the last element of the array
|
||||
* has all fields set to zero (this element is not included in `count`).
|
||||
*
|
||||
* The returned list is owned by the caller, and should be released with
|
||||
* SDL_free() when no longer needed.
|
||||
*
|
||||
* \param devid the camera device instance ID to query.
|
||||
* \param count a pointer filled in with the number of elements in the list. Can be NULL.
|
||||
* \returns a 0 terminated array of SDL_CameraSpecs, which should be
|
||||
* freed with SDL_free(), or NULL on error; call SDL_GetError() for
|
||||
* more details.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.0.0.
|
||||
*
|
||||
* \sa SDL_GetCameraDevices
|
||||
* \sa SDL_OpenCameraDevice
|
||||
*/
|
||||
extern DECLSPEC SDL_CameraSpec *SDLCALL SDL_GetCameraDeviceSupportedSpecs(SDL_CameraDeviceID devid, int *count);
|
||||
|
||||
/**
|
||||
* Get human-readable device name for a camera.
|
||||
*
|
||||
* The returned string is owned by the caller; please release it with
|
||||
* SDL_free() when done with it.
|
||||
*
|
||||
* \param instance_id the camera device instance ID
|
||||
* \returns Human-readable device name, or NULL on error; call SDL_GetError() for more information.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.0.0.
|
||||
*
|
||||
* \sa SDL_GetCameraDevices
|
||||
*/
|
||||
extern DECLSPEC char * SDLCALL SDL_GetCameraDeviceName(SDL_CameraDeviceID instance_id);
|
||||
|
||||
/**
|
||||
* Open a video capture device (a "camera").
|
||||
*
|
||||
* You can open the device with any reasonable spec, and if the hardware can't
|
||||
* directly support it, it will convert data seamlessly to the requested
|
||||
* format. This might incur overhead, including scaling of image data.
|
||||
*
|
||||
* If you would rather accept whatever format the device offers, you can
|
||||
* pass a NULL spec here and it will choose one for you (and you can use
|
||||
* SDL_Surface's conversion/scaling functions directly if necessary).
|
||||
*
|
||||
* You can call SDL_GetCameraSpec() to get the actual data format if
|
||||
* passing a NULL spec here. You can see the exact specs a device can
|
||||
* support without conversion with SDL_GetCameraSupportedSpecs().
|
||||
*
|
||||
* \param instance_id the camera device instance ID
|
||||
* \param spec The desired format for data the device will provide. Can be NULL.
|
||||
* \returns device, or NULL on failure; call SDL_GetError() for more
|
||||
* information.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.0.0.
|
||||
*
|
||||
* \sa SDL_GetCameraDeviceName
|
||||
* \sa SDL_GetCameraDevices
|
||||
* \sa SDL_OpenCameraWithSpec
|
||||
*/
|
||||
extern DECLSPEC SDL_CameraDevice *SDLCALL SDL_OpenCamera(SDL_CameraDeviceID instance_id);
|
||||
extern DECLSPEC SDL_Camera *SDLCALL SDL_OpenCameraDevice(SDL_CameraDeviceID instance_id, const SDL_CameraSpec *spec);
|
||||
|
||||
/**
|
||||
* Set specification
|
||||
* Get the instance ID of an opened camera.
|
||||
*
|
||||
* \param device opened camera device
|
||||
* \param desired desired camera spec
|
||||
* \param obtained obtained camera spec
|
||||
* \param allowed_changes allow changes or not
|
||||
* \returns 0 on success or a negative error code on failure; call
|
||||
* \param device an SDL_Camera to query
|
||||
* \returns the instance ID of the specified camera on success or 0 on
|
||||
* failure; call SDL_GetError() for more information.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.0.0.
|
||||
*
|
||||
* \sa SDL_OpenCameraDevice
|
||||
*/
|
||||
extern DECLSPEC SDL_CameraDeviceID SDLCALL SDL_GetCameraInstanceID(SDL_Camera *camera);
|
||||
|
||||
/**
|
||||
* Get the properties associated with an opened camera.
|
||||
*
|
||||
* \param device the SDL_Camera obtained from SDL_OpenCameraDevice()
|
||||
* \returns a valid property ID on success or 0 on failure; call
|
||||
* SDL_GetError() for more information.
|
||||
*
|
||||
* \since This function is available since SDL 3.0.0.
|
||||
*
|
||||
* \sa SDL_OpenCamera
|
||||
* \sa SDL_OpenCameraWithSpec
|
||||
* \sa SDL_GetCameraSpec
|
||||
*/
|
||||
extern DECLSPEC int SDLCALL SDL_SetCameraSpec(SDL_CameraDevice *device,
|
||||
const SDL_CameraSpec *desired,
|
||||
SDL_CameraSpec *obtained,
|
||||
int allowed_changes);
|
||||
|
||||
/**
|
||||
* Open a Video Capture device and set specification
|
||||
*
|
||||
* \param instance_id the camera device instance ID
|
||||
* \param desired desired camera spec
|
||||
* \param obtained obtained camera spec
|
||||
* \param allowed_changes allow changes or not
|
||||
* \returns device, or NULL on failure; call SDL_GetError() for more
|
||||
* information.
|
||||
* \threadsafety It is safe to call this function from any thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.0.0.
|
||||
*
|
||||
* \sa SDL_OpenCamera
|
||||
* \sa SDL_SetCameraSpec
|
||||
* \sa SDL_GetCameraSpec
|
||||
* \sa SDL_GetProperty
|
||||
* \sa SDL_SetProperty
|
||||
*/
|
||||
extern DECLSPEC SDL_CameraDevice *SDLCALL SDL_OpenCameraWithSpec(SDL_CameraDeviceID instance_id,
|
||||
const SDL_CameraSpec *desired,
|
||||
SDL_CameraSpec *obtained,
|
||||
int allowed_changes);
|
||||
extern DECLSPEC SDL_PropertiesID SDLCALL SDL_GetCameraProperties(SDL_Camera *camera);
|
||||
|
||||
/**
|
||||
* Get device name
|
||||
* Get the spec that a camera is using when generating images.
|
||||
*
|
||||
* \param instance_id the camera device instance ID
|
||||
* \returns device name, shouldn't be freed
|
||||
*
|
||||
* \since This function is available since SDL 3.0.0.
|
||||
*
|
||||
* \sa SDL_GetCameraDevices
|
||||
*/
|
||||
extern DECLSPEC const char * SDLCALL SDL_GetCameraDeviceName(SDL_CameraDeviceID instance_id);
|
||||
|
||||
/**
|
||||
* Get the obtained camera spec
|
||||
* Note that this might not be the native format of the hardware, as SDL
|
||||
* might be converting to this format behind the scenes.
|
||||
*
|
||||
* \param device opened camera device
|
||||
* \param spec The SDL_CameraSpec to be initialized by this function.
|
||||
* \returns 0 on success or a negative error code on failure; call
|
||||
* SDL_GetError() for more information.
|
||||
*
|
||||
* \since This function is available since SDL 3.0.0.
|
||||
*
|
||||
* \sa SDL_SetCameraSpec
|
||||
* \sa SDL_OpenCameraWithSpec
|
||||
*/
|
||||
extern DECLSPEC int SDLCALL SDL_GetCameraSpec(SDL_CameraDevice *device, SDL_CameraSpec *spec);
|
||||
|
||||
|
||||
/**
|
||||
* Get frame format of camera device.
|
||||
*
|
||||
* The value can be used to fill SDL_CameraSpec structure.
|
||||
*
|
||||
* \param device opened camera device
|
||||
* \param index format between 0 and num -1
|
||||
* \param format pointer output format (SDL_PixelFormatEnum)
|
||||
* \returns 0 on success or a negative error code on failure; call
|
||||
* SDL_GetError() for more information.
|
||||
* \threadsafety It is safe to call this function from any thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.0.0.
|
||||
*
|
||||
* \sa SDL_GetNumCameraFormats
|
||||
* \sa SDL_OpenCameraDevice
|
||||
*/
|
||||
extern DECLSPEC int SDLCALL SDL_GetCameraFormat(SDL_CameraDevice *device,
|
||||
int index,
|
||||
Uint32 *format);
|
||||
|
||||
/**
|
||||
* Number of available formats for the device
|
||||
*
|
||||
* \param device opened camera device
|
||||
* \returns number of formats or a negative error code on failure; call
|
||||
* SDL_GetError() for more information.
|
||||
*
|
||||
* \since This function is available since SDL 3.0.0.
|
||||
*
|
||||
* \sa SDL_GetCameraFormat
|
||||
* \sa SDL_SetCameraSpec
|
||||
*/
|
||||
extern DECLSPEC int SDLCALL SDL_GetNumCameraFormats(SDL_CameraDevice *device);
|
||||
|
||||
/**
|
||||
* Get frame sizes of the device and the specified input format.
|
||||
*
|
||||
* The value can be used to fill SDL_CameraSpec structure.
|
||||
*
|
||||
* \param device opened camera device
|
||||
* \param format a format that can be used by the device (SDL_PixelFormatEnum)
|
||||
* \param index framesize between 0 and num -1
|
||||
* \param width output width
|
||||
* \param height output height
|
||||
* \returns 0 on success or a negative error code on failure; call
|
||||
* SDL_GetError() for more information.
|
||||
*
|
||||
* \since This function is available since SDL 3.0.0.
|
||||
*
|
||||
* \sa SDL_GetNumCameraFrameSizes
|
||||
*/
|
||||
extern DECLSPEC int SDLCALL SDL_GetCameraFrameSize(SDL_CameraDevice *device, Uint32 format, int index, int *width, int *height);
|
||||
|
||||
/**
|
||||
* Number of different framesizes available for the device and pixel format.
|
||||
*
|
||||
* \param device opened camera device
|
||||
* \param format frame pixel format (SDL_PixelFormatEnum)
|
||||
* \returns number of framesizes or a negative error code on failure; call
|
||||
* SDL_GetError() for more information.
|
||||
*
|
||||
* \since This function is available since SDL 3.0.0.
|
||||
*
|
||||
* \sa SDL_GetCameraFrameSize
|
||||
* \sa SDL_SetCameraSpec
|
||||
*/
|
||||
extern DECLSPEC int SDLCALL SDL_GetNumCameraFrameSizes(SDL_CameraDevice *device, Uint32 format);
|
||||
|
||||
|
||||
/**
|
||||
* Get camera status
|
||||
*
|
||||
* \param device opened camera device
|
||||
* \returns 0 on success or a negative error code on failure; call
|
||||
* SDL_GetError() for more information.
|
||||
*
|
||||
* \since This function is available since SDL 3.0.0.
|
||||
*
|
||||
* \sa SDL_CameraStatus
|
||||
*/
|
||||
extern DECLSPEC SDL_CameraStatus SDLCALL SDL_GetCameraStatus(SDL_CameraDevice *device);
|
||||
|
||||
/**
|
||||
* Start camera
|
||||
*
|
||||
* \param device opened camera device
|
||||
* \returns 0 on success or a negative error code on failure; call
|
||||
* SDL_GetError() for more information.
|
||||
*
|
||||
* \since This function is available since SDL 3.0.0.
|
||||
*
|
||||
* \sa SDL_StopCamera
|
||||
*/
|
||||
extern DECLSPEC int SDLCALL SDL_StartCamera(SDL_CameraDevice *device);
|
||||
extern DECLSPEC int SDLCALL SDL_GetCameraSpec(SDL_Camera *camera, SDL_CameraSpec *spec);
|
||||
|
||||
/**
|
||||
* Acquire a frame.
|
||||
*
|
||||
* The frame is a memory pointer to the image data, whose size and format are
|
||||
* given by the the obtained spec.
|
||||
* given by the spec requested when opening the device.
|
||||
*
|
||||
* Non blocking API. If there is a frame available, frame->num_planes is non
|
||||
* 0. If frame->num_planes is 0 and returned code is 0, there is no frame at
|
||||
* that time.
|
||||
* This is a non blocking API. If there is a frame available, a non-NULL surface is
|
||||
* returned, and timestampNS will be filled with a non-zero value.
|
||||
*
|
||||
* After used, the frame should be released with SDL_ReleaseCameraFrame
|
||||
* Note that an error case can also return NULL, but a NULL by itself is normal
|
||||
* and just signifies that a new frame is not yet available. Note that even if a
|
||||
* camera device fails outright (a USB camera is unplugged while in use, etc), SDL
|
||||
* will send an event separately to notify the app, but continue to provide blank
|
||||
* frames at ongoing intervals until SDL_CloseCamera() is called, so real
|
||||
* failure here is almost always an out of memory condition.
|
||||
*
|
||||
* After use, the frame should be released with SDL_ReleaseCameraFrame(). If you
|
||||
* don't do this, the system may stop providing more video! If the hardware is
|
||||
* using DMA to write directly into memory, frames held too long may be overwritten
|
||||
* with new data.
|
||||
*
|
||||
* Do not call SDL_FreeSurface() on the returned surface! It must be given back
|
||||
* to the camera subsystem with SDL_ReleaseCameraFrame!
|
||||
*
|
||||
* \param device opened camera device
|
||||
* \param frame pointer to get the frame
|
||||
* \returns 0 on success or a negative error code on failure; call
|
||||
* SDL_GetError() for more information.
|
||||
* \param timestampNS a pointer filled in with the frame's timestamp, or 0 on error. Can be NULL.
|
||||
* \returns A new frame of video on success, NULL if none is currently available.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.0.0.
|
||||
*
|
||||
* \sa SDL_ReleaseCameraFrame
|
||||
*/
|
||||
extern DECLSPEC int SDLCALL SDL_AcquireCameraFrame(SDL_CameraDevice *device, SDL_CameraFrame *frame);
|
||||
extern DECLSPEC SDL_Surface * SDLCALL SDL_AcquireCameraFrame(SDL_Camera *camera, Uint64 *timestampNS);
|
||||
|
||||
/**
|
||||
* Release a frame.
|
||||
* Release a frame of video acquired from a camera.
|
||||
*
|
||||
* Let the back-end re-use the internal buffer for camera.
|
||||
*
|
||||
* All acquired frames should be released before closing the device.
|
||||
* This function _must_ be called only on surface objects returned by
|
||||
* SDL_AcquireCameraFrame(). This function should be called as quickly as
|
||||
* possible after acquisition, as SDL keeps a small FIFO queue of surfaces
|
||||
* for video frames; if surfaces aren't released in a timely manner, SDL
|
||||
* may drop upcoming video frames from the camera.
|
||||
*
|
||||
* If the app needs to keep the surface for a significant time, they should
|
||||
* make a copy of it and release the original.
|
||||
*
|
||||
* The app should not use the surface again after calling this function;
|
||||
* assume the surface is freed and the pointer is invalid.
|
||||
*
|
||||
* \param device opened camera device
|
||||
* \param frame frame pointer.
|
||||
* \param frame The video frame surface to release.
|
||||
* \returns 0 on success or a negative error code on failure; call
|
||||
* SDL_GetError() for more information.
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread.
|
||||
*
|
||||
* \since This function is available since SDL 3.0.0.
|
||||
*
|
||||
* \sa SDL_AcquireCameraFrame
|
||||
*/
|
||||
extern DECLSPEC int SDLCALL SDL_ReleaseCameraFrame(SDL_CameraDevice *device, SDL_CameraFrame *frame);
|
||||
|
||||
/**
|
||||
* Stop Video Capture
|
||||
*
|
||||
* \param device opened camera device
|
||||
* \returns 0 on success or a negative error code on failure; call
|
||||
* SDL_GetError() for more information.
|
||||
*
|
||||
* \since This function is available since SDL 3.0.0.
|
||||
*
|
||||
* \sa SDL_StartCamera
|
||||
*/
|
||||
extern DECLSPEC int SDLCALL SDL_StopCamera(SDL_CameraDevice *device);
|
||||
extern DECLSPEC int SDLCALL SDL_ReleaseCameraFrame(SDL_Camera *camera, SDL_Surface *frame);
|
||||
|
||||
/**
|
||||
* Use this function to shut down camera processing and close the
|
||||
|
@ -426,12 +353,16 @@ extern DECLSPEC int SDLCALL SDL_StopCamera(SDL_CameraDevice *device);
|
|||
*
|
||||
* \param device opened camera device
|
||||
*
|
||||
* \threadsafety It is safe to call this function from any thread, but
|
||||
* no thread may reference `device` once this function
|
||||
* is called.
|
||||
*
|
||||
* \since This function is available since SDL 3.0.0.
|
||||
*
|
||||
* \sa SDL_OpenCameraWithSpec
|
||||
* \sa SDL_OpenCamera
|
||||
*/
|
||||
extern DECLSPEC void SDLCALL SDL_CloseCamera(SDL_CameraDevice *device);
|
||||
extern DECLSPEC void SDLCALL SDL_CloseCamera(SDL_Camera *camera);
|
||||
|
||||
/* Ends C function definitions when using C++ */
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -205,6 +205,10 @@ typedef enum
|
|||
SDL_EVENT_PEN_BUTTON_DOWN, /**< Pressure-sensitive pen button pressed */
|
||||
SDL_EVENT_PEN_BUTTON_UP, /**< Pressure-sensitive pen button released */
|
||||
|
||||
/* Camera hotplug events */
|
||||
SDL_EVENT_CAMERA_DEVICE_ADDED = 0x1400, /**< A new camera device is available */
|
||||
SDL_EVENT_CAMERA_DEVICE_REMOVED, /**< A camera device has been removed. */
|
||||
|
||||
/* Render events */
|
||||
SDL_EVENT_RENDER_TARGETS_RESET = 0x2000, /**< The render targets have been reset and their contents need to be updated */
|
||||
SDL_EVENT_RENDER_DEVICE_RESET, /**< The device has been reset and all textures need to be recreated */
|
||||
|
@ -526,6 +530,18 @@ typedef struct SDL_AudioDeviceEvent
|
|||
Uint8 padding3;
|
||||
} SDL_AudioDeviceEvent;
|
||||
|
||||
/**
|
||||
* Camera device event structure (event.cdevice.*)
|
||||
*/
|
||||
typedef struct SDL_CameraDeviceEvent
|
||||
{
|
||||
Uint32 type; /**< ::SDL_EVENT_CAMERA_DEVICE_ADDED, or ::SDL_EVENT_CAMERA_DEVICE_REMOVED */
|
||||
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
|
||||
SDL_CameraDeviceID which; /**< SDL_CameraDeviceID for the device being added or removed or changing */
|
||||
Uint8 padding1;
|
||||
Uint8 padding2;
|
||||
Uint8 padding3;
|
||||
} SDL_CameraDeviceEvent;
|
||||
|
||||
/**
|
||||
* Touch finger event structure (event.tfinger.*)
|
||||
|
@ -699,6 +715,7 @@ typedef union SDL_Event
|
|||
SDL_GamepadTouchpadEvent gtouchpad; /**< Gamepad touchpad event data */
|
||||
SDL_GamepadSensorEvent gsensor; /**< Gamepad sensor event data */
|
||||
SDL_AudioDeviceEvent adevice; /**< Audio device event data */
|
||||
SDL_CameraDeviceEvent cdevice; /**< Camera device event data */
|
||||
SDL_SensorEvent sensor; /**< Sensor event data */
|
||||
SDL_QuitEvent quit; /**< Quit request event data */
|
||||
SDL_UserEvent user; /**< Custom event data */
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -29,4 +29,7 @@ int SDL_CameraInit(const char *driver_name);
|
|||
// Shutdown the camera subsystem
|
||||
void SDL_QuitCamera(void);
|
||||
|
||||
// "Pump" the event queue.
|
||||
extern void SDL_UpdateCamera(void);
|
||||
|
||||
#endif // SDL_camera_c_h_
|
||||
|
|
|
@ -23,67 +23,141 @@
|
|||
#ifndef SDL_syscamera_h_
|
||||
#define SDL_syscamera_h_
|
||||
|
||||
#include "../SDL_list.h"
|
||||
#include "../SDL_hashtable.h"
|
||||
|
||||
#define DEBUG_CAMERA 1
|
||||
|
||||
// The SDL camera driver
|
||||
|
||||
// !!! FIXME: update these drivers!
|
||||
#ifdef SDL_CAMERA_DRIVER_COREMEDIA
|
||||
#undef SDL_CAMERA_DRIVER_COREMEDIA
|
||||
#endif
|
||||
#ifdef SDL_CAMERA_DRIVER_ANDROID
|
||||
#undef SDL_CAMERA_DRIVER_ANDROID
|
||||
#endif
|
||||
|
||||
typedef struct SDL_CameraDevice SDL_CameraDevice;
|
||||
|
||||
/* Backends should call this as devices are added to the system (such as
|
||||
a USB camera being plugged in), and should also be called for
|
||||
for every device found during DetectDevices(). */
|
||||
extern SDL_CameraDevice *SDL_AddCameraDevice(const char *name, int num_specs, const SDL_CameraSpec *specs, void *handle);
|
||||
|
||||
/* Backends should call this if an opened camera device is lost.
|
||||
This can happen due to i/o errors, or a device being unplugged, etc. */
|
||||
extern void SDL_CameraDeviceDisconnected(SDL_CameraDevice *device);
|
||||
|
||||
// Find an SDL_CameraDevice, selected by a callback. NULL if not found. DOES NOT LOCK THE DEVICE.
|
||||
extern SDL_CameraDevice *SDL_FindPhysicalCameraDeviceByCallback(SDL_bool (*callback)(SDL_CameraDevice *device, void *userdata), void *userdata);
|
||||
|
||||
// These functions are the heart of the camera threads. Backends can call them directly if they aren't using the SDL-provided thread.
|
||||
extern void SDL_CameraThreadSetup(SDL_CameraDevice *device);
|
||||
extern SDL_bool SDL_CameraThreadIterate(SDL_CameraDevice *device);
|
||||
extern void SDL_CameraThreadShutdown(SDL_CameraDevice *device);
|
||||
|
||||
typedef struct SurfaceList
|
||||
{
|
||||
SDL_Surface *surface;
|
||||
Uint64 timestampNS;
|
||||
struct SurfaceList *next;
|
||||
} SurfaceList;
|
||||
|
||||
// Define the SDL camera driver structure
|
||||
struct SDL_CameraDevice
|
||||
{
|
||||
// The device's current camera specification
|
||||
// A mutex for locking
|
||||
SDL_Mutex *lock;
|
||||
|
||||
// Human-readable device name.
|
||||
char *name;
|
||||
|
||||
// When refcount hits zero, we destroy the device object.
|
||||
SDL_AtomicInt refcount;
|
||||
|
||||
// All supported formats/dimensions for this device.
|
||||
SDL_CameraSpec *all_specs;
|
||||
|
||||
// Elements in all_specs.
|
||||
int num_specs;
|
||||
|
||||
// The device's actual specification that the camera is outputting, before conversion.
|
||||
SDL_CameraSpec actual_spec;
|
||||
|
||||
// The device's current camera specification, after conversions.
|
||||
SDL_CameraSpec spec;
|
||||
|
||||
// Device name
|
||||
char *dev_name;
|
||||
// Unique value assigned at creation time.
|
||||
SDL_CameraDeviceID instance_id;
|
||||
|
||||
// Driver-specific hardware data on how to open device (`hidden` is driver-specific data _when opened_).
|
||||
void *handle;
|
||||
|
||||
// Pixel data flows from the driver into these, then gets converted for the app if necessary.
|
||||
SDL_Surface *acquire_surface;
|
||||
|
||||
// acquire_surface converts or scales to this surface before landing in output_surfaces, if necessary.
|
||||
SDL_Surface *conversion_surface;
|
||||
|
||||
// A queue of surfaces that buffer converted/scaled frames of video until the app claims them.
|
||||
SurfaceList output_surfaces[8];
|
||||
SurfaceList filled_output_surfaces; // this is FIFO
|
||||
SurfaceList empty_output_surfaces; // this is LIFO
|
||||
SurfaceList app_held_output_surfaces;
|
||||
|
||||
// non-zero if acquire_surface needs to be scaled for final output.
|
||||
int needs_scaling; // -1: downscale, 0: no scaling, 1: upscale
|
||||
|
||||
// SDL_TRUE if acquire_surface needs to be converted for final output.
|
||||
SDL_bool needs_conversion;
|
||||
|
||||
// Current state flags
|
||||
SDL_AtomicInt shutdown;
|
||||
SDL_AtomicInt enabled;
|
||||
SDL_bool is_spec_set;
|
||||
|
||||
// A mutex for locking the queue buffers
|
||||
SDL_Mutex *device_lock;
|
||||
SDL_Mutex *acquiring_lock;
|
||||
SDL_AtomicInt zombie;
|
||||
|
||||
// A thread to feed the camera device
|
||||
SDL_Thread *thread;
|
||||
SDL_ThreadID threadid;
|
||||
|
||||
// Queued buffers (if app not using callback).
|
||||
SDL_ListNode *buffer_queue;
|
||||
// Optional properties.
|
||||
SDL_PropertiesID props;
|
||||
|
||||
// Data private to this driver
|
||||
// Data private to this driver, used when device is opened and running.
|
||||
struct SDL_PrivateCameraData *hidden;
|
||||
};
|
||||
|
||||
typedef struct SDL_CameraDriverImpl
|
||||
{
|
||||
void (*DetectDevices)(void);
|
||||
int (*OpenDevice)(SDL_CameraDevice *_this);
|
||||
void (*CloseDevice)(SDL_CameraDevice *_this);
|
||||
int (*InitDevice)(SDL_CameraDevice *_this);
|
||||
int (*GetDeviceSpec)(SDL_CameraDevice *_this, SDL_CameraSpec *spec);
|
||||
int (*StartCamera)(SDL_CameraDevice *_this);
|
||||
int (*StopCamera)(SDL_CameraDevice *_this);
|
||||
int (*AcquireFrame)(SDL_CameraDevice *_this, SDL_CameraFrame *frame);
|
||||
int (*ReleaseFrame)(SDL_CameraDevice *_this, SDL_CameraFrame *frame);
|
||||
int (*GetNumFormats)(SDL_CameraDevice *_this);
|
||||
int (*GetFormat)(SDL_CameraDevice *_this, int index, Uint32 *format);
|
||||
int (*GetNumFrameSizes)(SDL_CameraDevice *_this, Uint32 format);
|
||||
int (*GetFrameSize)(SDL_CameraDevice *_this, Uint32 format, int index, int *width, int *height);
|
||||
int (*GetDeviceName)(SDL_CameraDeviceID instance_id, char *buf, int size);
|
||||
SDL_CameraDeviceID *(*GetDevices)(int *count);
|
||||
int (*OpenDevice)(SDL_CameraDevice *device, const SDL_CameraSpec *spec);
|
||||
void (*CloseDevice)(SDL_CameraDevice *device);
|
||||
int (*WaitDevice)(SDL_CameraDevice *device);
|
||||
int (*AcquireFrame)(SDL_CameraDevice *device, SDL_Surface *frame, Uint64 *timestampNS); // set frame->pixels, frame->pitch, and *timestampNS!
|
||||
void (*ReleaseFrame)(SDL_CameraDevice *device, SDL_Surface *frame); // Reclaim frame->pixels and frame->pitch!
|
||||
void (*FreeDeviceHandle)(SDL_CameraDevice *device); // SDL is done with this device; free the handle from SDL_AddCameraDevice()
|
||||
void (*Deinitialize)(void);
|
||||
|
||||
SDL_bool ProvidesOwnCallbackThread;
|
||||
} SDL_CameraDriverImpl;
|
||||
|
||||
typedef struct SDL_PendingCameraDeviceEvent
|
||||
{
|
||||
Uint32 type;
|
||||
SDL_CameraDeviceID devid;
|
||||
struct SDL_PendingCameraDeviceEvent *next;
|
||||
} SDL_PendingCameraDeviceEvent;
|
||||
|
||||
typedef struct SDL_CameraDriver
|
||||
{
|
||||
const char *name; // The name of this camera driver
|
||||
const char *desc; // The description of this camera driver
|
||||
SDL_CameraDriverImpl impl; // the backend's interface
|
||||
|
||||
SDL_RWLock *device_hash_lock; // A rwlock that protects `device_hash`
|
||||
SDL_HashTable *device_hash; // the collection of currently-available camera devices
|
||||
SDL_PendingCameraDeviceEvent pending_events;
|
||||
SDL_PendingCameraDeviceEvent *pending_events_tail;
|
||||
|
||||
SDL_AtomicInt device_count;
|
||||
SDL_AtomicInt shutting_down; // non-zero during SDL_Quit, so we known not to accept any last-minute device hotplugs.
|
||||
} SDL_CameraDriver;
|
||||
|
||||
typedef struct CameraBootStrap
|
||||
|
|
|
@ -135,7 +135,9 @@ static Uint32 nsfourcc_to_sdlformat(NSString *nsfourcc)
|
|||
if (SDL_strcmp("yuvs", str) == 0) return SDL_PIXELFORMAT_UYVY;
|
||||
if (SDL_strcmp("420f", str) == 0) return SDL_PIXELFORMAT_UNKNOWN;
|
||||
|
||||
SDL_Log("Unknown format '%s'", str);
|
||||
#if DEBUG_CAMERA
|
||||
SDL_Log("CAMERA: Unknown format '%s'", str);
|
||||
#endif
|
||||
|
||||
return SDL_PIXELFORMAT_UNKNOWN;
|
||||
}
|
||||
|
@ -177,8 +179,9 @@ static NSString *sdlformat_to_nsfourcc(Uint32 fmt)
|
|||
- (void)captureOutput:(AVCaptureOutput *)output
|
||||
didDropSampleBuffer:(CMSampleBufferRef)sampleBuffer
|
||||
fromConnection:(AVCaptureConnection *)connection {
|
||||
// !!! FIXME #if DEBUG_CAMERA
|
||||
SDL_Log("Drop frame..");
|
||||
#if DEBUG_CAMERA
|
||||
SDL_Log("CAMERA: Drop frame..");
|
||||
#endif
|
||||
}
|
||||
@end
|
||||
|
||||
|
@ -362,13 +365,13 @@ static int COREMEDIA_AcquireFrame(SDL_CameraDevice *_this, SDL_CameraFrame *fram
|
|||
const int numPlanes = CVPixelBufferGetPlaneCount(image);
|
||||
const int planar = CVPixelBufferIsPlanar(image);
|
||||
|
||||
#if 0
|
||||
#if DEBUG_CAMERA
|
||||
const int w = CVPixelBufferGetWidth(image);
|
||||
const int h = CVPixelBufferGetHeight(image);
|
||||
const int sz = CVPixelBufferGetDataSize(image);
|
||||
const int pitch = CVPixelBufferGetBytesPerRow(image);
|
||||
SDL_Log("buffer planar=%d count:%d %d x %d sz=%d pitch=%d", planar, numPlanes, w, h, sz, pitch);
|
||||
#endif
|
||||
SDL_Log("CAMERA: buffer planar=%d count:%d %d x %d sz=%d pitch=%d", planar, numPlanes, w, h, sz, pitch);
|
||||
#endif
|
||||
|
||||
CVPixelBufferLockBaseAddress(image, 0);
|
||||
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2023 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "SDL_internal.h"
|
||||
|
||||
#ifdef SDL_CAMERA_DRIVER_DUMMY
|
||||
|
||||
#include "../SDL_syscamera.h"
|
||||
|
||||
static int DUMMYCAMERA_OpenDevice(SDL_CameraDevice *device, const SDL_CameraSpec *spec)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static void DUMMYCAMERA_CloseDevice(SDL_CameraDevice *device)
|
||||
{
|
||||
}
|
||||
|
||||
static int DUMMYCAMERA_WaitDevice(SDL_CameraDevice *device)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static int DUMMYCAMERA_AcquireFrame(SDL_CameraDevice *device, SDL_Surface *frame, Uint64 *timestampNS)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static void DUMMYCAMERA_ReleaseFrame(SDL_CameraDevice *device, SDL_Surface *frame)
|
||||
{
|
||||
}
|
||||
|
||||
static void DUMMYCAMERA_DetectDevices(void)
|
||||
{
|
||||
}
|
||||
|
||||
static void DUMMYCAMERA_FreeDeviceHandle(SDL_CameraDevice *device)
|
||||
{
|
||||
}
|
||||
|
||||
static void DUMMYCAMERA_Deinitialize(void)
|
||||
{
|
||||
}
|
||||
|
||||
static SDL_bool DUMMYCAMERA_Init(SDL_CameraDriverImpl *impl)
|
||||
{
|
||||
impl->DetectDevices = DUMMYCAMERA_DetectDevices;
|
||||
impl->OpenDevice = DUMMYCAMERA_OpenDevice;
|
||||
impl->CloseDevice = DUMMYCAMERA_CloseDevice;
|
||||
impl->WaitDevice = DUMMYCAMERA_WaitDevice;
|
||||
impl->AcquireFrame = DUMMYCAMERA_AcquireFrame;
|
||||
impl->ReleaseFrame = DUMMYCAMERA_ReleaseFrame;
|
||||
impl->FreeDeviceHandle = DUMMYCAMERA_FreeDeviceHandle;
|
||||
impl->Deinitialize = DUMMYCAMERA_Deinitialize;
|
||||
|
||||
return SDL_TRUE;
|
||||
}
|
||||
|
||||
CameraBootStrap DUMMYCAMERA_bootstrap = {
|
||||
"dummy", "SDL dummy camera driver", DUMMYCAMERA_Init, SDL_TRUE
|
||||
};
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -957,21 +957,18 @@ SDL3_0.0.0 {
|
|||
SDL_SetWindowShape;
|
||||
SDL_RenderViewportSet;
|
||||
SDL_HasProperty;
|
||||
SDL_GetNumCameraDrivers;
|
||||
SDL_GetCameraDriver;
|
||||
SDL_GetCurrentCameraDriver;
|
||||
SDL_GetCameraDevices;
|
||||
SDL_OpenCamera;
|
||||
SDL_SetCameraSpec;
|
||||
SDL_OpenCameraWithSpec;
|
||||
SDL_GetCameraDeviceSupportedSpecs;
|
||||
SDL_GetCameraDeviceName;
|
||||
SDL_OpenCameraDevice;
|
||||
SDL_GetCameraInstanceID;
|
||||
SDL_GetCameraProperties;
|
||||
SDL_GetCameraSpec;
|
||||
SDL_GetCameraFormat;
|
||||
SDL_GetNumCameraFormats;
|
||||
SDL_GetCameraFrameSize;
|
||||
SDL_GetNumCameraFrameSizes;
|
||||
SDL_GetCameraStatus;
|
||||
SDL_StartCamera;
|
||||
SDL_AcquireCameraFrame;
|
||||
SDL_ReleaseCameraFrame;
|
||||
SDL_StopCamera;
|
||||
SDL_CloseCamera;
|
||||
# extra symbols go here (don't modify this line)
|
||||
local: *;
|
||||
|
|
|
@ -982,19 +982,16 @@
|
|||
#define SDL_SetWindowShape SDL_SetWindowShape_REAL
|
||||
#define SDL_RenderViewportSet SDL_RenderViewportSet_REAL
|
||||
#define SDL_HasProperty SDL_HasProperty_REAL
|
||||
#define SDL_GetNumCameraDrivers SDL_GetNumCameraDrivers_REAL
|
||||
#define SDL_GetCameraDriver SDL_GetCameraDriver_REAL
|
||||
#define SDL_GetCurrentCameraDriver SDL_GetCurrentCameraDriver_REAL
|
||||
#define SDL_GetCameraDevices SDL_GetCameraDevices_REAL
|
||||
#define SDL_OpenCamera SDL_OpenCamera_REAL
|
||||
#define SDL_SetCameraSpec SDL_SetCameraSpec_REAL
|
||||
#define SDL_OpenCameraWithSpec SDL_OpenCameraWithSpec_REAL
|
||||
#define SDL_GetCameraDeviceSupportedSpecs SDL_GetCameraDeviceSupportedSpecs_REAL
|
||||
#define SDL_GetCameraDeviceName SDL_GetCameraDeviceName_REAL
|
||||
#define SDL_OpenCameraDevice SDL_OpenCameraDevice_REAL
|
||||
#define SDL_GetCameraInstanceID SDL_GetCameraInstanceID_REAL
|
||||
#define SDL_GetCameraProperties SDL_GetCameraProperties_REAL
|
||||
#define SDL_GetCameraSpec SDL_GetCameraSpec_REAL
|
||||
#define SDL_GetCameraFormat SDL_GetCameraFormat_REAL
|
||||
#define SDL_GetNumCameraFormats SDL_GetNumCameraFormats_REAL
|
||||
#define SDL_GetCameraFrameSize SDL_GetCameraFrameSize_REAL
|
||||
#define SDL_GetNumCameraFrameSizes SDL_GetNumCameraFrameSizes_REAL
|
||||
#define SDL_GetCameraStatus SDL_GetCameraStatus_REAL
|
||||
#define SDL_StartCamera SDL_StartCamera_REAL
|
||||
#define SDL_AcquireCameraFrame SDL_AcquireCameraFrame_REAL
|
||||
#define SDL_ReleaseCameraFrame SDL_ReleaseCameraFrame_REAL
|
||||
#define SDL_StopCamera SDL_StopCamera_REAL
|
||||
#define SDL_CloseCamera SDL_CloseCamera_REAL
|
||||
|
|
|
@ -1007,19 +1007,16 @@ SDL_DYNAPI_PROC(int,SDL_RenderGeometryRawFloat,(SDL_Renderer *a, SDL_Texture *b,
|
|||
SDL_DYNAPI_PROC(int,SDL_SetWindowShape,(SDL_Window *a, SDL_Surface *b),(a,b),return)
|
||||
SDL_DYNAPI_PROC(SDL_bool,SDL_RenderViewportSet,(SDL_Renderer *a),(a),return)
|
||||
SDL_DYNAPI_PROC(SDL_bool,SDL_HasProperty,(SDL_PropertiesID a, const char *b),(a,b),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_GetNumCameraDrivers,(void),(),return)
|
||||
SDL_DYNAPI_PROC(const char*,SDL_GetCameraDriver,(int a),(a),return)
|
||||
SDL_DYNAPI_PROC(const char*,SDL_GetCurrentCameraDriver,(void),(),return)
|
||||
SDL_DYNAPI_PROC(SDL_CameraDeviceID*,SDL_GetCameraDevices,(int *a),(a),return)
|
||||
SDL_DYNAPI_PROC(SDL_CameraDevice*,SDL_OpenCamera,(SDL_CameraDeviceID a),(a),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_SetCameraSpec,(SDL_CameraDevice *a, const SDL_CameraSpec *b, SDL_CameraSpec *c, int d),(a,b,c,d),return)
|
||||
SDL_DYNAPI_PROC(SDL_CameraDevice*,SDL_OpenCameraWithSpec,(SDL_CameraDeviceID a, const SDL_CameraSpec *b, SDL_CameraSpec *c, int d),(a,b,c,d),return)
|
||||
SDL_DYNAPI_PROC(const char*,SDL_GetCameraDeviceName,(SDL_CameraDeviceID a),(a),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_GetCameraSpec,(SDL_CameraDevice *a, SDL_CameraSpec *b),(a,b),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_GetCameraFormat,(SDL_CameraDevice *a, int b, Uint32 *c),(a,b,c),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_GetNumCameraFormats,(SDL_CameraDevice *a),(a),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_GetCameraFrameSize,(SDL_CameraDevice *a, Uint32 b, int c, int *d, int *e),(a,b,c,d,e),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_GetNumCameraFrameSizes,(SDL_CameraDevice *a, Uint32 b),(a,b),return)
|
||||
SDL_DYNAPI_PROC(SDL_CameraStatus,SDL_GetCameraStatus,(SDL_CameraDevice *a),(a),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_StartCamera,(SDL_CameraDevice *a),(a),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_AcquireCameraFrame,(SDL_CameraDevice *a, SDL_CameraFrame *b),(a,b),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_ReleaseCameraFrame,(SDL_CameraDevice *a, SDL_CameraFrame *b),(a,b),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_StopCamera,(SDL_CameraDevice *a),(a),return)
|
||||
SDL_DYNAPI_PROC(void,SDL_CloseCamera,(SDL_CameraDevice *a),(a),)
|
||||
SDL_DYNAPI_PROC(SDL_CameraSpec*,SDL_GetCameraDeviceSupportedSpecs,(SDL_CameraDeviceID a, int *b),(a,b),return)
|
||||
SDL_DYNAPI_PROC(char*,SDL_GetCameraDeviceName,(SDL_CameraDeviceID a),(a),return)
|
||||
SDL_DYNAPI_PROC(SDL_Camera*,SDL_OpenCameraDevice,(SDL_CameraDeviceID a, const SDL_CameraSpec *b),(a,b),return)
|
||||
SDL_DYNAPI_PROC(SDL_CameraDeviceID,SDL_GetCameraInstanceID,(SDL_Camera *a),(a),return)
|
||||
SDL_DYNAPI_PROC(SDL_PropertiesID,SDL_GetCameraProperties,(SDL_Camera *a),(a),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_GetCameraSpec,(SDL_Camera *a, SDL_CameraSpec *b),(a,b),return)
|
||||
SDL_DYNAPI_PROC(SDL_Surface*,SDL_AcquireCameraFrame,(SDL_Camera *a, Uint64 *b),(a,b),return)
|
||||
SDL_DYNAPI_PROC(int,SDL_ReleaseCameraFrame,(SDL_Camera *a, SDL_Surface *b),(a,b),return)
|
||||
SDL_DYNAPI_PROC(void,SDL_CloseCamera,(SDL_Camera *a),(a),)
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "SDL_events_c.h"
|
||||
#include "../SDL_hints_c.h"
|
||||
#include "../audio/SDL_audio_c.h"
|
||||
#include "../camera/SDL_camera_c.h"
|
||||
#include "../timer/SDL_timer_c.h"
|
||||
#ifndef SDL_JOYSTICK_DISABLED
|
||||
#include "../joystick/SDL_joystick_c.h"
|
||||
|
@ -554,6 +555,15 @@ static void SDL_LogEvent(const SDL_Event *event)
|
|||
break;
|
||||
#undef PRINT_AUDIODEV_EVENT
|
||||
|
||||
#define PRINT_CAMERADEV_EVENT(event) (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u which=%u)", (uint)event->cdevice.timestamp, (uint)event->cdevice.which)
|
||||
SDL_EVENT_CASE(SDL_EVENT_CAMERA_DEVICE_ADDED)
|
||||
PRINT_CAMERADEV_EVENT(event);
|
||||
break;
|
||||
SDL_EVENT_CASE(SDL_EVENT_CAMERA_DEVICE_REMOVED)
|
||||
PRINT_CAMERADEV_EVENT(event);
|
||||
break;
|
||||
#undef PRINT_CAMERADEV_EVENT
|
||||
|
||||
SDL_EVENT_CASE(SDL_EVENT_SENSOR_UPDATE)
|
||||
(void)SDL_snprintf(details, sizeof(details), " (timestamp=%u which=%d data[0]=%f data[1]=%f data[2]=%f data[3]=%f data[4]=%f data[5]=%f)",
|
||||
(uint)event->sensor.timestamp, (int)event->sensor.which,
|
||||
|
@ -942,6 +952,10 @@ static void SDL_PumpEventsInternal(SDL_bool push_sentinel)
|
|||
SDL_UpdateAudio();
|
||||
#endif
|
||||
|
||||
#ifndef SDL_CAMERA_DISABLED
|
||||
SDL_UpdateCamera();
|
||||
#endif
|
||||
|
||||
#ifndef SDL_SENSOR_DISABLED
|
||||
/* Check for sensor state change */
|
||||
if (SDL_update_sensors) {
|
||||
|
|
|
@ -18,8 +18,13 @@
|
|||
#include <emscripten/emscripten.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#if 1
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
SDL_Log("FIXME: update me");
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
static const char *usage = "\
|
||||
\n\
|
||||
=========================================================================\n\
|
||||
|
@ -769,3 +774,4 @@ int main(int argc, char **argv)
|
|||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
|
@ -28,21 +28,14 @@ int main(int argc, char **argv)
|
|||
int quit = 0;
|
||||
SDLTest_CommonState *state = NULL;
|
||||
|
||||
SDL_CameraDevice *device = NULL;
|
||||
SDL_CameraSpec obtained;
|
||||
|
||||
SDL_CameraFrame frame_current;
|
||||
SDL_Camera *camera = NULL;
|
||||
SDL_CameraSpec spec;
|
||||
SDL_Texture *texture = NULL;
|
||||
int texture_updated = 0;
|
||||
SDL_Surface *frame_current = NULL;
|
||||
|
||||
SDL_zero(evt);
|
||||
SDL_zero(obtained);
|
||||
SDL_zero(frame_current);
|
||||
|
||||
/* Set 0 to disable TouchEvent to be duplicated as MouseEvent with SDL_TOUCH_MOUSEID */
|
||||
SDL_SetHint(SDL_HINT_TOUCH_MOUSE_EVENTS, "0");
|
||||
/* Set 0 to disable MouseEvent to be duplicated as TouchEvent with SDL_MOUSE_TOUCHID */
|
||||
SDL_SetHint(SDL_HINT_MOUSE_TOUCH_EVENTS, "0");
|
||||
SDL_zero(spec);
|
||||
|
||||
/* Initialize test framework */
|
||||
state = SDLTest_CommonCreateState(argv, 0);
|
||||
|
@ -73,20 +66,42 @@ int main(int argc, char **argv)
|
|||
return 1;
|
||||
}
|
||||
|
||||
device = SDL_OpenCameraWithSpec(0, NULL, &obtained, SDL_CAMERA_ALLOW_ANY_CHANGE);
|
||||
if (!device) {
|
||||
SDL_Log("No camera? %s", SDL_GetError());
|
||||
SDL_CameraDeviceID *devices = SDL_GetCameraDevices(NULL);
|
||||
if (!devices) {
|
||||
SDL_Log("SDL_GetCameraDevices failed: %s", SDL_GetError());
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (SDL_StartCamera(device) < 0) {
|
||||
SDL_Log("error SDL_StartCamera(): %s", SDL_GetError());
|
||||
const SDL_CameraDeviceID devid = devices[0]; /* just take the first one. */
|
||||
SDL_free(devices);
|
||||
|
||||
if (!devid) {
|
||||
SDL_Log("No cameras available? %s", SDL_GetError());
|
||||
return 1;
|
||||
}
|
||||
|
||||
SDL_CameraSpec *pspec = NULL;
|
||||
#if 0 /* just for edge-case testing purposes, ignore. */
|
||||
pspec = &spec;
|
||||
spec.width = 100 /*1280 * 2*/;
|
||||
spec.height = 100 /*720 * 2*/;
|
||||
spec.format = SDL_PIXELFORMAT_YUY2 /*SDL_PIXELFORMAT_RGBA8888*/;
|
||||
#endif
|
||||
|
||||
camera = SDL_OpenCameraDevice(devid, pspec);
|
||||
if (!camera) {
|
||||
SDL_Log("Failed to open camera device: %s", SDL_GetError());
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (SDL_GetCameraSpec(camera, &spec) < 0) {
|
||||
SDL_Log("Couldn't get camera spec: %s", SDL_GetError());
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Create texture with appropriate format */
|
||||
if (texture == NULL) {
|
||||
texture = SDL_CreateTexture(renderer, obtained.format, SDL_TEXTUREACCESS_STATIC, obtained.width, obtained.height);
|
||||
texture = SDL_CreateTexture(renderer, spec.format, SDL_TEXTUREACCESS_STATIC, spec.width, spec.height);
|
||||
if (texture == NULL) {
|
||||
SDL_Log("Couldn't create texture: %s", SDL_GetError());
|
||||
return 1;
|
||||
|
@ -118,21 +133,18 @@ int main(int argc, char **argv)
|
|||
}
|
||||
|
||||
{
|
||||
SDL_CameraFrame frame_next;
|
||||
SDL_zero(frame_next);
|
||||
Uint64 timestampNS = 0;
|
||||
SDL_Surface *frame_next = SDL_AcquireCameraFrame(camera, ×tampNS);
|
||||
|
||||
if (SDL_AcquireCameraFrame(device, &frame_next) < 0) {
|
||||
SDL_Log("err SDL_AcquireCameraFrame: %s", SDL_GetError());
|
||||
}
|
||||
#if 0
|
||||
if (frame_next.num_planes) {
|
||||
SDL_Log("frame: %p at %" SDL_PRIu64, (void*)frame_next.data[0], frame_next.timestampNS);
|
||||
if (frame_next) {
|
||||
SDL_Log("frame: %p at %" SDL_PRIu64, (void*)frame_next->pixels, timestampNS);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (frame_next.num_planes) {
|
||||
if (frame_current.num_planes) {
|
||||
if (SDL_ReleaseCameraFrame(device, &frame_current) < 0) {
|
||||
if (frame_next) {
|
||||
if (frame_current) {
|
||||
if (SDL_ReleaseCameraFrame(camera, frame_current) < 0) {
|
||||
SDL_Log("err SDL_ReleaseCameraFrame: %s", SDL_GetError());
|
||||
}
|
||||
}
|
||||
|
@ -146,20 +158,8 @@ int main(int argc, char **argv)
|
|||
}
|
||||
|
||||
/* Update SDL_Texture with last video frame (only once per new frame) */
|
||||
if (frame_current.num_planes && texture_updated == 0) {
|
||||
/* Use software data */
|
||||
if (frame_current.num_planes == 1) {
|
||||
SDL_UpdateTexture(texture, NULL,
|
||||
frame_current.data[0], frame_current.pitch[0]);
|
||||
} else if (frame_current.num_planes == 2) {
|
||||
SDL_UpdateNVTexture(texture, NULL,
|
||||
frame_current.data[0], frame_current.pitch[0],
|
||||
frame_current.data[1], frame_current.pitch[1]);
|
||||
} else if (frame_current.num_planes == 3) {
|
||||
SDL_UpdateYUVTexture(texture, NULL, frame_current.data[0], frame_current.pitch[0],
|
||||
frame_current.data[1], frame_current.pitch[1],
|
||||
frame_current.data[2], frame_current.pitch[2]);
|
||||
}
|
||||
if (frame_current && texture_updated == 0) {
|
||||
SDL_UpdateTexture(texture, NULL, frame_current->pixels, frame_current->pitch);
|
||||
texture_updated = 1;
|
||||
}
|
||||
|
||||
|
@ -177,7 +177,7 @@ int main(int argc, char **argv)
|
|||
th = (int)((float) th * scale);
|
||||
}
|
||||
d.x = (float)(10 );
|
||||
d.y = (float)(win_h - th);
|
||||
d.y = ((float)(win_h - th)) / 2.0f;
|
||||
d.w = (float)tw;
|
||||
d.h = (float)(th - 10);
|
||||
SDL_RenderTexture(renderer, texture, NULL, &d);
|
||||
|
@ -186,13 +186,10 @@ int main(int argc, char **argv)
|
|||
SDL_RenderPresent(renderer);
|
||||
}
|
||||
|
||||
if (SDL_StopCamera(device) < 0) {
|
||||
SDL_Log("error SDL_StopCamera(): %s", SDL_GetError());
|
||||
if (frame_current) {
|
||||
SDL_ReleaseCameraFrame(camera, frame_current);
|
||||
}
|
||||
if (frame_current.num_planes) {
|
||||
SDL_ReleaseCameraFrame(device, &frame_current);
|
||||
}
|
||||
SDL_CloseCamera(device);
|
||||
SDL_CloseCamera(camera);
|
||||
|
||||
if (texture) {
|
||||
SDL_DestroyTexture(texture);
|
||||
|
@ -205,3 +202,4 @@ int main(int argc, char **argv)
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue