extcam camera preview

This commit is contained in:
milek7
2019-09-07 02:06:09 +02:00
parent 4b50fba6bc
commit c651ba21a2
10 changed files with 283 additions and 5 deletions

View File

@@ -29,7 +29,8 @@ file(GLOB HEADERS "*.h"
"network/*.h"
"network/backend/*.h"
"widgets/*.h"
"launcher/*.h")
"launcher/*.h"
"extras/*.h")
if (APPLE)
set (CMAKE_EXE_LINKER_FLAGS "-pagezero_size 10000 -image_base 100000000")
@@ -37,6 +38,7 @@ endif()
option(USE_IMGUI_GL3 "Use OpenGL3+ imgui implementation" ON)
option(WITH_UART "Compile with libserialport" ON)
option(USE_VSDEV_CAMERA "Use VS_Dev camera preview implementation" OFF)
set(SOURCES
"Texture.cpp"
@@ -140,7 +142,6 @@ set(SOURCES
"widgets/vehicleparams.cpp"
"widgets/trainingcard.cpp"
"widgets/perfgraphs.cpp"
"widgets/cameraview.cpp"
"ref/glad/src/glad.c"
@@ -163,7 +164,6 @@ set(SOURCES
"imgui/imgui_impl_glfw.cpp"
"stb/stb_image.c"
"extras/VS_Dev.cpp"
"launcher/launchermode.cpp"
"launcher/scenery_list.cpp"
@@ -186,6 +186,14 @@ if (WITH_UART)
set(SOURCES ${SOURCES} "uart.cpp")
endif()
if (USE_VSDEV_CAMERA)
add_definitions(-DUSE_VSDEV_CAMERA)
set(SOURCES ${SOURCES} "extras/VS_Dev.cpp" "widgets/cameraview_vsdev.cpp")
else()
add_definitions(-DUSE_EXTCAM_CAMERA)
set(SOURCES ${SOURCES} "extras/piped_proc.cpp" "widgets/cameraview_extcam.cpp")
endif()
set (PREFIX "")
if (WIN32)

View File

@@ -702,6 +702,16 @@ global_settings::ConfigParse(cParser &Parser) {
Parser.getTokens( 1 );
Parser >> uart_conf.debug;
}
#endif
#ifdef USE_EXTCAM_CAMERA
else if( token == "extcam.cmd" ) {
Parser.getTokens( 1 );
Parser >> extcam_cmd;
}
else if( token == "extcam.res" ) {
Parser.getTokens( 2 );
Parser >> extcam_res.x >> extcam_res.y;
}
#endif
else if (token == "loadinglog") {
Parser.getTokens( 1 );

View File

@@ -187,6 +187,11 @@ struct global_settings {
bool captureonstart = true;
bool render_cab = true;
#ifdef USE_EXTCAM_CAMERA
std::string extcam_cmd;
glm::ivec2 extcam_res{800, 600};
#endif
std::chrono::duration<float> minframetime {0.0f};
std::string fullscreen_monitor;

View File

@@ -18,8 +18,12 @@ http://mozilla.org/MPL/2.0/.
#include "widgets/map.h"
#include "widgets/time.h"
#include "widgets/trainingcard.h"
#include "widgets/cameraview.h"
#include "widgets/perfgraphs.h"
#ifdef USE_EXTCAM_CAMERA
#include "widgets/cameraview_extcam.h"
#elif USE_VSDEV_CAMERA
#include "widgets/cameraview_vsdev.h"
#endif
class driver_ui : public ui_layer {

87
extras/piped_proc.cpp Normal file
View File

@@ -0,0 +1,87 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "stdafx.h"
#include "piped_proc.h"
#include "Logs.h"
#ifdef __unix__
piped_proc::piped_proc(std::string cmd)
{
file = popen(cmd.c_str(), "r");
}
piped_proc::~piped_proc()
{
if (file)
pclose(file);
}
size_t piped_proc::read(unsigned char *buf, size_t len)
{
if (!file)
return 0;
return fread(buf, 1, len, file);
}
#elif _WIN32
piped_proc::piped_proc(std::string cmd)
{
PROCESS_INFORMATION process;
STARTUPINFO siStartInfo;
SECURITY_ATTRIBUTES saAttr;
memset(&process, 0, sizeof(PROCESS_INFORMATION));
memset(&siStartInfo, 0, sizeof(STARTUPINFO));
memset(&saAttr, 0, sizeof(SECURITY_ATTRIBUTES));
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
saAttr.bInheritHandle = TRUE;
saAttr.lpSecurityDescriptor = NULL;
if (!CreatePipe(&pipe_rd, &pipe_wr, &saAttr, 0)) {
ErrorLog("piped_proc: CreatePipe failed!");
return;
}
if (!SetHandleInformation(pipe_rd, HANDLE_FLAG_INHERIT, 0)) {
ErrorLog("piped_proc: SetHandleInformation failed!");
return;
}
siStartInfo.cb = sizeof(STARTUPINFO);
siStartInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE);
siStartInfo.hStdOutput = pipe_wr;
siStartInfo.dwFlags |= STARTF_USESTDHANDLES;
if (!CreateProcessA(NULL, (char*)cmd.c_str(), NULL, NULL, TRUE, 0, NULL, NULL, &siStartInfo, &process)) {
ErrorLog("piped_proc: CreateProcess failed!");
return;
}
if (process.hProcess)
CloseHandle(process.hProcess);
if (process.hThread)
CloseHandle(process.hThread);
}
piped_proc::~piped_proc()
{
if (pipe_wr)
CloseHandle(pipe_wr);
if (pipe_rd)
CloseHandle(pipe_rd);
}
size_t piped_proc::read(unsigned char *buf, size_t len)
{
if (!pipe_rd)
return 0;
DWORD read = 0;
BOOL ret = ReadFile(pipe_rd, buf, len, &read, NULL);
return read;
}
#endif

28
extras/piped_proc.h Normal file
View File

@@ -0,0 +1,28 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#pragma once
#ifdef __unix__
#include <cstdio>
#elif _WIN32
#include "winheaders.h"
#endif
#include <string>
class piped_proc
{
private:
#ifdef __unix__
FILE *file = nullptr;
#elif _WIN32
HANDLE pipe_rd = nullptr;
HANDLE pipe_wr = nullptr;
#endif
public:
piped_proc(std::string cmd);
size_t read(unsigned char *buf, size_t len);
~piped_proc();
};

View File

@@ -0,0 +1,105 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "stdafx.h"
#include "widgets/cameraview_extcam.h"
#include "stb/stb_image.h"
#include "Globals.h"
#include "Logs.h"
#include "extras/piped_proc.h"
ui::cameraview_panel::cameraview_panel()
: ui_panel(STR_C("Camera preview"), false)
{
size_min = { -2, -2 };
}
void cameraview_window_callback(ImGuiSizeCallbackData *data) {
data->DesiredSize.y = data->DesiredSize.x * (float)Global.extcam_res.y / (float)Global.extcam_res.x;
}
ui::cameraview_panel::~cameraview_panel() {
exit_thread = true;
if (workthread.joinable())
workthread.detach();
}
void ui::cameraview_panel::render()
{
if (!is_open)
exit_thread = true;
if (is_open)
ImGui::SetNextWindowSizeConstraints(ImVec2(200, 200), ImVec2(2500, 2500), cameraview_window_callback);
ui_panel::render();
}
void ui::cameraview_panel::render_contents()
{
if (exit_thread) {
if (workthread.joinable())
workthread.join();
exit_thread = false;
if (!Global.extcam_cmd.empty())
workthread = std::thread(&cameraview_panel::workthread_func, this);
}
if (!texture) {
texture.emplace();
texture->make_stub();
}
texture->bind(0);
{
std::lock_guard<std::mutex> lock(mutex);
if (image_ptr) {
glActiveTexture(GL_TEXTURE0);
glTexImage2D(
GL_TEXTURE_2D, 0,
GL_SRGB8_ALPHA8,
Global.extcam_res.x, Global.extcam_res.y, 0,
GL_RGB, GL_UNSIGNED_BYTE, image_ptr);
image_ptr = nullptr;
if (Global.python_mipmaps) {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glGenerateMipmap(GL_TEXTURE_2D);
}
else {
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
}
}
}
ImVec2 surface_size = ImGui::GetContentRegionAvail();
ImGui::Image(reinterpret_cast<void*>(texture->id), surface_size);
}
void ui::cameraview_panel::workthread_func()
{
piped_proc proc(Global.extcam_cmd);
size_t frame_size = Global.extcam_res.x * Global.extcam_res.y * 3;
uint8_t *read_buffer = new uint8_t[frame_size];
uint8_t *active_buffer = new uint8_t[frame_size];
while (!exit_thread) {
if (proc.read(read_buffer, frame_size) != frame_size)
break;
std::lock_guard<std::mutex> lock(mutex);
image_ptr = read_buffer;
read_buffer = active_buffer;
active_buffer = image_ptr;
}
std::lock_guard<std::mutex> lock(mutex);
image_ptr = nullptr;
delete[] read_buffer;
delete[] active_buffer;
}

View File

@@ -0,0 +1,31 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#pragma once
#include "stdafx.h"
#include "uilayer.h"
namespace ui
{
class cameraview_panel : public ui_panel
{
std::atomic_bool exit_thread = true;
std::thread workthread;
uint8_t* image_ptr = nullptr;
std::mutex mutex;
std::optional<opengl_texture> texture;
void workthread_func();
public:
cameraview_panel();
~cameraview_panel();
void render() override;
void render_contents() override;
};
} // namespace ui

View File

@@ -1,5 +1,5 @@
#include "stdafx.h"
#include "widgets/cameraview.h"
#include "widgets/cameraview_vsdev.h"
#include "stb/stb_image.h"
#include "Globals.h"
#include "Logs.h"