SDL: camera: Renamed everything from "video capture" to "camera", wired to CMake.

From 7ae955ce68318c5405bb5310e688270d344c5a3e Mon Sep 17 00:00:00 2001
From: "Ryan C. Gordon" <[EMAIL REDACTED]>
Date: Mon, 27 Nov 2023 23:05:54 -0500
Subject: [PATCH] camera: Renamed everything from "video capture" to "camera",
 wired to CMake.

---
 CMakeLists.txt                                |  23 +-
 include/SDL3/SDL_camera.h                     | 204 +++++-----
 include/build_config/SDL_build_config.h.cmake |   9 +-
 .../build_config/SDL_build_config_android.h   |   3 +
 .../SDL_build_config_emscripten.h             |   3 +
 include/build_config/SDL_build_config_ios.h   |   3 +
 include/build_config/SDL_build_config_macos.h |   3 +
 .../build_config/SDL_build_config_minimal.h   |   3 +
 include/build_config/SDL_build_config_ngage.h |   3 +
 .../build_config/SDL_build_config_windows.h   |   3 +
 .../build_config/SDL_build_config_wingdk.h    |   3 +
 include/build_config/SDL_build_config_winrt.h |   3 +
 include/build_config/SDL_build_config_xbox.h  |   3 +
 src/camera/SDL_camera.c                       | 383 +++++-------------
 src/camera/SDL_camera_c.h                     |  15 +-
 src/camera/SDL_syscamera.h                    |  54 +--
 src/camera/android/SDL_camera_android.c       |  71 ++--
 src/camera/apple/SDL_camera_apple.m           |  95 ++---
 src/camera/v4l2/SDL_camera_v4l2.c             | 187 ++++-----
 src/dynapi/SDL_dynapi.sym                     |  32 +-
 src/dynapi/SDL_dynapi_overrides.h             |  32 +-
 src/dynapi/SDL_dynapi_procs.h                 |  32 +-
 src/video/SDL_video.c                         |  12 +-
 test/CMakeLists.txt                           |   4 +-
 test/testcamera.c                             | 122 +++---
 test/testcameraminimal.c                      |  32 +-
 26 files changed, 588 insertions(+), 749 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index c7686fd1ff77..d3b09c6b3fe6 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -331,7 +331,7 @@ set_option(SDL_METAL               "Enable Metal support" ${APPLE})
 set_option(SDL_KMSDRM              "Use KMS DRM video driver" ${UNIX_SYS})
 dep_option(SDL_KMSDRM_SHARED       "Dynamically load KMS DRM support" ON "SDL_KMSDRM" OFF)
 set_option(SDL_OFFSCREEN           "Use offscreen video driver" ON)
-dep_option(SDL_VIDEO_CAPTURE       "Enable video capturing" ON SDL_VIDEO OFF)
+dep_option(SDL_CAMERA              "Enable camera support" ON SDL_VIDEO OFF)
 option_string(SDL_BACKGROUNDING_SIGNAL "number to use for magic backgrounding signal or 'OFF'" OFF)
 option_string(SDL_FOREGROUNDING_SIGNAL "number to use for magic foregrounding signal or 'OFF'" OFF)
 dep_option(SDL_HIDAPI              "Enable the HIDAPI subsystem" ON "NOT VISIONOS" OFF)
@@ -1289,6 +1289,12 @@ if(ANDROID)
     sdl_glob_sources("${SDL3_SOURCE_DIR}/src/sensor/android/*.c")
   endif()
 
+  if(SDL_CAMERA)
+    set(SDL_CAMERA_ANDROID 1)
+    set(HAVE_CAMERA TRUE)
+    sdl_glob_sources("${SDL3_SOURCE_DIR}/src/camera/android/*.c")
+  endif()
+
   if(SDL_VIDEO)
     set(SDL_VIDEO_DRIVER_ANDROID 1)
     sdl_glob_sources("${SDL3_SOURCE_DIR}/src/video/android/*.c")
@@ -1498,6 +1504,9 @@ elseif(UNIX AND NOT APPLE AND NOT RISCOS AND NOT HAIKU)
               ioctl(0, KDGKBENT, &kbe);
               return 0;
           }" HAVE_INPUT_KD)
