(Camera) Add camera driver init/deinit when HAVE_CAMERA is defined

This commit is contained in:
twinaphex 2013-11-11 14:26:57 +01:00
parent 672594d7d3
commit f8d44c6e60
7 changed files with 163 additions and 11 deletions

View File

@ -29,6 +29,7 @@
#include <sys/time.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include "../compat/strl.h"
#include <asm/types.h>
@ -49,7 +50,7 @@ struct buffer
typedef struct video4linux
{
char *dev_name;
char dev_name[256];
int fd;
bool ready;
io_method io;
@ -537,17 +538,23 @@ static int v4l_start(void *data)
return 0;
}
static void *v4l_init(void)
static void *v4l_init(const char *device, unsigned width, unsigned height)
{
(void)width;
(void)height;
struct stat st;
video4linux_t *v4l = (video4linux_t*)calloc(1, sizeof(video4linux_t));
if (!v4l)
return NULL;
// FIXME - /dev/video0 assumed for now - should allow for selecting which device
v4l->dev_name = "/dev/video0";
v4l->width = 640;
v4l->height = 480;
if (device == NULL)
strlcpy(v4l->dev_name, "/dev/video0", sizeof(v4l->dev_name));
else
strlcpy(v4l->dev_name, device, sizeof(v4l->dev_name));
v4l->width = 640; //FIXME - use width param
v4l->height = 480; //FIXME - use height param
v4l->ready = false;
if (stat(v4l->dev_name, &st) == -1)

View File

@ -79,7 +79,10 @@ enum
INPUT_APPLE,
INPUT_QNX,
INPUT_RWEBINPUT,
INPUT_NULL
INPUT_NULL,
CAMERA_V4L2,
CAMERA_NULL,
};
#if defined(HAVE_OPENGL) || defined(HAVE_OPENGLES) || defined(__CELLOS_LV2__)
@ -178,6 +181,12 @@ enum
#define INPUT_DEFAULT_DRIVER INPUT_NULL
#endif
#if defined(HAVE_V4L2)
#define CAMERA_DEFAULT_DRIVER CAMERA_V4L2
#else
#define CAMERA_DEFAULT_DRIVER CAMERA_NULL
#endif
#if defined(XENON) || defined(_XBOX360) || defined(__CELLOS_LV2__)
#define DEFAULT_ASPECT_RATIO 1.7778f
#elif defined(_XBOX1) || defined(GEKKO) || defined(ANDROID) || defined(__BLACKBERRY_QNX__)

View File

@ -179,6 +179,41 @@ static const input_driver_t *input_drivers[] = {
NULL,
};
#ifdef HAVE_CAMERA
static const camera_driver_t *camera_drivers[] = {
#ifdef HAVE_V4L2
&camera_v4l2,
#endif
NULL,
};
static int find_camera_driver_index(const char *driver)
{
unsigned i;
for (i = 0; camera_drivers[i]; i++)
if (strcasecmp(driver, camera_drivers[i]->ident) == 0)
return i;
return -1;
}
static void find_camera_driver(void)
{
int i = find_camera_driver_index(g_settings.camera.driver);
if (i >= 0)
driver.camera = camera_drivers[i];
else
{
unsigned d;
RARCH_ERR("Couldn't find any camera driver named \"%s\"\n", g_settings.camera.driver);
RARCH_LOG_OUTPUT("Available camera drivers are:\n");
for (d = 0; camera_drivers[d]; d++)
RARCH_LOG_OUTPUT("\t%s\n", camera_drivers[d]->ident);
rarch_fail(1, "find_camera_driver()");
}
}
#endif
static int find_audio_driver_index(const char *driver)
{
unsigned i;
@ -327,6 +362,9 @@ void init_drivers_pre(void)
find_audio_driver();
find_video_driver();
find_input_driver();
#ifdef HAVE_CAMERA
find_camera_driver();
#endif
}
static void adjust_system_rates(void)
@ -468,13 +506,44 @@ void global_uninit_drivers(void)
driver.input->free(driver.input_data);
driver.input_data = NULL;
}
#ifdef HAVE_CAMERA
if (driver.camera && driver.camera_data)
{
driver.camera->free(driver.camera_data);
driver.camera_data = NULL;
}
#endif
}
#ifdef HAVE_CAMERA
void init_camera(void)
{
// Resource leaks will follow if camera is initialized twice.
if (driver.camera_data)
return;
find_camera_driver();
driver.camera_data = camera_init_func(*g_settings.camera.device ? g_settings.camera.device : NULL,
g_settings.camera.width, g_settings.camera.height);
if (!driver.camera_data)
{
RARCH_ERR("Failed to initialize camera driver. Will continue without camera.\n");
g_extern.camera_active = false;
}
}
#endif
void init_drivers(void)
{
driver.video_data_own = !driver.video_data;
driver.audio_data_own = !driver.audio_data;
driver.input_data_own = !driver.input_data;
#ifdef HAVE_CAMERA
driver.camera_data_own = !driver.camera_data_own;
#endif
adjust_system_rates();
@ -487,6 +556,10 @@ void init_drivers(void)
init_audio();
#ifdef HAVE_CAMERA
init_camera();
#endif
// Keep non-throttled state as good as possible.
if (driver.nonblock_state)
driver_set_nonblock_state(driver.nonblock_state);
@ -494,6 +567,14 @@ void init_drivers(void)
g_extern.system.frame_time_last = 0;
}
#ifdef HAVE_CAMERA
void uninit_camera(void)
{
if (driver.camera_data && driver.camera)
driver.camera->free(driver.camera_data);
}
#endif
void uninit_drivers(void)
{
uninit_audio();
@ -503,6 +584,12 @@ void uninit_drivers(void)
uninit_video_input();
#ifdef HAVE_CAMERA
uninit_camera();
if (driver.camera_data_own)
driver.camera_data = NULL;
#endif
if (driver.video_data_own)
driver.video_data = NULL;
if (driver.audio_data_own)
@ -510,9 +597,12 @@ void uninit_drivers(void)
if (driver.input_data_own)
driver.input_data = NULL;
driver.video_data_own = false;
driver.audio_data_own = false;
driver.input_data_own = false;
#ifdef HAVE_CAMERA
driver.camera_data_own = false;
#endif
driver.video_data_own = false;
driver.audio_data_own = false;
driver.input_data_own = false;
}
#ifdef HAVE_DYLIB
@ -692,6 +782,7 @@ void init_audio(void)
audio_start_func();
}
static void compute_audio_buffer_statistics(void)
{
unsigned i, samples;

View File

@ -335,7 +335,7 @@ typedef struct camera_driver
{
//FIXME - params for init - queries for resolution, framerate, color format
//which might or might not be honored
void *(*init)(void);
void *(*init)(const char *device, unsigned width, unsigned height);
void (*free)(void *data);
int (*start)(void *data);
int (*stop)(void *data);
@ -430,6 +430,10 @@ typedef struct driver
const audio_driver_t *audio;
const video_driver_t *video;
const input_driver_t *input;
#ifdef HAVE_CAMERA
const camera_driver_t *camera;
void *camera_data;
#endif
void *audio_data;
void *video_data;
void *input_data;
@ -451,6 +455,9 @@ typedef struct driver
bool video_data_own;
bool audio_data_own;
bool input_data_own;
#ifdef HAVE_CAMERA
bool camera_data_own;
#endif
#ifdef HAVE_COMMAND
rarch_cmd_t *command;

View File

@ -18,6 +18,8 @@
#ifndef _RARCH_DRIVER_FUNCS_H
#define _RARCH_DRIVER_FUNCS_H
#define camera_init_func(device, width, height) driver.camera->init(device, width, height)
#define audio_init_func(device, rate, latency) driver.audio->init(device, rate, latency)
#define audio_write_func(buf, size) driver.audio->write(driver.audio_data, buf, size)
#define audio_stop_func() driver.audio->stop(driver.audio_data)

View File

@ -185,6 +185,16 @@ struct settings
bool allow_rotate;
} video;
#ifdef HAVE_CAMERA
struct
{
char driver[32];
char device[PATH_MAX];
unsigned width;
unsigned height;
} camera;
#endif
struct
{
char driver[32];
@ -309,6 +319,9 @@ struct global
bool verbose;
bool audio_active;
bool video_active;
#ifdef HAVE_CAMERA
bool camera_active;
#endif
bool force_fullscreen;
bool rom_file_temporary;
@ -621,6 +634,9 @@ struct rarch_main_wrap
// Public functions
void config_load(void);
void config_set_defaults(void);
#ifdef HAVE_CAMERA
const char *config_get_default_camera(void);
#endif
const char *config_get_default_video(void);
const char *config_get_default_audio(void);
const char *config_get_default_input(void);

View File

@ -148,13 +148,33 @@ const char *config_get_default_input(void)
}
}
#ifdef HAVE_CAMERA
const char *config_get_default_camera(void)
{
switch (CAMERA_DEFAULT_DRIVER)
{
case CAMERA_V4L2:
return "video4linux2";
case CAMERA_NULL:
return "null";
default:
return NULL;
}
}
#endif
void config_set_defaults(void)
{
unsigned i, j;
const char *def_video = config_get_default_video();
const char *def_audio = config_get_default_audio();
const char *def_input = config_get_default_input();
#ifdef HAVE_CAMERA
const char *def_camera = config_get_default_camera();
if (def_camera)
strlcpy(g_settings.camera.driver, def_camera, sizeof(g_settings.camera.driver));
#endif
if (def_video)
strlcpy(g_settings.video.driver, def_video, sizeof(g_settings.video.driver));
if (def_audio)