Skip to content

Commit

Permalink
SDL_GetCameraSupportedFormats() follows the SDL_GetStringRule
Browse files Browse the repository at this point in the history
Also changed the function to return an array of pointers and added example usage to testcamera
  • Loading branch information
slouken committed Jul 18, 2024
1 parent 7257262 commit 11ff4dc
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 17 deletions.
19 changes: 7 additions & 12 deletions include/SDL3/SDL_camera.h
Original file line number Diff line number Diff line change
Expand Up @@ -198,24 +198,19 @@ extern SDL_DECLSPEC SDL_CameraID * SDLCALL SDL_GetCameras(int *count);
* 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 array.
*
* The returned list is owned by the caller, and should be released with
* SDL_free() when no longer needed.
*
* Note that it's legal for a camera to supply a list with only the zeroed
* final element and `*count` set to zero; this is what will happen on
* Note that it's legal for a camera to supply an empty list. This is what will happen on
* Emscripten builds, since that platform won't tell _anything_ about
* available cameras until you've opened one, and won't even tell if there
* _is_ a camera until the user has given you permission to check through a
* scary warning popup.
*
* The returned array follows the SDL_GetStringRule, and will be automatically freed later.
*
* \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 failure; call
* \param count a pointer filled in with the number of elements in the list, may be NULL.
* \returns a NULL terminated array of pointers to SDL_CameraSpec or NULL on failure; call
* SDL_GetError() for more information.
*
* \threadsafety It is safe to call this function from any thread.
Expand All @@ -225,7 +220,7 @@ extern SDL_DECLSPEC SDL_CameraID * SDLCALL SDL_GetCameras(int *count);
* \sa SDL_GetCameras
* \sa SDL_OpenCamera
*/
extern SDL_DECLSPEC SDL_CameraSpec * SDLCALL SDL_GetCameraSupportedFormats(SDL_CameraID devid, int *count);
extern SDL_DECLSPEC const SDL_CameraSpec * const * SDLCALL SDL_GetCameraSupportedFormats(SDL_CameraID devid, int *count);

/**
* Get the human-readable device name for a camera.
Expand Down
17 changes: 13 additions & 4 deletions src/camera/SDL_camera.c
Original file line number Diff line number Diff line change
Expand Up @@ -734,7 +734,7 @@ SDL_CameraID *SDL_GetCameras(int *count)
return retval;
}

SDL_CameraSpec *SDL_GetCameraSupportedFormats(SDL_CameraID instance_id, int *count)
const SDL_CameraSpec * const *SDL_GetCameraSupportedFormats(SDL_CameraID instance_id, int *count)
{
if (count) {
*count = 0;
Expand All @@ -745,16 +745,25 @@ SDL_CameraSpec *SDL_GetCameraSupportedFormats(SDL_CameraID instance_id, int *cou
return NULL;
}

SDL_CameraSpec *retval = (SDL_CameraSpec *) SDL_calloc(device->num_specs + 1, sizeof (SDL_CameraSpec));
int i;
int num_specs = device->num_specs;
const SDL_CameraSpec **retval = (const SDL_CameraSpec **) SDL_malloc(((num_specs + 1) * sizeof(SDL_CameraSpec *)) + (num_specs * sizeof (SDL_CameraSpec)));
if (retval) {
SDL_memcpy(retval, device->all_specs, sizeof (SDL_CameraSpec) * device->num_specs);
SDL_CameraSpec *specs = (SDL_CameraSpec *)((Uint8 *)retval + ((num_specs + 1) * sizeof(SDL_CameraSpec *)));
SDL_memcpy(specs, device->all_specs, sizeof (SDL_CameraSpec) * num_specs);
for (i = 0; i < num_specs; ++i) {
retval[i] = specs++;
}
retval[i] = NULL;

if (count) {
*count = device->num_specs;
*count = num_specs;
}
}

ReleaseCamera(device);

SDL_FreeLater(retval);
return retval;
}

Expand Down
2 changes: 1 addition & 1 deletion src/dynapi/SDL_dynapi_procs.h
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ SDL_DYNAPI_PROC(const char*,SDL_GetCameraName,(SDL_CameraID a),(a),return)
SDL_DYNAPI_PROC(int,SDL_GetCameraPermissionState,(SDL_Camera *a),(a),return)
SDL_DYNAPI_PROC(SDL_CameraPosition,SDL_GetCameraPosition,(SDL_CameraID a),(a),return)
SDL_DYNAPI_PROC(SDL_PropertiesID,SDL_GetCameraProperties,(SDL_Camera *a),(a),return)
SDL_DYNAPI_PROC(SDL_CameraSpec*,SDL_GetCameraSupportedFormats,(SDL_CameraID a, int *b),(a,b),return)
SDL_DYNAPI_PROC(const SDL_CameraSpec* const*,SDL_GetCameraSupportedFormats,(SDL_CameraID a, int *b),(a,b),return)
SDL_DYNAPI_PROC(SDL_CameraID*,SDL_GetCameras,(int *a),(a),return)
SDL_DYNAPI_PROC(void*,SDL_GetClipboardData,(const char *a, size_t *b),(a,b),return)
SDL_DYNAPI_PROC(const char*,SDL_GetClipboardText,(void),(),return)
Expand Down
16 changes: 16 additions & 0 deletions test/testcamera.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,20 @@ static SDL_Surface *frame_current = NULL;
static SDL_CameraID front_camera = 0;
static SDL_CameraID back_camera = 0;

static void PrintCameraSpecs(SDL_CameraID camera_id)
{
const SDL_CameraSpec *const *specs = SDL_GetCameraSupportedFormats(camera_id, NULL);
if (specs) {
int i;

SDL_Log("Available formats:\n");
for (i = 0; specs[i]; ++i) {
const SDL_CameraSpec *s = specs[i];
SDL_Log(" %dx%d %.2f FPS %s\n", s->width, s->height, (float)s->framerate_numerator / s->framerate_denominator, SDL_GetPixelFormatName(s->format));
}
}
}

int SDL_AppInit(void **appstate, int argc, char *argv[])
{
char window_title[128];
Expand Down Expand Up @@ -133,6 +147,8 @@ int SDL_AppInit(void **appstate, int argc, char *argv[])
return SDL_APP_FAILURE;
}

PrintCameraSpecs(camera_id);

SDL_CameraSpec *pspec = &spec;
spec.framerate_numerator = 1000;
spec.framerate_denominator = 1;
Expand Down

0 comments on commit 11ff4dc

Please sign in to comment.