camera: Add an optional property that reports if a camera is back or front.

This is useful for iOS and Android, so an app can find the camera it cares
about in the list of devices.
main
Ryan C. Gordon 2024-02-07 09:17:01 -05:00
parent 0b8617f71d
commit 8db2a3b27a
3 changed files with 37 additions and 6 deletions

View File

@ -305,6 +305,16 @@ extern DECLSPEC SDL_CameraDeviceID SDLCALL SDL_GetCameraInstanceID(SDL_Camera *c
/**
* Get the properties associated with an opened camera.
*
* The following read-only properties are provided by SDL:
*
* - `SDL_PROP_CAMERA_POSITION_STRING`: the position of the camera in
* relation to the hardware it is connected to. This is currently either
* the string "front" or "back", to signify which side of the user's
* device a camera is on. Future versions of SDL may add other position
* strings. This property is only set if this information can be
* determined by SDL. Most platforms do not set this attribute at all,
* but mobile devices tend to.
*
* \param camera the SDL_Camera obtained from SDL_OpenCameraDevice()
* \returns a valid property ID on success or 0 on failure; call
* SDL_GetError() for more information.
@ -318,6 +328,8 @@ extern DECLSPEC SDL_CameraDeviceID SDLCALL SDL_GetCameraInstanceID(SDL_Camera *c
*/
extern DECLSPEC SDL_PropertiesID SDLCALL SDL_GetCameraProperties(SDL_Camera *camera);
#define SDL_PROP_CAMERA_POSITION_STRING "SDL.camera.position"
/**
* Get the spec that a camera is using when generating images.
*

View File

@ -183,6 +183,9 @@ extern DECLSPEC int SDLCALL SDL_SetProperty(SDL_PropertiesID props, const char *
/**
* Set a string property on a set of properties
*
* This function makes a copy of the string; the caller does not have to
* preserve the data after this call completes.
*
* \param props the properties to modify
* \param name the name of the property to modify
* \param value the new value of the property, or NULL to delete the property

View File

@ -386,20 +386,36 @@ static SDL_bool FindCoreMediaCameraDeviceByUniqueID(SDL_CameraDevice *device, vo
return ([uniqueid isEqualToString:avdev.uniqueID]) ? SDL_TRUE : SDL_FALSE;
}
static void MaybeAddDevice(AVCaptureDevice *device)
static void MaybeAddDevice(AVCaptureDevice *avdevice)
{
if (!device.connected) {
if (!avdevice.connected) {
return; // not connected.
} else if (![device hasMediaType:AVMediaTypeVideo]) {
} else if (![avdevice hasMediaType:AVMediaTypeVideo]) {
return; // not a camera.
} else if (SDL_FindPhysicalCameraDeviceByCallback(FindCoreMediaCameraDeviceByUniqueID, (__bridge void *) device.uniqueID)) {
} else if (SDL_FindPhysicalCameraDeviceByCallback(FindCoreMediaCameraDeviceByUniqueID, (__bridge void *) avdevice.uniqueID)) {
return; // already have this one.
}
CameraFormatAddData add_data;
GatherCameraSpecs(device, &add_data);
GatherCameraSpecs(avdevice, &add_data);
if (add_data.num_specs > 0) {
SDL_AddCameraDevice(device.localizedName.UTF8String, add_data.num_specs, add_data.specs, (void *) CFBridgingRetain(device));
SDL_CameraDevice *device = SDL_AddCameraDevice(avdevice.localizedName.UTF8String, add_data.num_specs, add_data.specs, (void *) CFBridgingRetain(avdevice));
if (device) {
const char *posstr = NULL;
if (avdevice.position == AVCaptureDevicePositionFront) {
posstr = "front";
} else if (avdevice.position == AVCaptureDevicePositionBack) {
posstr = "back";
}
if (posstr) {
SDL_Camera *camera = (SDL_Camera *) device; // currently there's no separation between physical and logical device.
SDL_PropertiesID props = SDL_GetCameraProperties(camera);
if (props) {
SDL_SetStringProperty(props, SDL_PROP_CAMERA_POSITION_STRING, posstr);
}
}
}
}
SDL_free(add_data.specs);
}