+      check_c_source_compiles("
+          #include <linux/videodev2.h>
+          int main(int argc, char** argv) { return 0; }" HAVE_LINUX_VIDEODEV2_H)
     elseif(FREEBSD)
       check_c_source_compiles("
           #include <sys/kbio.h>
@@ -1521,6 +1530,12 @@ elseif(UNIX AND NOT APPLE AND NOT RISCOS AND NOT HAIKU)
           }" HAVE_INPUT_WSCONS)
     endif()
 
+    if(SDL_CAMERA AND HAVE_LINUX_VIDEODEV2_H)
+      set(SDL_CAMERA_V4L2 1)
+      set(HAVE_CAMERA TRUE)
+      sdl_glob_sources("${SDL3_SOURCE_DIR}/src/camera/v4l2/*.c")
+    endif()
+
     if(HAVE_LINUX_INPUT_H)
       set(SDL_INPUT_LINUXEV 1)
     endif()
@@ -2020,6 +2035,8 @@ elseif(APPLE)
   sdl_glob_sources("${SDL3_SOURCE_DIR}/src/file/cocoa/*.m")
 
   if(IOS OR TVOS OR MACOSX OR DARWIN)
+    set(SDL_CAMERA_APPLE TRUE)
+    set(HAVE_CAMERA TRUE)
     sdl_sources("${SDL3_SOURCE_DIR}/src/camera/apple/SDL_camera_apple.m")
   endif()
 
@@ -2721,6 +2738,10 @@ if(NOT HAVE_SDL_MISC)
   set(SDL_MISC_DUMMY 1)
   sdl_glob_sources("${SDL3_SOURCE_DIR}/src/misc/dummy/*.c")
 endif()
+if(NOT HAVE_CAMERA)
+  set(SDL_CAMERA_DUMMY 1)
+  sdl_glob_sources("${SDL3_SOURCE_DIR}/src/camera/dummy/*.c")
+endif()
 
 # We always need to have threads and timers around
 if(NOT HAVE_SDL_THREADS)
diff --git a/include/SDL3/SDL_camera.h b/include/SDL3/SDL_camera.h
index 7325fb8ca6f6..c37499c54592 100644
--- a/include/SDL3/SDL_camera.h
+++ b/include/SDL3/SDL_camera.h
@@ -37,182 +37,182 @@ extern "C" {
 #endif
 
 /**
- * This is a unique ID for a video capture device for the time it is connected to the system,
+ * This is a unique ID for a camera device for the time it is connected to the system,
  * and is never reused for the lifetime of the application. If the device is
  * disconnected and reconnected, it will get a new ID.
  *
  * The ID value starts at 1 and increments from there. The value 0 is an invalid ID.
  *
- * \sa SDL_GetVideoCaptureDevices
+ * \sa SDL_GetCameraDevices
  */
-typedef Uint32 SDL_VideoCaptureDeviceID;
+typedef Uint32 SDL_CameraDeviceID;
 
 
 /**
- * The structure used to identify an SDL video capture device
+ * The structure used to identify an SDL camera device
  */
-struct SDL_VideoCaptureDevice;
-typedef struct SDL_VideoCaptureDevice SDL_VideoCaptureDevice;
+struct SDL_CameraDevice;
+typedef struct SDL_CameraDevice SDL_CameraDevice;
 
-#define SDL_VIDEO_CAPTURE_ALLOW_ANY_CHANGE          1
+#define SDL_CAMERA_ALLOW_ANY_CHANGE          1
 
 /**
- *  SDL_VideoCaptureSpec structure
+ *  SDL_CameraSpec structure
  *
  *  Only those field can be 'desired' when configuring the device:
  *  - format
  *  - width
  *  - height
  *
- *  \sa SDL_GetVideoCaptureFormat
- *  \sa SDL_GetVideoCaptureFrameSize
+ *  \sa SDL_GetCameraFormat
+ *  \sa SDL_GetCameraFrameSize
  *
  */
-typedef struct SDL_VideoCaptureSpec
+typedef struct SDL_CameraSpec
 {
     Uint32 format;          /**< Frame SDL_PixelFormatEnum format */
     int width;              /**< Frame width */
     int height;             /**< Frame height */
-} SDL_VideoCaptureSpec;
+} SDL_CameraSpec;
 
 /**
- *  SDL Video Capture Status
+ *  SDL Camera Status
  *
  *  Change states but calling the function in this order:
  *
- *  SDL_OpenVideoCapture()
- *  SDL_SetVideoCaptureSpec()  -> Init
- *  SDL_StartVideoCapture()    -> Playing
- *  SDL_StopVideoCapture()     -> Stopped
- *  SDL_CloseVideoCapture()
+ *  SDL_OpenCamera()
+ *  SDL_SetCameraSpec()  -> Init
+ *  SDL_StartCamera()    -> Playing
+ *  SDL_StopCamera()     -> Stopped
+ *  SDL_CloseCamera()
  *
  */
 typedef enum
 {
-    SDL_VIDEO_CAPTURE_FAIL = -1,    /**< Failed */
-    SDL_VIDEO_CAPTURE_INIT = 0,     /**< Init, spec hasn't been set */
-    SDL_VIDEO_CAPTURE_STOPPED,      /**< Stopped */
-    SDL_VIDEO_CAPTURE_PLAYING       /**< Playing */
-} SDL_VideoCaptureStatus;
+    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_VideoCaptureFrame
+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_VideoCaptureFrame;
+} SDL_CameraFrame;
 
 
 /**
- * Get a list of currently connected video capture devices.
+ * Get a list of currently connected camera devices.
  *
- * \param count a pointer filled in with the number of video capture devices
- * \returns a 0 terminated array of video capture instance IDs which should be
+ * \param count a pointer filled in with the number of camera devices
+ * \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.
  *
  * \since This function is available since SDL 3.0.0.
  *
- * \sa SDL_OpenVideoCapture
+ * \sa SDL_OpenCamera
  */
