summaryrefslogtreecommitdiffhomepage
path: root/video-ps3eye
diff options
context:
space:
mode:
Diffstat (limited to 'video-ps3eye')
-rw-r--r--video-ps3eye/CMakeLists.txt33
-rw-r--r--video-ps3eye/shm-layout.hpp20
-rw-r--r--video-ps3eye/shm.cxx3
-rw-r--r--video-ps3eye/shm.hpp2
-rw-r--r--video-ps3eye/wrapper.cxx105
5 files changed, 141 insertions, 22 deletions
diff --git a/video-ps3eye/CMakeLists.txt b/video-ps3eye/CMakeLists.txt
index d42c83ff..888c4fc7 100644
--- a/video-ps3eye/CMakeLists.txt
+++ b/video-ps3eye/CMakeLists.txt
@@ -21,18 +21,6 @@ if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/ps3eye-driver/CMakeLists.txt")
endif()
endif()
-if(TARGET ps3eye-driver)
- otr_module(video-ps3eye)
- link_libraries(ps3eye-driver)
- add_executable(ps3eye-subprocess "wrapper.cxx")
- if(WIN32)
- set(path "${SDK_LIBUSB}/libusb-1.0.dll")
- if(EXISTS "${path}")
- otr_install_lib("${path}" "${opentrack-hier-pfx}")
- endif()
- endif()
-endif()
-
if(TARGET ps3eye-sdl)
install(TARGETS "ps3eye-sdl" DESTINATION "${opentrack-hier-pfx}")
if(WIN32)
@@ -51,6 +39,25 @@ if(TARGET ps3eye-mode-test)
install(TARGETS "ps3eye-mode-test" DESTINATION "${opentrack-hier-pfx}")
endif()
+if(TARGET ps3eye-driver)
+ add_executable(ps3eye-subprocess "wrapper.cxx" "shm.cxx")
+ if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux")
+ target_link_libraries(ps3eye-subprocess rt ps3eye-driver)
+ endif()
+ install(TARGETS "ps3eye-subprocess" DESTINATION "${opentrack-hier-pfx}")
+endif()
+
+if(TARGET ps3eye-subprocess)
+ otr_module(video-ps3eye)
+ link_libraries(ps3eye-driver)
+ if(WIN32)
+ set(path "${SDK_LIBUSB}/libusb-1.0.dll")
+ if(EXISTS "${path}")
+ otr_install_lib("${path}" "${opentrack-hier-pfx}")
+ endif()
+ endif()
+endif()
+
if(TARGET ps3eye-frame-test)
install(TARGETS "ps3eye-frame-test" DESTINATION "${opentrack-hier-pfx}")
-endif() \ No newline at end of file
+endif()
diff --git a/video-ps3eye/shm-layout.hpp b/video-ps3eye/shm-layout.hpp
index 7fa29115..eba4b8b0 100644
--- a/video-ps3eye/shm-layout.hpp
+++ b/video-ps3eye/shm-layout.hpp
@@ -3,25 +3,27 @@
namespace ps3eye {
-struct shm_out {
+struct shm_in {
enum class mode : uint8_t { qvga, vga, };
enum class status : uint8_t { starting, running, fail, terminate, };
- uint8_t settings_updated;
+ uint32_t settings_updated;
uint16_t framerate;
mode resolution;
status status_;
- uint8_t sharpness, contrast, brightness, hue, saturation;
- uint8_t gain, exposure, auto_gain, awb, test_pattern;
+ //uint8_t sharpness, contrast, brightness hue, saturation;
+ uint8_t gain, exposure, auto_gain, test_pattern;
+ uint8_t do_exit;
};
-struct shm_in {
- uint8_t settings_updated_ack;
- uint8_t timecode;
+struct shm_out {
+ uint32_t timecode;
+ uint32_t settings_updated_ack;
union {
uint8_t data_320x240[320][240][3];
uint8_t data_640x480[640][480][3];
};
+ char error_string[256];
};
struct shm {
@@ -29,8 +31,8 @@ struct shm {
static constexpr unsigned _padding_len =
(_cacheline_len - (sizeof(shm_in) & (_cacheline_len - 1))) & (_cacheline_len - 1);
- using resolution = shm_out::mode;
- using status = shm_out::status;
+ using resolution = shm_in::mode;
+ using status = shm_in::status;
shm_out out;
const char* _padding[_padding_len];
diff --git a/video-ps3eye/shm.cxx b/video-ps3eye/shm.cxx
new file mode 100644
index 00000000..6a8c0f53
--- /dev/null
+++ b/video-ps3eye/shm.cxx
@@ -0,0 +1,3 @@
+#define OTR_GENERIC_EXPORT
+#define OTR_GENERIC_IMPORT
+#include "../compat/shm.cpp"
diff --git a/video-ps3eye/shm.hpp b/video-ps3eye/shm.hpp
new file mode 100644
index 00000000..ef73be8a
--- /dev/null
+++ b/video-ps3eye/shm.hpp
@@ -0,0 +1,2 @@
+#pragma once
+#include "../compat/shm.h"
diff --git a/video-ps3eye/wrapper.cxx b/video-ps3eye/wrapper.cxx
index add62992..be9e338e 100644
--- a/video-ps3eye/wrapper.cxx
+++ b/video-ps3eye/wrapper.cxx
@@ -1,7 +1,112 @@
#include "shm-layout.hpp"
+#include "shm.hpp"
+
+#include "ps3eye-driver/ps3eye.hpp"
+
+#include <cstdlib>
+
+#ifdef __clang__
+# pragma clang diagnostic ignored "-Watomic-implicit-seq-cst"
+#endif
+
+#ifdef __GNUG__
+# pragma GCC diagnostic ignored "-Wcast-qual"
+# pragma GCC diagnostic ignored "-Wformat-security"
+# pragma GCC diagnostic ignored "-Wformat-nonliteral"
+#endif
+
+#ifdef _MSC_VER
+# include <windows.h>
+# define FULL_BARRIER [](){ _ReadWriteBarrier(); MemoryBarrier(); }
+#else
+# define FULL_BARRIER __sync_synchronize
+#endif
+
+template<int N, typename... xs>
+[[noreturn]]
+static void error(volatile ps3eye::shm_out& out, const char (&error)[N], const xs&... args)
+{
+ snprintf((char*)out.error_string, sizeof(ps3eye::shm_out::error_string), error, args...);
+ std::quick_exit(2);
+}
+
+static void update_settings(ps3eye::camera& camera, const volatile ps3eye::shm_in& in)
+{
+ camera.set_framerate(in.framerate);
+ camera.set_auto_gain(in.auto_gain);
+ camera.set_gain(in.gain);
+ camera.set_exposure(in.exposure);
+ camera.set_test_pattern_status(in.test_pattern);
+}
int main(int argc, char** argv)
{
(void)argc; (void)argv;
+ shm_wrapper mem_("ps3eye-driver-shm", nullptr, sizeof(ps3eye::shm));
+ volatile auto& ptr_ = *(ps3eye::shm*)mem_.ptr();
+ const volatile auto& in = ptr_.in;
+ volatile auto& out = ptr_.out;
+
+ auto cameras = ps3eye::list_devices();
+
+ if (cameras.empty())
+ error(out, "no camera found");
+
+ auto& camera = cameras[0];
+ uint8_t* frame;
+ decltype(out.timecode) timecode = 0;
+
+ {
+ ps3eye::resolution mode;
+ switch (in.resolution)
+ {
+ case ps3eye::shm_in::mode::qvga:
+ mode = ps3eye::res_QVGA;
+ frame = (uint8_t*)out.data_320x240;
+ break;
+ case ps3eye::shm_in::mode::vga:
+ mode = ps3eye::res_VGA;
+ frame = (uint8_t*)out.data_640x480;
+ break;
+ default: error(out, "wrong resolution %u", (unsigned)mode);
+ }
+
+ int framerate = in.framerate;
+ if (!framerate)
+ framerate = 60;
+
+ bool ret = camera->init(mode, framerate) && camera->start();
+ if (!ret)
+ error(out, "camera init failed: %s", camera->error_string());
+ }
+
+ update_settings(*camera, in);
+
+ for (;;)
+ {
+ {
+ auto cookie = in.settings_updated;
+ if (cookie != out.settings_updated_ack)
+ {
+ update_settings(*camera, in);
+ out.settings_updated_ack = cookie;
+ }
+ }
+
+ bool success = true;
+
+ success &= camera->get_frame(frame);
+
+ if (!success)
+ error(out, "error %s", camera->error_string());
+
+ out.timecode = ++timecode;
+
+ if (in.do_exit)
+ break;
+
+ FULL_BARRIER();
+ }
+
return 0;
}