diff --git a/projects/VisualStudio2013/mupen64plus-core.vcxproj b/projects/VisualStudio2013/mupen64plus-core.vcxproj index cf4bc6290..a6d2871b1 100644 --- a/projects/VisualStudio2013/mupen64plus-core.vcxproj +++ b/projects/VisualStudio2013/mupen64plus-core.vcxproj @@ -41,11 +41,13 @@ + + - + true true true @@ -55,7 +57,6 @@ true true - @@ -266,20 +267,9 @@ - + - - true - true - true - true - true - true - true - true - - diff --git a/projects/VisualStudio2013/mupen64plus-core.vcxproj.filters b/projects/VisualStudio2013/mupen64plus-core.vcxproj.filters index bbd8c6de3..db51c1892 100644 --- a/projects/VisualStudio2013/mupen64plus-core.vcxproj.filters +++ b/projects/VisualStudio2013/mupen64plus-core.vcxproj.filters @@ -192,10 +192,10 @@ backends - + backends - + backends @@ -300,6 +300,9 @@ device\pif + + backends + backends\plugins_compat @@ -494,12 +497,6 @@ backends - - backends - - - backends - device\dd @@ -635,7 +632,7 @@ backends\api - + backends\api diff --git a/projects/unix/Makefile b/projects/unix/Makefile index 3375dd7eb..a92ac2186 100755 --- a/projects/unix/Makefile +++ b/projects/unix/Makefile @@ -455,11 +455,12 @@ SOURCE = \ $(SRCDIR)/api/debugger.c \ $(SRCDIR)/api/frontend.c \ $(SRCDIR)/api/vidext.c \ + $(SRCDIR)/backends/api/video_capture_backend.c \ $(SRCDIR)/backends/plugins_compat/audio_plugin_compat.c \ $(SRCDIR)/backends/plugins_compat/input_plugin_compat.c \ $(SRCDIR)/backends/clock_ctime_plus_delta.c \ + $(SRCDIR)/backends/dummy_video_capture.c \ $(SRCDIR)/backends/file_storage.c \ - $(SRCDIR)/backends/dummy_video_backend.c \ $(SRCDIR)/device/cart/cart.c \ $(SRCDIR)/device/cart/af_rtc.c \ $(SRCDIR)/device/cart/cart_rom.c \ @@ -629,7 +630,7 @@ ifeq ($(DEBUGGER), 1) endif ifeq ($(OPENCV), 1) - SOURCE += $(SRCDIR)/backends/opencv_video_backend.cpp + SOURCE += $(SRCDIR)/backends/opencv_video_capture.cpp CFLAGS += -DM64P_OPENCV endif diff --git a/src/backends/dummy_video_backend.c b/src/backends/api/video_capture_backend.c similarity index 57% rename from src/backends/dummy_video_backend.c rename to src/backends/api/video_capture_backend.c index e31fccb10..975d0e182 100644 --- a/src/backends/dummy_video_backend.c +++ b/src/backends/api/video_capture_backend.c @@ -1,5 +1,5 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Mupen64plus - dummy_video_backend.c * + * Mupen64plus - video_capture_backend.c * * Mupen64Plus homepage: https://mupen64plus.org/ * * Copyright (C) 2018 Bobby Smiles * * * @@ -19,28 +19,38 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -#include "backends/dummy_video_backend.h" -#include "backends/api/video_backend.h" +#include "video_capture_backend.h" -#include "api/m64p_types.h" +#include -static m64p_error dummy_video_open(void* vin, unsigned int width, unsigned int height) -{ - return M64ERR_SUCCESS; -} +/* exported video capture backends */ +extern const struct video_capture_backend_interface g_idummy_video_capture_backend; +#if defined(M64P_OPENCV) +extern const struct video_capture_backend_interface g_iopencv_video_capture_backend; +#endif -static void dummy_video_close(void* vin) -{ -} -static m64p_error dummy_grab_image(void* vin, void* data) +const struct video_capture_backend_interface* g_video_capture_backend_interfaces[] = { - return M64ERR_UNSUPPORTED; -} +#if defined(M64P_OPENCV) + &g_iopencv_video_capture_backend, +#endif + &g_idummy_video_capture_backend, + NULL /* sentinel - must be last element */ +}; -const struct video_input_backend_interface g_idummy_video_input_backend = + +const struct video_capture_backend_interface* get_video_capture_backend(const char* name) { - dummy_video_open, - dummy_video_close, - dummy_grab_image -}; + const struct video_capture_backend_interface** i; + + /* passing NULL or empty string gives the dummy video input backend interface */ + if (!name || strlen(name) == 0) { return &g_idummy_video_capture_backend; } + + /* iterate through interfaces to find matching name */ + for (i = g_video_capture_backend_interfaces; (*i) != NULL; ++i) { + if (strcmp((*i)->name, name) == 0) { return (*i); } + } + + return NULL; +} diff --git a/src/backends/api/video_backend.h b/src/backends/api/video_capture_backend.h similarity index 60% rename from src/backends/api/video_backend.h rename to src/backends/api/video_capture_backend.h index 2ed448743..5e078878b 100644 --- a/src/backends/api/video_backend.h +++ b/src/backends/api/video_capture_backend.h @@ -1,5 +1,5 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Mupen64plus - video_backend.h * + * Mupen64plus - video_capture_backend.h * * Mupen64Plus homepage: https://mupen64plus.org/ * * Copyright (C) 2017 Bobby Smiles * * * @@ -19,13 +19,43 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -#ifndef M64P_BACKENDS_API_VIDEO_BACKEND_H -#define M64P_BACKENDS_API_VIDEO_BACKEND_H +#ifndef M64P_BACKENDS_API_VIDEO_CAPTURE_BACKEND_H +#define M64P_BACKENDS_API_VIDEO_CAPTURE_BACKEND_H #include "api/m64p_types.h" -struct video_input_backend_interface +/* Define default video capture backend + * if not defined by Makefile/msvc + */ +#if !defined(DEFAULT_VIDEO_CAPTURE_BACKEND) +#if defined(M64P_OPENCV) +#define DEFAULT_VIDEO_CAPTURE_BACKEND "opencv" +#else +#define DEFAULT_VIDEO_CAPTURE_BACKEND "" +#endif +#endif + + +struct video_capture_backend_interface { + /* Backend class name. + * Must be unique. + */ + const char* name; + + /* Initialize backend instance (*vin) + * using (when provided) parameters from config section. + * + * Returns M64ERR_SUCCESS on success. + * + * You must call corresponding release method to release any allocated resources. + */ + m64p_error (*init)(void** vin, const char* section); + + /* Release backend instance and any associated resouces. + */ + void (*release)(void* vin); + /* Open a video stream with following properties (width, height) * Returns M64ERR_SUCCESS on success. */ @@ -41,4 +71,10 @@ struct video_input_backend_interface m64p_error (*grab_image)(void* vin, void* data); }; +/* collection of available video capture backends */ +extern const struct video_capture_backend_interface* g_video_capture_backend_interfaces[]; + +/* helper function which find backend by name (or dummy when NULL/empty) */ +const struct video_capture_backend_interface* get_video_capture_backend(const char* name); + #endif diff --git a/src/backends/dummy_video_backend.h b/src/backends/dummy_video_backend.h deleted file mode 100644 index 2c9444ebc..000000000 --- a/src/backends/dummy_video_backend.h +++ /dev/null @@ -1,29 +0,0 @@ -/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Mupen64plus - dummy_video_backend.h * - * Mupen64Plus homepage: https://mupen64plus.org/ * - * Copyright (C) 2018 Bobby Smiles * - * * - * This program is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - -#ifndef M64P_BACKENDS_DUMMY_VIDEO_BACKEND_H -#define M64P_BACKENDS_DUMMY_VIDEO_BACKEND_H - -#include "api/video_backend.h" - -extern const struct video_input_backend_interface g_idummy_video_input_backend; - -#endif diff --git a/src/backends/opencv_video_backend.h b/src/backends/dummy_video_capture.c similarity index 51% rename from src/backends/opencv_video_backend.h rename to src/backends/dummy_video_capture.c index 999391b3d..2eb6375d8 100644 --- a/src/backends/opencv_video_backend.h +++ b/src/backends/dummy_video_capture.c @@ -1,5 +1,5 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Mupen64plus - opencv_video_backend.h * + * Mupen64plus - dummy_video_capture.c * * Mupen64Plus homepage: https://mupen64plus.org/ * * Copyright (C) 2017 Bobby Smiles * * * @@ -19,33 +19,66 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -#ifndef M64P_BACKENDS_OPENCV_VIDEO_BACKEND_H -#define M64P_BACKENDS_OPENCV_VIDEO_BACKEND_H +#include "backends/api/video_capture_backend.h" -#ifdef __cplusplus -extern "C" { -#endif +#include +#include -#include "backends/api/video_backend.h" +/* Dummy video capture backend + * + * Returns a black frame + */ +struct dummy_video_capture +{ + /* BGR frame size (no stride) */ + size_t size; +}; -struct opencv_video_backend +static m64p_error dummy_init(void** vcap, const char* config) { - char* device; - unsigned int width; - unsigned int height; + struct dummy_video_capture* dummy = malloc(sizeof(*dummy)); + if (dummy == NULL) { + *vcap = NULL; + return M64ERR_NO_MEMORY; + } - /* using void* to avoid leaking C++ stuff in this header */ - void* cap; -}; + memset(dummy, 0, sizeof(*dummy)); -#if 0 -void cv_imshow(const char* name, unsigned int width, unsigned int height, int channels, void* data); -#endif + *vcap = dummy; + return M64ERR_SUCCESS; +} -extern const struct video_input_backend_interface g_iopencv_video_input_backend; +static void dummy_release(void* vcap) +{ + free(vcap); +} -#ifdef __cplusplus +static m64p_error dummy_open(void* vcap, unsigned int width, unsigned int height) +{ + struct dummy_video_capture* dummy = (struct dummy_video_capture*)vcap; + dummy->size = 3 * width * height; + return M64ERR_SUCCESS; } -#endif -#endif +static void dummy_close(void* vcap) +{ + struct dummy_video_capture* dummy = (struct dummy_video_capture*)vcap; + dummy->size = 0; +} + +static m64p_error dummy_grab_image(void* vcap, void* data) +{ + struct dummy_video_capture* dummy = (struct dummy_video_capture*)vcap; + memset(data, 0, dummy->size); + return M64ERR_SUCCESS; +} + +const struct video_capture_backend_interface g_idummy_video_capture_backend = +{ + "dummy", + dummy_init, + dummy_release, + dummy_open, + dummy_close, + dummy_grab_image +}; diff --git a/src/backends/opencv_video_backend.cpp b/src/backends/opencv_video_capture.cpp similarity index 55% rename from src/backends/opencv_video_backend.cpp rename to src/backends/opencv_video_capture.cpp index 41b8b539f..f83e25acc 100644 --- a/src/backends/opencv_video_backend.cpp +++ b/src/backends/opencv_video_capture.cpp @@ -1,5 +1,5 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Mupen64plus - opencv_video_backend.h * + * Mupen64plus - opencv_video_capture.cpp * * Mupen64Plus homepage: https://mupen64plus.org/ * * Copyright (C) 2017 Bobby Smiles * * * @@ -34,59 +34,116 @@ #error "Unsupported version of OpenCV" #endif -#include +#include + +struct opencv_video_capture +{ + unsigned int width; + unsigned int height; + + std::string device; + cv::VideoCapture cap; +}; + extern "C" { -#include "backends/opencv_video_backend.h" -#include "backends/api/video_backend.h" + +#include "backends/api/video_capture_backend.h" #define M64P_CORE_PROTOTYPES 1 #include "api/callbacks.h" +#include "api/m64p_config.h" #include "api/m64p_types.h" #include "main/util.h" -/* Implements video_input_backend. - * Needs device field to be set before calling. - */ -static m64p_error opencv_video_open(void* vin, unsigned int width, unsigned int height) +extern "C" const struct video_capture_backend_interface g_iopencv_video_capture_backend; + + + +static m64p_error opencv_init_full(struct opencv_video_capture** cv, const char* dev) { try { - int dev_num; - struct opencv_video_backend* b = static_cast(vin); + std::string device; + if (dev != NULL) { + device = dev; + } + + *cv = new opencv_video_capture(); + + (*cv)->width = 0; + (*cv)->height = 0; + (*cv)->device = std::move(device); + + return M64ERR_SUCCESS; + } + /* C++ exception must not cross C-API boundaries */ + catch(...) { return M64ERR_INTERNAL; } +} + +static m64p_error opencv_init(void** vcap, const char* section) +{ + try { + /* default parameters */ + const char* device = "0"; + + if (section && strlen(section) > 0) { + m64p_handle config = NULL; - /* allocate memory for cv::VideoCapture */ - cv::VideoCapture* cap = static_cast(std::malloc(sizeof(cv::VideoCapture))); - if (cap == NULL) { - DebugMessage(M64MSG_ERROR, "Failed to allocated memory for video device %s", b->device); - return M64ERR_NO_MEMORY; + ConfigOpenSection(section, &config); + + /* set default parameters */ + ConfigSetDefaultString(config, "device", device, "Device to use for capture or \"0\" for default."); + + /* get parameters */ + device = ConfigGetParamString(config, "device"); } - /* placement new to call cv::VideoCapture constructor */ - new(cap)cv::VideoCapture(); + return opencv_init_full(reinterpret_cast(vcap), device); + } + /* C++ exception must not cross C-API boundaries */ + catch(...) { return M64ERR_INTERNAL; } +} +static void opencv_release(void* vcap) +{ + try { + struct opencv_video_capture* cv = static_cast(vcap); + if (cv == NULL) { + return; + } + + delete cv; + } + /* C++ exception must not cross C-API boundaries */ + catch(...) { return; } +} + +static m64p_error opencv_open(void* vcap, unsigned int width, unsigned int height) +{ + try { + int dev_num; + struct opencv_video_capture* cv = static_cast(vcap); /* open device (we support both device number or path */ - if (string_to_int(b->device, &dev_num)) { - cap->open(dev_num); + if (string_to_int(cv->device.c_str(), &dev_num)) { + cv->cap.open(dev_num); } else { - cap->open(b->device); + cv->cap.open(cv->device); } - if (!cap->isOpened()) { - DebugMessage(M64MSG_ERROR, "Failed to open video device %s", b->device); - std::free(cap); + if (!cv->cap.isOpened()) { + DebugMessage(M64MSG_ERROR, "Failed to open video device %s", cv->device.c_str()); return M64ERR_SYSTEM_FAIL; } /* TODO: adapt capture resolution to the desired resolution */ - DebugMessage(M64MSG_INFO, "Video successfully opened: %s", b->device); + DebugMessage(M64MSG_INFO, "Video successfully opened: %s", cv->device.c_str()); - b->cap = cap; - b->width = width; - b->height = height; + cv->width = width; + cv->height = height; return M64ERR_SUCCESS; } @@ -94,24 +151,12 @@ static m64p_error opencv_video_open(void* vin, unsigned int width, unsigned int catch(...) { return M64ERR_INTERNAL; } } -static void opencv_video_close(void* vin) +static void opencv_close(void* vcap) { try { - struct opencv_video_backend* b = static_cast(vin); + struct opencv_video_capture* cv = static_cast(vcap); - if (b->cap != NULL) { - /* explicit call to cv::VideoCapture destructor */ - static_cast(b->cap)->~VideoCapture(); - - /* free allocated memory */ - std::free(b->cap); - b->cap = NULL; - } - - if (b->device != NULL) { - std::free(b->device); - b->device = NULL; - } + cv->cap.release(); DebugMessage(M64MSG_INFO, "Video closed"); } @@ -119,21 +164,20 @@ static void opencv_video_close(void* vin) catch(...) { return; } } -static m64p_error opencv_grab_image(void* vin, void* data) +static m64p_error opencv_grab_image(void* vcap, void* data) { try { - struct opencv_video_backend* b = static_cast(vin); - cv::VideoCapture* cap = static_cast(b->cap); + struct opencv_video_capture* cv = static_cast(vcap); /* read next frame */ cv::Mat frame; - if (cap == NULL || !cap->read(frame)) { + if (!cv->cap.read(frame)) { DebugMessage(M64MSG_ERROR, "Failed to grab frame !"); return M64ERR_SYSTEM_FAIL; } /* resize image to desired resolution */ - cv::Mat output = cv::Mat(b->height, b->width, CV_8UC3, data); + cv::Mat output = cv::Mat(cv->height, cv->width, CV_8UC3, data); cv::resize(frame, output, output.size(), 0, 0, cv::INTER_AREA); return M64ERR_SUCCESS; @@ -158,10 +202,14 @@ void cv_imshow(const char* name, unsigned int width, unsigned int height, int ch } #endif -const struct video_input_backend_interface g_iopencv_video_input_backend = + +extern "C" const struct video_capture_backend_interface g_iopencv_video_capture_backend = { - opencv_video_open, - opencv_video_close, + "opencv", + opencv_init, + opencv_release, + opencv_open, + opencv_close, opencv_grab_image }; diff --git a/src/device/gb/gb_cart.c b/src/device/gb/gb_cart.c index fe6210a29..718bdfebe 100644 --- a/src/device/gb/gb_cart.c +++ b/src/device/gb/gb_cart.c @@ -29,9 +29,9 @@ #include "api/callbacks.h" #include "backends/api/rumble_backend.h" #include "backends/api/storage_backend.h" -#include "backends/api/video_backend.h" +#include "backends/api/video_capture_backend.h" #if 0 -#include "backends/opencv_video_backend.h" +void cv_imshow(const char* name, unsigned int width, unsigned int height, int channels, void* data); #else #define cv_imshow(...) #endif @@ -665,7 +665,7 @@ static void grab_pocket_cam_image(struct pocket_cam* cam) #endif /* grab BGR image */ - if (cam->ivin->grab_image(cam->vin, bgr) != M64ERR_SUCCESS) { + if (cam->ivcap->grab_image(cam->vcap, bgr) != M64ERR_SUCCESS) { memset(cam->ram, UINT8_C(0xff), sizeof(tiles)); return; } @@ -708,12 +708,12 @@ static void grab_pocket_cam_image(struct pocket_cam* cam) memcpy(cam->ram, tiles, sizeof(tiles)); } -static void init_pocket_cam(struct pocket_cam* cam, uint8_t* ram, void* vin, const struct video_input_backend_interface* ivin) +static void init_pocket_cam(struct pocket_cam* cam, uint8_t* ram, void* vcap, const struct video_capture_backend_interface* ivcap) { cam->ram = ram; - cam->vin = vin; - cam->ivin = ivin; + cam->vcap = vcap; + cam->ivcap = ivcap; } static void poweron_pocket_cam(struct pocket_cam* cam) @@ -969,7 +969,7 @@ void init_gb_cart(struct gb_cart* gb_cart, void* ram_opaque, void (*init_ram)(void* user_data, size_t ram_size, void** ram_storage, const struct storage_backend_interface** iram_storage), void (*release_ram)(void* user_data), void* clock, const struct clock_backend_interface* iclock, void* rumble, const struct rumble_backend_interface* irumble, - void* vin, const struct video_input_backend_interface* ivin) + void* vcap, const struct video_capture_backend_interface* ivcap) { const struct parsed_cart_type* type; void* rom_storage = NULL; @@ -1060,7 +1060,7 @@ void init_gb_cart(struct gb_cart* gb_cart, } if (type->extra_devices & GED_CAMERA) { - init_pocket_cam(&cam, iram_storage->data(ram_storage), vin, ivin); + init_pocket_cam(&cam, iram_storage->data(ram_storage), vcap, ivcap); } /* update gb_cart */ diff --git a/src/device/gb/gb_cart.h b/src/device/gb/gb_cart.h index df21606d6..c9cdae5ef 100644 --- a/src/device/gb/gb_cart.h +++ b/src/device/gb/gb_cart.h @@ -30,7 +30,7 @@ struct storage_backend_interface; struct rumble_backend_interface; -struct video_input_backend_interface; +struct video_capture_backend_interface; enum pocket_cam_registers { @@ -42,8 +42,8 @@ struct pocket_cam { uint8_t regs[POCKET_CAM_REGS_COUNT]; - void* vin; - const struct video_input_backend_interface* ivin; + void* vcap; + const struct video_capture_backend_interface* ivcap; uint8_t* ram; }; @@ -79,7 +79,7 @@ void init_gb_cart(struct gb_cart* gb_cart, void* ram_opaque, void (*init_ram)(void* user_data, size_t ram_size, void** ram_storage, const struct storage_backend_interface** iram_storage), void (*release_ram)(void* user_data), void* clock, const struct clock_backend_interface* iclock, void* rumble, const struct rumble_backend_interface* irumble, - void* vin, const struct video_input_backend_interface* ivin); + void* vcap, const struct video_capture_backend_interface* ivcap); void poweron_gb_cart(struct gb_cart* gb_cart); diff --git a/src/main/main.c b/src/main/main.c index ec1848cd5..185006a0c 100644 --- a/src/main/main.c +++ b/src/main/main.c @@ -29,6 +29,7 @@ */ #include +#include #include #include #include @@ -49,12 +50,10 @@ #include "backends/api/joybus.h" #include "backends/api/rumble_backend.h" #include "backends/api/storage_backend.h" -#include "backends/api/video_backend.h" +#include "backends/api/video_capture_backend.h" #include "backends/plugins_compat/plugins_compat.h" #include "backends/clock_ctime_plus_delta.h" #include "backends/file_storage.h" -#include "backends/opencv_video_backend.h" -#include "backends/dummy_video_backend.h" #include "cheat.h" #include "device/device.h" #include "device/controllers/paks/biopak.h" @@ -179,6 +178,46 @@ static char *get_gb_ram_path(const char* gbrom, unsigned int control_id) return formatstr("%s%s.%u.sav", get_savesrampath(), gbrom, control_id); } +static m64p_error init_video_capture_backend(const struct video_capture_backend_interface** ivcap, void** vcap, m64p_handle config, const char* key) +{ + m64p_error err; + + const char* name = ConfigGetParamString(config, key); + if (name == NULL) { + DebugMessage(M64MSG_WARNING, "Couldn't get %s value. Using NULL value instead.", key); + } + + /* try to find desired backend (by name) */ + *ivcap = get_video_capture_backend(name); + + /* handle not found case */ + if (*ivcap == NULL) { + /* default to dummy backend */ + *ivcap = get_video_capture_backend(NULL); + + DebugMessage(M64MSG_WARNING, "Could not find %s video_capture_backend_interface. Using %s instead.", + name, (*ivcap)->name); + } + + /* build section name */ + char* section = formatstr("%s:%s", key, (*ivcap)->name); + + /* init backend */ + err = (*ivcap)->init(vcap, section); + + if (err == M64ERR_SUCCESS) { + DebugMessage(M64MSG_INFO, "Using video capture backend: %s", (*ivcap)->name); + } + else { + DebugMessage(M64MSG_ERROR, "Failed to initialize video capture backend %s: %s", (*ivcap)->name, CoreErrorMessage(err)); + *ivcap = NULL; + } + + free(section); + + return err; +} + /********************************************************************************************************* * helper functions */ @@ -273,7 +312,7 @@ int main_set_core_defaults(void) ConfigSetDefaultBool(g_CoreConfig, "DisableSpecRecomp", 1, "Disable speculative precompilation in new dynarec"); ConfigSetDefaultBool(g_CoreConfig, "RandomizeInterrupt", 1, "Randomize PI/SI Interrupt Timing"); ConfigSetDefaultInt(g_CoreConfig, "SiDmaDuration", -1, "Duration of SI DMA (-1: use per game settings)"); - ConfigSetDefaultString(g_CoreConfig, "GbCameraVideoDevice", "0", "Gameboy Camera Video device - backend specific"); + ConfigSetDefaultString(g_CoreConfig, "GbCameraVideoCaptureBackend1", DEFAULT_VIDEO_CAPTURE_BACKEND, "Gameboy Camera Video Capture backend"); /* handle upgrades */ if (bUpgrade) @@ -1104,7 +1143,7 @@ struct gb_cart_data struct file_storage rom_fstorage; struct file_storage ram_fstorage; void* gbcam_backend; - const struct video_input_backend_interface* igbcam_backend; + const struct video_capture_backend_interface* igbcam_backend; }; static struct gb_cart_data l_gb_carts_data[GAME_CONTROLLERS_COUNT]; @@ -1259,8 +1298,8 @@ m64p_error main_run(void) struct file_storage mpk_storages[GAME_CONTROLLERS_COUNT]; struct file_storage mpk; - void* gbcam_backend = NULL; - const struct video_input_backend_interface* igbcam_backend = NULL; + void* gbcam_backend; + const struct video_capture_backend_interface* igbcam_backend; /* XXX: select type of flashram from db */ uint32_t flashram_type = MX29L1100_ID; @@ -1341,21 +1380,11 @@ m64p_error main_run(void) l_pak_type_idx[PLUGIN_TRANSFER_PAK] = k; } - /* open GB cam video device */ -#if defined(M64P_OPENCV) - { - struct opencv_video_backend* cv_backend = malloc(sizeof(*cv_backend)); - memset(cv_backend, 0, sizeof(*cv_backend)); - cv_backend->device = strdup(ConfigGetParamString(g_CoreConfig, "GbCameraVideoDevice")); - - gbcam_backend = cv_backend; - igbcam_backend = &g_iopencv_video_input_backend; - } -#else - gbcam_backend = NULL; - igbcam_backend = &g_idummy_video_input_backend; -#endif + /* init GbCamera backend specified in the configuration file */ + init_video_capture_backend(&igbcam_backend, &gbcam_backend, + g_CoreConfig, "GbCameraVideoCaptureBackend1"); + /* open GB cam video device */ igbcam_backend->open(gbcam_backend, M64282FP_SENSOR_W, M64282FP_SENSOR_H); /* open storage files, provide default content if not present */ @@ -1595,7 +1624,7 @@ m64p_error main_run(void) } igbcam_backend->close(gbcam_backend); - free(gbcam_backend); + igbcam_backend->release(gbcam_backend); close_file_storage(&sra); close_file_storage(&fla); @@ -1633,7 +1662,7 @@ m64p_error main_run(void) } igbcam_backend->close(gbcam_backend); - free(gbcam_backend); + igbcam_backend->release(gbcam_backend); /* release storage files */ close_file_storage(&sra);