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);