mirror of
https://github.com/cemu-project/Cemu.git
synced 2025-04-29 14:59:26 -04:00
Change from singleton CameraManager
to namespace.
Update `openpnp-capture` dep for static linking. Fix camera selection dropdown width
This commit is contained in:
parent
29feae80e4
commit
d00222be11
7 changed files with 194 additions and 189 deletions
2
.gitmodules
vendored
2
.gitmodules
vendored
|
@ -21,4 +21,4 @@
|
||||||
[submodule "dependencies/openpnp-capture"]
|
[submodule "dependencies/openpnp-capture"]
|
||||||
path = dependencies/openpnp-capture
|
path = dependencies/openpnp-capture
|
||||||
url = https://github.com/capitalistspz/openpnp-capture
|
url = https://github.com/capitalistspz/openpnp-capture
|
||||||
branch = dev-no-explicit-shared
|
branch = dev
|
||||||
|
|
2
dependencies/openpnp-capture
vendored
2
dependencies/openpnp-capture
vendored
|
@ -1 +1 @@
|
||||||
Subproject commit ba456ac7572c6e6db49da53d2f4985d65309e582
|
Subproject commit 3daf77d3d4013238af4c97f0e3ca46c6d3666d1b
|
|
@ -146,7 +146,7 @@ namespace camera
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CameraManager::instance().FillNV12Buffer(surfaceBuffer.GetPtr());
|
CameraManager::FillNV12Buffer(surfaceBuffer.GetPtr());
|
||||||
s_cameraEventData->data = surfaceBuffer;
|
s_cameraEventData->data = surfaceBuffer;
|
||||||
s_cameraEventData->errored = false;
|
s_cameraEventData->errored = false;
|
||||||
}
|
}
|
||||||
|
@ -189,6 +189,7 @@ namespace camera
|
||||||
*error = CAM_STATUS_INVALID_ARG;
|
*error = CAM_STATUS_INVALID_ARG;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
CameraManager::Init();
|
||||||
|
|
||||||
cemu_assert_debug(initInfo->forceDisplay != CAMForceDisplay::DRC);
|
cemu_assert_debug(initInfo->forceDisplay != CAMForceDisplay::DRC);
|
||||||
cemu_assert_debug(initInfo->workMemorySize != 0);
|
cemu_assert_debug(initInfo->workMemorySize != 0);
|
||||||
|
@ -221,7 +222,7 @@ namespace camera
|
||||||
return CAM_STATUS_UNINITIALIZED;
|
return CAM_STATUS_UNINITIALIZED;
|
||||||
s_instance.isOpen = false;
|
s_instance.isOpen = false;
|
||||||
}
|
}
|
||||||
CameraManager::instance().Close();
|
CameraManager::Close();
|
||||||
return CAM_STATUS_SUCCESS;
|
return CAM_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,7 +235,7 @@ namespace camera
|
||||||
return CAM_STATUS_UNINITIALIZED;
|
return CAM_STATUS_UNINITIALIZED;
|
||||||
if (s_instance.isOpen)
|
if (s_instance.isOpen)
|
||||||
return CAM_STATUS_DEVICE_IN_USE;
|
return CAM_STATUS_DEVICE_IN_USE;
|
||||||
CameraManager::instance().Open();
|
CameraManager::Open();
|
||||||
s_instance.isOpen = true;
|
s_instance.isOpen = true;
|
||||||
coreinit::OSSignalEvent(s_cameraOpenEvent);
|
coreinit::OSSignalEvent(s_cameraOpenEvent);
|
||||||
s_instance.inTargetBuffers.Clear();
|
s_instance.inTargetBuffers.Clear();
|
||||||
|
|
|
@ -8,7 +8,8 @@ add_library(CemuCamera
|
||||||
set_property(TARGET CemuCamera PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
|
set_property(TARGET CemuCamera PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
|
||||||
|
|
||||||
target_include_directories(CemuCamera PUBLIC "../")
|
target_include_directories(CemuCamera PUBLIC "../")
|
||||||
target_link_libraries(CemuCamera PRIVATE CemuCommon CemuUtil PUBLIC openpnp-capture)
|
target_link_libraries(CemuCamera PRIVATE CemuCommon CemuUtil openpnp-capture)
|
||||||
|
|
||||||
|
|
||||||
if (ENABLE_WXWIDGETS)
|
if (ENABLE_WXWIDGETS)
|
||||||
target_link_libraries(CemuCamera PRIVATE wx::base)
|
target_link_libraries(CemuCamera PRIVATE wx::base)
|
||||||
|
|
|
@ -1,170 +1,195 @@
|
||||||
#include "CameraManager.h"
|
#include "CameraManager.h"
|
||||||
#include "Rgb2Nv12.h"
|
|
||||||
#include "config/CemuConfig.h"
|
#include "config/CemuConfig.h"
|
||||||
#include "util/helpers/helpers.h"
|
#include "util/helpers/helpers.h"
|
||||||
|
#include "Rgb2Nv12.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <mutex>
|
||||||
|
#include <optional>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
#include <openpnp-capture.h>
|
||||||
|
|
||||||
constexpr unsigned CAMERA_WIDTH = 640;
|
constexpr unsigned CAMERA_WIDTH = 640;
|
||||||
constexpr unsigned CAMERA_HEIGHT = 480;
|
constexpr unsigned CAMERA_HEIGHT = 480;
|
||||||
constexpr unsigned CAMERA_PITCH = 768;
|
constexpr unsigned CAMERA_PITCH = 768;
|
||||||
|
|
||||||
CameraManager::CameraManager()
|
namespace CameraManager
|
||||||
: m_ctx(Cap_createContext()),
|
|
||||||
m_rgbBuffer(CAMERA_WIDTH * CAMERA_HEIGHT * 3),
|
|
||||||
m_nv12Buffer(CAMERA_PITCH * CAMERA_HEIGHT * 3 / 2),
|
|
||||||
m_refCount(0), m_capturing(false), m_running(true)
|
|
||||||
{
|
{
|
||||||
m_captureThread = std::thread(&CameraManager::CaptureWorker, this);
|
std::mutex s_mutex;
|
||||||
|
bool s_initialized = false;
|
||||||
|
CapContext s_ctx;
|
||||||
|
std::optional<CapDeviceID> s_device;
|
||||||
|
std::optional<CapStream> s_stream;
|
||||||
|
std::array<uint8, CAMERA_WIDTH * CAMERA_HEIGHT * 3> s_rgbBuffer;
|
||||||
|
std::array<uint8, CAMERA_PITCH * CAMERA_HEIGHT * 3 / 2> s_nv12Buffer;
|
||||||
|
int s_refCount = 0;
|
||||||
|
std::thread s_captureThread;
|
||||||
|
std::atomic_bool s_capturing = false;
|
||||||
|
std::atomic_bool s_running = false;
|
||||||
|
|
||||||
const auto uniqueId = GetConfig().camera_id.GetValue();
|
std::optional<CapFormatID> FindCorrectFormat()
|
||||||
if (!uniqueId.empty())
|
|
||||||
{
|
{
|
||||||
const auto devices = EnumerateDevices();
|
const auto formatCount = Cap_getNumFormats(s_ctx, *s_device);
|
||||||
for (CapDeviceID deviceId = 0; deviceId < devices.size(); ++deviceId)
|
for (int32_t formatId = 0; formatId < formatCount; ++formatId)
|
||||||
{
|
{
|
||||||
if (devices[deviceId].uniqueId == uniqueId)
|
CapFormatInfo formatInfo;
|
||||||
|
if (Cap_getFormatInfo(s_ctx, *s_device, formatId, &formatInfo) != CAPRESULT_OK)
|
||||||
|
continue;
|
||||||
|
if (formatInfo.width == CAMERA_WIDTH && formatInfo.height == CAMERA_HEIGHT)
|
||||||
|
return formatId;
|
||||||
|
}
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CaptureWorker()
|
||||||
|
{
|
||||||
|
SetThreadName("CameraManager");
|
||||||
|
while (s_running)
|
||||||
|
{
|
||||||
|
while (s_capturing)
|
||||||
{
|
{
|
||||||
m_device = deviceId;
|
s_mutex.lock();
|
||||||
return;
|
if (s_stream && Cap_hasNewFrame(s_ctx, *s_stream) &&
|
||||||
|
Cap_captureFrame(s_ctx, *s_stream, s_rgbBuffer.data(), s_rgbBuffer.size()) == CAPRESULT_OK)
|
||||||
|
Rgb2Nv12(s_rgbBuffer.data(), CAMERA_WIDTH, CAMERA_HEIGHT, s_nv12Buffer.data(), CAMERA_PITCH);
|
||||||
|
s_mutex.unlock();
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(30));
|
||||||
|
}
|
||||||
|
std::this_thread::sleep_for(std::chrono::seconds(1));
|
||||||
|
std::this_thread::yield();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void OpenStream()
|
||||||
|
{
|
||||||
|
const auto formatId = FindCorrectFormat();
|
||||||
|
if (!formatId)
|
||||||
|
return;
|
||||||
|
const auto stream = Cap_openStream(s_ctx, *s_device, *formatId);
|
||||||
|
if (stream == -1)
|
||||||
|
return;
|
||||||
|
s_capturing = true;
|
||||||
|
s_stream = stream;
|
||||||
|
}
|
||||||
|
void CloseStream()
|
||||||
|
{
|
||||||
|
s_capturing = false;
|
||||||
|
if (s_stream)
|
||||||
|
{
|
||||||
|
Cap_closeStream(s_ctx, *s_stream);
|
||||||
|
s_stream = std::nullopt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void ResetBuffers()
|
||||||
|
{
|
||||||
|
std::ranges::fill(s_rgbBuffer, 0);
|
||||||
|
std::ranges::fill_n(s_nv12Buffer.begin(), CAMERA_WIDTH * CAMERA_PITCH, 16);
|
||||||
|
std::ranges::fill_n(s_nv12Buffer.begin() + CAMERA_WIDTH * CAMERA_PITCH, (CAMERA_WIDTH / 2), 128);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Init()
|
||||||
|
{
|
||||||
|
std::scoped_lock lock(s_mutex);
|
||||||
|
if (s_initialized)
|
||||||
|
return;
|
||||||
|
s_mutex.unlock();
|
||||||
|
s_running = true;
|
||||||
|
s_captureThread = std::thread(&CaptureWorker);
|
||||||
|
s_ctx = Cap_createContext();
|
||||||
|
|
||||||
|
const auto uniqueId = GetConfig().camera_id.GetValue();
|
||||||
|
if (!uniqueId.empty())
|
||||||
|
{
|
||||||
|
const auto devices = EnumerateDevices();
|
||||||
|
for (CapDeviceID deviceId = 0; deviceId < devices.size(); ++deviceId)
|
||||||
|
{
|
||||||
|
if (devices[deviceId].uniqueId == uniqueId)
|
||||||
|
{
|
||||||
|
s_device = deviceId;
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
ResetBuffers();
|
|
||||||
}
|
|
||||||
CameraManager::~CameraManager()
|
|
||||||
{
|
|
||||||
m_running = false;
|
|
||||||
CloseStream();
|
|
||||||
Cap_releaseContext(m_ctx);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CameraManager::SetDevice(uint32 deviceNo)
|
|
||||||
{
|
|
||||||
std::scoped_lock lock(m_mutex);
|
|
||||||
CloseStream();
|
|
||||||
if (deviceNo == DEVICE_NONE)
|
|
||||||
{
|
|
||||||
m_device = std::nullopt;
|
|
||||||
ResetBuffers();
|
ResetBuffers();
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
m_device = deviceNo;
|
void Deinit()
|
||||||
if (m_refCount != 0)
|
|
||||||
OpenStream();
|
|
||||||
}
|
|
||||||
std::vector<CameraManager::DeviceInfo> CameraManager::EnumerateDevices()
|
|
||||||
{
|
|
||||||
std::scoped_lock lock(m_mutex);
|
|
||||||
std::vector<DeviceInfo> infos;
|
|
||||||
const auto deviceCount = Cap_getDeviceCount(m_ctx);
|
|
||||||
for (CapDeviceID deviceNo = 0; deviceNo < deviceCount; ++deviceNo)
|
|
||||||
{
|
{
|
||||||
const auto uniqueId = Cap_getDeviceUniqueID(m_ctx, deviceNo);
|
CloseStream();
|
||||||
const auto name = Cap_getDeviceName(m_ctx, deviceNo);
|
Cap_releaseContext(s_ctx);
|
||||||
DeviceInfo info;
|
s_captureThread.join();
|
||||||
info.uniqueId = uniqueId;
|
s_initialized = false;
|
||||||
|
|
||||||
if (name)
|
|
||||||
info.name = fmt::format("{}: {}", deviceNo + 1, name);
|
|
||||||
else
|
|
||||||
info.name = fmt::format("{}: Unknown", deviceNo + 1);
|
|
||||||
infos.push_back(info);
|
|
||||||
}
|
}
|
||||||
return infos;
|
void FillNV12Buffer(uint8* nv12Buffer)
|
||||||
}
|
|
||||||
void CameraManager::SaveDevice()
|
|
||||||
{
|
|
||||||
std::scoped_lock lock(m_mutex);
|
|
||||||
if (m_device)
|
|
||||||
GetConfig().camera_id = Cap_getDeviceUniqueID(m_ctx, *m_device);
|
|
||||||
else
|
|
||||||
GetConfig().camera_id = "";
|
|
||||||
}
|
|
||||||
void CameraManager::Open()
|
|
||||||
{
|
|
||||||
std::scoped_lock lock(m_mutex);
|
|
||||||
if (m_device && m_refCount == 0)
|
|
||||||
{
|
{
|
||||||
OpenStream();
|
std::scoped_lock lock(s_mutex);
|
||||||
|
std::ranges::copy(s_nv12Buffer, nv12Buffer);
|
||||||
}
|
}
|
||||||
m_refCount += 1;
|
|
||||||
}
|
|
||||||
void CameraManager::Close()
|
|
||||||
{
|
|
||||||
std::scoped_lock lock(m_mutex);
|
|
||||||
if (m_refCount == 0)
|
|
||||||
return;
|
|
||||||
m_refCount -= 1;
|
|
||||||
if (m_refCount != 0)
|
|
||||||
return;
|
|
||||||
CloseStream();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::optional<CapFormatID> CameraManager::FindCorrectFormat()
|
void FillRGBBuffer(uint8* rgbBuffer)
|
||||||
{
|
|
||||||
const auto formatCount = Cap_getNumFormats(m_ctx, *m_device);
|
|
||||||
for (CapFormatID formatId = 0; formatId < formatCount; ++formatId)
|
|
||||||
{
|
{
|
||||||
CapFormatInfo formatInfo;
|
std::scoped_lock lock(s_mutex);
|
||||||
if (Cap_getFormatInfo(m_ctx, *m_device, formatId, &formatInfo) != CAPRESULT_OK)
|
std::ranges::copy(s_rgbBuffer, rgbBuffer);
|
||||||
continue;
|
|
||||||
if (formatInfo.width == CAMERA_WIDTH && formatInfo.height == CAMERA_HEIGHT)
|
|
||||||
return formatId;
|
|
||||||
}
|
}
|
||||||
return std::nullopt;
|
void SetDevice(uint32 deviceNo)
|
||||||
}
|
|
||||||
void CameraManager::ResetBuffers()
|
|
||||||
{
|
|
||||||
std::ranges::fill(m_rgbBuffer, 0);
|
|
||||||
std::ranges::fill_n(m_nv12Buffer.begin(), CAMERA_WIDTH * CAMERA_PITCH, 16);
|
|
||||||
std::ranges::fill_n(m_nv12Buffer.begin() + CAMERA_WIDTH * CAMERA_PITCH, (CAMERA_WIDTH / 2), 128);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CameraManager::FillNV12Buffer(uint8* nv12Buffer) const
|
|
||||||
{
|
|
||||||
std::scoped_lock lock(m_mutex);
|
|
||||||
std::ranges::copy(m_nv12Buffer, nv12Buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CameraManager::FillRGBBuffer(uint8* rgbBuffer) const
|
|
||||||
{
|
|
||||||
std::scoped_lock lock(m_mutex);
|
|
||||||
std::ranges::copy(m_rgbBuffer, rgbBuffer);
|
|
||||||
}
|
|
||||||
void CameraManager::CaptureWorker()
|
|
||||||
{
|
|
||||||
SetThreadName("CameraManager");
|
|
||||||
while (m_running)
|
|
||||||
{
|
{
|
||||||
while (m_capturing)
|
std::scoped_lock lock(s_mutex);
|
||||||
|
CloseStream();
|
||||||
|
if (deviceNo == DEVICE_NONE)
|
||||||
{
|
{
|
||||||
m_mutex.lock();
|
s_device = std::nullopt;
|
||||||
if (m_stream && Cap_hasNewFrame(m_ctx, *m_stream) &&
|
ResetBuffers();
|
||||||
Cap_captureFrame(m_ctx, *m_stream, m_rgbBuffer.data(), m_rgbBuffer.size()) == CAPRESULT_OK)
|
return;
|
||||||
Rgb2Nv12(m_rgbBuffer.data(), CAMERA_WIDTH, CAMERA_HEIGHT, m_nv12Buffer.data(), CAMERA_PITCH);
|
|
||||||
m_mutex.unlock();
|
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(30));
|
|
||||||
}
|
}
|
||||||
std::this_thread::sleep_for(std::chrono::seconds(1));
|
s_device = deviceNo;
|
||||||
std::this_thread::yield();
|
if (s_refCount != 0)
|
||||||
|
OpenStream();
|
||||||
}
|
}
|
||||||
}
|
void Open()
|
||||||
void CameraManager::OpenStream()
|
|
||||||
{
|
|
||||||
const auto formatId = FindCorrectFormat();
|
|
||||||
if (!formatId)
|
|
||||||
return;
|
|
||||||
const auto stream = Cap_openStream(m_ctx, *m_device, *formatId);
|
|
||||||
if (stream == -1)
|
|
||||||
return;
|
|
||||||
m_capturing = true;
|
|
||||||
m_stream = stream;
|
|
||||||
}
|
|
||||||
void CameraManager::CloseStream()
|
|
||||||
{
|
|
||||||
m_capturing = false;
|
|
||||||
if (m_stream)
|
|
||||||
{
|
{
|
||||||
Cap_closeStream(m_ctx, *m_stream);
|
std::scoped_lock lock(s_mutex);
|
||||||
m_stream = std::nullopt;
|
if (s_device && s_refCount == 0)
|
||||||
|
{
|
||||||
|
OpenStream();
|
||||||
|
}
|
||||||
|
s_refCount += 1;
|
||||||
}
|
}
|
||||||
}
|
void Close()
|
||||||
|
{
|
||||||
|
std::scoped_lock lock(s_mutex);
|
||||||
|
if (s_refCount == 0)
|
||||||
|
return;
|
||||||
|
s_refCount -= 1;
|
||||||
|
if (s_refCount != 0)
|
||||||
|
return;
|
||||||
|
CloseStream();
|
||||||
|
}
|
||||||
|
std::vector<DeviceInfo> EnumerateDevices()
|
||||||
|
{
|
||||||
|
std::scoped_lock lock(s_mutex);
|
||||||
|
std::vector<DeviceInfo> infos;
|
||||||
|
const auto deviceCount = Cap_getDeviceCount(s_ctx);
|
||||||
|
for (CapDeviceID deviceNo = 0; deviceNo < deviceCount; ++deviceNo)
|
||||||
|
{
|
||||||
|
const auto uniqueId = Cap_getDeviceUniqueID(s_ctx, deviceNo);
|
||||||
|
const auto name = Cap_getDeviceName(s_ctx, deviceNo);
|
||||||
|
DeviceInfo info;
|
||||||
|
info.uniqueId = uniqueId;
|
||||||
|
|
||||||
|
if (name)
|
||||||
|
info.name = fmt::format("{}: {}", deviceNo + 1, name);
|
||||||
|
else
|
||||||
|
info.name = fmt::format("{}: Unknown", deviceNo + 1);
|
||||||
|
infos.push_back(info);
|
||||||
|
}
|
||||||
|
return infos;
|
||||||
|
}
|
||||||
|
void SaveDevice()
|
||||||
|
{
|
||||||
|
std::scoped_lock lock(s_mutex);
|
||||||
|
if (s_device)
|
||||||
|
GetConfig().camera_id = Cap_getDeviceUniqueID(s_ctx, *s_device);
|
||||||
|
else
|
||||||
|
GetConfig().camera_id = "";
|
||||||
|
}
|
||||||
|
} // namespace CameraManager
|
|
@ -1,46 +1,24 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <atomic>
|
#include <string>
|
||||||
#include <mutex>
|
|
||||||
#include <thread>
|
|
||||||
#include <openpnp-capture.h>
|
|
||||||
#include "util/helpers/Singleton.h"
|
|
||||||
|
|
||||||
class CameraManager : public Singleton<CameraManager>
|
namespace CameraManager
|
||||||
{
|
{
|
||||||
CapContext m_ctx;
|
|
||||||
std::optional<CapDeviceID> m_device;
|
|
||||||
std::optional<CapStream> m_stream;
|
|
||||||
std::vector<uint8> m_rgbBuffer;
|
|
||||||
std::vector<uint8> m_nv12Buffer;
|
|
||||||
int m_refCount;
|
|
||||||
std::thread m_captureThread;
|
|
||||||
std::atomic_bool m_capturing;
|
|
||||||
std::atomic_bool m_running;
|
|
||||||
mutable std::recursive_mutex m_mutex;
|
|
||||||
|
|
||||||
public:
|
|
||||||
constexpr static uint32 DEVICE_NONE = std::numeric_limits<uint32>::max();
|
|
||||||
struct DeviceInfo
|
struct DeviceInfo
|
||||||
{
|
{
|
||||||
std::string uniqueId;
|
std::string uniqueId;
|
||||||
std::string name;
|
std::string name;
|
||||||
};
|
};
|
||||||
CameraManager();
|
constexpr static uint32 DEVICE_NONE = std::numeric_limits<uint32>::max();
|
||||||
~CameraManager();
|
|
||||||
|
void Init();
|
||||||
|
void Deinit();
|
||||||
|
void Open();
|
||||||
|
void Close();
|
||||||
|
|
||||||
|
void FillNV12Buffer(uint8* nv12Buffer);
|
||||||
|
void FillRGBBuffer(uint8* rgbBuffer);
|
||||||
|
|
||||||
void SetDevice(uint32 deviceNo);
|
void SetDevice(uint32 deviceNo);
|
||||||
std::vector<DeviceInfo> EnumerateDevices();
|
std::vector<DeviceInfo> EnumerateDevices();
|
||||||
void SaveDevice();
|
void SaveDevice();
|
||||||
|
} // namespace CameraManager
|
||||||
void Open();
|
|
||||||
void Close();
|
|
||||||
void FillNV12Buffer(uint8* nv12Buffer) const;
|
|
||||||
void FillRGBBuffer(uint8* rgbBuffer) const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::optional<CapFormatID> FindCorrectFormat();
|
|
||||||
void ResetBuffers();
|
|
||||||
void CaptureWorker();
|
|
||||||
void OpenStream();
|
|
||||||
void CloseStream();
|
|
||||||
};
|
|
||||||
|
|
|
@ -20,8 +20,7 @@ CameraSettingsWindow::CameraSettingsWindow(wxWindow* parent)
|
||||||
{
|
{
|
||||||
auto* topSizer = new wxBoxSizer(wxHORIZONTAL);
|
auto* topSizer = new wxBoxSizer(wxHORIZONTAL);
|
||||||
{
|
{
|
||||||
wxString choices[] = {_("None")};
|
m_cameraChoice = new wxChoice(this, wxID_ANY, wxDefaultPosition, {300, -1});
|
||||||
m_cameraChoice = new wxChoice(this, wxID_ANY, wxDefaultPosition, {300, -1}, 1, choices);
|
|
||||||
m_cameraChoice->Bind(wxEVT_CHOICE, &CameraSettingsWindow::OnSelectCameraChoice, this);
|
m_cameraChoice->Bind(wxEVT_CHOICE, &CameraSettingsWindow::OnSelectCameraChoice, this);
|
||||||
|
|
||||||
m_refreshButton = new wxButton(this, wxID_ANY, wxString::FromUTF8("⟳"));
|
m_refreshButton = new wxButton(this, wxID_ANY, wxString::FromUTF8("⟳"));
|
||||||
|
@ -38,7 +37,8 @@ CameraSettingsWindow::CameraSettingsWindow(wxWindow* parent)
|
||||||
rootSizer->Add(m_imageWindow, wxEXPAND);
|
rootSizer->Add(m_imageWindow, wxEXPAND);
|
||||||
}
|
}
|
||||||
SetSizerAndFit(rootSizer);
|
SetSizerAndFit(rootSizer);
|
||||||
CameraManager::instance().Open();
|
CameraManager::Init();
|
||||||
|
CameraManager::Open();
|
||||||
m_imageUpdateTimer.Bind(wxEVT_TIMER, &CameraSettingsWindow::UpdateImage, this);
|
m_imageUpdateTimer.Bind(wxEVT_TIMER, &CameraSettingsWindow::UpdateImage, this);
|
||||||
m_imageUpdateTimer.Start(33, wxTIMER_CONTINUOUS);
|
m_imageUpdateTimer.Start(33, wxTIMER_CONTINUOUS);
|
||||||
this->Bind(wxEVT_CLOSE_WINDOW, &CameraSettingsWindow::OnClose, this);
|
this->Bind(wxEVT_CLOSE_WINDOW, &CameraSettingsWindow::OnClose, this);
|
||||||
|
@ -49,14 +49,14 @@ void CameraSettingsWindow::OnSelectCameraChoice(wxCommandEvent&)
|
||||||
if (selection < 0)
|
if (selection < 0)
|
||||||
return;
|
return;
|
||||||
if (selection == 0)
|
if (selection == 0)
|
||||||
CameraManager::instance().SetDevice(CameraManager::DEVICE_NONE);
|
CameraManager::SetDevice(CameraManager::DEVICE_NONE);
|
||||||
else
|
else
|
||||||
CameraManager::instance().SetDevice(selection - 1);
|
CameraManager::SetDevice(selection - 1);
|
||||||
}
|
}
|
||||||
void CameraSettingsWindow::OnRefreshPressed(wxCommandEvent&)
|
void CameraSettingsWindow::OnRefreshPressed(wxCommandEvent&)
|
||||||
{
|
{
|
||||||
wxArrayString choices = {_("None")};
|
wxArrayString choices = {_("None")};
|
||||||
for (const auto& entry : CameraManager::instance().EnumerateDevices())
|
for (const auto& entry : CameraManager::EnumerateDevices())
|
||||||
{
|
{
|
||||||
choices.push_back(entry.name);
|
choices.push_back(entry.name);
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,7 @@ void CameraSettingsWindow::OnRefreshPressed(wxCommandEvent&)
|
||||||
}
|
}
|
||||||
void CameraSettingsWindow::UpdateImage(const wxTimerEvent&)
|
void CameraSettingsWindow::UpdateImage(const wxTimerEvent&)
|
||||||
{
|
{
|
||||||
CameraManager::instance().FillRGBBuffer(m_imageBuffer.data());
|
CameraManager::FillRGBBuffer(m_imageBuffer.data());
|
||||||
|
|
||||||
wxNativePixelData data{m_imageBitmap};
|
wxNativePixelData data{m_imageBitmap};
|
||||||
if (!data)
|
if (!data)
|
||||||
|
@ -92,7 +92,7 @@ void CameraSettingsWindow::UpdateImage(const wxTimerEvent&)
|
||||||
}
|
}
|
||||||
void CameraSettingsWindow::OnClose(wxCloseEvent& event)
|
void CameraSettingsWindow::OnClose(wxCloseEvent& event)
|
||||||
{
|
{
|
||||||
CameraManager::instance().Close();
|
CameraManager::Close();
|
||||||
CameraManager::instance().SaveDevice();
|
CameraManager::SaveDevice();
|
||||||
event.Skip();
|
event.Skip();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue