Skip to content

Commit

Permalink
camera: Add an optional property that reports if a camera is back or …
Browse files Browse the repository at this point in the history
…front.

This is useful for iOS and Android, so an app can find the camera it cares
about in the list of devices.
  • Loading branch information
icculus committed Feb 7, 2024
1 parent e57c23f commit 0904501
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 6 deletions.
12 changes: 12 additions & 0 deletions include/SDL3/SDL_camera.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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.
*
Expand Down
3 changes: 3 additions & 0 deletions include/SDL3/SDL_properties.h
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,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
Expand Down
28 changes: 22 additions & 6 deletions src/camera/coremedia/SDL_camera_coremedia.m
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down

0 comments on commit 0904501

Please sign in to comment.