-extern DECLSPEC SDL_VideoCaptureDeviceID *SDLCALL SDL_GetVideoCaptureDevices(int *count);
+extern DECLSPEC SDL_CameraDeviceID *SDLCALL SDL_GetCameraDevices(int *count);
 
 /**
  * Open a Video Capture device
  *
- * \param instance_id the video capture device instance ID
+ * \param instance_id the camera device instance ID
  * \returns device, or NULL on failure; call SDL_GetError() for more
  *          information.
  *
  * \since This function is available since SDL 3.0.0.
  *
- * \sa SDL_GetVideoCaptureDeviceName
- * \sa SDL_GetVideoCaptureDevices
- * \sa SDL_OpenVideoCaptureWithSpec
+ * \sa SDL_GetCameraDeviceName
+ * \sa SDL_GetCameraDevices
+ * \sa SDL_OpenCameraWithSpec
  */
-extern DECLSPEC SDL_VideoCaptureDevice *SDLCALL SDL_OpenVideoCapture(SDL_VideoCaptureDeviceID instance_id);
+extern DECLSPEC SDL_CameraDevice *SDLCALL SDL_OpenCamera(SDL_CameraDeviceID instance_id);
 
 /**
  * Set specification
  *
- * \param device opened video capture device
- * \param desired desired video capture spec
- * \param obtained obtained video capture spec
+ * \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
  *          SDL_GetError() for more information.
  *
  * \since This function is available since SDL 3.0.0.
  *
- * \sa SDL_OpenVideoCapture
- * \sa SDL_OpenVideoCaptureWithSpec
- * \sa SDL_GetVideoCaptureSpec
+ * \sa SDL_OpenCamera
+ * \sa SDL_OpenCameraWithSpec
+ * \sa SDL_GetCameraSpec
  */
-extern DECLSPEC int SDLCALL SDL_SetVideoCaptureSpec(SDL_VideoCaptureDevice *device,
-                                                    const SDL_VideoCaptureSpec *desired,
-                                                    SDL_VideoCaptureSpec *obtained,
+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 video capture device instance ID
- * \param desired desired video capture spec
- * \param obtained obtained video capture spec
+ * \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.
  *
  * \since This function is available since SDL 3.0.0.
  *
- * \sa SDL_OpenVideoCapture
- * \sa SDL_SetVideoCaptureSpec
- * \sa SDL_GetVideoCaptureSpec
+ * \sa SDL_OpenCamera
+ * \sa SDL_SetCameraSpec
+ * \sa SDL_GetCameraSpec
  */
-extern DECLSPEC SDL_VideoCaptureDevice *SDLCALL SDL_OpenVideoCaptureWithSpec(SDL_VideoCaptureDeviceID instance_id,
-                                                                              const SDL_VideoCaptureSpec *desired,
-                                                                              SDL_VideoCaptureSpec *obtained,
+extern DECLSPEC SDL_CameraDevice *SDLCALL SDL_OpenCameraWithSpec(SDL_CameraDeviceID instance_id,
+                                                                              const SDL_CameraSpec *desired,
+                                                                              SDL_CameraSpec *obtained,
                                                                               int allowed_changes);
 
 /**
  * Get device name
  *
- * \param instance_id the video capture device instance ID
+ * \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_GetVideoCaptureDevices
+ * \sa SDL_GetCameraDevices
  */
-extern DECLSPEC const char * SDLCALL SDL_GetVideoCaptureDeviceName(SDL_VideoCaptureDeviceID instance_id);
+extern DECLSPEC const char * SDLCALL SDL_GetCameraDeviceName(SDL_CameraDeviceID instance_id);
 
 /**
- * Get the obtained video capture spec
+ * Get the obtained camera spec
  *
- * \param device opened video capture device
- * \param spec The SDL_VideoCaptureSpec to be initialized by this function.
+ * \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_SetVideoCaptureSpec
- * \sa SDL_OpenVideoCaptureWithSpec
+ * \sa SDL_SetCameraSpec
+ * \sa SDL_OpenCameraWithSpec
  */
-extern DECLSPEC int SDLCALL SDL_GetVideoCaptureSpec(SDL_VideoCaptureDevice *device, SDL_VideoCaptureSpec *spec);
+extern DECLSPEC int SDLCALL SDL_GetCameraSpec(SDL_CameraDevice *device, SDL_CameraSpec *spec);
 
 
 /**
- * Get frame format of video capture device.
+ * Get frame format of camera device.
  *
- * The value can be used to fill SDL_VideoCaptureSpec structure.
+ * The value can be used to fill SDL_CameraSpec structure.
  *
- * \param device opened video capture device
+ * \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
@@ -220,32 +220,32 @@ extern DECLSPEC int SDLCALL SDL_GetVideoCaptureSpec(SDL_VideoCaptureDevice *devi
  *
  * \since This function is available since SDL 3.0.0.
  *
- * \sa SDL_GetNumVideoCaptureFormats
+ * \sa SDL_GetNumCameraFormats
  */
-extern DECLSPEC int SDLCALL SDL_GetVideoCaptureFormat(SDL_VideoCaptureDevice *device,
+extern DECLSPEC int SDLCALL SDL_GetCameraFormat(SDL_CameraDevice *device,
                                                       int index,
                                                       Uint32 *format);
 
 /**
  * Number of available formats for the device
  *
- * \param device opened video capture 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_GetVideoCaptureFormat
- * \sa SDL_SetVideoCaptureSpec
+ * \sa SDL_GetCameraFormat
+ * \sa SDL_SetCameraSpec
  */
-extern DECLSPEC int SDLCALL SDL_GetNumVideoCaptureFormats(SDL_VideoCaptureDevice *device);
+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_VideoCaptureSpec structure.
+ * The value can be used to fill SDL_CameraSpec structure.
  *
- * \param device opened video capture device
+ * \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
@@ -255,51 +255,51 @@ extern DECLSPEC int SDLCALL SDL_GetNumVideoCaptureFormats(SDL_VideoCaptureDevice
  *
  * \since This function is available since SDL 3.0.0.
  *
- * \sa SDL_GetNumVideoCaptureFrameSizes
+ * \sa SDL_GetNumCameraFrameSizes
  */
-extern DECLSPEC int SDLCALL SDL_GetVideoCaptureFrameSize(SDL_VideoCaptureDevice *device, Uint32 format, int index, int *width, int *height);
+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 video capture device
+ * \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_GetVideoCaptureFrameSize
- * \sa SDL_SetVideoCaptureSpec
+ * \sa SDL_GetCameraFrameSize
+ * \sa SDL_SetCameraSpec
  */
-extern DECLSPEC int SDLCALL SDL_GetNumVideoCaptureFrameSizes(SDL_VideoCaptureDevice *device, Uint32 format);
+extern DECLSPEC int SDLCALL SDL_GetNumCameraFrameSizes(SDL_CameraDevice *device, Uint32 format);
 
 
 /**
- * Get video capture status
+ * Get camera status
  *
- * \param device opened video capture device
+ * \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_VideoCaptureStatus
+ * \sa SDL_CameraStatus
  */
-extern DECLSPEC SDL_VideoCaptureStatus SDLCALL SDL_GetVideoCaptureStatus(SDL_VideoCaptureDevice *device);
+extern DECLSPEC SDL_CameraStatus SDLCALL SDL_GetCameraStatus(SDL_CameraDevice *device);
 
 /**
- * Start video capture
+ * Start camera
  *
- * \param device opened video capture device
+ * \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_StopVideoCapture
+ * \sa SDL_StopCamera
  */
-extern DECLSPEC int SDLCALL SDL_StartVideoCapture(SDL_VideoCaptureDevice *device);
+extern DECLSPEC int SDLCALL SDL_StartCamera(SDL_CameraDevice *device);
 
 /**
  * Acquire a frame.
@@ -311,62 +311,62 @@ extern DECLSPEC int SDLCALL SDL_StartVideoCapture(SDL_VideoCaptureDevice *device
  * 0. If frame->num_planes is 0 and returned code is 0, there is no frame at
  * that time.
  *
- * After used, the frame should be released with SDL_ReleaseVideoCaptureFrame
+ * After used, the frame should be released with SDL_ReleaseCameraFrame
  *
- * \param device opened video capture device
+ * \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.
  *
  * \since This function is available since SDL 3.0.0.
  *
- * \sa SDL_ReleaseVideoCaptureFrame
+ * \sa SDL_ReleaseCameraFrame
  */
-extern DECLSPEC int SDLCALL SDL_AcquireVideoCaptureFrame(SDL_VideoCaptureDevice *device, SDL_VideoCaptureFrame *frame);
+extern DECLSPEC int SDLCALL SDL_AcquireCameraFrame(SDL_CameraDevice *device, SDL_CameraFrame *frame);
 
 /**
  * Release a frame.
  *
- * Let the back-end re-use the internal buffer for video capture.
+ * Let the back-end re-use the internal buffer for camera.
  *
  * All acquired frames should be released before closing the device.
  *
- * \param device opened video capture device
+ * \param device opened camera device
  * \param frame frame pointer.
  * \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_AcquireVideoCaptureFrame
+ * \sa SDL_AcquireCameraFrame
  */
-extern DECLSPEC int SDLCALL SDL_ReleaseVideoCaptureFrame(SDL_VideoCaptureDevice *device, SDL_VideoCaptureFrame *frame);
+extern DECLSPEC int SDLCALL SDL_ReleaseCameraFrame(SDL_CameraDevice *device, SDL_CameraFrame *frame);
 
 /**
  * Stop Video Capture
  *
- * \param device opened video capture device
+ * \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_StartVideoCapture
+ * \sa SDL_StartCamera
  */
-extern DECLSPEC int SDLCALL SDL_StopVideoCapture(SDL_VideoCaptureDevice *device);
+extern DECLSPEC int SDLCALL SDL_StopCamera(SDL_CameraDevice *device);
 
 /**
  * Use this function to shut down camera processing and close the
  * camera device.
  *
- * \param device opened video capture device
+ * \param device opened camera device
  *
  * \since This function is available since SDL 3.0.0.
  *
- * \sa SDL_OpenVideoCaptureWithSpec
- * \sa SDL_OpenVideoCapture
+ * \sa SDL_OpenCameraWithSpec
+ * \sa SDL_OpenCamera
  */
-extern DECLSPEC void SDLCALL SDL_CloseVideoCapture(SDL_VideoCaptureDevice *device);
+extern DECLSPEC void SDLCALL SDL_CloseCamera(SDL_CameraDevice *device);
 
 /* Ends C function definitions when using C++ */
 #ifdef __cplusplus
diff --git a/include/build_config/SDL_build_config.h.cmake b/include/build_config/SDL_build_config.h.cmake
index e44f38ef6398..076d3120f14f 100644
--- a/include/build_config/SDL_build_config.h.cmake
+++ b/include/build_config/SDL_build_config.h.cmake
@@ -253,8 +253,6 @@
 #cmakedefine SDL_DEFAULT_ASSERT_LEVEL @SDL_DEFAULT_ASSERT_LEVEL@
 #endif
 
-#cmakedefine SDL_VIDEO_CAPTURE
-
 /* Allow disabling of major subsystems */
 #cmakedefine SDL_AUDIO_DISABLED @SDL_AUDIO_DISABLED@
 #cmakedefine SDL_JOYSTICK_DISABLED @SDL_JOYSTICK_DISABLED@
@@ -265,6 +263,7 @@
 #cmakedefine SDL_THREADS_DISABLED @SDL_THREADS_DISABLED@
 #cmakedefine SDL_VIDEO_DISABLED @SDL_VIDEO_DISABLED@
 #cmakedefine SDL_POWER_DISABLED @SDL_POWER_DISABLED@
+#cmakedefine SDL_CAMERA_DISABLED @SDL_CAMERA_DISABLED@
 
 /* Enable various audio drivers */
 #cmakedefine SDL_AUDIO_DRIVER_ALSA @SDL_AUDIO_DRIVER_ALSA@
@@ -467,6 +466,12 @@
 #cmakedefine SDL_FILESYSTEM_PS2 @SDL_FILESYSTEM_PS2@
 #cmakedefine SDL_FILESYSTEM_N3DS @SDL_FILESYSTEM_N3DS@
 
+/* Enable camera subsystem */
+#cmakedefine SDL_CAMERA_DUMMY @SDL_CAMERA_DUMMY@
+#cmakedefine SDL_CAMERA_V4L2 @SDL_CAMERA_V4L2@
+#cmakedefine SDL_CAMERA_APPLE @SDL_CAMERA_APPLE@
+#cmakedefine SDL_CAMERA_ANDROID @SDL_CAMERA_ANDROID@
+
 /* Enable misc subsystem */
 #cmakedefine SDL_MISC_DUMMY @SDL_MISC_DUMMY@
 
diff --git a/include/build_config/SDL_build_config_android.h b/include/build_config/SDL_build_config_android.h
index 4e688d0d3f41..c2eaf0985921 100644
--- a/include/build_config/SDL_build_config_android.h
+++ b/include/build_config/SDL_build_config_android.h
@@ -190,4 +190,7 @@
 /* Enable the filesystem driver */
 #define SDL_FILESYSTEM_ANDROID   1
 
+/* Enable the camera driver */
+#define SDL_CAMERA_ANDROID 1
+
 #endif /* SDL_build_config_android_h_ */
diff --git a/include/build_config/SDL_build_config_emscripten.h b/include/build_config/SDL_build_config_emscripten.h
index 40876c3952fb..3d7836678229 100644
--- a/include/build_config/SDL_build_config_emscripten.h
+++ b/include/build_config/SDL_build_config_emscripten.h
@@ -209,4 +209,7 @@
 /* Enable system filesystem support */
 #define SDL_FILESYSTEM_EMSCRIPTEN 1
 
+/* Enable the camera driver (src/camera/dummy/\*.c) */  /* !!! FIXME */
+#define SDL_CAMERA_DUMMY  1
+
 #endif /* SDL_build_config_emscripten_h */
diff --git a/include/build_config/SDL_build_config_ios.h b/include/build_config/SDL_build_config_ios.h
index 48da8852997c..a356f8920fab 100644
--- a/include/build_config/SDL_build_config_ios.h
+++ b/include/build_config/SDL_build_config_ios.h
@@ -212,4 +212,7 @@
 /* enable filesystem support */
 #define SDL_FILESYSTEM_COCOA   1
 
+/* enable camera support */
+#define SDL_CAMERA_APPLE 1
+
 #endif /* SDL_build_config_ios_h_ */
diff --git a/include/build_config/SDL_build_config_macos.h b/include/build_config/SDL_build_config_macos.h
index 9eb5830cdd8b..d45a3980cd32 100644
--- a/include/build_config/SDL_build_config_macos.h
+++ b/include/build_config/SDL_build_config_macos.h
@@ -269,6 +269,9 @@
 /* enable filesystem support */
 #define SDL_FILESYSTEM_COCOA   1
 
+/* enable camera support */
+#define SDL_CAMERA_APPLE 1
+
 /* Enable assembly routines */
 #ifdef __ppc__
 #define SDL_ALTIVEC_BLITTERS    1
diff --git a/include/build_config/SDL_build_config_minimal.h b/include/build_config/SDL_build_config_minimal.h
index bb256fc3079d..38e870160a77 100644
--- a/include/build_config/SDL_build_config_minimal.h
+++ b/include/build_config/SDL_build_config_minimal.h
@@ -89,4 +89,7 @@ typedef unsigned int uintptr_t;
 /* Enable the dummy filesystem driver (src/filesystem/dummy/\*.c) */
 #define SDL_FILESYSTEM_DUMMY  1
 
+/* Enable the camera driver (src/camera/dummy/\*.c) */
+#define SDL_CAMERA_DUMMY  1
+
 #endif /* SDL_build_config_minimal_h_ */
diff --git a/include/build_config/SDL_build_config_ngage.h b/include/build_config/SDL_build_config_ngage.h
index 17872ef06581..a8719bd90905 100644
--- a/include/build_config/SDL_build_config_ngage.h
+++ b/include/build_config/SDL_build_config_ngage.h
@@ -86,4 +86,7 @@ typedef unsigned long      uintptr_t;
 /* Enable the dummy filesystem driver (src/filesystem/dummy/\*.c) */
 #define SDL_FILESYSTEM_DUMMY 1
 
+/* Enable the camera driver (src/camera/dummy/\*.c) */
+#define SDL_CAMERA_DUMMY  1
+
 #endif /* SDL_build_config_ngage_h_ */
diff --git a/include/build_config/SDL_build_config_windows.h b/include/build_config/SDL_build_config_windows.h
index 68664c5ba9a3..42682d8fcf3c 100644
--- a/include/build_config/SDL_build_config_windows.h
+++ b/include/build_config/SDL_build_config_windows.h
@@ -311,4 +311,7 @@ typedef unsigned int uintptr_t;
 /* Enable filesystem support */
 #define SDL_FILESYSTEM_WINDOWS  1
 
+/* Enable the camera driver (src/camera/dummy/\*.c) */  /* !!! FIXME */
+#define SDL_CAMERA_DUMMY  1
+
 #endif /* SDL_build_config_windows_h_ */
diff --git a/include/build_config/SDL_build_config_wingdk.h b/include/build_config/SDL_build_config_wingdk.h
index d856d2323e08..0c60bea6f32b 100644
--- a/include/build_config/SDL_build_config_wingdk.h
+++ b/include/build_config/SDL_build_config_wingdk.h
@@ -247,6 +247,9 @@
 /* Enable filesystem support */
 #define SDL_FILESYSTEM_WINDOWS  1
 
+/* Enable the camera driver (src/camera/dummy/\*.c) */  /* !!! FIXME */
+#define SDL_CAMERA_DUMMY  1
+
 /* Use the (inferior) GDK text input method for GDK platforms */
 /*#define SDL_GDK_TEXTINPUT 1*/
 
diff --git a/include/build_config/SDL_build_config_winrt.h b/include/build_config/SDL_build_config_winrt.h
index 08ec512b0708..4b3f865c4851 100644
--- a/include/build_config/SDL_build_config_winrt.h
+++ b/include/build_config/SDL_build_config_winrt.h
@@ -215,4 +215,7 @@
 /* Enable system power support */
 #define SDL_POWER_WINRT 1
 
+/* Enable the camera driver (src/camera/dummy/\*.c) */  /* !!! FIXME */
+#define SDL_CAMERA_DUMMY  1
+
 #endif /* SDL_build_config_winrt_h_ */
diff --git a/include/build_config/SDL_build_config_xbox.h b/include/build_config/SDL_build_config_xbox.h
index c5198aeec763..11116f9a6027 100644
--- a/include/build_config/SDL_build_config_xbox.h
+++ b/include/build_config/SDL_build_config_xbox.h
@@ -236,4 +236,7 @@
 /* Use the (inferior) GDK text input method for GDK platforms */
 #define SDL_GDK_TEXTINPUT 1
 
+/* Enable the camera driver (src/camera/dummy/\*.c) */
+#define SDL_CAMERA_DUMMY  1
+
 #endif /* SDL_build_config_wingdk_h_ */
diff --git a/src/camera/SDL_camera.c b/src/camera/SDL_camera.c
index f11601f0cd26..f10fc755fe7c 100644
--- a/src/camera/SDL_camera.c
+++ b/src/camera/SDL_camera.c
@@ -27,20 +27,18 @@
 #include "../video/SDL_pixels_c.h"
 #include "../thread/SDL_systhread.h"
 
-#define DEBUG_VIDEO_CAPTURE_CAPTURE 0
+#define DEBUG_CAMERA 1
 
-
-#ifdef SDL_VIDEO_CAPTURE
 /* list node entries to share frames between SDL and user app */
 typedef struct entry_t
 {
-    SDL_VideoCaptureFrame frame;
+    SDL_CameraFrame frame;
 } entry_t;
 
-static SDL_VideoCaptureDevice *open_devices[16];
+static SDL_CameraDevice *open_devices[16];
 
 static void
-close_device(SDL_VideoCaptureDevice *device)
+close_device(SDL_CameraDevice *device)
 {
     if (!device) {
         return;
@@ -73,7 +71,7 @@ close_device(SDL_VideoCaptureDevice *device)
         while (device->buffer_queue != NULL) {
             SDL_ListPop(&device->buffer_queue, (void**)&entry);
             if (entry) {
-                SDL_VideoCaptureFrame f = entry->frame;
+                SDL_CameraFrame f = entry->frame;
                 /* Release frames not acquired, if any */
                 if (f.timestampNS) {
                     ReleaseFrame(device, &f);
@@ -109,7 +107,7 @@ SDL_bool check_device_playing(void)
     int i, n = SDL_arraysize(open_devices);
     for (i = 0; i < n; i++) {
         if (open_devices[i]) {
-            if (SDL_GetVideoCaptureStatus(open_devices[i]) == SDL_VIDEO_CAPTURE_PLAYING) {
+            if (SDL_GetCameraStatus(open_devices[i]) == SDL_CAMERA_PLAYING) {
                 return SDL_TRUE;
             }
         }
@@ -117,26 +115,20 @@ SDL_bool check_device_playing(void)
     return SDL_FALSE;
 }
 
-
-#endif /* SDL_VIDEO_CAPTURE */
-
 void
-SDL_CloseVideoCapture(SDL_VideoCaptureDevice *device)
+SDL_CloseCamera(SDL_CameraDevice *device)
 {
-#ifdef SDL_VIDEO_CAPTURE
     if (!device) {
         SDL_InvalidParamError("device");
         return;
     }
     close_device(device);
-#endif
 }
 
 int
-SDL_StartVideoCapture(SDL_VideoCaptureDevice *device)
+SDL_StartCamera(SDL_CameraDevice *device)
 {
-#ifdef SDL_VIDEO_CAPTURE
-    SDL_VideoCaptureStatus status;
+    SDL_CameraStatus status;
     int result;
     if (!device) {
         return SDL_InvalidParamError("device");
@@ -146,12 +138,12 @@ SDL_StartVideoCapture(SDL_VideoCaptureDevice *device)
         return SDL_SetError("no spec set");
     }
 
-    status = SDL_GetVideoCaptureStatus(device);
-    if (status != SDL_VIDEO_CAPTURE_INIT) {
+    status = SDL_GetCameraStatus(device);
+    if (status != SDL_CAMERA_INIT) {
         return SDL_SetError("invalid state");
     }
 
-    result = StartCapture(device);
+    result = StartCamera(device);
     if (result < 0) {
         return result;
     }
@@ -159,15 +151,11 @@ SDL_StartVideoCapture(SDL_VideoCaptureDevice *device)
     SDL_AtomicSet(&device->enabled, 1);
 
     return 0;
-#else
-    return SDL_Unsupported();
-#endif
 }
 
 int
-SDL_GetVideoCaptureSpec(SDL_VideoCaptureDevice *device, SDL_VideoCaptureSpec *spec)
+SDL_GetCameraSpec(SDL_CameraDevice *device, SDL_CameraSpec *spec)
 {
-#ifdef SDL_VIDEO_CAPTURE
     if (!device) {
         return SDL_InvalidParamError("device");
     }
@@ -179,24 +167,20 @@ SDL_GetVideoCaptureSpec(SDL_VideoCaptureDevice *device, SDL_VideoCaptureSpec *sp
     SDL_zerop(spec);
 
     return GetDeviceSpec(device, spec);
-#else
-    return SDL_Unsupported();
-#endif
 }
 
 int
-SDL_StopVideoCapture(SDL_VideoCaptureDevice *device)
+SDL_StopCamera(SDL_CameraDevice *device)
 {
-#ifdef SDL_VIDEO_CAPTURE
-    SDL_VideoCaptureStatus status;
+    SDL_CameraStatus status;
     int ret;
     if (!device) {
         return SDL_InvalidParamError("device");
     }
 
-    status = SDL_GetVideoCaptureStatus(device);
+    status = SDL_GetCameraStatus(device);
 
-    if (status != SDL_VIDEO_CAPTURE_PLAYING) {
+    if (status != SDL_CAMERA_PLAYING) {
         return SDL_SetError("invalid state");
     }
 
@@ -204,7 +188,7 @@ SDL_StopVideoCapture(SDL_VideoCaptureDevice *device)
     SDL_AtomicSet(&device->shutdown, 1);
 
     SDL_LockMutex(device->acquiring_lock);
-    ret = StopCapture(device);
+    ret = StopCamera(device);
     SDL_UnlockMutex(device->acquiring_lock);
 
     if (ret < 0) {
@@ -212,25 +196,20 @@ SDL_StopVideoCapture(SDL_VideoCaptureDevice *device)
     }
 
     return 0;
-#else
-    return SDL_Unsupported();
-#endif
 }
 
-#ifdef SDL_VIDEO_CAPTURE
-
 /* Check spec has valid format and frame size */
 static int
-prepare_video_capt

(Patch may be truncated, please check the link at the top of this post.)