camera: Reworked to operate with a driver interface, like other subsystems.
parent
2ad44bd162
commit
cb10c80aaf
|
@ -332,6 +332,7 @@ 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)
|
dep_option(SDL_KMSDRM_SHARED "Dynamically load KMS DRM support" ON "SDL_KMSDRM" OFF)
|
||||||
set_option(SDL_OFFSCREEN "Use offscreen video driver" ON)
|
set_option(SDL_OFFSCREEN "Use offscreen video driver" ON)
|
||||||
dep_option(SDL_CAMERA "Enable camera support" ON SDL_VIDEO OFF)
|
dep_option(SDL_CAMERA "Enable camera support" ON SDL_VIDEO OFF)
|
||||||
|
set_option(SDL_DUMMYCAMERA "Support the dummy camera driver" ON)
|
||||||
option_string(SDL_BACKGROUNDING_SIGNAL "number to use for magic backgrounding signal or 'OFF'" 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)
|
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)
|
dep_option(SDL_HIDAPI "Enable the HIDAPI subsystem" ON "NOT VISIONOS" OFF)
|
||||||
|
@ -1172,6 +1173,23 @@ if(SDL_AUDIO)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(SDL_CAMERA)
|
||||||
|
# CheckDummyCamera/CheckDiskCamera - valid for all platforms
|
||||||
|
if(SDL_DUMMYCAMERA)
|
||||||
|
set(SDL_CAMERA_DRIVER_DUMMY 1)
|
||||||
|
sdl_glob_sources("${SDL3_SOURCE_DIR}/src/camera/dummy/*.c")
|
||||||
|
set(HAVE_DUMMYCAMERA TRUE)
|
||||||
|
set(HAVE_SDL_CAMERA TRUE)
|
||||||
|
endif()
|
||||||
|
# !!! FIXME: for later.
|
||||||
|
#if(SDL_DISKCAMERA)
|
||||||
|
# set(SDL_CAMERA_DRIVER_DISK 1)
|
||||||
|
# sdl_glob_sources("${SDL3_SOURCE_DIR}/src/camera/disk/*.c")
|
||||||
|
# set(HAVE_DISKCAMERA TRUE)
|
||||||
|
# set(HAVE_SDL_CAMERA TRUE)
|
||||||
|
#endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
if(UNIX OR APPLE)
|
if(UNIX OR APPLE)
|
||||||
# Relevant for Unix/Darwin only
|
# Relevant for Unix/Darwin only
|
||||||
set(DYNAPI_NEEDS_DLOPEN 1)
|
set(DYNAPI_NEEDS_DLOPEN 1)
|
||||||
|
@ -1290,7 +1308,7 @@ if(ANDROID)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(SDL_CAMERA)
|
if(SDL_CAMERA)
|
||||||
set(SDL_CAMERA_ANDROID 1)
|
set(SDL_CAMERA_DRIVER_ANDROID 1)
|
||||||
set(HAVE_CAMERA TRUE)
|
set(HAVE_CAMERA TRUE)
|
||||||
sdl_glob_sources("${SDL3_SOURCE_DIR}/src/camera/android/*.c")
|
sdl_glob_sources("${SDL3_SOURCE_DIR}/src/camera/android/*.c")
|
||||||
endif()
|
endif()
|
||||||
|
@ -1531,7 +1549,7 @@ elseif(UNIX AND NOT APPLE AND NOT RISCOS AND NOT HAIKU)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(SDL_CAMERA AND HAVE_LINUX_VIDEODEV2_H)
|
if(SDL_CAMERA AND HAVE_LINUX_VIDEODEV2_H)
|
||||||
set(SDL_CAMERA_V4L2 1)
|
set(SDL_CAMERA_DRIVER_V4L2 1)
|
||||||
set(HAVE_CAMERA TRUE)
|
set(HAVE_CAMERA TRUE)
|
||||||
sdl_glob_sources("${SDL3_SOURCE_DIR}/src/camera/v4l2/*.c")
|
sdl_glob_sources("${SDL3_SOURCE_DIR}/src/camera/v4l2/*.c")
|
||||||
endif()
|
endif()
|
||||||
|
@ -2035,9 +2053,9 @@ elseif(APPLE)
|
||||||
sdl_glob_sources("${SDL3_SOURCE_DIR}/src/file/cocoa/*.m")
|
sdl_glob_sources("${SDL3_SOURCE_DIR}/src/file/cocoa/*.m")
|
||||||
|
|
||||||
if(IOS OR TVOS OR MACOSX OR DARWIN)
|
if(IOS OR TVOS OR MACOSX OR DARWIN)
|
||||||
set(SDL_CAMERA_APPLE TRUE)
|
set(SDL_CAMERA_DRIVER_COREMEDIA 1)
|
||||||
set(HAVE_CAMERA TRUE)
|
set(HAVE_CAMERA TRUE)
|
||||||
sdl_sources("${SDL3_SOURCE_DIR}/src/camera/apple/SDL_camera_apple.m")
|
sdl_glob_sources("${SDL3_SOURCE_DIR}/src/camera/coremedia/*.m")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(IOS OR TVOS OR VISIONOS)
|
if(IOS OR TVOS OR VISIONOS)
|
||||||
|
@ -2739,7 +2757,7 @@ if(NOT HAVE_SDL_MISC)
|
||||||
sdl_glob_sources("${SDL3_SOURCE_DIR}/src/misc/dummy/*.c")
|
sdl_glob_sources("${SDL3_SOURCE_DIR}/src/misc/dummy/*.c")
|
||||||
endif()
|
endif()
|
||||||
if(NOT HAVE_CAMERA)
|
if(NOT HAVE_CAMERA)
|
||||||
set(SDL_CAMERA_DUMMY 1)
|
set(SDL_CAMERA_DRIVER_DUMMY 1)
|
||||||
sdl_glob_sources("${SDL3_SOURCE_DIR}/src/camera/dummy/*.c")
|
sdl_glob_sources("${SDL3_SOURCE_DIR}/src/camera/dummy/*.c")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
|
@ -108,6 +108,71 @@ typedef struct SDL_CameraFrame
|
||||||
} SDL_CameraFrame;
|
} SDL_CameraFrame;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use this function to get the number of built-in camera drivers.
|
||||||
|
*
|
||||||
|
* This function returns a hardcoded number. This never returns a negative
|
||||||
|
* value; if there are no drivers compiled into this build of SDL, this
|
||||||
|
* function returns zero. The presence of a driver in this list does not mean
|
||||||
|
* it will function, it just means SDL is capable of interacting with that
|
||||||
|
* interface. For example, a build of SDL might have v4l2 support, but if
|
||||||
|
* there's no kernel support available, SDL's v4l2 driver would fail if used.
|
||||||
|
*
|
||||||
|
* By default, SDL tries all drivers, in its preferred order, until one is
|
||||||
|
* found to be usable.
|
||||||
|
*
|
||||||
|
* \returns the number of built-in camera drivers.
|
||||||
|
*
|
||||||
|
* \threadsafety It is safe to call this function from any thread.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.0.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_GetCameraDriver
|
||||||
|
*/
|
||||||
|
extern DECLSPEC int SDLCALL SDL_GetNumCameraDrivers(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use this function to get the name of a built in camera driver.
|
||||||
|
*
|
||||||
|
* The list of camera drivers is given in the order that they are normally
|
||||||
|
* initialized by default; the drivers that seem more reasonable to choose
|
||||||
|
* first (as far as the SDL developers believe) are earlier in the list.
|
||||||
|
*
|
||||||
|
* The names of drivers are all simple, low-ASCII identifiers, like "v4l2",
|
||||||
|
* "coremedia" or "android". These never have Unicode characters, and are not
|
||||||
|
* meant to be proper names.
|
||||||
|
*
|
||||||
|
* \param index the index of the camera driver; the value ranges from 0 to
|
||||||
|
* SDL_GetNumCameraDrivers() - 1
|
||||||
|
* \returns the name of the camera driver at the requested index, or NULL if an
|
||||||
|
* invalid index was specified.
|
||||||
|
*
|
||||||
|
* \threadsafety It is safe to call this function from any thread.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.0.0.
|
||||||
|
*
|
||||||
|
* \sa SDL_GetNumCameraDrivers
|
||||||
|
*/
|
||||||
|
extern DECLSPEC const char *SDLCALL SDL_GetCameraDriver(int index);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the name of the current camera driver.
|
||||||
|
*
|
||||||
|
* The returned string points to internal static memory and thus never becomes
|
||||||
|
* invalid, even if you quit the camera subsystem and initialize a new driver
|
||||||
|
* (although such a case would return a different static string from another
|
||||||
|
* call to this function, of course). As such, you should not modify or free
|
||||||
|
* the returned string.
|
||||||
|
*
|
||||||
|
* \returns the name of the current camera driver or NULL if no driver has been
|
||||||
|
* initialized.
|
||||||
|
*
|
||||||
|
* \threadsafety It is safe to call this function from any thread.
|
||||||
|
*
|
||||||
|
* \since This function is available since SDL 3.0.0.
|
||||||
|
*/
|
||||||
|
extern DECLSPEC const char *SDLCALL SDL_GetCurrentCameraDriver(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a list of currently connected camera devices.
|
* Get a list of currently connected camera devices.
|
||||||
*
|
*
|
||||||
|
|
|
@ -355,6 +355,22 @@ extern "C" {
|
||||||
*/
|
*/
|
||||||
#define SDL_HINT_BMP_SAVE_LEGACY_FORMAT "SDL_BMP_SAVE_LEGACY_FORMAT"
|
#define SDL_HINT_BMP_SAVE_LEGACY_FORMAT "SDL_BMP_SAVE_LEGACY_FORMAT"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A variable that decides what camera backend to use.
|
||||||
|
*
|
||||||
|
* By default, SDL will try all available camera backends in a reasonable
|
||||||
|
* order until it finds one that can work, but this hint allows the app
|
||||||
|
* or user to force a specific target, such as "directshow" if, say, you are
|
||||||
|
* on Windows Media Foundations but want to try DirectShow instead.
|
||||||
|
*
|
||||||
|
* The default value is unset, in which case SDL will try to figure out
|
||||||
|
* the best camera backend on your behalf. This hint needs to be set
|
||||||
|
* before SDL_Init() is called to be useful.
|
||||||
|
*
|
||||||
|
* This hint is available since SDL 3.0.0.
|
||||||
|
*/
|
||||||
|
#define SDL_HINT_CAMERA_DRIVER "SDL_CAMERA_DRIVER"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A variable controlling whether DirectInput should be used for controllers
|
* A variable controlling whether DirectInput should be used for controllers
|
||||||
*
|
*
|
||||||
|
@ -2478,7 +2494,6 @@ extern "C" {
|
||||||
*/
|
*/
|
||||||
#define SDL_HINT_XINPUT_ENABLED "SDL_XINPUT_ENABLED"
|
#define SDL_HINT_XINPUT_ENABLED "SDL_XINPUT_ENABLED"
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An enumeration of hint priorities
|
* An enumeration of hint priorities
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -59,7 +59,8 @@ typedef enum
|
||||||
SDL_INIT_HAPTIC = 0x00001000,
|
SDL_INIT_HAPTIC = 0x00001000,
|
||||||
SDL_INIT_GAMEPAD = 0x00002000, /**< `SDL_INIT_GAMEPAD` implies `SDL_INIT_JOYSTICK` */
|
SDL_INIT_GAMEPAD = 0x00002000, /**< `SDL_INIT_GAMEPAD` implies `SDL_INIT_JOYSTICK` */
|
||||||
SDL_INIT_EVENTS = 0x00004000,
|
SDL_INIT_EVENTS = 0x00004000,
|
||||||
SDL_INIT_SENSOR = 0x00008000
|
SDL_INIT_SENSOR = 0x00008000,
|
||||||
|
SDL_INIT_CAMERA = 0x00010000 /**< `SDL_INIT_CAMERA` implies `SDL_INIT_EVENTS` */
|
||||||
} SDL_InitFlags;
|
} SDL_InitFlags;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -467,10 +467,11 @@
|
||||||
#cmakedefine SDL_FILESYSTEM_N3DS @SDL_FILESYSTEM_N3DS@
|
#cmakedefine SDL_FILESYSTEM_N3DS @SDL_FILESYSTEM_N3DS@
|
||||||
|
|
||||||
/* Enable camera subsystem */
|
/* Enable camera subsystem */
|
||||||
#cmakedefine SDL_CAMERA_DUMMY @SDL_CAMERA_DUMMY@
|
#cmakedefine SDL_CAMERA_DRIVER_DUMMY @SDL_CAMERA_DRIVER_DUMMY@
|
||||||
#cmakedefine SDL_CAMERA_V4L2 @SDL_CAMERA_V4L2@
|
/* !!! FIXME: for later cmakedefine SDL_CAMERA_DRIVER_DISK @SDL_CAMERA_DRIVER_DISK@ */
|
||||||
#cmakedefine SDL_CAMERA_APPLE @SDL_CAMERA_APPLE@
|
#cmakedefine SDL_CAMERA_DRIVER_V4L2 @SDL_CAMERA_DRIVER_V4L2@
|
||||||
#cmakedefine SDL_CAMERA_ANDROID @SDL_CAMERA_ANDROID@
|
#cmakedefine SDL_CAMERA_DRIVER_COREMEDIA @SDL_CAMERA_DRIVER_COREMEDIA@
|
||||||
|
#cmakedefine SDL_CAMERA_DRIVER_ANDROID @SDL_CAMERA_DRIVER_ANDROID@
|
||||||
|
|
||||||
/* Enable misc subsystem */
|
/* Enable misc subsystem */
|
||||||
#cmakedefine SDL_MISC_DUMMY @SDL_MISC_DUMMY@
|
#cmakedefine SDL_MISC_DUMMY @SDL_MISC_DUMMY@
|
||||||
|
|
|
@ -191,6 +191,6 @@
|
||||||
#define SDL_FILESYSTEM_ANDROID 1
|
#define SDL_FILESYSTEM_ANDROID 1
|
||||||
|
|
||||||
/* Enable the camera driver */
|
/* Enable the camera driver */
|
||||||
#define SDL_CAMERA_ANDROID 1
|
#define SDL_CAMERA_DRIVER_ANDROID 1
|
||||||
|
|
||||||
#endif /* SDL_build_config_android_h_ */
|
#endif /* SDL_build_config_android_h_ */
|
||||||
|
|
|
@ -210,6 +210,6 @@
|
||||||
#define SDL_FILESYSTEM_EMSCRIPTEN 1
|
#define SDL_FILESYSTEM_EMSCRIPTEN 1
|
||||||
|
|
||||||
/* Enable the camera driver (src/camera/dummy/\*.c) */ /* !!! FIXME */
|
/* Enable the camera driver (src/camera/dummy/\*.c) */ /* !!! FIXME */
|
||||||
#define SDL_CAMERA_DUMMY 1
|
#define SDL_CAMERA_DRIVER_DUMMY 1
|
||||||
|
|
||||||
#endif /* SDL_build_config_emscripten_h */
|
#endif /* SDL_build_config_emscripten_h */
|
||||||
|
|
|
@ -213,6 +213,6 @@
|
||||||
#define SDL_FILESYSTEM_COCOA 1
|
#define SDL_FILESYSTEM_COCOA 1
|
||||||
|
|
||||||
/* enable camera support */
|
/* enable camera support */
|
||||||
#define SDL_CAMERA_APPLE 1
|
#define SDL_CAMERA_DRIVER_COREMEDIA 1
|
||||||
|
|
||||||
#endif /* SDL_build_config_ios_h_ */
|
#endif /* SDL_build_config_ios_h_ */
|
||||||
|
|
|
@ -270,7 +270,8 @@
|
||||||
#define SDL_FILESYSTEM_COCOA 1
|
#define SDL_FILESYSTEM_COCOA 1
|
||||||
|
|
||||||
/* enable camera support */
|
/* enable camera support */
|
||||||
#define SDL_CAMERA_APPLE 1
|
#define SDL_CAMERA_DRIVER_COREMEDIA 1
|
||||||
|
#define SDL_CAMERA_DRIVER_DUMMY 1
|
||||||
|
|
||||||
/* Enable assembly routines */
|
/* Enable assembly routines */
|
||||||
#ifdef __ppc__
|
#ifdef __ppc__
|
||||||
|
|
|
@ -90,6 +90,6 @@ typedef unsigned int uintptr_t;
|
||||||
#define SDL_FILESYSTEM_DUMMY 1
|
#define SDL_FILESYSTEM_DUMMY 1
|
||||||
|
|
||||||
/* Enable the camera driver (src/camera/dummy/\*.c) */
|
/* Enable the camera driver (src/camera/dummy/\*.c) */
|
||||||
#define SDL_CAMERA_DUMMY 1
|
#define SDL_CAMERA_DRIVER_DUMMY 1
|
||||||
|
|
||||||
#endif /* SDL_build_config_minimal_h_ */
|
#endif /* SDL_build_config_minimal_h_ */
|
||||||
|
|
|
@ -87,6 +87,6 @@ typedef unsigned long uintptr_t;
|
||||||
#define SDL_FILESYSTEM_DUMMY 1
|
#define SDL_FILESYSTEM_DUMMY 1
|
||||||
|
|
||||||
/* Enable the camera driver (src/camera/dummy/\*.c) */
|
/* Enable the camera driver (src/camera/dummy/\*.c) */
|
||||||
#define SDL_CAMERA_DUMMY 1
|
#define SDL_CAMERA_DRIVER_DUMMY 1
|
||||||
|
|
||||||
#endif /* SDL_build_config_ngage_h_ */
|
#endif /* SDL_build_config_ngage_h_ */
|
||||||
|
|
|
@ -312,6 +312,6 @@ typedef unsigned int uintptr_t;
|
||||||
#define SDL_FILESYSTEM_WINDOWS 1
|
#define SDL_FILESYSTEM_WINDOWS 1
|
||||||
|
|
||||||
/* Enable the camera driver (src/camera/dummy/\*.c) */ /* !!! FIXME */
|
/* Enable the camera driver (src/camera/dummy/\*.c) */ /* !!! FIXME */
|
||||||
#define SDL_CAMERA_DUMMY 1
|
#define SDL_CAMERA_DRIVER_DUMMY 1
|
||||||
|
|
||||||
#endif /* SDL_build_config_windows_h_ */
|
#endif /* SDL_build_config_windows_h_ */
|
||||||
|
|
|
@ -248,7 +248,7 @@
|
||||||
#define SDL_FILESYSTEM_WINDOWS 1
|
#define SDL_FILESYSTEM_WINDOWS 1
|
||||||
|
|
||||||
/* Enable the camera driver (src/camera/dummy/\*.c) */ /* !!! FIXME */
|
/* Enable the camera driver (src/camera/dummy/\*.c) */ /* !!! FIXME */
|
||||||
#define SDL_CAMERA_DUMMY 1
|
#define SDL_CAMERA_DRIVER_DUMMY 1
|
||||||
|
|
||||||
/* Use the (inferior) GDK text input method for GDK platforms */
|
/* Use the (inferior) GDK text input method for GDK platforms */
|
||||||
/*#define SDL_GDK_TEXTINPUT 1*/
|
/*#define SDL_GDK_TEXTINPUT 1*/
|
||||||
|
|
|
@ -216,6 +216,6 @@
|
||||||
#define SDL_POWER_WINRT 1
|
#define SDL_POWER_WINRT 1
|
||||||
|
|
||||||
/* Enable the camera driver (src/camera/dummy/\*.c) */ /* !!! FIXME */
|
/* Enable the camera driver (src/camera/dummy/\*.c) */ /* !!! FIXME */
|
||||||
#define SDL_CAMERA_DUMMY 1
|
#define SDL_CAMERA_DRIVER_DUMMY 1
|
||||||
|
|
||||||
#endif /* SDL_build_config_winrt_h_ */
|
#endif /* SDL_build_config_winrt_h_ */
|
||||||
|
|
|
@ -237,6 +237,6 @@
|
||||||
#define SDL_GDK_TEXTINPUT 1
|
#define SDL_GDK_TEXTINPUT 1
|
||||||
|
|
||||||
/* Enable the camera driver (src/camera/dummy/\*.c) */
|
/* Enable the camera driver (src/camera/dummy/\*.c) */
|
||||||
#define SDL_CAMERA_DUMMY 1
|
#define SDL_CAMERA_DRIVER_DUMMY 1
|
||||||
|
|
||||||
#endif /* SDL_build_config_wingdk_h_ */
|
#endif /* SDL_build_config_wingdk_h_ */
|
||||||
|
|
37
src/SDL.c
37
src/SDL.c
|
@ -46,6 +46,7 @@
|
||||||
#include "joystick/SDL_gamepad_c.h"
|
#include "joystick/SDL_gamepad_c.h"
|
||||||
#include "joystick/SDL_joystick_c.h"
|
#include "joystick/SDL_joystick_c.h"
|
||||||
#include "sensor/SDL_sensor_c.h"
|
#include "sensor/SDL_sensor_c.h"
|
||||||
|
#include "camera/SDL_camera_c.h"
|
||||||
|
|
||||||
#define SDL_INIT_EVERYTHING ~0U
|
#define SDL_INIT_EVERYTHING ~0U
|
||||||
|
|
||||||
|
@ -365,6 +366,30 @@ int SDL_InitSubSystem(Uint32 flags)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Initialize the camera subsystem */
|
||||||
|
if (flags & SDL_INIT_CAMERA) {
|
||||||
|
#ifndef SDL_CAMERA_DISABLED
|
||||||
|
if (SDL_ShouldInitSubsystem(SDL_INIT_CAMERA)) {
|
||||||
|
/* camera implies events */
|
||||||
|
if (!SDL_InitOrIncrementSubsystem(SDL_INIT_EVENTS)) {
|
||||||
|
goto quit_and_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_IncrementSubsystemRefCount(SDL_INIT_CAMERA);
|
||||||
|
if (SDL_CameraInit(NULL) < 0) {
|
||||||
|
SDL_DecrementSubsystemRefCount(SDL_INIT_CAMERA);
|
||||||
|
goto quit_and_error;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
SDL_IncrementSubsystemRefCount(SDL_INIT_CAMERA);
|
||||||
|
}
|
||||||
|
flags_initialized |= SDL_INIT_CAMERA;
|
||||||
|
#else
|
||||||
|
SDL_SetError("SDL not built with camera support");
|
||||||
|
goto quit_and_error;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
(void)flags_initialized; /* make static analysis happy, since this only gets used in error cases. */
|
(void)flags_initialized; /* make static analysis happy, since this only gets used in error cases. */
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -382,6 +407,18 @@ int SDL_Init(Uint32 flags)
|
||||||
void SDL_QuitSubSystem(Uint32 flags)
|
void SDL_QuitSubSystem(Uint32 flags)
|
||||||
{
|
{
|
||||||
/* Shut down requested initialized subsystems */
|
/* Shut down requested initialized subsystems */
|
||||||
|
|
||||||
|
#ifndef SDL_CAMERA_DISABLED
|
||||||
|
if (flags & SDL_INIT_CAMERA) {
|
||||||
|
if (SDL_ShouldQuitSubsystem(SDL_INIT_CAMERA)) {
|
||||||
|
SDL_QuitCamera();
|
||||||
|
/* camera implies events */
|
||||||
|
SDL_QuitSubSystem(SDL_INIT_EVENTS);
|
||||||
|
}
|
||||||
|
SDL_DecrementSubsystemRefCount(SDL_INIT_CAMERA);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef SDL_SENSOR_DISABLED
|
#ifndef SDL_SENSOR_DISABLED
|
||||||
if (flags & SDL_INIT_SENSOR) {
|
if (flags & SDL_INIT_SENSOR) {
|
||||||
if (SDL_ShouldQuitSubsystem(SDL_INIT_SENSOR)) {
|
if (SDL_ShouldQuitSubsystem(SDL_INIT_SENSOR)) {
|
||||||
|
|
|
@ -25,7 +25,25 @@
|
||||||
#include "../video/SDL_pixels_c.h"
|
#include "../video/SDL_pixels_c.h"
|
||||||
#include "../thread/SDL_systhread.h"
|
#include "../thread/SDL_systhread.h"
|
||||||
|
|
||||||
#define DEBUG_CAMERA 1
|
// Available camera drivers
|
||||||
|
static const CameraBootStrap *const bootstrap[] = {
|
||||||
|
#ifdef SDL_CAMERA_DRIVER_V4L2
|
||||||
|
&V4L2_bootstrap,
|
||||||
|
#endif
|
||||||
|
#ifdef SDL_CAMERA_DRIVER_COREMEDIA
|
||||||
|
&COREMEDIA_bootstrap,
|
||||||
|
#endif
|
||||||
|
#ifdef SDL_CAMERA_DRIVER_ANDROID
|
||||||
|
&ANDROIDCAMERA_bootstrap,
|
||||||
|
#endif
|
||||||
|
#ifdef SDL_CAMERA_DRIVER_DUMMY
|
||||||
|
&DUMMYCAMERA_bootstrap,
|
||||||
|
#endif
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
static SDL_CameraDriver camera_driver;
|
||||||
|
|
||||||
|
|
||||||
// list node entries to share frames between SDL and user app
|
// list node entries to share frames between SDL and user app
|
||||||
// !!! FIXME: do we need this struct?
|
// !!! FIXME: do we need this struct?
|
||||||
|
@ -36,6 +54,25 @@ typedef struct entry_t
|
||||||
|
|
||||||
static SDL_CameraDevice *open_devices[16]; // !!! FIXME: remove limit
|
static SDL_CameraDevice *open_devices[16]; // !!! FIXME: remove limit
|
||||||
|
|
||||||
|
int SDL_GetNumCameraDrivers(void)
|
||||||
|
{
|
||||||
|
return SDL_arraysize(bootstrap) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *SDL_GetCameraDriver(int index)
|
||||||
|
{
|
||||||
|
if (index >= 0 && index < SDL_GetNumCameraDrivers()) {
|
||||||
|
return bootstrap[index]->name;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *SDL_GetCurrentCameraDriver(void)
|
||||||
|
{
|
||||||
|
return camera_driver.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void CloseCameraDevice(SDL_CameraDevice *device)
|
static void CloseCameraDevice(SDL_CameraDevice *device)
|
||||||
{
|
{
|
||||||
if (!device) {
|
if (!device) {
|
||||||
|
@ -69,46 +106,18 @@ static void CloseCameraDevice(SDL_CameraDevice *device)
|
||||||
SDL_CameraFrame f = entry->frame;
|
SDL_CameraFrame f = entry->frame;
|
||||||
// Release frames not acquired, if any
|
// Release frames not acquired, if any
|
||||||
if (f.timestampNS) {
|
if (f.timestampNS) {
|
||||||
ReleaseFrame(device, &f);
|
camera_driver.impl.ReleaseFrame(device, &f);
|
||||||
}
|
}
|
||||||
SDL_free(entry);
|
SDL_free(entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CloseDevice(device);
|
camera_driver.impl.CloseDevice(device);
|
||||||
|
|
||||||
SDL_free(device->dev_name);
|
SDL_free(device->dev_name);
|
||||||
SDL_free(device);
|
SDL_free(device);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Tell if all devices are closed
|
|
||||||
SDL_bool CheckAllDeviceClosed(void)
|
|
||||||
{
|
|
||||||
const int n = SDL_arraysize(open_devices);
|
|
||||||
int all_closed = SDL_TRUE;
|
|
||||||
for (int i = 0; i < n; i++) {
|
|
||||||
if (open_devices[i]) {
|
|
||||||
all_closed = SDL_FALSE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return all_closed;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tell if at least one device is in playing state
|
|
||||||
SDL_bool CheckDevicePlaying(void)
|
|
||||||
{
|
|
||||||
const int n = SDL_arraysize(open_devices);
|
|
||||||
for (int i = 0; i < n; i++) {
|
|
||||||
if (open_devices[i]) {
|
|
||||||
if (SDL_GetCameraStatus(open_devices[i]) == SDL_CAMERA_PLAYING) {
|
|
||||||
return SDL_TRUE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return SDL_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SDL_CloseCamera(SDL_CameraDevice *device)
|
void SDL_CloseCamera(SDL_CameraDevice *device)
|
||||||
{
|
{
|
||||||
if (!device) {
|
if (!device) {
|
||||||
|
@ -128,7 +137,7 @@ int SDL_StartCamera(SDL_CameraDevice *device)
|
||||||
return SDL_SetError("invalid state");
|
return SDL_SetError("invalid state");
|
||||||
}
|
}
|
||||||
|
|
||||||
const int result = StartCamera(device);
|
const int result = camera_driver.impl.StartCamera(device);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -147,7 +156,7 @@ int SDL_GetCameraSpec(SDL_CameraDevice *device, SDL_CameraSpec *spec)
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_zerop(spec);
|
SDL_zerop(spec);
|
||||||
return GetDeviceSpec(device, spec);
|
return camera_driver.impl.GetDeviceSpec(device, spec);
|
||||||
}
|
}
|
||||||
|
|
||||||
int SDL_StopCamera(SDL_CameraDevice *device)
|
int SDL_StopCamera(SDL_CameraDevice *device)
|
||||||
|
@ -162,7 +171,7 @@ int SDL_StopCamera(SDL_CameraDevice *device)
|
||||||
SDL_AtomicSet(&device->shutdown, 1);
|
SDL_AtomicSet(&device->shutdown, 1);
|
||||||
|
|
||||||
SDL_LockMutex(device->acquiring_lock);
|
SDL_LockMutex(device->acquiring_lock);
|
||||||
const int retval = StopCamera(device);
|
const int retval = camera_driver.impl.StopCamera(device);
|
||||||
SDL_UnlockMutex(device->acquiring_lock);
|
SDL_UnlockMutex(device->acquiring_lock);
|
||||||
|
|
||||||
return (retval < 0) ? -1 : 0;
|
return (retval < 0) ? -1 : 0;
|
||||||
|
@ -254,14 +263,13 @@ const char *SDL_GetCameraDeviceName(SDL_CameraDeviceID instance_id)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (GetCameraDeviceName(instance_id, buf, sizeof (buf)) < 0) {
|
if (camera_driver.impl.GetDeviceName(instance_id, buf, sizeof (buf)) < 0) {
|
||||||
buf[0] = 0;
|
buf[0] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
SDL_CameraDeviceID *SDL_GetCameraDevices(int *count)
|
SDL_CameraDeviceID *SDL_GetCameraDevices(int *count)
|
||||||
{
|
{
|
||||||
int dummycount = 0;
|
int dummycount = 0;
|
||||||
|
@ -270,7 +278,7 @@ SDL_CameraDeviceID *SDL_GetCameraDevices(int *count)
|
||||||
}
|
}
|
||||||
|
|
||||||
int num = 0;
|
int num = 0;
|
||||||
SDL_CameraDeviceID *retval = GetCameraDevices(&num);
|
SDL_CameraDeviceID *retval = camera_driver.impl.GetDevices(&num);
|
||||||
if (retval) {
|
if (retval) {
|
||||||
*count = num;
|
*count = num;
|
||||||
return retval;
|
return retval;
|
||||||
|
@ -279,7 +287,6 @@ SDL_CameraDeviceID *SDL_GetCameraDevices(int *count)
|
||||||
// return list of 0 ID, null terminated
|
// return list of 0 ID, null terminated
|
||||||
retval = (SDL_CameraDeviceID *)SDL_calloc(1, sizeof(*retval));
|
retval = (SDL_CameraDeviceID *)SDL_calloc(1, sizeof(*retval));
|
||||||
if (retval == NULL) {
|
if (retval == NULL) {
|
||||||
SDL_OutOfMemory();
|
|
||||||
*count = 0;
|
*count = 0;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -331,7 +338,7 @@ static int SDLCALL SDL_CameraThread(void *devicep)
|
||||||
SDL_zero(f);
|
SDL_zero(f);
|
||||||
|
|
||||||
SDL_LockMutex(device->acquiring_lock);
|
SDL_LockMutex(device->acquiring_lock);
|
||||||
ret = AcquireFrame(device, &f);
|
ret = camera_driver.impl.AcquireFrame(device, &f);
|
||||||
SDL_UnlockMutex(device->acquiring_lock);
|
SDL_UnlockMutex(device->acquiring_lock);
|
||||||
|
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
|
@ -376,7 +383,6 @@ error_mem:
|
||||||
SDL_Log("dev[%p] End thread 'SDL_CameraThread' with error: %s", (void *)device, SDL_GetError());
|
SDL_Log("dev[%p] End thread 'SDL_CameraThread' with error: %s", (void *)device, SDL_GetError());
|
||||||
#endif
|
#endif
|
||||||
SDL_AtomicSet(&device->shutdown, 1);
|
SDL_AtomicSet(&device->shutdown, 1);
|
||||||
SDL_OutOfMemory(); // !!! FIXME: this error isn't accessible since the thread is about to terminate
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -436,7 +442,6 @@ SDL_CameraDevice *SDL_OpenCamera(SDL_CameraDeviceID instance_id)
|
||||||
|
|
||||||
device = (SDL_CameraDevice *) SDL_calloc(1, sizeof (SDL_CameraDevice));
|
device = (SDL_CameraDevice *) SDL_calloc(1, sizeof (SDL_CameraDevice));
|
||||||
if (device == NULL) {
|
if (device == NULL) {
|
||||||
SDL_OutOfMemory();
|
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
device->dev_name = SDL_strdup(device_name);
|
device->dev_name = SDL_strdup(device_name);
|
||||||
|
@ -456,7 +461,7 @@ SDL_CameraDevice *SDL_OpenCamera(SDL_CameraDeviceID instance_id)
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (OpenDevice(device) < 0) {
|
if (camera_driver.impl.OpenDevice(device) < 0) {
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -515,7 +520,7 @@ int SDL_SetCameraSpec(SDL_CameraDevice *device, const SDL_CameraSpec *desired, S
|
||||||
|
|
||||||
device->spec = *obtained;
|
device->spec = *obtained;
|
||||||
|
|
||||||
result = InitDevice(device);
|
result = camera_driver.impl.InitDevice(device);
|
||||||
if (result < 0) {
|
if (result < 0) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -541,7 +546,7 @@ int SDL_AcquireCameraFrame(SDL_CameraDevice *device, SDL_CameraFrame *frame)
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
// Wait for a frame
|
// Wait for a frame
|
||||||
while ((ret = AcquireFrame(device, frame)) == 0) {
|
while ((ret = camera_driver.impl.AcquireFrame(device, frame)) == 0) {
|
||||||
if (frame->num_planes) {
|
if (frame->num_planes) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -576,7 +581,7 @@ int SDL_ReleaseCameraFrame(SDL_CameraDevice *device, SDL_CameraFrame *frame)
|
||||||
return SDL_InvalidParamError("device");
|
return SDL_InvalidParamError("device");
|
||||||
} else if (frame == NULL) {
|
} else if (frame == NULL) {
|
||||||
return SDL_InvalidParamError("frame");
|
return SDL_InvalidParamError("frame");
|
||||||
} else if (ReleaseFrame(device, frame) < 0) {
|
} else if (camera_driver.impl.ReleaseFrame(device, frame) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -589,7 +594,7 @@ int SDL_GetNumCameraFormats(SDL_CameraDevice *device)
|
||||||
if (!device) {
|
if (!device) {
|
||||||
return SDL_InvalidParamError("device");
|
return SDL_InvalidParamError("device");
|
||||||
}
|
}
|
||||||
return GetNumFormats(device);
|
return camera_driver.impl.GetNumFormats(device);
|
||||||
}
|
}
|
||||||
|
|
||||||
int SDL_GetCameraFormat(SDL_CameraDevice *device, int index, Uint32 *format)
|
int SDL_GetCameraFormat(SDL_CameraDevice *device, int index, Uint32 *format)
|
||||||
|
@ -600,7 +605,7 @@ int SDL_GetCameraFormat(SDL_CameraDevice *device, int index, Uint32 *format)
|
||||||
return SDL_InvalidParamError("format");
|
return SDL_InvalidParamError("format");
|
||||||
}
|
}
|
||||||
*format = 0;
|
*format = 0;
|
||||||
return GetFormat(device, index, format);
|
return camera_driver.impl.GetFormat(device, index, format);
|
||||||
}
|
}
|
||||||
|
|
||||||
int SDL_GetNumCameraFrameSizes(SDL_CameraDevice *device, Uint32 format)
|
int SDL_GetNumCameraFrameSizes(SDL_CameraDevice *device, Uint32 format)
|
||||||
|
@ -608,7 +613,7 @@ int SDL_GetNumCameraFrameSizes(SDL_CameraDevice *device, Uint32 format)
|
||||||
if (!device) {
|
if (!device) {
|
||||||
return SDL_InvalidParamError("device");
|
return SDL_InvalidParamError("device");
|
||||||
}
|
}
|
||||||
return GetNumFrameSizes(device, format);
|
return camera_driver.impl.GetNumFrameSizes(device, format);
|
||||||
}
|
}
|
||||||
|
|
||||||
int SDL_GetCameraFrameSize(SDL_CameraDevice *device, Uint32 format, int index, int *width, int *height)
|
int SDL_GetCameraFrameSize(SDL_CameraDevice *device, Uint32 format, int index, int *width, int *height)
|
||||||
|
@ -621,7 +626,7 @@ int SDL_GetCameraFrameSize(SDL_CameraDevice *device, Uint32 format, int index, i
|
||||||
return SDL_InvalidParamError("height");
|
return SDL_InvalidParamError("height");
|
||||||
}
|
}
|
||||||
*width = *height = 0;
|
*width = *height = 0;
|
||||||
return GetFrameSize(device, format, index, width, height);
|
return camera_driver.impl.GetFrameSize(device, format, index, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_CameraDevice *SDL_OpenCameraWithSpec(SDL_CameraDeviceID instance_id, const SDL_CameraSpec *desired, SDL_CameraSpec *obtained, int allowed_changes)
|
SDL_CameraDevice *SDL_OpenCameraWithSpec(SDL_CameraDeviceID instance_id, const SDL_CameraSpec *desired, SDL_CameraSpec *obtained, int allowed_changes)
|
||||||
|
@ -653,15 +658,35 @@ SDL_CameraStatus SDL_GetCameraStatus(SDL_CameraDevice *device)
|
||||||
return SDL_CAMERA_INIT;
|
return SDL_CAMERA_INIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SDL_CameraInit(void)
|
static void CompleteCameraEntryPoints(void)
|
||||||
{
|
{
|
||||||
SDL_zeroa(open_devices);
|
// this doesn't currently fill in stub implementations, it just asserts the backend filled them all in.
|
||||||
SDL_SYS_CameraInit();
|
#define FILL_STUB(x) SDL_assert(camera_driver.impl.x != NULL)
|
||||||
return 0;
|
FILL_STUB(DetectDevices);
|
||||||
|
FILL_STUB(OpenDevice);
|
||||||
|
FILL_STUB(CloseDevice);
|
||||||
|
FILL_STUB(InitDevice);
|
||||||
|
FILL_STUB(GetDeviceSpec);
|
||||||
|
FILL_STUB(StartCamera);
|
||||||
|
FILL_STUB(StopCamera);
|
||||||
|
FILL_STUB(AcquireFrame);
|
||||||
|
FILL_STUB(ReleaseFrame);
|
||||||
|
FILL_STUB(GetNumFormats);
|
||||||
|
FILL_STUB(GetFormat);
|
||||||
|
FILL_STUB(GetNumFrameSizes);
|
||||||
|
FILL_STUB(GetFrameSize);
|
||||||
|
FILL_STUB(GetDeviceName);
|
||||||
|
FILL_STUB(GetDevices);
|
||||||
|
FILL_STUB(Deinitialize);
|
||||||
|
#undef FILL_STUB
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDL_QuitCamera(void)
|
void SDL_QuitCamera(void)
|
||||||
{
|
{
|
||||||
|
if (!camera_driver.name) { // not initialized?!
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const int n = SDL_arraysize(open_devices);
|
const int n = SDL_arraysize(open_devices);
|
||||||
for (int i = 0; i < n; i++) {
|
for (int i = 0; i < n; i++) {
|
||||||
CloseCameraDevice(open_devices[i]);
|
CloseCameraDevice(open_devices[i]);
|
||||||
|
@ -669,6 +694,112 @@ void SDL_QuitCamera(void)
|
||||||
|
|
||||||
SDL_zeroa(open_devices);
|
SDL_zeroa(open_devices);
|
||||||
|
|
||||||
SDL_SYS_CameraQuit();
|
#if 0 // !!! FIXME
|
||||||
|
SDL_PendingCameraDeviceEvent *pending_events = camera_driver.pending_events.next;
|
||||||
|
camera_driver.pending_events.next = NULL;
|
||||||
|
|
||||||
|
SDL_PendingCameraDeviceEvent *pending_next = NULL;
|
||||||
|
for (SDL_PendingCameraDeviceEvent *i = pending_events; i; i = pending_next) {
|
||||||
|
pending_next = i->next;
|
||||||
|
SDL_free(i);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Free the driver data
|
||||||
|
camera_driver.impl.Deinitialize();
|
||||||
|
|
||||||
|
SDL_zero(camera_driver);
|
||||||
|
}
|
||||||
|
|
||||||
|
// this is 90% the same code as the audio subsystem uses.
|
||||||
|
int SDL_CameraInit(const char *driver_name)
|
||||||
|
{
|
||||||
|
if (SDL_GetCurrentCameraDriver()) {
|
||||||
|
SDL_QuitCamera(); // shutdown driver if already running.
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_zeroa(open_devices);
|
||||||
|
|
||||||
|
// Select the proper camera driver
|
||||||
|
if (!driver_name) {
|
||||||
|
driver_name = SDL_GetHint(SDL_HINT_CAMERA_DRIVER);
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_bool initialized = SDL_FALSE;
|
||||||
|
SDL_bool tried_to_init = SDL_FALSE;
|
||||||
|
|
||||||
|
if (driver_name && (*driver_name != 0)) {
|
||||||
|
char *driver_name_copy = SDL_strdup(driver_name);
|
||||||
|
const char *driver_attempt = driver_name_copy;
|
||||||
|
|
||||||
|
if (!driver_name_copy) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (driver_attempt && (*driver_attempt != 0) && !initialized) {
|
||||||
|
char *driver_attempt_end = SDL_strchr(driver_attempt, ',');
|
||||||
|
if (driver_attempt_end) {
|
||||||
|
*driver_attempt_end = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; bootstrap[i]; i++) {
|
||||||
|
if (SDL_strcasecmp(bootstrap[i]->name, driver_attempt) == 0) {
|
||||||
|
tried_to_init = SDL_TRUE;
|
||||||
|
SDL_zero(camera_driver);
|
||||||
|
#if 0 // !!! FIXME
|
||||||
|
camera_driver.pending_events_tail = &camera_driver.pending_events;
|
||||||
|
#endif
|
||||||
|
if (bootstrap[i]->init(&camera_driver.impl)) {
|
||||||
|
camera_driver.name = bootstrap[i]->name;
|
||||||
|
camera_driver.desc = bootstrap[i]->desc;
|
||||||
|
initialized = SDL_TRUE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
driver_attempt = (driver_attempt_end) ? (driver_attempt_end + 1) : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_free(driver_name_copy);
|
||||||
|
} else {
|
||||||
|
for (int i = 0; !initialized && bootstrap[i]; i++) {
|
||||||
|
if (bootstrap[i]->demand_only) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
tried_to_init = SDL_TRUE;
|
||||||
|
SDL_zero(camera_driver);
|
||||||
|
#if 0 // !!! FIXME
|
||||||
|
camera_driver.pending_events_tail = &camera_driver.pending_events;
|
||||||
|
#endif
|
||||||
|
if (bootstrap[i]->init(&camera_driver.impl)) {
|
||||||
|
camera_driver.name = bootstrap[i]->name;
|
||||||
|
camera_driver.desc = bootstrap[i]->desc;
|
||||||
|
initialized = SDL_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!initialized) {
|
||||||
|
// specific drivers will set the error message if they fail, but otherwise we do it here.
|
||||||
|
if (!tried_to_init) {
|
||||||
|
if (driver_name) {
|
||||||
|
SDL_SetError("Camera driver '%s' not available", driver_name);
|
||||||
|
} else {
|
||||||
|
SDL_SetError("No available camera driver");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_zero(camera_driver);
|
||||||
|
return -1; // No driver was available, so fail.
|
||||||
|
}
|
||||||
|
|
||||||
|
CompleteCameraEntryPoints();
|
||||||
|
|
||||||
|
// Make sure we have a list of devices available at startup...
|
||||||
|
camera_driver.impl.DetectDevices();
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
#define SDL_camera_c_h_
|
#define SDL_camera_c_h_
|
||||||
|
|
||||||
// Initialize the camera subsystem
|
// Initialize the camera subsystem
|
||||||
int SDL_CameraInit(void);
|
int SDL_CameraInit(const char *driver_name);
|
||||||
|
|
||||||
// Shutdown the camera subsystem
|
// Shutdown the camera subsystem
|
||||||
void SDL_QuitCamera(void);
|
void SDL_QuitCamera(void);
|
||||||
|
|
|
@ -25,6 +25,8 @@
|
||||||
|
|
||||||
#include "../SDL_list.h"
|
#include "../SDL_list.h"
|
||||||
|
|
||||||
|
#define DEBUG_CAMERA 1
|
||||||
|
|
||||||
// The SDL camera driver
|
// The SDL camera driver
|
||||||
typedef struct SDL_CameraDevice SDL_CameraDevice;
|
typedef struct SDL_CameraDevice SDL_CameraDevice;
|
||||||
|
|
||||||
|
@ -57,34 +59,45 @@ struct SDL_CameraDevice
|
||||||
struct SDL_PrivateCameraData *hidden;
|
struct SDL_PrivateCameraData *hidden;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern int SDL_SYS_CameraInit(void);
|
typedef struct SDL_CameraDriverImpl
|
||||||
extern int SDL_SYS_CameraQuit(void);
|
{
|
||||||
|
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);
|
||||||
|
void (*Deinitialize)(void);
|
||||||
|
} SDL_CameraDriverImpl;
|
||||||
|
|
||||||
// !!! FIXME: These names need to be made camera-specific.
|
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_CameraDriver;
|
||||||
|
|
||||||
extern int OpenDevice(SDL_CameraDevice *_this);
|
typedef struct CameraBootStrap
|
||||||
extern void CloseDevice(SDL_CameraDevice *_this);
|
{
|
||||||
|
const char *name;
|
||||||
|
const char *desc;
|
||||||
|
SDL_bool (*init)(SDL_CameraDriverImpl *impl);
|
||||||
|
SDL_bool demand_only; // if SDL_TRUE: request explicitly, or it won't be available.
|
||||||
|
} CameraBootStrap;
|
||||||
|
|
||||||
extern int InitDevice(SDL_CameraDevice *_this);
|
// Not all of these are available in a given build. Use #ifdefs, etc.
|
||||||
|
extern CameraBootStrap DUMMYCAMERA_bootstrap;
|
||||||
extern int GetDeviceSpec(SDL_CameraDevice *_this, SDL_CameraSpec *spec);
|
extern CameraBootStrap V4L2_bootstrap;
|
||||||
|
extern CameraBootStrap COREMEDIA_bootstrap;
|
||||||
extern int StartCamera(SDL_CameraDevice *_this);
|
extern CameraBootStrap ANDROIDCAMERA_bootstrap;
|
||||||
extern int StopCamera(SDL_CameraDevice *_this);
|
|
||||||
|
|
||||||
extern int AcquireFrame(SDL_CameraDevice *_this, SDL_CameraFrame *frame);
|
|
||||||
extern int ReleaseFrame(SDL_CameraDevice *_this, SDL_CameraFrame *frame);
|
|
||||||
|
|
||||||
extern int GetNumFormats(SDL_CameraDevice *_this);
|
|
||||||
extern int GetFormat(SDL_CameraDevice *_this, int index, Uint32 *format);
|
|
||||||
|
|
||||||
extern int GetNumFrameSizes(SDL_CameraDevice *_this, Uint32 format);
|
|
||||||
extern int GetFrameSize(SDL_CameraDevice *_this, Uint32 format, int index, int *width, int *height);
|
|
||||||
|
|
||||||
extern int GetCameraDeviceName(SDL_CameraDeviceID instance_id, char *buf, int size);
|
|
||||||
extern SDL_CameraDeviceID *GetCameraDevices(int *count);
|
|
||||||
|
|
||||||
extern SDL_bool CheckAllDeviceClosed(void);
|
|
||||||
extern SDL_bool CheckDevicePlaying(void);
|
|
||||||
|
|
||||||
#endif // SDL_syscamera_h_
|
#endif // SDL_syscamera_h_
|
||||||
|
|
|
@ -25,9 +25,9 @@
|
||||||
#include "../../video/SDL_pixels_c.h"
|
#include "../../video/SDL_pixels_c.h"
|
||||||
#include "../../thread/SDL_systhread.h"
|
#include "../../thread/SDL_systhread.h"
|
||||||
|
|
||||||
#define DEBUG_CAMERA 1
|
#if defined(SDL_CAMERA_DRIVER_ANDROID)
|
||||||
|
|
||||||
#if defined(SDL_CAMERA_ANDROID) && __ANDROID_API__ >= 24
|
#if __ANDROID_API__ >= 24
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* APP_PLATFORM=android-24
|
* APP_PLATFORM=android-24
|
||||||
|
@ -62,7 +62,7 @@
|
||||||
static ACameraManager *cameraMgr = NULL;
|
static ACameraManager *cameraMgr = NULL;
|
||||||
static ACameraIdList *cameraIdList = NULL;
|
static ACameraIdList *cameraIdList = NULL;
|
||||||
|
|
||||||
static void create_cameraMgr(void)
|
static int CreateCameraManager(void)
|
||||||
{
|
{
|
||||||
if (cameraMgr == NULL) {
|
if (cameraMgr == NULL) {
|
||||||
#if 0 // !!! FIXME: this is getting replaced in a different branch.
|
#if 0 // !!! FIXME: this is getting replaced in a different branch.
|
||||||
|
@ -78,9 +78,13 @@ static void create_cameraMgr(void)
|
||||||
SDL_Log("Create ACameraManager");
|
SDL_Log("Create ACameraManager");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cameraMgr = ACameraManager_create();
|
||||||
|
|
||||||
|
return cameraMgr ? 0 : SDL_SetError("Error creating ACameraManager");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void delete_cameraMgr(void)
|
static void DestroyCameraManager(void)
|
||||||
{
|
{
|
||||||
if (cameraIdList) {
|
if (cameraIdList) {
|
||||||
ACameraManager_deleteCameraIdList(cameraIdList);
|
ACameraManager_deleteCameraIdList(cameraIdList);
|
||||||
|
@ -215,7 +219,7 @@ static void onActive(void* context, ACameraCaptureSession *session)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int OpenDevice(SDL_CameraDevice *_this)
|
static int ANDROIDCAMERA_OpenDevice(SDL_CameraDevice *_this)
|
||||||
{
|
{
|
||||||
/* Cannot open a second camera, while the first one is opened.
|
/* Cannot open a second camera, while the first one is opened.
|
||||||
* If you want to play several camera, they must all be opened first, then played.
|
* If you want to play several camera, they must all be opened first, then played.
|
||||||
|
@ -231,10 +235,10 @@ int OpenDevice(SDL_CameraDevice *_this)
|
||||||
|
|
||||||
_this->hidden = (struct SDL_PrivateCameraData *) SDL_calloc(1, sizeof (struct SDL_PrivateCameraData));
|
_this->hidden = (struct SDL_PrivateCameraData *) SDL_calloc(1, sizeof (struct SDL_PrivateCameraData));
|
||||||
if (_this->hidden == NULL) {
|
if (_this->hidden == NULL) {
|
||||||
return SDL_OutOfMemory();
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
create_cameraMgr();
|
CreateCameraManager();
|
||||||
|
|
||||||
_this->hidden->dev_callbacks.context = (void *) _this;
|
_this->hidden->dev_callbacks.context = (void *) _this;
|
||||||
_this->hidden->dev_callbacks.onDisconnected = onDisconnected;
|
_this->hidden->dev_callbacks.onDisconnected = onDisconnected;
|
||||||
|
@ -248,7 +252,7 @@ int OpenDevice(SDL_CameraDevice *_this)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CloseDevice(SDL_CameraDevice *_this)
|
static void ANDROIDCAMERA_CloseDevice(SDL_CameraDevice *_this)
|
||||||
{
|
{
|
||||||
if (_this && _this->hidden) {
|
if (_this && _this->hidden) {
|
||||||
if (_this->hidden->session) {
|
if (_this->hidden->session) {
|
||||||
|
@ -271,14 +275,9 @@ void CloseDevice(SDL_CameraDevice *_this)
|
||||||
|
|
||||||
_this->hidden = NULL;
|
_this->hidden = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// !!! FIXME: just refcount this?
|
|
||||||
if (CheckAllDeviceClosed()) {
|
|
||||||
delete_cameraMgr();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int InitDevice(SDL_CameraDevice *_this)
|
static int ANDROIDCAMERA_InitDevice(SDL_CameraDevice *_this)
|
||||||
{
|
{
|
||||||
size_t size, pitch;
|
size_t size, pitch;
|
||||||
SDL_CalculateSize(_this->spec.format, _this->spec.width, _this->spec.height, &size, &pitch, SDL_FALSE);
|
SDL_CalculateSize(_this->spec.format, _this->spec.width, _this->spec.height, &size, &pitch, SDL_FALSE);
|
||||||
|
@ -286,7 +285,7 @@ int InitDevice(SDL_CameraDevice *_this)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetDeviceSpec(SDL_CameraDevice *_this, SDL_CameraSpec *spec)
|
static int ANDROIDCAMERA_GetDeviceSpec(SDL_CameraDevice *_this, SDL_CameraSpec *spec)
|
||||||
{
|
{
|
||||||
// !!! FIXME: catch NULLs at higher level
|
// !!! FIXME: catch NULLs at higher level
|
||||||
if (spec) {
|
if (spec) {
|
||||||
|
@ -296,7 +295,7 @@ int GetDeviceSpec(SDL_CameraDevice *_this, SDL_CameraSpec *spec)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int StartCamera(SDL_CameraDevice *_this)
|
static int ANDROIDCAMERA_StartCamera(SDL_CameraDevice *_this)
|
||||||
{
|
{
|
||||||
// !!! FIXME: maybe log the error code in SDL_SetError
|
// !!! FIXME: maybe log the error code in SDL_SetError
|
||||||
camera_status_t res;
|
camera_status_t res;
|
||||||
|
@ -377,14 +376,14 @@ error:
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int StopCamera(SDL_CameraDevice *_this)
|
static int ANDROIDCAMERA_StopCamera(SDL_CameraDevice *_this)
|
||||||
{
|
{
|
||||||
ACameraCaptureSession_close(_this->hidden->session);
|
ACameraCaptureSession_close(_this->hidden->session);
|
||||||
_this->hidden->session = NULL;
|
_this->hidden->session = NULL;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int AcquireFrame(SDL_CameraDevice *_this, SDL_CameraFrame *frame)
|
static int ANDROIDCAMERA_AcquireFrame(SDL_CameraDevice *_this, SDL_CameraFrame *frame)
|
||||||
{
|
{
|
||||||
media_status_t res;
|
media_status_t res;
|
||||||
AImage *image;
|
AImage *image;
|
||||||
|
@ -435,7 +434,7 @@ int AcquireFrame(SDL_CameraDevice *_this, SDL_CameraFrame *frame)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ReleaseFrame(SDL_CameraDevice *_this, SDL_CameraFrame *frame)
|
static int ANDROIDCAMERA_ReleaseFrame(SDL_CameraDevice *_this, SDL_CameraFrame *frame)
|
||||||
{
|
{
|
||||||
if (frame->internal){
|
if (frame->internal){
|
||||||
AImage_delete((AImage *)frame->internal);
|
AImage_delete((AImage *)frame->internal);
|
||||||
|
@ -443,7 +442,7 @@ int ReleaseFrame(SDL_CameraDevice *_this, SDL_CameraFrame *frame)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetNumFormats(SDL_CameraDevice *_this)
|
static int ANDROIDCAMERA_GetNumFormats(SDL_CameraDevice *_this)
|
||||||
{
|
{
|
||||||
camera_status_t res;
|
camera_status_t res;
|
||||||
SDL_bool unknown = SDL_FALSE;
|
SDL_bool unknown = SDL_FALSE;
|
||||||
|
@ -505,7 +504,7 @@ int GetNumFormats(SDL_CameraDevice *_this)
|
||||||
return _this->hidden->num_formats;
|
return _this->hidden->num_formats;
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetFormat(SDL_CameraDevice *_this, int index, Uint32 *format)
|
static int ANDROIDCAMERA_GetFormat(SDL_CameraDevice *_this, int index, Uint32 *format)
|
||||||
{
|
{
|
||||||
int i2 = 0;
|
int i2 = 0;
|
||||||
|
|
||||||
|
@ -533,7 +532,7 @@ int GetFormat(SDL_CameraDevice *_this, int index, Uint32 *format)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetNumFrameSizes(SDL_CameraDevice *_this, Uint32 format)
|
static int ANDROIDCAMERA_GetNumFrameSizes(SDL_CameraDevice *_this, Uint32 format)
|
||||||
{
|
{
|
||||||
// !!! FIXME: call SDL_SetError()?
|
// !!! FIXME: call SDL_SetError()?
|
||||||
if (_this->hidden->num_formats == 0) {
|
if (_this->hidden->num_formats == 0) {
|
||||||
|
@ -559,7 +558,7 @@ int GetNumFrameSizes(SDL_CameraDevice *_this, Uint32 format)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetFrameSize(SDL_CameraDevice *_this, Uint32 format, int index, int *width, int *height)
|
static int ANDROIDCAMERA_GetFrameSize(SDL_CameraDevice *_this, Uint32 format, int index, int *width, int *height)
|
||||||
{
|
{
|
||||||
// !!! FIXME: call SDL_SetError()?
|
// !!! FIXME: call SDL_SetError()?
|
||||||
camera_status_t res;
|
camera_status_t res;
|
||||||
|
@ -608,10 +607,10 @@ int GetFrameSize(SDL_CameraDevice *_this, Uint32 format, int index, int *width,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int GetNumDevices(void)
|
static int ANDROIDCAMERA_GetNumDevices(void)
|
||||||
{
|
{
|
||||||
camera_status_t res;
|
camera_status_t res;
|
||||||
create_cameraMgr();
|
CreateCameraManager();
|
||||||
|
|
||||||
if (cameraIdList) {
|
if (cameraIdList) {
|
||||||
ACameraManager_deleteCameraIdList(cameraIdList);
|
ACameraManager_deleteCameraIdList(cameraIdList);
|
||||||
|
@ -628,11 +627,11 @@ static int GetNumDevices(void)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetCameraDeviceName(SDL_CameraDeviceID instance_id, char *buf, int size)
|
static int ANDROIDCAMERA_GetDeviceName(SDL_CameraDeviceID instance_id, char *buf, int size)
|
||||||
{
|
{
|
||||||
// !!! FIXME: call SDL_SetError()?
|
// !!! FIXME: call SDL_SetError()?
|
||||||
int index = instance_id - 1;
|
int index = instance_id - 1;
|
||||||
create_cameraMgr();
|
CreateCameraManager();
|
||||||
|
|
||||||
if (cameraIdList == NULL) {
|
if (cameraIdList == NULL) {
|
||||||
GetNumDevices();
|
GetNumDevices();
|
||||||
|
@ -648,14 +647,13 @@ int GetCameraDeviceName(SDL_CameraDeviceID instance_id, char *buf, int size)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_CameraDeviceID *GetCameraDevices(int *count)
|
static SDL_CameraDeviceID *ANDROIDCAMERA_GetDevices(int *count)
|
||||||
{
|
{
|
||||||
// hard-coded list of ID
|
// hard-coded list of ID
|
||||||
const int num = GetNumDevices();
|
const int num = GetNumDevices();
|
||||||
SDL_CameraDeviceID *retval = (SDL_CameraDeviceID *)SDL_malloc((num + 1) * sizeof(*ret));
|
SDL_CameraDeviceID *retval = (SDL_CameraDeviceID *)SDL_malloc((num + 1) * sizeof(*ret));
|
||||||
|
|
||||||
if (retval == NULL) {
|
if (retval == NULL) {
|
||||||
SDL_OutOfMemory();
|
|
||||||
*count = 0;
|
*count = 0;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -668,15 +666,47 @@ SDL_CameraDeviceID *GetCameraDevices(int *count)
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SDL_SYS_CameraInit(void)
|
static void ANDROIDCAMERA_Deinitialize(void)
|
||||||
{
|
{
|
||||||
return 0;
|
DestroyCameraManager();
|
||||||
}
|
}
|
||||||
|
|
||||||
int SDL_SYS_CameraQuit(void)
|
#endif // __ANDROID_API__ >= 24
|
||||||
|
|
||||||
|
|
||||||
|
static SDL_bool ANDROIDCAMERA_Init(SDL_CameraDriverImpl *impl)
|
||||||
{
|
{
|
||||||
return 0;
|
#if __ANDROID_API__ < 24
|
||||||
|
return SDL_FALSE;
|
||||||
|
#else
|
||||||
|
if (CreateCameraManager() < 0) {
|
||||||
|
return SDL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl->DetectDevices = ANDROIDCAMERA_DetectDevices;
|
||||||
|
impl->OpenDevice = ANDROIDCAMERA_OpenDevice;
|
||||||
|
impl->CloseDevice = ANDROIDCAMERA_CloseDevice;
|
||||||
|
impl->InitDevice = ANDROIDCAMERA_InitDevice;
|
||||||
|
impl->GetDeviceSpec = ANDROIDCAMERA_GetDeviceSpec;
|
||||||
|
impl->StartCamera = ANDROIDCAMERA_StartCamera;
|
||||||
|
impl->StopCamera = ANDROIDCAMERA_StopCamera;
|
||||||
|
impl->AcquireFrame = ANDROIDCAMERA_AcquireFrame;
|
||||||
|
impl->ReleaseFrame = ANDROIDCAMERA_ReleaseFrame;
|
||||||
|
impl->GetNumFormats = ANDROIDCAMERA_GetNumFormats;
|
||||||
|
impl->GetFormat = ANDROIDCAMERA_GetFormat;
|
||||||
|
impl->GetNumFrameSizes = ANDROIDCAMERA_GetNumFrameSizes;
|
||||||
|
impl->GetFrameSize = ANDROIDCAMERA_GetFrameSize;
|
||||||
|
impl->GetDeviceName = ANDROIDCAMERA_GetDeviceName;
|
||||||
|
impl->GetDevices = ANDROIDCAMERA_GetDevices;
|
||||||
|
impl->Deinitialize = ANDROIDCAMERA_Deinitialize;
|
||||||
|
|
||||||
|
return SDL_TRUE;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CameraBootStrap ANDROIDCAMERA_bootstrap = {
|
||||||
|
"android", "SDL Android camera driver", ANDROIDCAMERA_Init, SDL_FALSE
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
*/
|
*/
|
||||||
#include "SDL_internal.h"
|
#include "SDL_internal.h"
|
||||||
|
|
||||||
#ifdef SDL_CAMERA_APPLE
|
#ifdef SDL_CAMERA_DRIVER_COREMEDIA
|
||||||
|
|
||||||
#include "../SDL_syscamera.h"
|
#include "../SDL_syscamera.h"
|
||||||
#include "../SDL_camera_c.h"
|
#include "../SDL_camera_c.h"
|
||||||
|
@ -35,59 +35,7 @@
|
||||||
#undef HAVE_COREMEDIA
|
#undef HAVE_COREMEDIA
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// !!! FIXME: use the dummy driver
|
#ifdef HAVE_COREMEDIA
|
||||||
// !!! FIXME: actually, move everything over to backend callbacks instead.
|
|
||||||
#ifndef HAVE_COREMEDIA
|
|
||||||
int InitDevice(SDL_CameraDevice *_this) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
int OpenDevice(SDL_CameraDevice *_this) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
int AcquireFrame(SDL_CameraDevice *_this, SDL_CameraFrame *frame) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
void CloseDevice(SDL_CameraDevice *_this) {
|
|
||||||
}
|
|
||||||
int GetCameraDeviceName(SDL_CameraDeviceID instance_id, char *buf, int size) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
int GetDeviceSpec(SDL_CameraDevice *_this, SDL_CameraSpec *spec) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
int GetFormat(SDL_CameraDevice *_this, int index, Uint32 *format) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
int GetFrameSize(SDL_CameraDevice *_this, Uint32 format, int index, int *width, int *height) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
SDL_CameraDeviceID *GetCameraDevices(int *count) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
int GetNumFormats(SDL_CameraDevice *_this) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
int GetNumFrameSizes(SDL_CameraDevice *_this, Uint32 format) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
int ReleaseFrame(SDL_CameraDevice *_this, SDL_CameraFrame *frame) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
int StartCapture(SDL_CameraDevice *_this) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
int StopCapture(SDL_CameraDevice *_this) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
int SDL_SYS_CameraInit(void) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
int SDL_SYS_CameraQuit(void) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#import <AVFoundation/AVFoundation.h>
|
#import <AVFoundation/AVFoundation.h>
|
||||||
#import <CoreMedia/CoreMedia.h>
|
#import <CoreMedia/CoreMedia.h>
|
||||||
|
@ -234,16 +182,16 @@ static NSString *sdlformat_to_nsfourcc(Uint32 fmt)
|
||||||
}
|
}
|
||||||
@end
|
@end
|
||||||
|
|
||||||
int OpenDevice(SDL_CameraDevice *_this)
|
static int COREMEDIA_OpenDevice(SDL_CameraDevice *_this)
|
||||||
{
|
{
|
||||||
_this->hidden = (struct SDL_PrivateCameraData *) SDL_calloc(1, sizeof (struct SDL_PrivateCameraData));
|
_this->hidden = (struct SDL_PrivateCameraData *) SDL_calloc(1, sizeof (struct SDL_PrivateCameraData));
|
||||||
if (_this->hidden == NULL) {
|
if (_this->hidden == NULL) {
|
||||||
return SDL_OutOfMemory();
|
return -1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CloseDevice(SDL_CameraDevice *_this)
|
static void COREMEDIA_CloseDevice(SDL_CameraDevice *_this)
|
||||||
{
|
{
|
||||||
if (!_this) {
|
if (!_this) {
|
||||||
return;
|
return;
|
||||||
|
@ -271,7 +219,7 @@ void CloseDevice(SDL_CameraDevice *_this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int InitDevice(SDL_CameraDevice *_this)
|
static int COREMEDIA_InitDevice(SDL_CameraDevice *_this)
|
||||||
{
|
{
|
||||||
// !!! FIXME: autorelease pool?
|
// !!! FIXME: autorelease pool?
|
||||||
NSString *fmt = sdlformat_to_nsfourcc(_this->spec.format);
|
NSString *fmt = sdlformat_to_nsfourcc(_this->spec.format);
|
||||||
|
@ -381,7 +329,7 @@ int InitDevice(SDL_CameraDevice *_this)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetDeviceSpec(SDL_CameraDevice *_this, SDL_CameraSpec *spec)
|
static int COREMEDIA_GetDeviceSpec(SDL_CameraDevice *_this, SDL_CameraSpec *spec)
|
||||||
{
|
{
|
||||||
// !!! FIXME: make sure higher level checks spec != NULL
|
// !!! FIXME: make sure higher level checks spec != NULL
|
||||||
if (spec) {
|
if (spec) {
|
||||||
|
@ -391,19 +339,19 @@ int GetDeviceSpec(SDL_CameraDevice *_this, SDL_CameraSpec *spec)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int StartCamera(SDL_CameraDevice *_this)
|
static int COREMEDIA_StartCamera(SDL_CameraDevice *_this)
|
||||||
{
|
{
|
||||||
[_this->hidden->session startRunning];
|
[_this->hidden->session startRunning];
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int StopCamera(SDL_CameraDevice *_this)
|
static int COREMEDIA_StopCamera(SDL_CameraDevice *_this)
|
||||||
{
|
{
|
||||||
[_this->hidden->session stopRunning];
|
[_this->hidden->session stopRunning];
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int AcquireFrame(SDL_CameraDevice *_this, SDL_CameraFrame *frame)
|
static int COREMEDIA_AcquireFrame(SDL_CameraDevice *_this, SDL_CameraFrame *frame)
|
||||||
{
|
{
|
||||||
if (CMSimpleQueueGetCount(_this->hidden->frame_queue) > 0) {
|
if (CMSimpleQueueGetCount(_this->hidden->frame_queue) > 0) {
|
||||||
CMSampleBufferRef sampleBuffer = (CMSampleBufferRef)CMSimpleQueueDequeue(_this->hidden->frame_queue);
|
CMSampleBufferRef sampleBuffer = (CMSampleBufferRef)CMSimpleQueueDequeue(_this->hidden->frame_queue);
|
||||||
|
@ -444,7 +392,7 @@ int AcquireFrame(SDL_CameraDevice *_this, SDL_CameraFrame *frame)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ReleaseFrame(SDL_CameraDevice *_this, SDL_CameraFrame *frame)
|
static int COREMEDIA_ReleaseFrame(SDL_CameraDevice *_this, SDL_CameraFrame *frame)
|
||||||
{
|
{
|
||||||
if (frame->internal) {
|
if (frame->internal) {
|
||||||
CMSampleBufferRef sampleBuffer = (CMSampleBufferRef) frame->internal;
|
CMSampleBufferRef sampleBuffer = (CMSampleBufferRef) frame->internal;
|
||||||
|
@ -456,7 +404,7 @@ int ReleaseFrame(SDL_CameraDevice *_this, SDL_CameraFrame *frame)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetNumFormats(SDL_CameraDevice *_this)
|
static int COREMEDIA_GetNumFormats(SDL_CameraDevice *_this)
|
||||||
{
|
{
|
||||||
AVCaptureDevice *device = GetCameraDeviceByName(_this->dev_name);
|
AVCaptureDevice *device = GetCameraDeviceByName(_this->dev_name);
|
||||||
if (device) {
|
if (device) {
|
||||||
|
@ -476,7 +424,7 @@ int GetNumFormats(SDL_CameraDevice *_this)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetFormat(SDL_CameraDevice *_this, int index, Uint32 *format)
|
static int COREMEDIA_GetFormat(SDL_CameraDevice *_this, int index, Uint32 *format)
|
||||||
{
|
{
|
||||||
AVCaptureDevice *device = GetCameraDeviceByName(_this->dev_name);
|
AVCaptureDevice *device = GetCameraDeviceByName(_this->dev_name);
|
||||||
if (device) {
|
if (device) {
|
||||||
|
@ -503,7 +451,7 @@ int GetFormat(SDL_CameraDevice *_this, int index, Uint32 *format)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetNumFrameSizes(SDL_CameraDevice *_this, Uint32 format)
|
static int COREMEDIA_GetNumFrameSizes(SDL_CameraDevice *_this, Uint32 format)
|
||||||
{
|
{
|
||||||
AVCaptureDevice *device = GetCameraDeviceByName(_this->dev_name);
|
AVCaptureDevice *device = GetCameraDeviceByName(_this->dev_name);
|
||||||
if (device) {
|
if (device) {
|
||||||
|
@ -525,8 +473,7 @@ int GetNumFrameSizes(SDL_CameraDevice *_this, Uint32 format)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
static int COREMEDIA_GetFrameSize(SDL_CameraDevice *_this, Uint32 format, int index, int *width, int *height)
|
||||||
GetFrameSize(SDL_CameraDevice *_this, Uint32 format, int index, int *width, int *height)
|
|
||||||
{
|
{
|
||||||
AVCaptureDevice *device = GetCameraDeviceByName(_this->dev_name);
|
AVCaptureDevice *device = GetCameraDeviceByName(_this->dev_name);
|
||||||
if (device) {
|
if (device) {
|
||||||
|
@ -553,7 +500,7 @@ GetFrameSize(SDL_CameraDevice *_this, Uint32 format, int index, int *width, int
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetCameraDeviceName(SDL_CameraDeviceID instance_id, char *buf, int size)
|
static int COREMEDIA_GetDeviceName(SDL_CameraDeviceID instance_id, char *buf, int size)
|
||||||
{
|
{
|
||||||
int index = instance_id - 1;
|
int index = instance_id - 1;
|
||||||
NSArray<AVCaptureDevice *> *devices = DiscoverCameraDevices();
|
NSArray<AVCaptureDevice *> *devices = DiscoverCameraDevices();
|
||||||
|
@ -567,20 +514,19 @@ int GetCameraDeviceName(SDL_CameraDeviceID instance_id, char *buf, int size)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int GetNumDevices(void)
|
static int GetNumCameraDevices(void)
|
||||||
{
|
{
|
||||||
NSArray<AVCaptureDevice *> *devices = DiscoverCameraDevices();
|
NSArray<AVCaptureDevice *> *devices = DiscoverCameraDevices();
|
||||||
return [devices count];
|
return [devices count];
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_CameraDeviceID *GetCameraDevices(int *count)
|
static SDL_CameraDeviceID *COREMEDIA_GetDevices(int *count)
|
||||||
{
|
{
|
||||||
// hard-coded list of ID
|
// hard-coded list of ID
|
||||||
const int num = GetNumDevices();
|
const int num = GetNumCameraDevices();
|
||||||
SDL_CameraDeviceID *retval = (SDL_CameraDeviceID *)SDL_calloc((num + 1), sizeof(*ret));
|
SDL_CameraDeviceID *retval = (SDL_CameraDeviceID *)SDL_calloc((num + 1), sizeof(*ret));
|
||||||
|
|
||||||
if (retval == NULL) {
|
if (retval == NULL) {
|
||||||
SDL_OutOfMemory();
|
|
||||||
*count = 0;
|
*count = 0;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -593,17 +539,45 @@ SDL_CameraDeviceID *GetCameraDevices(int *count)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int SDL_SYS_CameraInit(void)
|
static void COREMEDIA_DetectDevices(void)
|
||||||
{
|
{
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int SDL_SYS_CameraQuit(void)
|
static void COREMEDIA_Deinitialize(void)
|
||||||
{
|
{
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static SDL_bool COREMEDIA_Init(SDL_CameraDriverImpl *impl)
|
||||||
|
{
|
||||||
|
#ifndef HAVE_COREMEDIA
|
||||||
|
return SDL_FALSE;
|
||||||
|
#else
|
||||||
|
impl->DetectDevices = COREMEDIA_DetectDevices;
|
||||||
|
impl->OpenDevice = COREMEDIA_OpenDevice;
|
||||||
|
impl->CloseDevice = COREMEDIA_CloseDevice;
|
||||||
|
impl->InitDevice = COREMEDIA_InitDevice;
|
||||||
|
impl->GetDeviceSpec = COREMEDIA_GetDeviceSpec;
|
||||||
|
impl->StartCamera = COREMEDIA_StartCamera;
|
||||||
|
impl->StopCamera = COREMEDIA_StopCamera;
|
||||||
|
impl->AcquireFrame = COREMEDIA_AcquireFrame;
|
||||||
|
impl->ReleaseFrame = COREMEDIA_ReleaseFrame;
|
||||||
|
impl->GetNumFormats = COREMEDIA_GetNumFormats;
|
||||||
|
impl->GetFormat = COREMEDIA_GetFormat;
|
||||||
|
impl->GetNumFrameSizes = COREMEDIA_GetNumFrameSizes;
|
||||||
|
impl->GetFrameSize = COREMEDIA_GetFrameSize;
|
||||||
|
impl->GetDeviceName = COREMEDIA_GetDeviceName;
|
||||||
|
impl->GetDevices = COREMEDIA_GetDevices;
|
||||||
|
impl->Deinitialize = COREMEDIA_Deinitialize;
|
||||||
|
|
||||||
|
return SDL_TRUE;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
CameraBootStrap COREMEDIA_bootstrap = {
|
||||||
|
"coremedia", "SDL Apple CoreMedia camera driver", COREMEDIA_Init, SDL_FALSE
|
||||||
|
};
|
||||||
|
|
||||||
#endif // HAVE_COREMEDIA
|
#endif // HAVE_COREMEDIA
|
||||||
|
|
||||||
#endif // SDL_CAMERA_APPLE
|
#endif // SDL_CAMERA_COREMEDIA
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
*/
|
*/
|
||||||
#include "SDL_internal.h"
|
#include "SDL_internal.h"
|
||||||
|
|
||||||
#ifdef SDL_CAMERA_V4L2
|
#ifdef SDL_CAMERA_DRIVER_V4L2
|
||||||
|
|
||||||
#include "../SDL_syscamera.h"
|
#include "../SDL_syscamera.h"
|
||||||
#include "../SDL_camera_c.h"
|
#include "../SDL_camera_c.h"
|
||||||
|
@ -30,8 +30,6 @@
|
||||||
#include "../../core/linux/SDL_udev.h"
|
#include "../../core/linux/SDL_udev.h"
|
||||||
#include <limits.h> // INT_MAX
|
#include <limits.h> // INT_MAX
|
||||||
|
|
||||||
#define DEBUG_CAMERA 1
|
|
||||||
|
|
||||||
#define MAX_CAMERA_DEVICES 128 // It's doubtful someone has more than that
|
#define MAX_CAMERA_DEVICES 128 // It's doubtful someone has more than that
|
||||||
|
|
||||||
static int MaybeAddDevice(const char *path);
|
static int MaybeAddDevice(const char *path);
|
||||||
|
@ -206,7 +204,7 @@ static int acquire_frame(SDL_CameraDevice *_this, SDL_CameraFrame *frame)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int ReleaseFrame(SDL_CameraDevice *_this, SDL_CameraFrame *frame)
|
static int V4L2_ReleaseFrame(SDL_CameraDevice *_this, SDL_CameraFrame *frame)
|
||||||
{
|
{
|
||||||
struct v4l2_buffer buf;
|
struct v4l2_buffer buf;
|
||||||
const int fd = _this->hidden->fd;
|
const int fd = _this->hidden->fd;
|
||||||
|
@ -259,8 +257,7 @@ int ReleaseFrame(SDL_CameraDevice *_this, SDL_CameraFrame *frame)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int V4L2_AcquireFrame(SDL_CameraDevice *_this, SDL_CameraFrame *frame)
|
||||||
int AcquireFrame(SDL_CameraDevice *_this, SDL_CameraFrame *frame)
|
|
||||||
{
|
{
|
||||||
fd_set fds;
|
fd_set fds;
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
|
@ -310,7 +307,7 @@ int AcquireFrame(SDL_CameraDevice *_this, SDL_CameraFrame *frame)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int StopCamera(SDL_CameraDevice *_this)
|
static int V4L2_StopCamera(SDL_CameraDevice *_this)
|
||||||
{
|
{
|
||||||
enum v4l2_buf_type type;
|
enum v4l2_buf_type type;
|
||||||
const int fd = _this->hidden->fd;
|
const int fd = _this->hidden->fd;
|
||||||
|
@ -428,7 +425,7 @@ static int PreEnqueueBuffers(SDL_CameraDevice *_this)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int StartCamera(SDL_CameraDevice *_this)
|
static int V4L2_StartCamera(SDL_CameraDevice *_this)
|
||||||
{
|
{
|
||||||
enum v4l2_buf_type type;
|
enum v4l2_buf_type type;
|
||||||
|
|
||||||
|
@ -476,15 +473,10 @@ static int AllocBufferRead(SDL_CameraDevice *_this, size_t buffer_size)
|
||||||
{
|
{
|
||||||
_this->hidden->buffers[0].length = buffer_size;
|
_this->hidden->buffers[0].length = buffer_size;
|
||||||
_this->hidden->buffers[0].start = SDL_calloc(1, buffer_size);
|
_this->hidden->buffers[0].start = SDL_calloc(1, buffer_size);
|
||||||
|
return _this->hidden->buffers[0].start ? 0 : -1;
|
||||||
if (!_this->hidden->buffers[0].start) {
|
|
||||||
return SDL_OutOfMemory();
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int AllocBufferMmap(SDL_CameraDevice *_this)
|
||||||
AllocBufferMmap(SDL_CameraDevice *_this)
|
|
||||||
{
|
{
|
||||||
int fd = _this->hidden->fd;
|
int fd = _this->hidden->fd;
|
||||||
int i;
|
int i;
|
||||||
|
@ -516,8 +508,7 @@ AllocBufferMmap(SDL_CameraDevice *_this)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int AllocBufferUserPtr(SDL_CameraDevice *_this, size_t buffer_size)
|
||||||
AllocBufferUserPtr(SDL_CameraDevice *_this, size_t buffer_size)
|
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < _this->hidden->nb_buffers; ++i) {
|
for (i = 0; i < _this->hidden->nb_buffers; ++i) {
|
||||||
|
@ -525,41 +516,38 @@ AllocBufferUserPtr(SDL_CameraDevice *_this, size_t buffer_size)
|
||||||
_this->hidden->buffers[i].start = SDL_calloc(1, buffer_size);
|
_this->hidden->buffers[i].start = SDL_calloc(1, buffer_size);
|
||||||
|
|
||||||
if (!_this->hidden->buffers[i].start) {
|
if (!_this->hidden->buffers[i].start) {
|
||||||
return SDL_OutOfMemory();
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Uint32
|
static Uint32 format_v4l2_to_sdl(Uint32 fmt)
|
||||||
format_v4l2_2_sdl(Uint32 fmt)
|
|
||||||
{
|
{
|
||||||
switch (fmt) {
|
switch (fmt) {
|
||||||
#define CASE(x, y) case x: return y
|
#define CASE(x, y) case x: return y
|
||||||
CASE(V4L2_PIX_FMT_YUYV, SDL_PIXELFORMAT_YUY2);
|
CASE(V4L2_PIX_FMT_YUYV, SDL_PIXELFORMAT_YUY2);
|
||||||
CASE(V4L2_PIX_FMT_MJPEG, SDL_PIXELFORMAT_UNKNOWN);
|
CASE(V4L2_PIX_FMT_MJPEG, SDL_PIXELFORMAT_UNKNOWN);
|
||||||
#undef CASE
|
#undef CASE
|
||||||
default:
|
default:
|
||||||
SDL_Log("Unknown format V4L2_PIX_FORMAT '%d'", fmt);
|
SDL_Log("Unknown format V4L2_PIX_FORMAT '%d'", fmt);
|
||||||
return SDL_PIXELFORMAT_UNKNOWN;
|
return SDL_PIXELFORMAT_UNKNOWN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static Uint32
|
static Uint32 format_sdl_to_v4l2(Uint32 fmt)
|
||||||
format_sdl_2_v4l2(Uint32 fmt)
|
|
||||||
{
|
{
|
||||||
switch (fmt) {
|
switch (fmt) {
|
||||||
#define CASE(y, x) case x: return y
|
#define CASE(y, x) case x: return y
|
||||||
CASE(V4L2_PIX_FMT_YUYV, SDL_PIXELFORMAT_YUY2);
|
CASE(V4L2_PIX_FMT_YUYV, SDL_PIXELFORMAT_YUY2);
|
||||||
CASE(V4L2_PIX_FMT_MJPEG, SDL_PIXELFORMAT_UNKNOWN);
|
CASE(V4L2_PIX_FMT_MJPEG, SDL_PIXELFORMAT_UNKNOWN);
|
||||||
#undef CASE
|
#undef CASE
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
static int V4L2_GetNumFormats(SDL_CameraDevice *_this)
|
||||||
GetNumFormats(SDL_CameraDevice *_this)
|
|
||||||
{
|
{
|
||||||
int fd = _this->hidden->fd;
|
int fd = _this->hidden->fd;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
@ -574,8 +562,7 @@ GetNumFormats(SDL_CameraDevice *_this)
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
static int V4L2_GetFormat(SDL_CameraDevice *_this, int index, Uint32 *format)
|
||||||
GetFormat(SDL_CameraDevice *_this, int index, Uint32 *format)
|
|
||||||
{
|
{
|
||||||
int fd = _this->hidden->fd;
|
int fd = _this->hidden->fd;
|
||||||
struct v4l2_fmtdesc fmtdesc;
|
struct v4l2_fmtdesc fmtdesc;
|
||||||
|
@ -584,7 +571,7 @@ GetFormat(SDL_CameraDevice *_this, int index, Uint32 *format)
|
||||||
fmtdesc.index = index;
|
fmtdesc.index = index;
|
||||||
fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||||
if (ioctl(fd,VIDIOC_ENUM_FMT,&fmtdesc) == 0) {
|
if (ioctl(fd,VIDIOC_ENUM_FMT,&fmtdesc) == 0) {
|
||||||
*format = format_v4l2_2_sdl(fmtdesc.pixelformat);
|
*format = format_v4l2_to_sdl(fmtdesc.pixelformat);
|
||||||
|
|
||||||
#if DEBUG_CAMERA
|
#if DEBUG_CAMERA
|
||||||
if (fmtdesc.flags & V4L2_FMT_FLAG_EMULATED) {
|
if (fmtdesc.flags & V4L2_FMT_FLAG_EMULATED) {
|
||||||
|
@ -600,8 +587,7 @@ GetFormat(SDL_CameraDevice *_this, int index, Uint32 *format)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
static int V4L2_GetNumFrameSizes(SDL_CameraDevice *_this, Uint32 format)
|
||||||
GetNumFrameSizes(SDL_CameraDevice *_this, Uint32 format)
|
|
||||||
{
|
{
|
||||||
int fd = _this->hidden->fd;
|
int fd = _this->hidden->fd;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
@ -609,7 +595,7 @@ GetNumFrameSizes(SDL_CameraDevice *_this, Uint32 format)
|
||||||
|
|
||||||
SDL_zero(frmsizeenum);
|
SDL_zero(frmsizeenum);
|
||||||
frmsizeenum.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
frmsizeenum.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||||
frmsizeenum.pixel_format = format_sdl_2_v4l2(format);
|
frmsizeenum.pixel_format = format_sdl_to_v4l2(format);
|
||||||
while (ioctl(fd,VIDIOC_ENUM_FRAMESIZES, &frmsizeenum) == 0) {
|
while (ioctl(fd,VIDIOC_ENUM_FRAMESIZES, &frmsizeenum) == 0) {
|
||||||
frmsizeenum.index++;
|
frmsizeenum.index++;
|
||||||
if (frmsizeenum.type == V4L2_FRMSIZE_TYPE_DISCRETE) {
|
if (frmsizeenum.type == V4L2_FRMSIZE_TYPE_DISCRETE) {
|
||||||
|
@ -624,8 +610,7 @@ GetNumFrameSizes(SDL_CameraDevice *_this, Uint32 format)
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
static int V4L2_GetFrameSize(SDL_CameraDevice *_this, Uint32 format, int index, int *width, int *height)
|
||||||
GetFrameSize(SDL_CameraDevice *_this, Uint32 format, int index, int *width, int *height)
|
|
||||||
{
|
{
|
||||||
int fd = _this->hidden->fd;
|
int fd = _this->hidden->fd;
|
||||||
struct v4l2_frmsizeenum frmsizeenum;
|
struct v4l2_frmsizeenum frmsizeenum;
|
||||||
|
@ -633,7 +618,7 @@ GetFrameSize(SDL_CameraDevice *_this, Uint32 format, int index, int *width, int
|
||||||
|
|
||||||
SDL_zero(frmsizeenum);
|
SDL_zero(frmsizeenum);
|
||||||
frmsizeenum.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
frmsizeenum.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
|
||||||
frmsizeenum.pixel_format = format_sdl_2_v4l2(format);
|
frmsizeenum.pixel_format = format_sdl_to_v4l2(format);
|
||||||
while (ioctl(fd,VIDIOC_ENUM_FRAMESIZES, &frmsizeenum) == 0) {
|
while (ioctl(fd,VIDIOC_ENUM_FRAMESIZES, &frmsizeenum) == 0) {
|
||||||
frmsizeenum.index++;
|
frmsizeenum.index++;
|
||||||
|
|
||||||
|
@ -663,12 +648,8 @@ GetFrameSize(SDL_CameraDevice *_this, Uint32 format, int index, int *width, int
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
static void dbg_v4l2_pixelformat(const char *str, int f)
|
||||||
|
{
|
||||||
|
|
||||||
#if DEBUG_VIDEO_CAPTURE_CAPTURE
|
|
||||||
static void
|
|
||||||
dbg_v4l2_pixelformat(const char *str, int f) {
|
|
||||||
SDL_Log("%s V4L2_format=%d %c%c%c%c", str, f,
|
SDL_Log("%s V4L2_format=%d %c%c%c%c", str, f,
|
||||||
(f >> 0) & 0xff,
|
(f >> 0) & 0xff,
|
||||||
(f >> 8) & 0xff,
|
(f >> 8) & 0xff,
|
||||||
|
@ -677,8 +658,7 @@ dbg_v4l2_pixelformat(const char *str, int f) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int
|
static int V4L2_GetDeviceSpec(SDL_CameraDevice *_this, SDL_CameraSpec *spec)
|
||||||
GetDeviceSpec(SDL_CameraDevice *_this, SDL_CameraSpec *spec)
|
|
||||||
{
|
{
|
||||||
struct v4l2_format fmt;
|
struct v4l2_format fmt;
|
||||||
int fd = _this->hidden->fd;
|
int fd = _this->hidden->fd;
|
||||||
|
@ -705,13 +685,12 @@ GetDeviceSpec(SDL_CameraDevice *_this, SDL_CameraSpec *spec)
|
||||||
//spec->width = fmt.fmt.pix.width;
|
//spec->width = fmt.fmt.pix.width;
|
||||||
//spec->height = fmt.fmt.pix.height;
|
//spec->height = fmt.fmt.pix.height;
|
||||||
_this->hidden->driver_pitch = fmt.fmt.pix.bytesperline;
|
_this->hidden->driver_pitch = fmt.fmt.pix.bytesperline;
|
||||||
//spec->format = format_v4l2_2_sdl(fmt.fmt.pix.pixelformat);
|
//spec->format = format_v4l2_to_sdl(fmt.fmt.pix.pixelformat);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
static int V4L2_InitDevice(SDL_CameraDevice *_this)
|
||||||
InitDevice(SDL_CameraDevice *_this)
|
|
||||||
{
|
{
|
||||||
struct v4l2_cropcap cropcap;
|
struct v4l2_cropcap cropcap;
|
||||||
struct v4l2_crop crop;
|
struct v4l2_crop crop;
|
||||||
|
@ -753,7 +732,7 @@ InitDevice(SDL_CameraDevice *_this)
|
||||||
fmt.fmt.pix.height = _this->spec.height;
|
fmt.fmt.pix.height = _this->spec.height;
|
||||||
|
|
||||||
|
|
||||||
fmt.fmt.pix.pixelformat = format_sdl_2_v4l2(_this->spec.format);
|
fmt.fmt.pix.pixelformat = format_sdl_to_v4l2(_this->spec.format);
|
||||||
// fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
|
// fmt.fmt.pix.field = V4L2_FIELD_INTERLACED;
|
||||||
fmt.fmt.pix.field = V4L2_FIELD_ANY;
|
fmt.fmt.pix.field = V4L2_FIELD_ANY;
|
||||||
|
|
||||||
|
@ -767,7 +746,7 @@ InitDevice(SDL_CameraDevice *_this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GetDeviceSpec(_this, &_this->spec);
|
V4L2_GetDeviceSpec(_this, &_this->spec);
|
||||||
|
|
||||||
if (PreEnqueueBuffers(_this) < 0) {
|
if (PreEnqueueBuffers(_this) < 0) {
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -776,7 +755,7 @@ InitDevice(SDL_CameraDevice *_this)
|
||||||
{
|
{
|
||||||
_this->hidden->buffers = SDL_calloc(_this->hidden->nb_buffers, sizeof(*_this->hidden->buffers));
|
_this->hidden->buffers = SDL_calloc(_this->hidden->nb_buffers, sizeof(*_this->hidden->buffers));
|
||||||
if (!_this->hidden->buffers) {
|
if (!_this->hidden->buffers) {
|
||||||
return SDL_OutOfMemory();
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -802,7 +781,7 @@ InitDevice(SDL_CameraDevice *_this)
|
||||||
return (retval < 0) ? -1 : 0;
|
return (retval < 0) ? -1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CloseDevice(SDL_CameraDevice *_this)
|
static void V4L2_CloseDevice(SDL_CameraDevice *_this)
|
||||||
{
|
{
|
||||||
if (!_this) {
|
if (!_this) {
|
||||||
return;
|
return;
|
||||||
|
@ -846,8 +825,7 @@ void CloseDevice(SDL_CameraDevice *_this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int V4L2_OpenDevice(SDL_CameraDevice *_this)
|
||||||
int OpenDevice(SDL_CameraDevice *_this)
|
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
struct v4l2_capability cap;
|
struct v4l2_capability cap;
|
||||||
|
@ -856,7 +834,6 @@ int OpenDevice(SDL_CameraDevice *_this)
|
||||||
|
|
||||||
_this->hidden = (struct SDL_PrivateCameraData *) SDL_calloc(1, sizeof (struct SDL_PrivateCameraData));
|
_this->hidden = (struct SDL_PrivateCameraData *) SDL_calloc(1, sizeof (struct SDL_PrivateCameraData));
|
||||||
if (_this->hidden == NULL) {
|
if (_this->hidden == NULL) {
|
||||||
SDL_OutOfMemory();
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -921,7 +898,7 @@ int OpenDevice(SDL_CameraDevice *_this)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int GetCameraDeviceName(SDL_CameraDeviceID instance_id, char *buf, int size)
|
static int V4L2_GetDeviceName(SDL_CameraDeviceID instance_id, char *buf, int size)
|
||||||
{
|
{
|
||||||
SDL_cameralist_item *item;
|
SDL_cameralist_item *item;
|
||||||
for (item = SDL_cameralist; item; item = item->next) {
|
for (item = SDL_cameralist; item; item = item->next) {
|
||||||
|
@ -935,15 +912,13 @@ int GetCameraDeviceName(SDL_CameraDeviceID instance_id, char *buf, int size)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static SDL_CameraDeviceID *V4L2_GetDevices(int *count)
|
||||||
SDL_CameraDeviceID *GetCameraDevices(int *count)
|
|
||||||
{
|
{
|
||||||
// real list of ID
|
// real list of ID
|
||||||
const int num = num_cameras;
|
const int num = num_cameras;
|
||||||
SDL_CameraDeviceID *retval = (SDL_CameraDeviceID *)SDL_malloc((num + 1) * sizeof(*retval));
|
SDL_CameraDeviceID *retval = (SDL_CameraDeviceID *)SDL_malloc((num + 1) * sizeof(*retval));
|
||||||
|
|
||||||
if (retval == NULL) {
|
if (retval == NULL) {
|
||||||
SDL_OutOfMemory();
|
|
||||||
*count = 0;
|
*count = 0;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -959,55 +934,6 @@ SDL_CameraDeviceID *GetCameraDevices(int *count)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Initializes the subsystem by finding available devices.
|
|
||||||
int SDL_SYS_CameraInit(void)
|
|
||||||
{
|
|
||||||
const char pattern[] = "/dev/video%d";
|
|
||||||
char path[PATH_MAX];
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Limit amount of checks to MAX_CAMERA_DEVICES since we may or may not have
|
|
||||||
* permission to some or all devices.
|
|
||||||
*/
|
|
||||||
for (int i = 0; i < MAX_CAMERA_DEVICES; i++) {
|
|
||||||
(void)SDL_snprintf(path, PATH_MAX, pattern, i);
|
|
||||||
if (MaybeAddDevice(path) == -2) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef SDL_USE_LIBUDEV
|
|
||||||
if (SDL_UDEV_Init() < 0) {
|
|
||||||
return SDL_SetError("Could not initialize UDEV");
|
|
||||||
} else if (SDL_UDEV_AddCallback(CameraUdevCallback) < 0) {
|
|
||||||
SDL_UDEV_Quit();
|
|
||||||
return SDL_SetError("Could not setup Video Capture <-> udev callback");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Force a scan to build the initial device list
|
|
||||||
SDL_UDEV_Scan();
|
|
||||||
#endif // SDL_USE_LIBUDEV
|
|
||||||
|
|
||||||
return num_cameras;
|
|
||||||
}
|
|
||||||
|
|
||||||
int SDL_SYS_CameraQuit(void)
|
|
||||||
{
|
|
||||||
for (SDL_cameralist_item *item = SDL_cameralist; item; ) {
|
|
||||||
SDL_cameralist_item *tmp = item->next;
|
|
||||||
SDL_free(item->fname);
|
|
||||||
SDL_free(item->bus_info);
|
|
||||||
SDL_free(item);
|
|
||||||
item = tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
num_cameras = 0;
|
|
||||||
SDL_cameralist = NULL;
|
|
||||||
SDL_cameralist_tail = NULL;
|
|
||||||
|
|
||||||
return SDL_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef SDL_USE_LIBUDEV
|
#ifdef SDL_USE_LIBUDEV
|
||||||
static void CameraUdevCallback(SDL_UDEV_deviceevent udev_type, int udev_class, const char *devpath)
|
static void CameraUdevCallback(SDL_UDEV_deviceevent udev_type, int udev_class, const char *devpath)
|
||||||
{
|
{
|
||||||
|
@ -1150,5 +1076,78 @@ static int MaybeRemoveDevice(const char *path)
|
||||||
}
|
}
|
||||||
#endif // SDL_USE_LIBUDEV
|
#endif // SDL_USE_LIBUDEV
|
||||||
|
|
||||||
|
|
||||||
|
static void V4L2_Deinitialize(void)
|
||||||
|
{
|
||||||
|
for (SDL_cameralist_item *item = SDL_cameralist; item; ) {
|
||||||
|
SDL_cameralist_item *tmp = item->next;
|
||||||
|
SDL_free(item->fname);
|
||||||
|
SDL_free(item->bus_info);
|
||||||
|
SDL_free(item);
|
||||||
|
item = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
num_cameras = 0;
|
||||||
|
SDL_cameralist = NULL;
|
||||||
|
SDL_cameralist_tail = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void V4L2_DetectDevices(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static SDL_bool V4L2_Init(SDL_CameraDriverImpl *impl)
|
||||||
|
{
|
||||||
|
// !!! FIXME: move to DetectDevices
|
||||||
|
const char pattern[] = "/dev/video%d";
|
||||||
|
char path[PATH_MAX];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Limit amount of checks to MAX_CAMERA_DEVICES since we may or may not have
|
||||||
|
* permission to some or all devices.
|
||||||
|
*/
|
||||||
|
for (int i = 0; i < MAX_CAMERA_DEVICES; i++) {
|
||||||
|
(void)SDL_snprintf(path, PATH_MAX, pattern, i);
|
||||||
|
if (MaybeAddDevice(path) == -2) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef SDL_USE_LIBUDEV
|
||||||
|
if (SDL_UDEV_Init() < 0) {
|
||||||
|
return SDL_SetError("Could not initialize UDEV");
|
||||||
|
} else if (SDL_UDEV_AddCallback(CameraUdevCallback) < 0) {
|
||||||
|
SDL_UDEV_Quit();
|
||||||
|
return SDL_SetError("Could not setup Video Capture <-> udev callback");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Force a scan to build the initial device list
|
||||||
|
SDL_UDEV_Scan();
|
||||||
|
#endif // SDL_USE_LIBUDEV
|
||||||
|
|
||||||
|
impl->DetectDevices = V4L2_DetectDevices;
|
||||||
|
impl->OpenDevice = V4L2_OpenDevice;
|
||||||
|
impl->CloseDevice = V4L2_CloseDevice;
|
||||||
|
impl->InitDevice = V4L2_InitDevice;
|
||||||
|
impl->GetDeviceSpec = V4L2_GetDeviceSpec;
|
||||||
|
impl->StartCamera = V4L2_StartCamera;
|
||||||
|
impl->StopCamera = V4L2_StopCamera;
|
||||||
|
impl->AcquireFrame = V4L2_AcquireFrame;
|
||||||
|
impl->ReleaseFrame = V4L2_ReleaseFrame;
|
||||||
|
impl->GetNumFormats = V4L2_GetNumFormats;
|
||||||
|
impl->GetFormat = V4L2_GetFormat;
|
||||||
|
impl->GetNumFrameSizes = V4L2_GetNumFrameSizes;
|
||||||
|
impl->GetFrameSize = V4L2_GetFrameSize;
|
||||||
|
impl->GetDeviceName = V4L2_GetDeviceName;
|
||||||
|
impl->GetDevices = V4L2_GetDevices;
|
||||||
|
impl->Deinitialize = V4L2_Deinitialize;
|
||||||
|
|
||||||
|
return SDL_TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
CameraBootStrap V4L2_bootstrap = {
|
||||||
|
"v4l2", "SDL Video4Linux2 camera driver", V4L2_Init, SDL_FALSE
|
||||||
|
};
|
||||||
|
|
||||||
#endif // SDL_CAMERA_V4L2
|
#endif // SDL_CAMERA_V4L2
|
||||||
|
|
||||||
|
|
|
@ -458,7 +458,6 @@ int SDL_VideoInit(const char *driver_name)
|
||||||
SDL_bool init_keyboard = SDL_FALSE;
|
SDL_bool init_keyboard = SDL_FALSE;
|
||||||
SDL_bool init_mouse = SDL_FALSE;
|
SDL_bool init_mouse = SDL_FALSE;
|
||||||
SDL_bool init_touch = SDL_FALSE;
|
SDL_bool init_touch = SDL_FALSE;
|
||||||
SDL_bool init_camera = SDL_FALSE;
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
/* Check to make sure we don't overwrite '_this' */
|
/* Check to make sure we don't overwrite '_this' */
|
||||||
|
@ -485,10 +484,6 @@ int SDL_VideoInit(const char *driver_name)
|
||||||
goto pre_driver_error;
|
goto pre_driver_error;
|
||||||
}
|
}
|
||||||
init_touch = SDL_TRUE;
|
init_touch = SDL_TRUE;
|
||||||
if (SDL_CameraInit() < 0) {
|
|
||||||
goto pre_driver_error;
|
|
||||||
}
|
|
||||||
init_camera = SDL_TRUE;
|
|
||||||
|
|
||||||
/* Select the proper video driver */
|
/* Select the proper video driver */
|
||||||
video = NULL;
|
video = NULL;
|
||||||
|
@ -590,9 +585,6 @@ int SDL_VideoInit(const char *driver_name)
|
||||||
|
|
||||||
pre_driver_error:
|
pre_driver_error:
|
||||||
SDL_assert(_this == NULL);
|
SDL_assert(_this == NULL);
|
||||||
if (init_camera) {
|
|
||||||
SDL_QuitCamera();
|
|
||||||
}
|
|
||||||
if (init_touch) {
|
if (init_touch) {
|
||||||
SDL_QuitTouch();
|
SDL_QuitTouch();
|
||||||
}
|
}
|
||||||
|
@ -3784,7 +3776,6 @@ void SDL_VideoQuit(void)
|
||||||
SDL_ClearClipboardData();
|
SDL_ClearClipboardData();
|
||||||
|
|
||||||
/* Halt event processing before doing anything else */
|
/* Halt event processing before doing anything else */
|
||||||
SDL_QuitCamera();
|
|
||||||
SDL_QuitTouch();
|
SDL_QuitTouch();
|
||||||
SDL_QuitMouse();
|
SDL_QuitMouse();
|
||||||
SDL_QuitKeyboard();
|
SDL_QuitKeyboard();
|
||||||
|
|
|
@ -213,7 +213,7 @@ int main(int argc, char **argv)
|
||||||
SDL_Log("%s", usage);
|
SDL_Log("%s", usage);
|
||||||
|
|
||||||
/* Load the SDL library */
|
/* Load the SDL library */
|
||||||
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) < 0) { /* FIXME: SDL_INIT_JOYSTICK needed for add/removing devices at runtime */
|
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_CAMERA) < 0) {
|
||||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s", SDL_GetError());
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s", SDL_GetError());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,7 +54,7 @@ int main(int argc, char **argv)
|
||||||
SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
|
SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
|
||||||
|
|
||||||
/* Load the SDL library */
|
/* Load the SDL library */
|
||||||
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) < 0) { /* FIXME: SDL_INIT_JOYSTICK needed for add/removing devices at runtime */
|
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_CAMERA) < 0) {
|
||||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s", SDL_GetError());
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s", SDL_GetError());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue