SDL_VideoCapture: allow add/remove device at runtime on linux
parent
f0e47f8ee0
commit
6bb40f1d8d
|
@ -53,6 +53,7 @@ typedef enum
|
|||
SDL_UDEV_DEVICE_ACCELEROMETER = 0x0020,
|
||||
SDL_UDEV_DEVICE_TOUCHPAD = 0x0040,
|
||||
SDL_UDEV_DEVICE_HAS_KEYS = 0x0080,
|
||||
SDL_UDEV_DEVICE_VIDEO_CAPTURE = 0x0100,
|
||||
} SDL_UDEV_deviceclass;
|
||||
|
||||
#define BITS_PER_LONG (sizeof(unsigned long) * 8)
|
||||
|
|
|
@ -139,6 +139,7 @@ int SDL_UDEV_Init(void)
|
|||
|
||||
_this->syms.udev_monitor_filter_add_match_subsystem_devtype(_this->udev_mon, "input", NULL);
|
||||
_this->syms.udev_monitor_filter_add_match_subsystem_devtype(_this->udev_mon, "sound", NULL);
|
||||
_this->syms.udev_monitor_filter_add_match_subsystem_devtype(_this->udev_mon, "video4linux", NULL);
|
||||
_this->syms.udev_monitor_enable_receiving(_this->udev_mon);
|
||||
|
||||
/* Do an initial scan of existing devices */
|
||||
|
@ -200,6 +201,7 @@ int SDL_UDEV_Scan(void)
|
|||
|
||||
_this->syms.udev_enumerate_add_match_subsystem(enumerate, "input");
|
||||
_this->syms.udev_enumerate_add_match_subsystem(enumerate, "sound");
|
||||
_this->syms.udev_enumerate_add_match_subsystem(enumerate, "video4linux");
|
||||
|
||||
_this->syms.udev_enumerate_scan_devices(enumerate);
|
||||
devs = _this->syms.udev_enumerate_get_list_entry(enumerate);
|
||||
|
@ -405,8 +407,16 @@ static void device_event(SDL_UDEV_deviceevent type, struct udev_device *dev)
|
|||
}
|
||||
|
||||
subsystem = _this->syms.udev_device_get_subsystem(dev);
|
||||
|
||||
if (SDL_strcmp(subsystem, "sound") == 0) {
|
||||
devclass = SDL_UDEV_DEVICE_SOUND;
|
||||
} else if (SDL_strcmp(subsystem, "video4linux") == 0) {
|
||||
devclass = SDL_UDEV_DEVICE_VIDEO_CAPTURE;
|
||||
|
||||
val = _this->syms.udev_device_get_property_value(dev, "ID_V4L_CAPABILITIES");
|
||||
if (!val || !SDL_strcasestr(val, "capture")) {
|
||||
return;
|
||||
}
|
||||
} else if (SDL_strcmp(subsystem, "input") == 0) {
|
||||
/* udev rules reference: http://cgit.freedesktop.org/systemd/systemd/tree/src/udev/udev-builtin-input_id.c */
|
||||
|
||||
|
|
|
@ -61,6 +61,9 @@ struct SDL_VideoCaptureDevice
|
|||
struct SDL_PrivateVideoCaptureData *hidden;
|
||||
};
|
||||
|
||||
extern int SDL_SYS_VideoCaptureInit(void);
|
||||
extern int SDL_SYS_VideoCaptureQuit(void);
|
||||
|
||||
extern int OpenDevice(SDL_VideoCaptureDevice *_this);
|
||||
extern void CloseDevice(SDL_VideoCaptureDevice *_this);
|
||||
|
||||
|
@ -80,9 +83,8 @@ extern int GetFormat(SDL_VideoCaptureDevice *_this, int index, Uint32 *format);
|
|||
extern int GetNumFrameSizes(SDL_VideoCaptureDevice *_this, Uint32 format);
|
||||
extern int GetFrameSize(SDL_VideoCaptureDevice *_this, Uint32 format, int index, int *width, int *height);
|
||||
|
||||
extern int GetDeviceName(int index, char *buf, int size);
|
||||
extern int GetNumDevices(void);
|
||||
|
||||
extern int GetDeviceName(SDL_VideoCaptureDeviceID instance_id, char *buf, int size);
|
||||
extern SDL_VideoCaptureDeviceID *GetVideoCaptureDevices(int *count);
|
||||
|
||||
extern SDL_bool check_all_device_closed(void);
|
||||
extern SDL_bool check_device_playing(void);
|
||||
|
|
|
@ -311,7 +311,6 @@ const char *
|
|||
SDL_GetVideoCaptureDeviceName(SDL_VideoCaptureDeviceID instance_id)
|
||||
{
|
||||
#ifdef SDL_VIDEO_CAPTURE
|
||||
int index = instance_id - 1;
|
||||
static char buf[256];
|
||||
buf[0] = 0;
|
||||
buf[255] = 0;
|
||||
|
@ -321,7 +320,7 @@ SDL_GetVideoCaptureDeviceName(SDL_VideoCaptureDeviceID instance_id)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (GetDeviceName(index, buf, sizeof (buf)) < 0) {
|
||||
if (GetDeviceName(instance_id, buf, sizeof (buf)) < 0) {
|
||||
buf[0] = 0;
|
||||
}
|
||||
return buf;
|
||||
|
@ -336,14 +335,21 @@ SDL_VideoCaptureDeviceID *
|
|||
SDL_GetVideoCaptureDevices(int *count)
|
||||
{
|
||||
|
||||
int i;
|
||||
#ifdef SDL_VIDEO_CAPTURE
|
||||
int num = GetNumDevices();
|
||||
#else
|
||||
int num = 0;
|
||||
SDL_VideoCaptureDeviceID *ret = NULL;
|
||||
#ifdef SDL_VIDEO_CAPTURE
|
||||
ret = GetVideoCaptureDevices(&num);
|
||||
#endif
|
||||
SDL_VideoCaptureDeviceID *ret;
|
||||
|
||||
if (ret) {
|
||||
if (count) {
|
||||
*count = num;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* return list of 0 ID, null terminated */
|
||||
num = 0;
|
||||
ret = (SDL_VideoCaptureDeviceID *)SDL_malloc((num + 1) * sizeof(*ret));
|
||||
|
||||
if (ret == NULL) {
|
||||
|
@ -354,11 +360,7 @@ SDL_GetVideoCaptureDevices(int *count)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
ret[i] = i + 1;
|
||||
}
|
||||
ret[num] = 0;
|
||||
|
||||
if (count) {
|
||||
*count = num;
|
||||
}
|
||||
|
@ -501,6 +503,8 @@ SDL_OpenVideoCapture(SDL_VideoCaptureDeviceID instance_id)
|
|||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
// FIXME do we need this ?
|
||||
/* Let the user override. */
|
||||
{
|
||||
const char *dev = SDL_getenv("SDL_VIDEO_CAPTURE_DEVICE_NAME");
|
||||
|
@ -508,6 +512,7 @@ SDL_OpenVideoCapture(SDL_VideoCaptureDeviceID instance_id)
|
|||
device_name = dev;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (device_name == NULL) {
|
||||
goto error;
|
||||
|
@ -823,6 +828,8 @@ SDL_VideoCaptureInit(void)
|
|||
{
|
||||
#ifdef SDL_VIDEO_CAPTURE
|
||||
SDL_zeroa(open_devices);
|
||||
|
||||
SDL_SYS_VideoCaptureInit();
|
||||
return 0;
|
||||
#else
|
||||
return 0;
|
||||
|
@ -839,6 +846,8 @@ SDL_QuitVideoCapture(void)
|
|||
}
|
||||
|
||||
SDL_zeroa(open_devices);
|
||||
|
||||
SDL_SYS_VideoCaptureQuit();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -857,6 +866,16 @@ SDL_QuitVideoCapture(void)
|
|||
/* See SDL_video_capture_apple.m */
|
||||
#else
|
||||
|
||||
int SDL_SYS_VideoCaptureInit(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SDL_SYS_VideoCaptureQuit(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
OpenDevice(SDL_VideoCaptureDevice *_this)
|
||||
{
|
||||
|
@ -933,16 +952,17 @@ GetFrameSize(SDL_VideoCaptureDevice *_this, Uint32 format, int index, int *width
|
|||
}
|
||||
|
||||
int
|
||||
GetDeviceName(int index, char *buf, int size)
|
||||
GetDeviceName(SDL_VideoCaptureDeviceID instance_id, char *buf, int size)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
GetNumDevices(void)
|
||||
SDL_VideoCaptureDeviceID *
|
||||
GetVideoCaptureDevices(int *count)
|
||||
{
|
||||
return -1;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* SDL_VIDEO_CAPTURE */
|
||||
|
|
|
@ -49,7 +49,7 @@ int AcquireFrame(SDL_VideoCaptureDevice *_this, SDL_VideoCaptureFrame *frame) {
|
|||
}
|
||||
void CloseDevice(SDL_VideoCaptureDevice *_this) {
|
||||
}
|
||||
int GetDeviceName(int index, char *buf, int size) {
|
||||
int GetDeviceName(SDL_VideoCaptureDeviceID instance_id, char *buf, int size) {
|
||||
return -1;
|
||||
}
|
||||
int GetDeviceSpec(SDL_VideoCaptureDevice *_this, SDL_VideoCaptureSpec *spec) {
|
||||
|
@ -61,8 +61,8 @@ int GetFormat(SDL_VideoCaptureDevice *_this, int index, Uint32 *format) {
|
|||
int GetFrameSize(SDL_VideoCaptureDevice *_this, Uint32 format, int index, int *width, int *height) {
|
||||
return -1;
|
||||
}
|
||||
int GetNumDevices(void) {
|
||||
return 0;
|
||||
SDL_VideoCaptureDeviceID *GetVideoCaptureDevices(int *count) {
|
||||
return NULL;
|
||||
}
|
||||
int GetNumFormats(SDL_VideoCaptureDevice *_this) {
|
||||
return 0;
|
||||
|
@ -79,6 +79,13 @@ int StartCapture(SDL_VideoCaptureDevice *_this) {
|
|||
int StopCapture(SDL_VideoCaptureDevice *_this) {
|
||||
return 0;
|
||||
}
|
||||
int SDL_SYS_VideoCaptureInit(void) {
|
||||
return 0;
|
||||
}
|
||||
int SDL_SYS_VideoCaptureQuit(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#else
|
||||
|
||||
|
@ -589,8 +596,9 @@ GetFrameSize(SDL_VideoCaptureDevice *_this, Uint32 format, int index, int *width
|
|||
}
|
||||
|
||||
int
|
||||
GetDeviceName(int index, char *buf, int size)
|
||||
GetDeviceName(SDL_VideoCaptureDeviceID instance_id, char *buf, int size)
|
||||
{
|
||||
int index = instance_id - 1;
|
||||
NSArray<AVCaptureDevice *> *devices = discover_devices();
|
||||
if (index < [devices count]) {
|
||||
AVCaptureDevice *device = devices[index];
|
||||
|
@ -602,13 +610,49 @@ GetDeviceName(int index, char *buf, int size)
|
|||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
static int
|
||||
GetNumDevices(void)
|
||||
{
|
||||
NSArray<AVCaptureDevice *> *devices = discover_devices();
|
||||
return [devices count];
|
||||
}
|
||||
|
||||
SDL_VideoCaptureDeviceID *GetVideoCaptureDevices(int *count)
|
||||
{
|
||||
/* hard-coded list of ID */
|
||||
int i;
|
||||
int num = GetNumDevices();
|
||||
SDL_VideoCaptureDeviceID *ret;
|
||||
|
||||
ret = (SDL_VideoCaptureDeviceID *)SDL_malloc((num + 1) * sizeof(*ret));
|
||||
|
||||
if (ret == NULL) {
|
||||
SDL_OutOfMemory();
|
||||
*count = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
ret[i] = i + 1;
|
||||
}
|
||||
ret[num] = 0;
|
||||
*count = num;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SDL_SYS_VideoCaptureInit(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SDL_SYS_VideoCaptureQuit(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* HAVE_COREMEDIA */
|
||||
|
||||
#endif /* SDL_VIDEO_CAPTURE */
|
||||
|
|
|
@ -28,11 +28,41 @@
|
|||
#include "SDL_video_capture_c.h"
|
||||
#include "SDL_pixels_c.h"
|
||||
#include "../thread/SDL_systhread.h"
|
||||
#include "../../core/linux/SDL_evdev_capabilities.h"
|
||||
#include "../../core/linux/SDL_udev.h"
|
||||
#include <limits.h> /* INT_MAX */
|
||||
|
||||
#define DEBUG_VIDEO_CAPTURE_CAPTURE 1
|
||||
|
||||
#if defined(__linux__) && !defined(__ANDROID__)
|
||||
|
||||
|
||||
#define MAX_CAPTURE_DEVICES 128 /* It's doubtful someone has more than that */
|
||||
|
||||
static int MaybeAddDevice(const char *path);
|
||||
#ifdef SDL_USE_LIBUDEV
|
||||
static int MaybeRemoveDevice(const char *path);
|
||||
static void capture_udev_callback(SDL_UDEV_deviceevent udev_type, int udev_class, const char *devpath);
|
||||
#endif /* SDL_USE_LIBUDEV */
|
||||
|
||||
/*
|
||||
* List of available capture devices.
|
||||
*/
|
||||
typedef struct SDL_capturelist_item
|
||||
{
|
||||
char *fname; /* Dev path name (like /dev/video0) */
|
||||
char *bus_info; /* don't add two paths with same bus_info (eg /dev/video0 and /dev/video1 */
|
||||
SDL_VideoCaptureDeviceID instance_id;
|
||||
SDL_VideoCaptureDevice *device; /* Associated device */
|
||||
struct SDL_capturelist_item *next;
|
||||
} SDL_capturelist_item;
|
||||
|
||||
static SDL_capturelist_item *SDL_capturelist = NULL;
|
||||
static SDL_capturelist_item *SDL_capturelist_tail = NULL;
|
||||
static int num_video_captures = 0;
|
||||
|
||||
|
||||
|
||||
enum io_method {
|
||||
IO_METHOD_READ,
|
||||
IO_METHOD_MMAP,
|
||||
|
@ -933,32 +963,252 @@ OpenDevice(SDL_VideoCaptureDevice *_this)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
GetDeviceName(int index, char *buf, int size) {
|
||||
SDL_snprintf(buf, size, "/dev/video%d", index);
|
||||
GetDeviceName(SDL_VideoCaptureDeviceID instance_id, char *buf, int size)
|
||||
{
|
||||
SDL_capturelist_item *item;
|
||||
for (item = SDL_capturelist; item; item = item->next) {
|
||||
if (item->instance_id == instance_id) {
|
||||
SDL_snprintf(buf, size, "%s", item->fname);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* unknown instance_id */
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
SDL_VideoCaptureDeviceID *GetVideoCaptureDevices(int *count)
|
||||
{
|
||||
/* real list of ID */
|
||||
int i = 0;
|
||||
int num = num_video_captures;
|
||||
SDL_VideoCaptureDeviceID *ret;
|
||||
SDL_capturelist_item *item;
|
||||
|
||||
ret = (SDL_VideoCaptureDeviceID *)SDL_malloc((num + 1) * sizeof(*ret));
|
||||
|
||||
if (ret == NULL) {
|
||||
SDL_OutOfMemory();
|
||||
*count = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (item = SDL_capturelist; item; item = item->next) {
|
||||
ret[i] = item->instance_id;
|
||||
i++;
|
||||
}
|
||||
|
||||
ret[num] = 0;
|
||||
*count = num;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initializes the subsystem by finding available devices.
|
||||
*/
|
||||
int SDL_SYS_VideoCaptureInit(void)
|
||||
{
|
||||
const char pattern[] = "/dev/video%d";
|
||||
char path[PATH_MAX];
|
||||
int i, j;
|
||||
|
||||
/*
|
||||
* Limit amount of checks to MAX_CAPTURE_DEVICES since we may or may not have
|
||||
* permission to some or all devices.
|
||||
*/
|
||||
i = 0;
|
||||
for (j = 0; j < MAX_CAPTURE_DEVICES; ++j) {
|
||||
(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");
|
||||
}
|
||||
|
||||
if (SDL_UDEV_AddCallback(capture_udev_callback) < 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_video_captures;
|
||||
}
|
||||
|
||||
|
||||
int SDL_SYS_VideoCaptureQuit(void)
|
||||
{
|
||||
SDL_capturelist_item *item;
|
||||
for (item = SDL_capturelist; item; ) {
|
||||
SDL_capturelist_item *tmp = item->next;
|
||||
|
||||
SDL_free(item->fname);
|
||||
SDL_free(item->bus_info);
|
||||
SDL_free(item);
|
||||
item = tmp;
|
||||
}
|
||||
|
||||
num_video_captures = 0;
|
||||
SDL_capturelist = NULL;
|
||||
SDL_capturelist_tail = NULL;
|
||||
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
#ifdef SDL_USE_LIBUDEV
|
||||
static void capture_udev_callback(SDL_UDEV_deviceevent udev_type, int udev_class, const char *devpath)
|
||||
{
|
||||
if (!devpath || !(udev_class & SDL_UDEV_DEVICE_VIDEO_CAPTURE)) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (udev_type) {
|
||||
case SDL_UDEV_DEVICEADDED:
|
||||
MaybeAddDevice(devpath);
|
||||
break;
|
||||
|
||||
case SDL_UDEV_DEVICEREMOVED:
|
||||
MaybeRemoveDevice(devpath);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif /* SDL_USE_LIBUDEV */
|
||||
|
||||
static SDL_bool DeviceExists(const char *path, const char *bus_info) {
|
||||
SDL_capturelist_item *item;
|
||||
|
||||
for (item = SDL_capturelist; item; item = item->next) {
|
||||
/* found same dev name */
|
||||
if (SDL_strcmp(path, item->fname) == 0) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
/* found same bus_info */
|
||||
if (SDL_strcmp(bus_info, item->bus_info) == 0) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
}
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
static int MaybeAddDevice(const char *path)
|
||||
{
|
||||
char *bus_info = NULL;
|
||||
struct v4l2_capability vcap;
|
||||
int err;
|
||||
int fd;
|
||||
SDL_capturelist_item *item;
|
||||
|
||||
if (!path) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
fd = open(path, O_RDWR);
|
||||
if (fd < 0) {
|
||||
return -2; /* stop iterating /dev/video%d */
|
||||
}
|
||||
err = ioctl(fd, VIDIOC_QUERYCAP, &vcap);
|
||||
close(fd);
|
||||
if (err) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
bus_info = SDL_strdup((char *)vcap.bus_info);
|
||||
|
||||
if (DeviceExists(path, bus_info)) {
|
||||
SDL_free(bus_info);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Add new item */
|
||||
item = (SDL_capturelist_item *)SDL_calloc(1, sizeof(SDL_capturelist_item));
|
||||
if (!item) {
|
||||
SDL_free(bus_info);
|
||||
return -1;
|
||||
}
|
||||
|
||||
item->fname = SDL_strdup(path);
|
||||
if (!item->fname) {
|
||||
SDL_free(item);
|
||||
SDL_free(bus_info);
|
||||
return -1;
|
||||
}
|
||||
|
||||
item->fname = SDL_strdup(path);
|
||||
item->bus_info = bus_info;
|
||||
item->instance_id = SDL_GetNextObjectID();
|
||||
|
||||
|
||||
if (!SDL_capturelist_tail) {
|
||||
SDL_capturelist = SDL_capturelist_tail = item;
|
||||
} else {
|
||||
SDL_capturelist_tail->next = item;
|
||||
SDL_capturelist_tail = item;
|
||||
}
|
||||
|
||||
++num_video_captures;
|
||||
|
||||
/* !!! TODO: Send a add event? */
|
||||
#if DEBUG_VIDEO_CAPTURE_CAPTURE
|
||||
SDL_Log("Added video capture ID: %d %s (%s) (total: %d)", item->instance_id, path, bus_info, num_video_captures);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
GetNumDevices(void) {
|
||||
int num;
|
||||
for (num = 0; num < 128; num++) {
|
||||
static char buf[256];
|
||||
buf[0] = 0;
|
||||
buf[255] = 0;
|
||||
GetDeviceName(num, buf, sizeof (buf));
|
||||
SDL_RWops *src = SDL_RWFromFile(buf, "rb");
|
||||
if (src == NULL) {
|
||||
// When file does not exist, an error is set. Clear it.
|
||||
SDL_ClearError();
|
||||
return num;
|
||||
}
|
||||
SDL_RWclose(src);
|
||||
#ifdef SDL_USE_LIBUDEV
|
||||
static int MaybeRemoveDevice(const char *path)
|
||||
{
|
||||
|
||||
SDL_capturelist_item *item;
|
||||
SDL_capturelist_item *prev = NULL;
|
||||
#if DEBUG_VIDEO_CAPTURE_CAPTURE
|
||||
SDL_Log("Remove video capture %s", path);
|
||||
#endif
|
||||
if (!path) {
|
||||
return -1;
|
||||
}
|
||||
return num;
|
||||
|
||||
for (item = SDL_capturelist; item; item = item->next) {
|
||||
/* found it, remove it. */
|
||||
if (SDL_strcmp(path, item->fname) == 0) {
|
||||
if (prev) {
|
||||
prev->next = item->next;
|
||||
} else {
|
||||
SDL_assert(SDL_capturelist == item);
|
||||
SDL_capturelist = item->next;
|
||||
}
|
||||
if (item == SDL_capturelist_tail) {
|
||||
SDL_capturelist_tail = prev;
|
||||
}
|
||||
|
||||
/* Need to decrement the count */
|
||||
--num_video_captures;
|
||||
/* !!! TODO: Send a remove event? */
|
||||
|
||||
SDL_free(item->fname);
|
||||
SDL_free(item->bus_info);
|
||||
SDL_free(item);
|
||||
return 0;
|
||||
}
|
||||
prev = item;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif /* SDL_USE_LIBUDEV */
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -633,9 +633,12 @@ GetFrameSize(SDL_VideoCaptureDevice *_this, Uint32 format, int index, int *width
|
|||
return -1;
|
||||
}
|
||||
|
||||
static int GetNumDevices(void);
|
||||
|
||||
int
|
||||
GetDeviceName(int index, char *buf, int size)
|
||||
GetDeviceName(SDL_VideoCaptureDeviceID instance_id, char *buf, int size)
|
||||
{
|
||||
int index = instance_id - 1;
|
||||
create_cameraMgr();
|
||||
|
||||
if (cameraIdList == NULL) {
|
||||
|
@ -652,7 +655,7 @@ GetDeviceName(int index, char *buf, int size)
|
|||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
static int
|
||||
GetNumDevices(void)
|
||||
{
|
||||
camera_status_t res;
|
||||
|
@ -673,6 +676,38 @@ GetNumDevices(void)
|
|||
return -1;
|
||||
}
|
||||
|
||||
SDL_VideoCaptureDeviceID *GetVideoCaptureDevices(int *count)
|
||||
{
|
||||
/* hard-coded list of ID */
|
||||
int i;
|
||||
int num = GetNumDevices();
|
||||
SDL_VideoCaptureDeviceID *ret;
|
||||
|
||||
ret = (SDL_VideoCaptureDeviceID *)SDL_malloc((num + 1) * sizeof(*ret));
|
||||
|
||||
if (ret == NULL) {
|
||||
SDL_OutOfMemory();
|
||||
*count = 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < num; i++) {
|
||||
ret[i] = i + 1;
|
||||
}
|
||||
ret[num] = 0;
|
||||
*count = num;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int SDL_SYS_VideoCaptureInit(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SDL_SYS_VideoCaptureQuit(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -125,7 +125,7 @@ static SDL_VideoCaptureDeviceID get_instance_id(int index) {
|
|||
}
|
||||
|
||||
if (ret == 0) {
|
||||
SDL_Log("invalid index");
|
||||
/* SDL_Log("invalid index"); */
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -212,7 +212,7 @@ int main(int argc, char **argv)
|
|||
SDL_Log("%s", usage);
|
||||
|
||||
/* Load the SDL library */
|
||||
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
|
||||
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) < 0) { /* FIXME: SDL_INIT_JOYSTICK needed for add/removing devices at runtime */
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s", SDL_GetError());
|
||||
return 1;
|
||||
}
|
||||
|
@ -439,7 +439,7 @@ int main(int argc, char **argv)
|
|||
SAVE_CAPTURE_STATE(current_dev);
|
||||
|
||||
current_dev += 1;
|
||||
if (current_dev == num || current_dev >= (int) SDL_arraysize(data_capture_tab)) {
|
||||
if (current_dev >= num || current_dev >= (int) SDL_arraysize(data_capture_tab)) {
|
||||
current_dev = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ int main(int argc, char **argv)
|
|||
SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
|
||||
|
||||
/* Load the SDL library */
|
||||
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
|
||||
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK) < 0) { /* FIXME: SDL_INIT_JOYSTICK needed for add/removing devices at runtime */
|
||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s", SDL_GetError());
|
||||
return 1;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue